Skip to content

Commit be7f57f

Browse files
committed
Got device discovery working
1 parent 8f43ffd commit be7f57f

2 files changed

Lines changed: 94 additions & 10 deletions

File tree

lib/device.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import socket
2+
3+
PH803W_DEFAULT_TCP_PORT = 12416
4+
PH803W_PING_INTERVAL = 4000
5+
RECONNECT_DELAY = 10000
6+
RESPONSE_TIMEOUT = 5000
7+
8+
9+
class Device(object):
10+
def __init__(self):
11+
#self.result = {}
12+
13+
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
14+
# Enable broadcasting mode
15+
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
16+
# Set a timeout so the socket does not block
17+
# indefinitely when trying to receive data.
18+
self.socket.settimeout(1)

lib/discovery.py

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,81 @@
1-
include socket
1+
import socket
22

3-
class Discover:
3+
PH803W_UDP_PORT = 12414
4+
5+
6+
class Discovery(object):
47
def __init__(self):
5-
print('Init')
6-
pass
8+
self.result = {}
9+
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
10+
# Enable broadcasting mode
11+
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
12+
# Set a timeout so the socket does not block
13+
# indefinitely when trying to receive data.
14+
self.socket.settimeout(1)
15+
16+
def run(self):
17+
data = bytes.fromhex('0000000303000003')
18+
self.socket.sendto(data, ('<broadcast>', PH803W_UDP_PORT))
19+
print("Sent request message!")
20+
21+
data, remote = self.socket.recvfrom(2048)
22+
23+
if data[0] != 0 and data[1] != 0 and data[2] != 0 and data[2] != 3:
24+
print('Ignore data package because invalid prefix: %s' % data[0:3])
25+
self.result['status'] = ['Error', 'Ignore data package because invalid prefix']
26+
return
27+
data_length = data[4]
28+
if len(data) != data_length + 5:
29+
print('Ignore data package because invalid length(%s): %s' % (data_length, data))
30+
self.result['status'] = ['Error', 'Ignore data package because invalid length']
31+
return
32+
if data[7] == 3:
33+
self.result['status'] = ['Unknown']
34+
return
35+
if data[7] != 4:
36+
print('Ignore data package because invalid message type ${data[7]}')
37+
self.result['status'] = ['Error', 'Ignore data package because invalid message type']
38+
return
39+
40+
print('Parsing discovered device: %s: %s - %s' % (remote[0], remote[1], data[7:]))
41+
self.result['status'] = ['Error'] # Temporary until all pass
42+
self.result['result'] = {}
43+
44+
id1_length = data[9]
45+
id1_raw = data[10 : 10 + id1_length]
46+
self.result['result']['id1'] = id1_raw.decode("utf-8")
47+
48+
id2_length = data[9 + id1_length + 12]
49+
id2_raw = data[9 + id1_length + 13 : 9 + id1_length + 13 + id2_length]
50+
self.result['result']['id2'] = id2_raw.decode("utf-8")
51+
52+
idx = 9 + id1_length + 13 + id2_length + 8
53+
idx_start = idx
54+
while data[idx] != 0:
55+
idx += 1
56+
api_server_raw = data[idx_start: idx]
57+
self.result['result']['api_server'] = api_server_raw.decode("utf-8")
58+
59+
idx += 1
60+
61+
idx_start = idx
62+
while data[idx] != 0:
63+
idx += 1
64+
version_raw = data[idx_start: idx]
65+
self.result['result']['version_server'] = version_raw.decode("utf-8")
66+
67+
self.result['status'] = ['success']
68+
69+
def get_result(self):
70+
return str(self.result)
771

8-
def run():
9-
print('Running')
10-
pass
72+
def __enter__(self):
73+
self.run()
74+
return self
1175

76+
def __exit__(self, type, value, traceback):
77+
self.socket.close()
1278

13-
if __name__ == __main__:
14-
discover = Discover()
15-
discover.run()
79+
if __name__ == '__main__':
80+
with Discovery() as d:
81+
print(d.get_result())

0 commit comments

Comments
 (0)