From ccd71b9e23a8d6d99546a2555058b84f5bbe0a6c Mon Sep 17 00:00:00 2001 From: Tomi Tuhkanen Date: Tue, 26 Nov 2024 21:26:58 +0200 Subject: [PATCH] fix: ensure BLE scanner is stopped by explicitly closing the generator (#263) --- CHANGELOG.md | 1 + ruuvitag_sensor/ruuvi.py | 55 ++++++++++++++++++++++--------------- ruuvitag_sensor/ruuvi_rx.py | 16 +++++++---- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05c137e..a8f2304 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * CHANGE: Support only Python 3.9 and above * FIX: Check if async adapter in use in RuuviTagReactive * FIX: Correct typo in argument name search\_duration\_sec +* FIX: Ensure the BLE scanner is stopped by explicitly closing the generator ## [2.3.1] - 2024-03-10 * ADD: Bluez as option to RUUVI_BLE_ADAPTER environment variable diff --git a/ruuvitag_sensor/ruuvi.py b/ruuvitag_sensor/ruuvi.py index a17a14a..8eb332f 100644 --- a/ruuvitag_sensor/ruuvi.py +++ b/ruuvitag_sensor/ruuvi.py @@ -111,15 +111,18 @@ async def find_ruuvitags_async(bt_device: str = "") -> Dict[Mac, MacAndSensorDat mac_blacklist = Manager().list() data_iter = ble.get_data(mac_blacklist, bt_device) - async for new_data in data_iter: - if new_data[0] in data: - continue - - parsed_data = RuuviTagSensor._parse_data(new_data, mac_blacklist) - if parsed_data: - data[new_data[0]] = parsed_data - log.info(new_data[0]) - log.info(parsed_data) + try: + async for new_data in data_iter: + if new_data[0] in data: + continue + + parsed_data = RuuviTagSensor._parse_data(new_data, mac_blacklist) + if parsed_data: + data[new_data[0]] = parsed_data + log.info(new_data[0]) + log.info(parsed_data) + finally: + await data_iter.aclose() return data @@ -174,11 +177,16 @@ async def get_data_for_sensors_async( data: Dict[Mac, SensorData] = {} start_time = time.time() - async for new_data in RuuviTagSensor.get_data_async(macs, bt_device): - mac, sensor_data = new_data - data[mac] = sensor_data - if search_duration_sec and time.time() - start_time > search_duration_sec: - break + data_iter = RuuviTagSensor.get_data_async(macs, bt_device) + + try: + async for new_data in data_iter: + mac, sensor_data = new_data + data[mac] = sensor_data + if search_duration_sec and time.time() - start_time > search_duration_sec: + break + finally: + await data_iter.aclose() return data @@ -198,16 +206,19 @@ async def get_data_async(macs: List[str] = [], bt_device: str = "") -> AsyncGene mac_blacklist = Manager().list() data_iter = ble.get_data(mac_blacklist, bt_device) - async for ble_data in data_iter: - data = RuuviTagSensor._parse_data(ble_data, mac_blacklist, macs) + try: + async for ble_data in data_iter: + data = RuuviTagSensor._parse_data(ble_data, mac_blacklist, macs) - # Check MAC whitelist if advertised MAC available - if ble_data[0] and macs and not ble_data[0] in macs: - log.debug("MAC not whitelisted: %s", ble_data[0]) - continue + # Check MAC whitelist if advertised MAC available + if ble_data[0] and macs and not ble_data[0] in macs: + log.debug("MAC not whitelisted: %s", ble_data[0]) + continue - if data: - yield data + if data: + yield data + finally: + await data_iter.aclose() @staticmethod def get_data( diff --git a/ruuvitag_sensor/ruuvi_rx.py b/ruuvitag_sensor/ruuvi_rx.py index c28c7f3..b0b67b4 100644 --- a/ruuvitag_sensor/ruuvi_rx.py +++ b/ruuvitag_sensor/ruuvi_rx.py @@ -18,12 +18,16 @@ async def _run_get_data_background_async(macs: List[str], queue: Queue, shared_d """ Async background process function for RuuviTag Sensors """ - async for data in RuuviTagSensor.get_data_async(macs, bt_device): - if not shared_data["run_flag"]: - break - - data[1]["time"] = datetime.utcnow().isoformat() # type: ignore - queue.put(data) + data_iter = RuuviTagSensor.get_data_async(macs, bt_device) + try: + async for data in data_iter: + if not shared_data["run_flag"]: + break + + data[1]["time"] = datetime.utcnow().isoformat() # type: ignore + queue.put(data) + finally: + await data_iter.aclose() def _run_get_data_background(macs: List[str], queue: Queue, shared_data: DictProxy, bt_device: str):