from typing import Dict, Optional from platypush.backend.sensor import SensorBackend from platypush.message.event.bluetooth import BluetoothDeviceFoundEvent, BluetoothDeviceLostEvent class BluetoothScannerBackend(SensorBackend): """ This backend periodically scans for available bluetooth devices and returns events when a devices enter or exits the range. Triggers: * :class:`platypush.message.event.bluetooth.BluetoothDeviceFoundEvent` when a new bluetooth device is found. * :class:`platypush.message.event.bluetooth.BluetoothDeviceLostEvent` when a bluetooth device is lost. Requires: * The :class:`platypush.plugins.bluetooth.BluetoothPlugin` plugin working. """ def __init__(self, device_id: Optional[int] = None, scan_duration: int = 10, **kwargs): """ :param device_id: Bluetooth adapter ID to use (default configured on the ``bluetooth`` plugin if None). :param scan_duration: How long the scan should run (default: 10 seconds). """ super().__init__(plugin='bluetooth', plugin_args={ 'device_id': device_id, 'duration': scan_duration, }, **kwargs) self._last_seen_devices = {} def process_data(self, data: Dict[str, dict], new_data: Dict[str, dict]): for addr, dev in data.items(): if addr not in self._last_seen_devices: self.bus.post(BluetoothDeviceFoundEvent(address=dev.pop('addr'), **dev)) self._last_seen_devices[addr] = {'addr': addr, **dev} for addr, dev in self._last_seen_devices.copy().items(): if addr not in data: self.bus.post(BluetoothDeviceLostEvent(address=dev.pop('addr'), **dev)) del self._last_seen_devices[addr] # vim:sw=4:ts=4:et: