Skip to content

Commit 870a042

Browse files
committed
Make PyStageLinQ listen to broadcasts on all interfaces
The patch also updates the local IP detection method, as it did not work on Linux. This also added the psutils as a dependency. Solves #47
1 parent 6e95559 commit 870a042

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed

PyStageLinQ/PyStageLinQ.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import time
99
import asyncio
1010
import logging
11+
import psutil
1112
from typing import Callable
1213

1314
from . import Device
@@ -63,11 +64,13 @@ def __init__(
6364

6465
self.device_list = Device.DeviceList()
6566

67+
self.ip = []
6668
if ip is None:
67-
interfaces = socket.getaddrinfo(
68-
host=socket.gethostname(), port=None, family=socket.AF_INET
69-
)
70-
self.ip = [ip[-1][0] for ip in interfaces]
69+
interfaces = psutil.net_if_addrs()
70+
for interface in interfaces.items():
71+
for interface_address in interface[1]:
72+
if socket.AF_INET == interface_address.family:
73+
self.ip.append(interface_address.address)
7174

7275
else:
7376
self.ip = [ip]
@@ -155,7 +158,7 @@ async def _discover_stagelinq_device(self, host_ip, timeout=10):
155158
discover_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
156159
try:
157160
discover_socket.bind(
158-
(host_ip, self.StageLinQ_discovery_port)
161+
("255.255.255.255", self.StageLinQ_discovery_port)
159162
) # bind socket StageLinQ interface
160163
except:
161164
# Cannot bind to socket, check if IP is correct and link is up

changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
Here follows a log of released versions of PyStageLinQ.
33

44
## [0.2.2]
5+
### Fixed
6+
Problems on Linux should now be solved.
7+
PyStageLinQ will now listen to address "255.255.255.255" on all interfaces, and transmit discovery frames on either the
8+
interface specified by `PyStageLinQ(..., ip=)` or on all interfaces if `ip` is not set.
9+
510
### Added
611
More logging output in PyStageLinQ.py.
712

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ keywords = ["StageLinQ", "DJ", "VJ", "Denon DJ", "Prime Go", "Streaming"]
2121

2222
version = "0.0.0"
2323

24+
dependencies = [
25+
"psutil",
26+
]
27+
2428
[project.urls]
2529
"Homepage" = "https://github.com/Jaxc/PyStageLinQ"
2630
"Bug Tracker" = "https://github.com/Jaxc/PyStageLinQ/issues"

test_requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pytest==8.3.2
22
pytest-cov==5.0.0
3-
pytest-asyncio==0.23.8
3+
pytest-asyncio==0.23.8
4+
psutil==6.1.0

tests/unit/test_unit_PyStageLinQ.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from PyStageLinQ.ErrorCodes import *
44
from unittest.mock import AsyncMock, Mock, MagicMock
55
from unittest import mock
6+
from socket import AF_INET
67

78
import random
89

@@ -77,13 +78,26 @@ def test_init_values(dummy_pystagelinq, dummy_ip):
7778

7879

7980
def test_init_values_ip_none(monkeypatch, dummy_socket):
80-
dummy_ips = [[["1,2,3,4"]], [["5.6.7.8"]]]
81-
dummy_socket.getaddrinfo.return_value = dummy_ips
82-
monkeypatch.setattr(PyStageLinQ.PyStageLinQ, "socket", dummy_socket)
81+
class ifutils_net_if_addrs:
82+
def __init__(self, ip=[]):
83+
self.address = ip
84+
self.family = AF_INET
85+
86+
dummy_psutil = MagicMock()
87+
dummy_ips = {
88+
"interface1": [ifutils_net_if_addrs(ip="1.2.3.4")],
89+
"interface2": [ifutils_net_if_addrs(ip="5.6.7.8")],
90+
"interface3": [ifutils_net_if_addrs(ip="9.10.11.12")],
91+
}
92+
93+
dummy_ips["interface3"][0].family = None
94+
95+
dummy_psutil.net_if_addrs.return_value = dummy_ips
96+
monkeypatch.setattr(PyStageLinQ.PyStageLinQ, "psutil", dummy_psutil)
8397

8498
dummy_pystagelinq = PyStageLinQ.PyStageLinQ.PyStageLinQ(None, ip=None)
8599

86-
assert dummy_pystagelinq.ip == [dummy_ips[0][0][0], dummy_ips[1][0][0]]
100+
assert dummy_pystagelinq.ip == ["1.2.3.4", "5.6.7.8"]
87101

88102

89103
def test_start_standalone(dummy_pystagelinq, monkeypatch):
@@ -243,7 +257,7 @@ async def test_discover_stagelinq_check_initialization(
243257
dummy_socket.AF_INET, dummy_socket.SOCK_DGRAM
244258
)
245259
dummy_socket.socket.return_value.bind.assert_called_once_with(
246-
(dummy_pystagelinq.ip[0], dummy_pystagelinq.StageLinQ_discovery_port)
260+
("255.255.255.255", dummy_pystagelinq.StageLinQ_discovery_port)
247261
)
248262
dummy_socket.socket.return_value.setblocking.assert_called_once_with(False)
249263

0 commit comments

Comments
 (0)