-
Notifications
You must be signed in to change notification settings - Fork 4
/
mdns.py
159 lines (141 loc) · 5.84 KB
/
mdns.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# -*- coding: utf-8 -*-
"""
This module is dedicated to MDNS
class:
mDNS_BrowserThread(Used to continuously check mDNS)
"""
import time
from zeroconf import ServiceBrowser, Zeroconf
from PySide2.QtCore import *
class mDNS_BrowserThread(QThread):
"""
This is a QT thread that gets the MDNS information and sends it to the UI thread via the get_sub_new signal.
"""
get_sub_new = Signal(str)
def __init__(self, parent=None, **func_task):
super(mDNS_BrowserThread, self).__init__(parent)
self.ID_list = []
self.zeroconf = Zeroconf()
self.listener = MyListener()
def __def__(self):
self.wait()
def run(self):
"""
The data of the searched device is refreshed every second,
and each update is converted into a string and sent to the interface(name ip port data)
"""
print("mDNS_BrowserThread start !")
browser = ServiceBrowser(
self.zeroconf,
"_ewelink._tcp.local.",
listener=self.listener)
while True:
if self.listener.all_sub_num > 0:
# Copy from the listener's dictionary to the current file
dict = self.listener.all_info_dict.copy()
for x in dict.keys():
# print("new updata ID:",x[8:18])
info = dict[x]
info = self.zeroconf.get_service_info(info.type, x)
print("updata", x, "info", "len", len(str(info)), info)
if info is not None:
data = info.properties
cur_str = x[8:18] + "\n" + self.parseAddress(
info.address) + "\n" + str(info.port) + "\n" + str(data)
self.get_sub_new.emit(cur_str)
# Send deleted devices
if len(self.listener.all_del_sub) > 0:
for x in self.listener.all_del_sub:
cur_str = x[8:18] + "\nDEL"
self.get_sub_new.emit(cur_str)
time.sleep(0.5)
def parseAddress(self, address):
"""
Resolve the IP address of the device
:param address:
:return: add_str
"""
add_list = []
for i in range(4):
add_list.append(int(address.hex()[(i * 2):(i + 1) * 2], 16))
add_str = str(add_list[0]) + "." + str(add_list[1]) + \
"." + str(add_list[2]) + "." + str(add_list[3])
return add_str
class MyListener(object):
"""
This class is used for the mDNS browsing discovery device, including calling the remove_service and add_service
properties to ServiceBrowser, and also contains broadcasts for querying and updating existing devices.
Dictionary
all_info_dict:Qualified device information in the current network [keys:info.name,val:info]
"""
def __init__(self):
self.all_del_sub = []
self.all_info_dict = {}
self.all_sub_num = 0
self.new_sub = False
def remove_service(self, zeroconf, type, name):
"""
This function is called for ServiceBrowser.
This function is triggered when ServiceBrowser discovers that some device has logged out
"""
print("inter remove_service()")
if name not in self.all_info_dict:
return
self.all_sub_num -= 1
del self.all_info_dict[name]
self.all_del_sub.append(name)
print("self.all_info_dict[name]", self.all_info_dict)
print("Service %s removed" % (name))
def add_service(self, zeroconf, type, name):
"""
This function is called for ServiceBrowser.This function is triggered when ServiceBrowser finds a new device
When a subdevice is found, the device information is stored into the all_info_dict
"""
self.new_sub = True
print("inter add_service()")
self.all_sub_num += 1
info = zeroconf.get_service_info(type, name)
if info.properties[b'type'] == b'diy_plug':
self.all_info_dict[name] = info
if name in self.all_del_sub:
self.all_del_sub.remove(name)
print("Service %s added, service info: %s" % (name, info))
def flash_all_sub_info(self,):
"""
Update all found subdevice information
"""
info_list = list(self.all_info_dict.keys())
for x in info_list:
current_info = all_info_dict[x]
name = current_info["name"]
type = current_info["type"]
info = zeroconf.get_service_info(type=type, name=name)
current_info["info"] = info
self.all_info_dict[x] = current_info["info"]
def main():
zeroconf = Zeroconf()
listener = MyListener()
browser = ServiceBrowser(zeroconf, "_ewelink._tcp.local.",listener= listener)
while True:
if listener.all_sub_num>0:
dict=listener.all_info_dict.copy()
for x in dict.keys():
info=dict[x]
info=zeroconf.get_service_info(info.type,x)
if info!= None:
data=info.properties
cur_str=x[8:18]+" "+parseAddress(info.address)+" "+str(info.port)+" " +str(data)
print(cur_str)
if len(listener.all_del_sub)>0:
for x in listener.all_del_sub:
cur_str=x[8:18]+"\nDEL"
print(cur_str)
time.sleep(0.5)
def parseAddress(address):
add_list = []
for i in range(4):
add_list.append(int(address.hex()[(i*2):(i+1)*2], 16))
add_str = str(add_list[0]) + "." + str(add_list[1]) + "." + str(add_list[2])+ "." + str(add_list[3])
return add_str
if __name__ == "__main__":
main()