def COLLECTOR(timeout): global runthegame global pmdata global playermonitor global stopmeplease scanner = Scanner().withDelegate(ScanDelegate()) while True: if runthegame: # 0: rawrssi 1:timestamp 2:lastresult 3: ? 4: item counter 5: KalmanRssi 6:KalmanTime pmdata = [ [0, [[], [], 0, 0, 0, [], []]], [1, [[], [], 0, 0, 0, [], []]], [2, [[], [], 0, 0, 0, [], []]], [3, [[], [], 0, 0, 0, [], []]], [4, [[], [], 0, 0, 0, [], []]], ] playermonitor = [] scanner.clear() scanner.start(passive=True) while runthegame: most = timer() scanner.process(0.1) if stopmeplease == True: runthegame = False scanner.stop() time.sleep(0.01)
def run(self): while not self.stop_event.wait(2): if not self.scanDelegate.identify_queue.empty(): #check for pending identify command delegate = self.scanDelegate.identify_queue.get() time_wait = .25 cnt = int(delegate.identify_timeout/time_wait) logger.debug('identifying: cnt=' + str(cnt) +', timeout = ' + str(delegate.identify_timeout)) cmd = '{:02x}'.format(tb_protocol.TB_COMMAND_IDENTIFY) for i in range(cnt): f, data = btle_sendcmd(delegate.target_mac, cmd) if f: delegate.identified = True delegate.stop_event.set() #logger.debug('identify succeeded ' + data.hex()) logger.debug('identify succeeded ') break if delegate.stop_event.wait(time_wait): break self.scanDelegate.identify_queue.task_done() scanner = Scanner().withDelegate(self.scanDelegate) try: scanner.clear() scanner.start() scanner.process(10) scanner.stop() except Exception as exc: logger.debug('Exception > ' + str(exc)) pass logger.debug('ScannerThread: exit')
def scan(match=None, duration=5, just_one=False, match_scan_entry=False): """This looks through any advertising btle devices for matching ones. *** Note you must run this as root *** match(scan_data) should return True if scan_data is from the device you're looking for. If no match function is provided, it is treated as always returning True (you want to see all devices that respond within duration). scan_data is a dict mapping description to value, unless match_scan_entry is True in which case scan_data is a btle ScanEntry object. Duration is how many seconds to scan before returning. If just_one is False, scans for the full duration and then returns a list of matching ScanEntry objects. (https://ianharvey.github.io/bluepy-doc/scanentry.html) If just_one is True, this returns the first match immediately (no list) or None after full duration timeout. Note (match==None and just_one==True) results in just the first device to respond being immediately returned. """ scanner = Scanner().withDelegate(DefaultDelegate()) scanner.clear() scanner.start() if not just_one: found = [] try: for i in range(max(int(duration * 10), 1)): # Break duration into 10ths scanner.process( 0.1) # Handle incoming messages for 1/10th of a second... devices = scanner.getDevices() for dev in devices: if debug: BtleDevice.dump_scan_entry(dev) if match_scan_entry: params = dev else: params = { name: val for tag, name, val in dev.getScanData() } if match is None or match(params): if just_one: return dev else: found.append(dev) scanner.clear() finally: scanner.stop() if just_one: return None return found
def status(mac_address): print('Looking for switchmate status...') sys.stdout.flush() scanner = Scanner().withDelegate(ScanDelegate(mac_address)) scanner.clear() scanner.start() scanner.process(5) scanner.stop()
def run(self): while True: # Do something print('Starting Scan Process') scanner = Scanner(int(os.environ['SCAN_HCI'])).withDelegate( ScanDelegate()) scanner.clear() scanner.start() scanner.process(5) scanner.stop() time.sleep(self.interval)
class BadgeBTLE(): def __init__(self, manufacturer=None, appearance=None, scanTimeout=2, fields=[]): """Construct new BadgeBTLE instance. Args: manufacturer: Bluetooth Manufacturer ID [1] to scan for. Default is no filter. appearance: Optional Bluetooth Appearance ID [2] to scan for. If not set, defaults to current or upcoming DEF CON (e.g. 0x26dc). scanTimeout: Timeout for Bluetooth scan. Defaults to 2 seconds. References: [1] https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.manufacturer_name_string.xml [2] https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml """ self.scanner = Scanner() self.scanTimeout = scanTimeout self.manufacturer = manufacturer self.appearance = appearance if appearance else self.__determineAppearance( ) def __determineAppearance(self): year = datetime.now().year dcyear = year - 1992 # Calculate DEF CON year return "dc" + str(dcyear) def scan(self): """Perform Bluetooth scan until timeout and return list of nearby BLE devices with the specificed (or default) Appearance ID. Returns: A list of tuples containing these data points: Appearance ID, Manufacturer ID, Local Name, and Signal strength (RSSI). """ devices = self.scanner.scan(self.scanTimeout) neighbors = [] for dev in devices: appearance = None manufacturer = None localName = None for (adtype, desc, value) in dev.getScanData(): if desc.lower() == "appearance": appearance = value.lower() if desc.lower() == "manufacturer": manufacturer = value[0:4] if desc.lower() == "complete local name": localName = value if appearance == self.appearance and manufacturer is not None: neighbors.append( ScanResult(manufacturer, appearance, localName, dev.rssi, dev.addr)) self.scanner.clear() return neighbors
def run(self): while True: print("Scanning bluetooth devices...") scanner = Scanner() devices = scanner.scan(self.timeout) neighbors = [] for dev in devices: if dev.addr in self.addresses: neighbors.append(Neighbor(dev)) self.onScan(neighbors) scanner.clear() sleep(self.delay)
def main(): logging.basicConfig(filename='logs/' + __file__ + '.log', level=logging.INFO, format='%(message)s') scanner = Scanner(BLE_INTERFACE).withDelegate(ScanDelegate()) try: while True: scanner.start() scanner.process(timeout=5) scanner.stop() scanner.clear() except KeyboardInterrupt: pass
def run(self): while True: # Do something print('Starting Scan Process') items = set() scanner = Scanner(int(os.environ['SCAN_HCI'])).withDelegate( ScanDelegate(items)) scanner.clear() scanner.start() scanner.process(5) scanner.stop() for item in items: readnewFirmware(item) time.sleep(self.interval) sys.exit( ) #If the loop exists because of an error, let the process go down and have docker restart it.
def scan(self): """ Scans for PWS advertisements with the given SSID and returns the first match """ logger.info("Start scanning...") scanner = Scanner().withDelegate(self) scanner.clear() scanner.start(passive=True) while self.result is None: scanner.process(0.1) logger.info(f"SSID match in PWS advertisement from {self.result.addr}") scanner.stop() # return and clear result result = self.result self.result = None return result
def main(): #Scan for Bluetooth devices for 2 seconds scanner = Scanner().withDelegate(ScanDelegate()) scanner.clear() scanner.start() while(True): try: #Open threads to poll data bt_thread = _thread.start_new_thread(scanner.process,(3.0,)) us_thread = _thread.start_new_thread(distance,()) #Sleep for 4 seconds to ensure both threads safely complete time.sleep(4) #Transmit data to server for processing sendData(DEVICE_RSSI,DISTANCE_READ) scanner.clear() except Exception as e: print(e) return
class BLEService(Thread): def __init__(self, q): Thread.__init__(self) self.scanner = Scanner() self.queue = q self.devicesScanned = [] def run(self): print("Starting BLE service...") self.scanner.start() while True: self.devicesScanned.clear() self.scanner.clear() self.scanner.process(5.0) devices = self.scanner.getDevices() self.fillQueue(devices) #if len(self.queue) > 0: #test = self.getFromQueue() #for dev in test: # print("DEV: {}".format(dev.getJson())) # print("_________________________") print( "_____________________Save ble setup, queue size = {}".format( len(self.queue))) delay(3) def fillQueue(self, devices): for d in devices: devDto = BLEDeviceDto(d.addr, d.addrType, d.rssi, d.getScanData()) self.devicesScanned.append(devDto) self.queue.append(self.devicesScanned) def getFromQueue(self): if len(self.queue) is not 0: msg = self.queue.popleft() return msg else: return None
def main(): devices = [] d = ScanDelegate() scanner = Scanner().withDelegate(d) while True: scanner.scan(0.1) if d.dev is not None: net_device = None try: net_device = device(d.dev.getValueText(9), d.dev.addr, d.dev.rssi, d.dev.connectable) if True: # net_device.addr not in devices: SignDevice(net_device) devices.append(net_device.addr) scanner.clear() d.ClearDev() else: print("Device %s already signed upon" % net_device.addr) return except Exception as e: print( "Unable to Connect to Device at address: %s will try again | %s" % (d.dev.addr, d.dev.rssi))
class CentralManager(DefaultDelegate): SCAN_COUNT = 5 SCAN_INTERVAL = 2.0 def __init__(self): DefaultDelegate.__init__(self) self._scanner = Scanner().withDelegate(self) self._lamps = [] self._candidateFound = False self.isConnected = False def scan(self): self.isConnected = False # Clear existing connected lamps for lamp in self._lamps: lamp.disconnect() self._lamps = [] # Scan for new lamps to connect to print("Scanning for devices...") self._candidateFound = False self._scanner.clear() self._scanner.start() for iter in range(0, CentralManager.SCAN_COUNT): self._scanner.process(CentralManager.SCAN_INTERVAL) if (self._candidateFound): print("Candidate found after {} scan(s). Ending early".format( iter + 1)) break self._scanner.stop() scanResult = self._scanner.getDevices() # Connect to any lamps found for device in scanResult: if (Lampi.isLampCandidate(device)): lamp = Lampi(device) lamp.validate() if (lamp.isValid): print("Connected to a lamp with MAC address {}".format( device.addr)) self._lamps.append(lamp) self.isConnected = True else: lamp.disconnect() print("Scan complete") def handleDiscovery(self, device, isNew, _): if isNew and device.connectable: if (Lampi.isLampCandidate(device)): self._candidateFound = True print(" • Candidate found with MAC address {}".format( device.addr)) # Discard any lamps that are no longer connected def pruneLamps(self): for i in range(0, len(self._lamps)): lamp = self._lamps[i] if (not lamp.isConnected()): print("Pruned {}".format(lamp.addr)) self._lamps.pop(i) i -= 1 def toggleOnOff(self): print("Toggling on/off") self.pruneLamps() for lamp in self._lamps: lamp.toggleOnOff() def brightnessUp(self): print("Sending brightness up") self.pruneLamps() for lamp in self._lamps: lamp.brightnessUp() def brightnessDown(self): print("Sending brightness down") self.pruneLamps() for lamp in self._lamps: lamp.brightnessDown() def preset(self, number): print("Starting Preset", str(number)) self.pruneLamps() for lamp in self._lamps: lamp.setPreset(number)
from bluepy.btle import Scanner, DefaultDelegate import Yeelight class ScanDelegate(DefaultDelegate): def __init__(self): DefaultDelegate.__init__(self) def handleDiscovery(self, dev, isNewDev, isNewData): if isNewDev: print "Discovered device", dev.addr elif isNewData: print "Received new data from", dev.addr scanner = Scanner()#.withDelegate(ScanDelegate()) devices = scanner.scan(10.0) for dev in devices: if (dev.addr == "f0:a0:ee:76:4d:68") : print "finded!" Yeelight.set_bright(1, 90) detection_thread = Thread(target=Yeelight.bulbs_detection_loop) detection_thread.start() sleep(0.2) scanner.clear()
class InkbirdUpdater(Entity): entity_id = "inkbird.updater" def __init__(self, hass, inkbird_devices): """Initialize the thermometer.""" Entity.__init__(self) self._name = 'Inkbird Updater' self._state = None self._mac = None self.hass = hass self.scanner = Scanner() self.scanner.clear() self.scanner.start() self.no_results_counter = 0 self.inkbird_devices = inkbird_devices @property def mac(self): """Return the mac of the sensor.""" return self._mac @property def name(self): """Return the name of the sensor.""" return self._name @property def state(self): """Return the state of the sensor.""" return self._state @property def should_poll(self): """Return the name of the sensor.""" _LOGGER.debug("Should_Poll called") return True def update(self): """Get the latest data and use it to update our sensor state.""" _LOGGER.debug("UPDATE called") _LOGGER.debug(f"scanner here is {self.scanner}") # The btle on my raspberry pi 4 seems to go MIA if self.no_results_counter >= 5: _LOGGER.error("Btle went away .. restarting entire btle stack") self.scanner = Scanner() self.scanner.clear() self.scanner.start() self.no_results_counter = 0 try: self.scanner.process(timeout=8.0) except: e = sys.exc_info()[0] _LOGGER.error(f" Exception occoured during scanning: {e}") results = self.scanner.getDevices() _LOGGER.debug(f"got results {results}") for dev in results: self.handleDiscovery(dev) # if we have no results at all, the scanner may have gone MIA. # it happens apparently. So, let's count upto 5 and then, if it # still happens, restart/refresh the btle stack. # any results though will reset the btle 'MIA counter' to 0 if not any(results): self.no_results_counter += 1 else: self.no_results_counter = 0 self.scanner.clear() self._state = [] return True def handleDiscovery(self, dev): _LOGGER.debug(f"Discovered device {dev.addr}") _LOGGER.debug("Device {} ({}), RSSI={} dB".format( dev.addr, dev.addrType, dev.rssi)) for (adtype, desc, value) in dev.getScanData(): _LOGGER.debug("[%s] %s = %s" % (adtype, desc, value)) if adtype == 255: humidity = "%2.2f" % (int(value[6:8] + value[4:6], 16) / 100) #temperature = "%2.2f" % (int(value[2:4]+value[:2], 16)/100) temperature = int(value[2:4] + value[:2], 16) temperature_bits = 16 if temperature & (1 << (temperature_bits - 1)): temperature -= 1 << temperature_bits temperature = "%2.2f" % (temperature / 100) battery = int(value[14:16], 16) _LOGGER.debug(self.inkbird_devices) for device in self.inkbird_devices: _LOGGER.debug( f" dev addr is {dev.addr} and mac is {device.mac}") _LOGGER.debug( f" --> {temperature} - {humidity} - {battery} ") if dev.addr == device.mac: _LOGGER.debug( f" dev addr is {dev.addr} and mac is {device.mac} with parameter of {device.parameter}" ) old_state = self.hass.states.get( f"sensor.{device.entity_name}") if old_state: attrs = old_state.attributes else: attrs = None if device.parameter == "temperature": _LOGGER.debug( f" >>>> updating device {device.mac} with {temperature}" ) device.temperature = temperature device._state = temperature #self.hass.states.set(f"sensor.{device.entity_name}", temperature, attrs) elif device.parameter == "humidity": _LOGGER.debug( f" >>>> updating device {device.mac} with {humidity}" ) device.humidity = humidity device._state = humidity #self.hass.states.set(f"sensor.{device.entity_name}", humidity, attrs) else: _LOGGER.debug( f" >>>> updating device {device.mac} with {battery}" ) device.battery = battery device._state = battery
def scan(self): scanner = Scanner().withDelegate(ScanDelegate()) devices = scanner.clear() devices = scanner.start() data = scanner.process(timeout=10) devices = scanner.stop()
class BleAdapter: def __init__(self, yaml_config: dict, min_rssi: float = -65, ble_device: str = 'hci0'): self.devs_in_range = {} # Stores devices found to be in range self.active_connections = {} self._chrcs_cache = {} self.yaml_config = yaml_config self.valid_names = yaml_config['regex']['names'] self.valid_addrs = yaml_config['regex']['addrs'] self.chrc_handles = list(yaml_config['characteristics'].keys()) self.min_rssi = min_rssi self.ble_device = ble_device[-1] # Hacky self.scanner = Scanner() def update_tracked_devices(self, scan_timeout: float = 3): # Refreshes a list of devices that are in range of the bridge for conn in self.active_connections.values(): conn.disconnect() time.sleep(1) self.active_connections = {} self.scanner.clear() new_devs = self.scanner.scan(scan_timeout) new_devs_in_range = {} for dev in new_devs: # Exclude devices below a certain rssi if dev.rssi < self.min_rssi: continue # Get mac address and device name from ScanEntry class dev_addr = dev.addr.upper() dev_name = self._get_dev_name_from_scan_entry(dev) # If address is valid, add device dev_addr_valid = map( lambda x: re.match(x, dev_addr, re.IGNORECASE), self.valid_addrs) if any(dev_addr_valid): new_devs_in_range[dev_addr] = dev continue # if name is empty, continue if not dev_name: continue # If name is valid, add device dev_name_valid = map(lambda x: re.match(x, dev_name), self.valid_names) if any(dev_name_valid): new_devs_in_range[dev_addr] = dev continue self.devs_in_range = new_devs_in_range Utils.logger.info( f'Valid devices in range: {self.get_tracked_devices_summary()}') @timeout(4) def create_connection(self, addr: str): # Creates a handle to a Peripheral and adds it to active_connections try: assert addr in self.devs_in_range dev_addr = addr.upper() dev_addr_type = self.devs_in_range[dev_addr].addrType dev_name = self.get_dev_name(dev_addr) Utils.logger.info( f'Creating connection to {dev_addr_type} address: {dev_addr}') dev = Peripheral(dev_addr, dev_addr_type, self.ble_device) self.active_connections[dev_name] = dev self._chrcs_cache[dev_name] = dev.getCharacteristics() except TimeoutError: Utils.logger.error(f'Device {addr} not responding.') except Exception as e: Utils.logger.error(f'An error occurred. {e}') except AssertionError: Utils.logger.error(f'Device {addr} not in range right now') def maintain_connections(self): updated_active_connections = {} updated_chrc_cache = {} # Remove connections that have disconnected for dev_name, conn in self.active_connections.items(): if conn.getState() == 'conn': updated_active_connections[dev_name] = conn updated_chrc_cache[dev_name] = conn.getCharacteristics() self.active_connections = updated_active_connections self._chrcs_cache = updated_chrc_cache # Reconnect devices in range but are not active for addr, scan_entry in self.devs_in_range.items(): if self.get_dev_name(addr) not in self.active_connections.keys(): self.create_connection(addr) def pull_device_data(self): all_device_data = {} for dev_name in self.active_connections.keys(): try: all_device_data[dev_name] = self._get_data(dev_name) except Exception as e: continue return all_device_data def _get_data(self, dev_name: str): Utils.logger.info(f'Loading data from {dev_name}') data = {} try: chrcs = self._chrcs_cache[dev_name] except KeyError: Utils.logger.error(f'{dev_name} is not an active connection.') return chrc_handles = [x.replace('-', '') for x in self.chrc_handles] for c in chrcs: handle = str(c.uuid) h = handle.replace('-', '') if h not in chrc_handles: continue # Bottleneck here try: byte_val = c.read() except BTLEDisconnectError: Utils.logger.error(f'{dev_name} was disconnected,') Utils.logger.error('Will reattempt to connect on next rescan.') except Exception as e: Utils.logger.error( f'An unknown error occurred trying to read {handle}: {e}') raise data_type = self.yaml_config['characteristics'][handle]['msg_type'] if data_type == 'byte': data[handle] = str(byte_val) elif data_type == 'string': data[handle] = byte_val.decode('utf-8') elif data_type == 'int': data[handle] = int(byte_val.decode('utf-8')) elif data_type == 'float': data[handle] = float(byte_val.decode('utf-8')) elif data_type == 'bool': data[handle] = bool(byte_val.decode('utf-8')) else: Utils.logger.error(f'Invalid msg_type {data_type}') raise EnvironmentError return data def write_data(self, dev_name: str, handle: str, val: str): h = handle.replace('-', '') try: conn = self.active_connections[dev_name] except KeyError: Utils.logger.error(f'{dev_name} is not an active connection') return try: assert conn.getState() == 'conn' except AssertionError: Utils.logger.error(f'{dev_name} is disconnected.') try: chrc = conn.getCharacteristics(uuid=h)[0] except BTLEGattError: Utils.logger.error(f'Handle {handle} is invalid') raise except KeyError: Utils.logger.error('No characteristic was returned') raise Utils.logger.info( f'Writing value "{val}" to handle "{handle}" on device "{dev_name}"' ) try: chrc.write(val) except Exception as e: Utils.logger.error(e) def get_dev_name(self, addr: str): dev = self.devs_in_range[addr] return self._get_dev_name_from_scan_entry(dev) def _get_dev_name_from_scan_entry(self, dev: ScanEntry): dev_name = None # Attempt to load from Scandata for scan_data in dev.getScanData(): if scan_data[1] == 'Short Local Name': dev_name = scan_data[2] # Iterate through the dataTags if the above fails if dev_name is None: try: for idx, label in scan_data.dataTags: if label == 'Short Local Name': dev_name = dev.getValueText(idx) except AttributeError: pass # Load using handles if the above fails if dev_name is None: dev_name = dev.getValueText(8) return dev_name def get_tracked_devices_summary(self): return [(x.addr.upper(), x.getValueText(8)) for x in self.devs_in_range.values()] def get_active_connections_summary(self): return list(self.active_connections.keys())
def init_scanner(): scanner = Scanner() scanner.clear() scanner.start() return scanner
class InkbirdUpdater(Entity): entity_id = "inkbird.updater" def __init__(self, hass, inkbird_devices): """Initialize the thermometer.""" Entity.__init__(self) self._name = 'Inkbird Updater' self._state = None self._mac = None self.hass = hass self.scanner = Scanner() self.scanner.clear() self.scanner.start() self.inkbird_devices = inkbird_devices @property def mac(self): """Return the mac of the sensor.""" return self._mac @property def name(self): """Return the name of the sensor.""" return self._name @property def state(self): """Return the state of the sensor.""" return self._state @property def should_poll(self): """Return the name of the sensor.""" _LOGGER.debug("Should_Poll called") return True def update(self): # added global pid ## """Get the latest data and use it to update our sensor state.""" _LOGGER.debug("UPDATE called") _LOGGER.debug(f"scanner here is {self.scanner}") try: self.scanner.process(timeout=8.0) except: e = sys.exc_info()[0] _LOGGER.error(f" Exception occoured during scanning: {e}") results = self.scanner.getDevices() _LOGGER.debug(f"got results {results}") # The btle on my raspberry pi 4 seems to go MIA # if we have no results at all, the scanner may have gone MIA. # it happens apparently. So, let's count upto 5 and then, if it # still happens, restart/refresh the btle stack. # Seems to go MIA more frequently on RPi3B: removed counter and restart immediately if no results obtained # May generate 10 s update timeout errors if not any(results): _LOGGER.error("Btle went away .. restarting entire btle stack") ## Kill the bluepy-helper process # There is a memory leak: new instance of bluepy-helper is created with Scanner(), without terminating running instance # https://github.com/IanHarvey/bluepy/issues/267#issuecomment-657183840 # adapted from: https://github.com/JsBergbau/MiTemperature2/blob/master/LYWSD03MMC.py del self.scanner #probably not needed? bluepypid = 0 pstree = os.popen("pstree -p " + str(pid)).read( ) #we want to kill only bluepy from our own process tree, because other python scripts have there own bluepy-helper process _LOGGER.debug("PSTree: " + pstree) try: bluepypid = re.findall( r'bluepy-helper\((.*)\)', pstree)[0] #Store the bluepypid, to kill it later except IndexError: #Should not happen since we're now connected _LOGGER.debug("Couldn't find pid of bluepy-helper") if bluepypid is not 0: os.system("kill " + bluepypid) _LOGGER.debug("Killed bluepy with pid: " + str(bluepypid)) # Kill bluepy-helper systemwide anyways...not good if there are other scripts using bluepy # else: # os.system('pkill bluepy-helper') # _LOGGER.debug("Killed bluepy-helper") ## self.scanner = Scanner() self.scanner.clear() self.scanner.start() try: self.scanner.process(timeout=8.0) except: e = sys.exc_info()[0] _LOGGER.error(f" Exception occoured during scanning: {e}") results = self.scanner.getDevices() _LOGGER.debug(f"Got new results {results}") for dev in results: if dev.addr in devicemacs: self.handleDiscovery(dev) self.scanner.clear() self._state = [] return True def handleDiscovery(self, dev): # _LOGGER.debug(f"Discovered device {dev.addr}") _LOGGER.debug("Discovered device {} ({}), RSSI={} dB".format( dev.addr, dev.addrType, dev.rssi)) for (adtype, desc, value) in dev.getScanData(): _LOGGER.debug("[%s] %s = %s" % (adtype, desc, value)) if adtype == 255: _LOGGER.debug( f"{dev.addr} is in devicemacs list and now gets parameters!" ) humidity = "%2.2f" % (int(value[6:8] + value[4:6], 16) / 100) #temperature = "%2.2f" % (int(value[2:4]+value[:2], 16)/100) temperature = int(value[2:4] + value[:2], 16) temperature_bits = 16 if temperature & (1 << (temperature_bits - 1)): temperature -= 1 << temperature_bits temperature = "%2.2f" % (temperature / 100) battery = int(value[14:16], 16) _LOGGER.debug(self.inkbird_devices) for device in self.inkbird_devices: _LOGGER.debug( f" dev addr is {dev.addr} and mac is {device.mac}") # _LOGGER.debug(f" --> {temperature} - {humidity} - {battery} ") if dev.addr == device.mac: _LOGGER.debug( f" dev addr is {dev.addr} and mac is {device.mac} with parameter of {device.parameter}" ) # What does this do? Removed # old_state = self.hass.states.get(f"sensor.{device.entity_name}") # if old_state: # attrs = old_state.attributes # else: # attrs = None if device.parameter == "temperature": _LOGGER.debug( f" >>>> updating device {device.mac} with {temperature}" ) device.temperature = temperature device._state = temperature #self.hass.states.set(f"sensor.{device.entity_name}", temperature, attrs) elif device.parameter == "humidity": _LOGGER.debug( f" >>>> updating device {device.mac} with {humidity}" ) device.humidity = humidity device._state = humidity #self.hass.states.set(f"sensor.{device.entity_name}", humidity, attrs) else: _LOGGER.debug( f" >>>> updating device {device.mac} with {battery}" ) device.battery = battery device._state = battery #self.hass.states.set(f"sensor.{device.entity_name}", battery, attrs) _LOGGER.debug(f" Done with handleDiscovery")
def scan(callback, devices=None, raw=False, iface=0, reset_timeout=30, reset_deadtime=300): """Listen for BLE advertising packets from Ruuvitags. Args: callback: Function which will be called for each received Ruuvitag packet. devices: List of BT address strings in format "fe:ed:de:ad:be:ef" for whitelisting devices. If None, no address filtering is made. raw: If False, callback is called with a dictionary with decoded values from advertising message, plus "time" and "rssi" keys which have the packet arrival time and rssi as values. If True, callback is called with a tuple (value, addr, rssi) with the value being the raw BLE packet data, addr the BT address of the sending device and rssi the received signal strength indicator from the BT stack. iface: The number part of the BT interface device (0 for /dev/hci0 etc.) reset_timeout: Time in seconds, after which a reset of the BT adapter is made, if no packets are received. reset_deadtime: Time in seconds. If a BT reset is made and packets are still not arriving, the next reset attempt is made after this time has passed. """ if devices: dev = [s.lower() for s in devices] devices = dev recv_event = threading.Event() reset_thread = threading.Thread(target=idlereset, args=(recv_event, reset_timeout, reset_deadtime)) reset_thread.daemon = True reset_thread.start() # Start scanning scanner = Scanner(iface).withDelegate( ScanDelegate(recv_event, callback, devices, raw)) scanner.clear() scanner.start(passive=True) try: while True: try: scanner.process(0) except BTLEException: try: scanner.stop() except BTLEException: scanner._stopHelper() reset_btadapter() scanner.clear() scanner.start(passive=True) except (KeyboardInterrupt, SystemExit): pass log.info("Stopping scan.") scanner.stop()
class _StoppableScanner(threading.Thread): """Scanner class which can be started and stopped asynchronously. Non-thread-safe. It is implemented as a thread which checks regularly for the stop condition within the :meth:`run()` method; it can be stopped by calling the :meth:`stop()` method. """ def __init__(self, show_warnings=False, *args, **kwargs): """Constructor. Args: show_warnings (bool, optional): If True shows warnings, if any, when discovering devices not respecting the BlueSTSDK's advertising data format, nothing otherwise. """ try: super(_StoppableScanner, self).__init__(*args, **kwargs) self._stop_called = threading.Event() self._process_done = threading.Event() with lock(self): self._scanner = Scanner().withDelegate(_ScannerDelegate(show_warnings)) except BTLEException as e: # Save details of the exception raised but don't re-raise, just # complete the function. import sys self._exc = sys.exc_info() def run(self): """Run the thread.""" self._stop_called.clear() self._process_done.clear() try: with lock(self): self._scanner.clear() self._exc = None self._scanner.start(passive=False) while True: #print('.') self._scanner.process(_ScannerDelegate._SCANNING_TIME_PROCESS_s) if self._stop_called.isSet(): self._process_done.set() break except BTLEException as e: # Save details of the exception raised but don't re-raise, just # complete the function. import sys self._exc = sys.exc_info() def stop(self): """Stop the thread.""" self._stop_called.set() while not (self._process_done.isSet() or self._exc): pass try: self._exc = None with lock(self): self._scanner.stop() except BTLEException as e: # Save details of the exception raised but don't re-raise, just # complete the function. import sys self._exc = sys.exc_info() def join(self): """Join the thread. Raises: :exc:`blue_st_sdk.utils.blue_st_exceptions.BlueSTInvalidOperationException` is raised if this method is not run as root. """ super(_StoppableScanner, self).join() if self._exc: msg = '\nBluetooth scanning requires root privilege, ' \ 'so please run the script with \"sudo\".' raise BlueSTInvalidOperationException(msg)
while i < padding_size: padding = padding+"0" i+=1 new_package = package+padding try_until_success(output.write, msg="Failed to send to player 1", args=[new_package,True]) handler1 = BTEventHandler(1) handler2 = BTEventHandler(2) with open("mac.txt") as f: macAddresses = f.readlines() macAddresses = [m.strip() for m in macAddresses] # Create a scanner with the handler as delegate scanner1 = Scanner().withDelegate(handler1) scanner1.clear() while True: while True: # Start scanning. While scanning, handleDiscovery will be called whenever a new device or new data is found devs = scanner1.scan(3) # Get HEXIWEAR's address devices = [dev for dev in devs if dev.getValueText(0x8) == 'HEXIWEAR'] hexi_addr = [] for dev in devices: print dev.addr if dev.addr in macAddresses: hexi_addr.append(dev.addr) print hexi_addr if len(hexi_addr) >= 2: player1 = hexi_addr[0]
class BLEScan(): bledev = 0 timeout = 5.0 scanner = None devices = [] devrssi = [] lastscan = 0 def __init__(self,devnum=0,timeout=5.0): self.bledev = int(devnum) self.timeout = float(timeout) self.scanner = None self.devices = [] self.devrssi = [] self.lastscan = 0 self._scanning = False self.scantime = 10 self.minsleep = 15 self.maxsleep = 40 def stop(self): try: if self.scanner is not None: self.scanner.stop() except: pass self._scanning = False def scan(self): result = False devices = [] self._scanning = True try: self.scanner = Scanner(self.bledev) devices = self.scanner.scan(self.timeout) result = True self.lastscan = time.time() except Exception as e: print("BLE error: ",e) self.devices = [] self.devrssi = [] self._scanning = False tempdev = [] temprssi = [] for dev in devices: try: if self.bledev == int(dev.iface): temprssi.append(dev.rssi) tempdev.append(str(dev.addr).lower().strip()) except: pass self.devices = tempdev self.devrrsi = temprssi return result def isdevonline(self,devaddress): return (self.getdevrssi(devaddress) != -100) def getdevrssi(self,devaddress): try: for d in range(len(self.devices)): if str(devaddress).lower().strip()==str(self.devices[d]).lower().strip(): return self.devrrsi[d] return -100 except Exception as e: return -100 def getage(self): if self.lastscan==0: return -1 try: result = time.time()-self.lastscan except: result = -1 return result def sniff(self, callback,startwait=0,scantime=10,minsleep=15,maxsleep=40): self._scanning = True self.scantime = scantime self.minsleep = minsleep self.maxsleep = maxsleep _blestatus = BLEHelper.BLEStatus[self.bledev] time.sleep(startwait) try: if self.timeout==0: while self._scanning: while _blestatus.norequesters()==False or _blestatus.nodataflows()==False or _blestatus.isscaninprogress(): time.sleep(0.5) # print("scan start")#debug _blestatus.reportscan(1) try: self.scanner = Scanner(self.bledev).withDelegate(SniffDelegate(callback)) except: pass self.scanner.clear() self.scanner.start(passive=True) self.scanner.process(scantime) self.scanner.stop() _blestatus.reportscan(0) # print("scan pause")#debug time.sleep(uniform(minsleep,maxsleep)) else: while _blestatus.norequesters()==False or _blestatus.nodataflows()==False or _blestatus.isscaninprogress(): time.sleep(0.5) _blestatus.reportscan(1) self.scanner = Scanner(self.bledev).withDelegate(SniffDelegate(callback)) self.scanner.scan(self.timeout,passive=True) _blestatus.reportscan(0) self.lastscan = time.time() except Exception as e: _blestatus.reportscan(0) self._scanning = False