Skip to content

Commit 7960a9a

Browse files
author
James Boulton
committed
fix bugs, and advertise on ipv6 too if exists.
1 parent 7e97eab commit 7960a9a

File tree

5 files changed

+83
-41
lines changed

5 files changed

+83
-41
lines changed

dashio/device.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ def _on_command(self, data):
125125
if rx_device_id != self.device_id:
126126
return ""
127127
try:
128-
cntrl_type = data_array[1]
128+
ctrl_type = data_array[1]
129129
except KeyError:
130130
return ""
131-
if cntrl_type in self._device_commands_dict:
132-
return self._device_commands_dict[cntrl_type](data_array)
131+
if ctrl_type in self._device_commands_dict:
132+
return self._device_commands_dict[ctrl_type](data_array)
133133
try:
134-
reply = self.controls_dict[cntrl_type + "\t" + data_array[2]]._message_rx_event(data_array)
134+
reply = self.controls_dict[ctrl_type + "\t" + data_array[2]]._message_rx_event(data_array)
135135
if reply:
136136
return reply.replace("{device_id}", self.device_id)
137137
except (KeyError, IndexError):
@@ -159,14 +159,14 @@ def _make_cfg64(self, data):
159159
cfg = {}
160160
cfg["CFG"] = self._cfg
161161
for control in self.controls_dict.values():
162-
if control.cntrl_type == "ALM":
162+
if control.ctrl_type == "ALM":
163163
continue
164-
if control.cntrl_type in ("BLE"):
165-
cfg[control.cntrl_type] = control.get_cfg64(data)
164+
if control.ctrl_type in ("BLE"):
165+
cfg[control.ctrl_type] = control.get_cfg64(data)
166166
continue
167-
if control.cntrl_type not in cfg:
168-
cfg[control.cntrl_type] = []
169-
cfg[control.cntrl_type].extend(control.get_cfg64(data))
167+
if control.ctrl_type not in cfg:
168+
cfg[control.ctrl_type] = []
169+
cfg[control.ctrl_type].extend(control.get_cfg64(data))
170170
c64_json = encode_cfg64(cfg)
171171
reply += c64_json + "\n"
172172
return reply
@@ -180,9 +180,9 @@ def _make_cfg(self, data):
180180
reply = self._device_id_str + f"\tCFG\t{dashboard_id}\tDVCE\t{json.dumps(self._cfg)}\n"
181181
dvvw_str = ""
182182
for control in self.controls_dict.values():
183-
if control.cntrl_type == "ALM":
183+
if control.ctrl_type == "ALM":
184184
continue
185-
if control.cntrl_type == "DVVW":
185+
if control.ctrl_type == "DVVW":
186186
cfg_list = control.get_cfg(data)
187187
for cfg in cfg_list:
188188
dvvw_str += self._device_id_str + cfg
@@ -273,7 +273,7 @@ def add_control(self, iot_control):
273273
iot_control.add_transmit_message_callback(self._send_data)
274274
except AttributeError:
275275
pass
276-
key = f"{iot_control.cntrl_type}\t{iot_control.control_id}"
276+
key = f"{iot_control.ctrl_type}\t{iot_control.control_id}"
277277

278278
if key not in self.controls_dict:
279279
if isinstance(iot_control, DeviceView):
@@ -309,7 +309,7 @@ def remove_control(self, iot_control):
309309
"""
310310
if isinstance(iot_control, DeviceView):
311311
self._cfg["numDeviceViews"] -= 1
312-
key = f"{iot_control.cntrl_type}\t{iot_control.control_id}"
312+
key = f"{iot_control.ctrl_type}\t{iot_control.control_id}"
313313
if key in self.controls_dict:
314314
del self.controls_dict[key]
315315

dashio/ip.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,32 @@ def get_local_ip_v4_address():
3232
test_s.connect(('10.255.255.255', 1))
3333
i_address = test_s.getsockname()[0]
3434
except socket.error:
35-
i_address = '127.0.0.1'
35+
i_address = ''
3636
finally:
3737
test_s.close()
3838
return i_address
3939

4040

4141
def get_local_ip_v6_address():
4242
"""Find the external IP address."""
43-
i_address = socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET6)[1][4][0]
43+
test_s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
44+
try:
45+
# doesn't even have to be reachable
46+
test_s.connect(('google.com', 8888))
47+
i_address = test_s.getsockname()[0]
48+
except socket.error:
49+
return ''
4450
return i_address
4551

4652

53+
def get_local_ip_addresses():
54+
"""Retrieve local IPv4 and IPv6 addresses."""
55+
ipv4 = get_local_ip_v4_address()
56+
ipv6 = get_local_ip_v6_address()
57+
return ipv4, ipv6
58+
59+
4760
def is_port_in_use(ip_address, port):
61+
"Checks if port is in use"
4862
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as port_s:
4963
return port_s.connect_ex((ip_address, port)) == 0

dashio/load_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def encode_cfg64(cfg: dict) -> str:
123123
str: the cfg encoded as C64 format
124124
"""
125125
cfg_json = json.dumps(cfg)
126-
compress = zlib.compressobj(9, zlib.DEFLATED, -9, zlib.DEF_MEM_LEVEL, zlib.Z_DEFAULT_STRATEGY)
126+
compress = zlib.compressobj(9, zlib.DEFLATED, -15, zlib.DEF_MEM_LEVEL, zlib.Z_DEFAULT_STRATEGY)
127127
tmp_z = compress.compress(cfg_json.encode())
128128
tmp_z += compress.flush()
129129
return base64.b64encode(tmp_z).decode()

dashio/tcp_connection.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,15 @@ def __init__(self, ip_address="*", port=5650, use_zero_conf=True, context: zmq.C
8585
self.b_zmq_connection_uuid = self.zmq_connection_uuid.encode('utf-8')
8686
self.use_zeroconf = use_zero_conf
8787

88+
self.local_ipv4 = ''
89+
self.local_ipv6 = ''
8890
if ip_address == "*":
89-
self.local_ip = ip.get_local_ip_v4_address()
91+
self.local_ipv4 = ip.get_local_ip_v4_address()
92+
self.local_ipv6 = ip.get_local_ip_v6_address()
9093
else:
91-
self.local_ip = ip_address
94+
self.local_ipv4 = ip_address
9295
self.local_port = port
93-
while ip.is_port_in_use(self.local_ip, self.local_port) and use_zero_conf:
96+
while ip.is_port_in_use(self.local_ipv4, self.local_port) and use_zero_conf:
9497
# increment port until we find one that is free.
9598
self.local_port += 1
9699
self.ext_url = "tcp://*:" + str(self.local_port)
@@ -111,7 +114,7 @@ def __init__(self, ip_address="*", port=5650, use_zero_conf=True, context: zmq.C
111114
self.tx_zmq_pub.bind(CONNECTION_PUB_URL.format(id=self.zmq_connection_uuid))
112115

113116
if self.use_zeroconf:
114-
self.z_conf = ZeroconfService(self.zmq_connection_uuid, self.local_ip, self.local_port, self.context)
117+
self.z_conf = ZeroconfService(self.zmq_connection_uuid, self.local_ipv4, self.local_ipv6, self.local_port, self.context)
115118

116119
self.start()
117120

dashio/zeroconf_service.py

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,27 @@ def _zconf_update_zmq(self):
112112
'connectionUUID': self.connection_uuid,
113113
'deviceID': ','.join(self.device_id_list)
114114
}
115-
zconf_info = ServiceInfo(
116-
self.fully_qualified_name,
117-
f"{self.connection_uuid}._DashIO._tcp.local.",
118-
addresses=[socket.inet_aton(self.local_ip_address)],
119-
port=self.local_port,
120-
properties=zconf_desc,
121-
server=self.host_name + ".",
122-
)
123-
self.zeroconf.update_service(zconf_info)
115+
if self.local_ipv4_address:
116+
zconf_ipv4_info = ServiceInfo(
117+
self.fully_qualified_name,
118+
f"{self.connection_uuid}._DashIO._tcp.local.",
119+
addresses=[socket.inet_aton(self.local_ipv4_address)],
120+
port=self.local_port,
121+
properties=zconf_desc,
122+
server=self.host_name + ".",
123+
)
124+
self.zeroconf.update_service(zconf_ipv4_info)
125+
126+
if self.local_ipv6_address:
127+
zconf_ipv6_info = ServiceInfo(
128+
self.fully_qualified_name,
129+
f"{self.connection_uuid}._DashIO._tcp.local.",
130+
addresses=[socket.inet_pton(socket.AF_INET6, self.local_ipv6_address)],
131+
port=self.local_port,
132+
properties=zconf_desc,
133+
server=self.host_name + ".",
134+
)
135+
self.zeroconf.update_service(zconf_ipv6_info)
124136

125137
def add_device(self, device_id):
126138
"""Add a device_id to the advertiser"""
@@ -139,7 +151,7 @@ def close(self):
139151
self.zeroconf.unregister_all_services()
140152
self.zeroconf.close()
141153

142-
def __init__(self, connection_uuid: str, ip_address: str, port: int, context: zmq.Context | None = None):
154+
def __init__(self, connection_uuid: str, ipv4_address: str, ipv6_address: str, port: int, context: zmq.Context | None = None):
143155
threading.Thread.__init__(self, daemon=True)
144156
self.context = context or zmq.Context.instance()
145157
self.connection_uuid = connection_uuid
@@ -148,7 +160,8 @@ def __init__(self, connection_uuid: str, ip_address: str, port: int, context: zm
148160
host_list = host_name.split(".")
149161
# rename for .local mDNS advertising
150162
self.host_name = f"{host_list[0]}.local"
151-
self.local_ip_address = ip_address
163+
self.local_ipv4_address = ipv4_address
164+
self.local_ipv6_address = ipv6_address
152165
self.local_port = port
153166
self.zeroconf = Zeroconf()
154167
self.listener = ZeroConfDashTCPListener(self.fully_qualified_name, self.connection_uuid, self.context)
@@ -161,12 +174,24 @@ def run(self):
161174
'connectionUUID': self.connection_uuid,
162175
'deviceID': ','.join(self.device_id_list)
163176
}
164-
zconf_info = ServiceInfo(
165-
self.fully_qualified_name,
166-
f"{self.connection_uuid}._DashIO._tcp.local.",
167-
addresses=[socket.inet_aton(self.local_ip_address)],
168-
port=self.local_port,
169-
properties=zconf_desc,
170-
server=self.host_name + ".",
171-
)
172-
self.zeroconf.update_service(zconf_info)
177+
if self.local_ipv4_address:
178+
zconf_ipv4_info = ServiceInfo(
179+
self.fully_qualified_name,
180+
f"{self.connection_uuid}._DashIO._tcp.local.",
181+
addresses=[socket.inet_aton(self.local_ipv4_address)],
182+
port=self.local_port,
183+
properties=zconf_desc,
184+
server=self.host_name + ".",
185+
)
186+
self.zeroconf.update_service(zconf_ipv4_info)
187+
188+
if self.local_ipv6_address:
189+
zconf_ipv6_info = ServiceInfo(
190+
self.fully_qualified_name,
191+
f"{self.connection_uuid}._DashIO._tcp.local.",
192+
addresses=[socket.inet_pton(socket.AF_INET6, self.local_ipv6_address)],
193+
port=self.local_port,
194+
properties=zconf_desc,
195+
server=self.host_name + ".",
196+
)
197+
self.zeroconf.update_service(zconf_ipv6_info)

0 commit comments

Comments
 (0)