33
44import binascii
55import logging
6- from multiprocessing import Manager , Process
6+ import threading
77import time
88
99import bluepy
3131PRESS_KEY_SUFFIX = "00"
3232
3333_LOGGER = logging .getLogger (__name__ )
34+ CONNECT_LOCK = threading .Lock ()
3435
3536
3637def _process_wohand (data ) -> dict :
@@ -93,34 +94,6 @@ def _process_wosensorth(data) -> dict:
9394 return _wosensorth_data
9495
9596
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-
12497class GetSwitchbotDevices :
12598 """Scan for all Switchbot devices and return by type."""
12699
@@ -137,9 +110,7 @@ def discover(
137110 devices = None
138111
139112 try :
140- devices = BLEScanner (
141- scan_timeout = scan_timeout , interface = self ._interface
142- ).start ()
113+ devices = bluepy .btle .Scanner (self ._interface ).scan (scan_timeout )
143114
144115 except bluepy .btle .BTLEManagementError :
145116 _LOGGER .error ("Error scanning for switchbot devices" , exc_info = True )
@@ -165,7 +136,7 @@ def discover(
165136 self ._all_services_data [dev_id ]["mac_address" ] = dev .addr
166137 for (adtype , desc , value ) in dev .getScanData ():
167138 if adtype == 22 :
168- _model = binascii .unhexlify (value [ 4 : 6 ]). decode ( )
139+ _model = chr ( binascii .unhexlify (value . encode ())[ 2 ] & 0b01111111 )
169140 if _model == "H" :
170141 self ._all_services_data [dev_id ]["data" ] = _process_wohand (
171142 value [4 :]
@@ -229,7 +200,7 @@ def get_device_data(self, mac) -> dict | None:
229200 _switchbot_data = {}
230201
231202 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 :
233204 _switchbot_data = self ._all_services_data [item ]
234205
235206 return _switchbot_data
@@ -241,7 +212,7 @@ class SwitchbotDevice:
241212 def __init__ (self , mac , password = None , interface = None , ** kwargs ) -> None :
242213 """Switchbot base class constructor."""
243214 self ._interface = interface
244- self ._mac = mac . replace ( "-" , ":" ). lower ()
215+ self ._mac = mac
245216 self ._device = None
246217 self ._switchbot_device_data = {}
247218 self ._scan_timeout = kwargs .pop ("scan_timeout" , DEFAULT_SCAN_TIMEOUT )
@@ -307,13 +278,14 @@ def _sendcommand(self, key, retry) -> bool:
307278 send_success = False
308279 command = self ._commandkey (key )
309280 _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 ()
317289 if send_success :
318290 return True
319291 if retry < 1 :
@@ -345,9 +317,7 @@ def get_device_data(self, retry=DEFAULT_RETRY_COUNT, interface=None) -> dict | N
345317 devices = None
346318
347319 try :
348- devices = BLEScanner (
349- scan_timeout = self ._scan_timeout , interface = _interface
350- ).start ()
320+ devices = bluepy .btle .Scanner (_interface ).scan (self ._scan_timeout )
351321
352322 except bluepy .btle .BTLEManagementError :
353323 _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
371341 self ._switchbot_device_data ["mac_address" ] = dev .addr
372342 for (adtype , desc , value ) in dev .getScanData ():
373343 if adtype == 22 :
374- _model = binascii .unhexlify (value [ 4 : 6 ]). decode ( )
344+ _model = chr ( binascii .unhexlify (value . encode ())[ 2 ] & 0b01111111 )
375345 if _model == "H" :
376346 self ._switchbot_device_data ["data" ] = _process_wohand (
377347 value [4 :]
0 commit comments