diff --git a/CHANGELOG.md b/CHANGELOG.md index 67d936a..03bac1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## Changelog ### [Unreleased] - +* ADD: RUUVI_MACOS_USE_MAC_ADDR environment variable to enable MAC address usage on macOS ## [3.0.0] - 2025-01-13 * ADD: Install Bleak automatically on all platforms diff --git a/README.md b/README.md index a78a178..8800bcb 100644 --- a/README.md +++ b/README.md @@ -479,6 +479,16 @@ if __name__ == "__main__": Check [get_async_bleak](https://github.com/ttu/ruuvitag-sensor/blob/master/examples/get_async_bleak.py) and other async examples from [examples](https://github.com/ttu/ruuvitag-sensor/tree/master/examples) directory. +#### Use MAC Address Instead of Device-Specific ID on macOS + +Bleak has a workaround for macOS to use MAC address instead of device-specific ID. This is experimental feature from Bleak and may break with macOS updates. + +Set the `RUUVI_MACOS_USE_MAC_ADDR` environment variable to `true` to enable it. + +```sh +$ export RUUVI_MACOS_USE_MAC_ADDR=true +``` + #### Bleak dummy BLE data Bleak-adapter has a development-time generator for dummy data, which can be useful during development if no sensors are available. Set the `RUUVI_BLE_ADAPTER` environment variable to `bleak_dev`. diff --git a/ruuvitag_sensor/adapters/bleak_ble.py b/ruuvitag_sensor/adapters/bleak_ble.py index a82e9bd..d58b14d 100644 --- a/ruuvitag_sensor/adapters/bleak_ble.py +++ b/ruuvitag_sensor/adapters/bleak_ble.py @@ -14,6 +14,14 @@ MAC_REGEX = "[0-9a-f]{2}([:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$" +# NOTE: macOS uses device specific IDs instead of MAC addresses +# Bleak has a workaround for this, but it's not enabled by default +# https://github.com/hbldh/bleak/pull/1073 +# This is behind a env variable as macOS update can break the workaround +MACOS_USE_MAC_ADDR = os.environ.get("RUUVI_MACOS_USE_MAC_ADDR", "false").strip().lower() == "true" +MACOS_SCANNER_ARGS = dict(use_bdaddr=True) if MACOS_USE_MAC_ADDR else {} +SCANNER_ARGS = MACOS_SCANNER_ARGS if sys.platform == "darwin" else {} + def _get_scanner(detection_callback: AdvertisementDataCallback, bt_device: str = ""): # NOTE: On Linux - bleak.exc.BleakError: passive scanning mode requires bluez or_patterns @@ -30,9 +38,14 @@ def _get_scanner(detection_callback: AdvertisementDataCallback, bt_device: str = detection_callback=detection_callback, scanning_mode=scanning_mode, # type: ignore[arg-type] adapter=bt_device, + cb=SCANNER_ARGS, # type: ignore[arg-type] ) - return BleakScanner(detection_callback=detection_callback, scanning_mode=scanning_mode) # type: ignore[arg-type] + return BleakScanner( + detection_callback=detection_callback, + scanning_mode=scanning_mode, # type: ignore[arg-type] + cb=SCANNER_ARGS, # type: ignore[arg-type] + ) queue = asyncio.Queue[Tuple[str, str]]()