forked from platypush/platypush
Passing a boolean exclude_known_noisy_beacons
to bluetooth
plugin.
The logic to exclude BLE beacons from randomized devices needs to be a bit more granular and not limited only to the reported device manufacturer.
This commit is contained in:
parent
f6e09d34e4
commit
01d323fad0
3 changed files with 24 additions and 32 deletions
|
@ -60,6 +60,7 @@ class BLEManager(BaseBluetoothManager):
|
||||||
device_queue=self._device_queue,
|
device_queue=self._device_queue,
|
||||||
device_cache=self._device_cache,
|
device_cache=self._device_cache,
|
||||||
entity_cache=self._cache,
|
entity_cache=self._cache,
|
||||||
|
exclude_known_noisy_beacons=self._exclude_known_noisy_beacons,
|
||||||
)
|
)
|
||||||
""" Bluetooth device event handler """
|
""" Bluetooth device event handler """
|
||||||
self._main_loop: Optional[asyncio.AbstractEventLoop] = None
|
self._main_loop: Optional[asyncio.AbstractEventLoop] = None
|
||||||
|
|
|
@ -28,6 +28,7 @@ class BaseBluetoothManager(ABC, threading.Thread):
|
||||||
device_queue: Queue[BluetoothDevice],
|
device_queue: Queue[BluetoothDevice],
|
||||||
service_uuids: Optional[Collection[RawServiceClass]] = None,
|
service_uuids: Optional[Collection[RawServiceClass]] = None,
|
||||||
device_cache: Optional[EntityCache] = None,
|
device_cache: Optional[EntityCache] = None,
|
||||||
|
exclude_known_noisy_beacons: bool = True,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -40,6 +41,7 @@ class BaseBluetoothManager(ABC, threading.Thread):
|
||||||
:param device_queue: Queue used by the ``EventHandler`` to publish
|
:param device_queue: Queue used by the ``EventHandler`` to publish
|
||||||
updates with the new parsed device entities.
|
updates with the new parsed device entities.
|
||||||
:param device_cache: Cache used to keep track of discovered devices.
|
:param device_cache: Cache used to keep track of discovered devices.
|
||||||
|
:param exclude_known_noisy_beacons: Exclude known noisy beacons.
|
||||||
"""
|
"""
|
||||||
kwargs['name'] = f'Bluetooth:{self.__class__.__name__}'
|
kwargs['name'] = f'Bluetooth:{self.__class__.__name__}'
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
@ -53,6 +55,7 @@ class BaseBluetoothManager(ABC, threading.Thread):
|
||||||
self._scan_lock = scan_lock
|
self._scan_lock = scan_lock
|
||||||
self._scan_enabled = scan_enabled
|
self._scan_enabled = scan_enabled
|
||||||
self._device_queue = device_queue
|
self._device_queue = device_queue
|
||||||
|
self._exclude_known_noisy_beacons = exclude_known_noisy_beacons
|
||||||
|
|
||||||
self._cache = device_cache or EntityCache()
|
self._cache = device_cache or EntityCache()
|
||||||
""" Cache of discovered devices. """
|
""" Cache of discovered devices. """
|
||||||
|
|
|
@ -9,7 +9,6 @@ from typing import (
|
||||||
Final,
|
Final,
|
||||||
List,
|
List,
|
||||||
Optional,
|
Optional,
|
||||||
Set,
|
|
||||||
Union,
|
Union,
|
||||||
Type,
|
Type,
|
||||||
)
|
)
|
||||||
|
@ -77,16 +76,6 @@ class BluetoothPlugin(RunnablePlugin, EntityManager):
|
||||||
_default_scan_duration: Final[float] = 10.0
|
_default_scan_duration: Final[float] = 10.0
|
||||||
""" Default duration of a discovery session (in seconds) """
|
""" Default duration of a discovery session (in seconds) """
|
||||||
|
|
||||||
_default_excluded_manufacturers = (
|
|
||||||
'Apple, Inc.',
|
|
||||||
'Google',
|
|
||||||
'Microsoft',
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
Exclude beacons from these device manufacturers by default (main offenders
|
|
||||||
when it comes to Bluetooth device space pollution).
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
interface: Optional[str] = None,
|
interface: Optional[str] = None,
|
||||||
|
@ -94,9 +83,7 @@ class BluetoothPlugin(RunnablePlugin, EntityManager):
|
||||||
service_uuids: Optional[Collection[RawServiceClass]] = None,
|
service_uuids: Optional[Collection[RawServiceClass]] = None,
|
||||||
scan_paused_on_start: bool = False,
|
scan_paused_on_start: bool = False,
|
||||||
poll_interval: float = _default_scan_duration,
|
poll_interval: float = _default_scan_duration,
|
||||||
excluded_manufacturers: Optional[
|
exclude_known_noisy_beacons: bool = True,
|
||||||
Collection[str]
|
|
||||||
] = _default_excluded_manufacturers,
|
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -109,14 +96,14 @@ class BluetoothPlugin(RunnablePlugin, EntityManager):
|
||||||
:param scan_paused_on_start: If ``True``, the plugin will not the
|
:param scan_paused_on_start: If ``True``, the plugin will not the
|
||||||
scanning thread until :meth:`.scan_resume` is called (default:
|
scanning thread until :meth:`.scan_resume` is called (default:
|
||||||
``False``).
|
``False``).
|
||||||
:param excluded_manufacturers: Exclude beacons from these device
|
:param exclude_known_noisy_beacons: Exclude BLE beacons from devices
|
||||||
manufacturers. The default list includes Apple, Google and
|
known for being very noisy. It mainly includes tracking services on
|
||||||
Microsoft, who are among the main offenders when it comes to
|
Google, Apple, Microsoft and Samsung devices. These devices are
|
||||||
Bluetooth device address space pollution. Set this value to an
|
also known for refreshing their MAC address very frequently, which
|
||||||
empty list if you want to get all beacons (e.g. because you need to
|
may result in a large (and constantly increasing) list of devices.
|
||||||
communicate with Apple AirTags or Google devices over Bluetooth),
|
Disable this flag if you need to track BLE beacons from these
|
||||||
but be warned that the list of discovered Bluetooth devices may
|
devices, but beware that you may need periodically clean up your
|
||||||
dramatically increase over time.
|
list of scanned devices.
|
||||||
"""
|
"""
|
||||||
kwargs['poll_interval'] = poll_interval
|
kwargs['poll_interval'] = poll_interval
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
@ -140,10 +127,8 @@ class BluetoothPlugin(RunnablePlugin, EntityManager):
|
||||||
"""
|
"""
|
||||||
Cache of the devices discovered by the plugin.
|
Cache of the devices discovered by the plugin.
|
||||||
"""
|
"""
|
||||||
self._excluded_manufacturers: Set[str] = set(excluded_manufacturers or [])
|
self._excluded_known_noisy_beacons = exclude_known_noisy_beacons
|
||||||
"""
|
""" Exclude known noisy BLE beacons. """
|
||||||
Set of manufacturer strings whose associated devices should be ignored.
|
|
||||||
"""
|
|
||||||
|
|
||||||
self._managers: Dict[Type[BaseBluetoothManager], BaseBluetoothManager] = {}
|
self._managers: Dict[Type[BaseBluetoothManager], BaseBluetoothManager] = {}
|
||||||
"""
|
"""
|
||||||
|
@ -183,6 +168,7 @@ class BluetoothPlugin(RunnablePlugin, EntityManager):
|
||||||
'device_queue': self._device_queue,
|
'device_queue': self._device_queue,
|
||||||
'service_uuids': list(map(BluetoothService.to_uuid, self._service_uuids)),
|
'service_uuids': list(map(BluetoothService.to_uuid, self._service_uuids)),
|
||||||
'device_cache': self._device_cache,
|
'device_cache': self._device_cache,
|
||||||
|
'exclude_known_noisy_beacons': self._excluded_known_noisy_beacons,
|
||||||
}
|
}
|
||||||
|
|
||||||
self._managers = {
|
self._managers = {
|
||||||
|
@ -488,11 +474,14 @@ class BluetoothPlugin(RunnablePlugin, EntityManager):
|
||||||
file = os.path.abspath(os.path.expanduser(file))
|
file = os.path.abspath(os.path.expanduser(file))
|
||||||
with open(file, 'rb') as f:
|
with open(file, 'rb') as f:
|
||||||
binary_data = f.read()
|
binary_data = f.read()
|
||||||
|
elif binary:
|
||||||
|
binary_data = base64.b64decode(
|
||||||
|
data.encode() if isinstance(data, str) else data
|
||||||
|
)
|
||||||
|
elif isinstance(data, str):
|
||||||
|
binary_data = data.encode()
|
||||||
else:
|
else:
|
||||||
if binary:
|
binary_data = data
|
||||||
binary_data = base64.b64decode(
|
|
||||||
data.encode() if isinstance(data, str) else data
|
|
||||||
)
|
|
||||||
|
|
||||||
sender = FileSender(self._managers[LegacyManager]) # type: ignore
|
sender = FileSender(self._managers[LegacyManager]) # type: ignore
|
||||||
sender.send_file(file, device, binary_data)
|
sender.send_file(file, device, binary_data)
|
||||||
|
@ -578,8 +567,7 @@ class BluetoothPlugin(RunnablePlugin, EntityManager):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
device = self._device_cache.add(device)
|
device = self._device_cache.add(device)
|
||||||
if device.manufacturer not in self._excluded_manufacturers:
|
self.publish_entities([device], callback=self._device_cache.add)
|
||||||
self.publish_entities([device], callback=self._device_cache.add)
|
|
||||||
finally:
|
finally:
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue