3
3
4
4
import binascii
5
5
import logging
6
- from multiprocessing import Manager , Process
6
+ import threading
7
7
import time
8
8
9
9
import bluepy
31
31
PRESS_KEY_SUFFIX = "00"
32
32
33
33
_LOGGER = logging .getLogger (__name__ )
34
+ CONNECT_LOCK = threading .Lock ()
34
35
35
36
36
37
def _process_wohand (data ) -> dict :
@@ -93,34 +94,6 @@ def _process_wosensorth(data) -> dict:
93
94
return _wosensorth_data
94
95
95
96
96
- class BLEScanner :
97
- """Helper for bluepy device scanning."""
98
-
99
- def __init__ (self , scan_timeout = DEFAULT_SCAN_TIMEOUT , interface = None ) -> None :
100
- """Init class constructor."""
101
- self ._scan_timeout = scan_timeout
102
- self ._interface = interface
103
- self ._devices = None
104
-
105
- def start (self ) -> dict | None :
106
- """Start scan in seperate process."""
107
- with Manager () as manager :
108
- _devices = manager .dict ()
109
- process = Process (target = self ._scan , args = (_devices ,))
110
- process .start ()
111
- process .join ()
112
-
113
- return _devices .get (0 , None )
114
-
115
- def _scan (self , devices ) -> dict | None :
116
- """Scan for advertisement data."""
117
- try :
118
- devices [0 ] = bluepy .btle .Scanner (self ._interface ).scan (self ._scan_timeout )
119
-
120
- except bluepy .btle .BTLEDisconnectError :
121
- pass
122
-
123
-
124
97
class GetSwitchbotDevices :
125
98
"""Scan for all Switchbot devices and return by type."""
126
99
@@ -137,9 +110,7 @@ def discover(
137
110
devices = None
138
111
139
112
try :
140
- devices = BLEScanner (
141
- scan_timeout = scan_timeout , interface = self ._interface
142
- ).start ()
113
+ devices = bluepy .btle .Scanner (self ._interface ).scan (scan_timeout )
143
114
144
115
except bluepy .btle .BTLEManagementError :
145
116
_LOGGER .error ("Error scanning for switchbot devices" , exc_info = True )
@@ -165,7 +136,7 @@ def discover(
165
136
self ._all_services_data [dev_id ]["mac_address" ] = dev .addr
166
137
for (adtype , desc , value ) in dev .getScanData ():
167
138
if adtype == 22 :
168
- _model = binascii .unhexlify (value [ 4 : 6 ]). decode ( )
139
+ _model = chr ( binascii .unhexlify (value . encode ())[ 2 ] & 0b01111111 )
169
140
if _model == "H" :
170
141
self ._all_services_data [dev_id ]["data" ] = _process_wohand (
171
142
value [4 :]
@@ -229,7 +200,7 @@ def get_device_data(self, mac) -> dict | None:
229
200
_switchbot_data = {}
230
201
231
202
for item in self ._all_services_data :
232
- if self ._all_services_data [item ]["mac_address" ] == mac . replace ( "-" , ":" ). lower () :
203
+ if self ._all_services_data [item ]["mac_address" ] == mac :
233
204
_switchbot_data = self ._all_services_data [item ]
234
205
235
206
return _switchbot_data
@@ -241,7 +212,7 @@ class SwitchbotDevice:
241
212
def __init__ (self , mac , password = None , interface = None , ** kwargs ) -> None :
242
213
"""Switchbot base class constructor."""
243
214
self ._interface = interface
244
- self ._mac = mac . replace ( "-" , ":" ). lower ()
215
+ self ._mac = mac
245
216
self ._device = None
246
217
self ._switchbot_device_data = {}
247
218
self ._scan_timeout = kwargs .pop ("scan_timeout" , DEFAULT_SCAN_TIMEOUT )
@@ -307,13 +278,14 @@ def _sendcommand(self, key, retry) -> bool:
307
278
send_success = False
308
279
command = self ._commandkey (key )
309
280
_LOGGER .debug ("Sending command to switchbot %s" , command )
310
- try :
311
- self ._connect ()
312
- send_success = self ._writekey (command )
313
- except bluepy .btle .BTLEException :
314
- _LOGGER .warning ("Error talking to Switchbot" , exc_info = True )
315
- finally :
316
- self ._disconnect ()
281
+ with CONNECT_LOCK :
282
+ try :
283
+ self ._connect ()
284
+ send_success = self ._writekey (command )
285
+ except bluepy .btle .BTLEException :
286
+ _LOGGER .warning ("Error talking to Switchbot" , exc_info = True )
287
+ finally :
288
+ self ._disconnect ()
317
289
if send_success :
318
290
return True
319
291
if retry < 1 :
@@ -345,9 +317,7 @@ def get_device_data(self, retry=DEFAULT_RETRY_COUNT, interface=None) -> dict | N
345
317
devices = None
346
318
347
319
try :
348
- devices = BLEScanner (
349
- scan_timeout = self ._scan_timeout , interface = _interface
350
- ).start ()
320
+ devices = bluepy .btle .Scanner (_interface ).scan (self ._scan_timeout )
351
321
352
322
except bluepy .btle .BTLEManagementError :
353
323
_LOGGER .error ("Error scanning for switchbot devices" , exc_info = True )
@@ -371,7 +341,7 @@ def get_device_data(self, retry=DEFAULT_RETRY_COUNT, interface=None) -> dict | N
371
341
self ._switchbot_device_data ["mac_address" ] = dev .addr
372
342
for (adtype , desc , value ) in dev .getScanData ():
373
343
if adtype == 22 :
374
- _model = binascii .unhexlify (value [ 4 : 6 ]). decode ( )
344
+ _model = chr ( binascii .unhexlify (value . encode ())[ 2 ] & 0b01111111 )
375
345
if _model == "H" :
376
346
self ._switchbot_device_data ["data" ] = _process_wohand (
377
347
value [4 :]
0 commit comments