From d973b4de34b60fbf80315b9bf5012e2abc39dba2 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 01:09:06 +0300 Subject: [PATCH 01/13] Convert bluetooth device tracker to async --- .../bluetooth_tracker/device_tracker.py | 76 ++++++++----------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index 8f01036da75911..2bbfcd39325ce0 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -21,10 +21,9 @@ async_load_config, ) import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.event import track_point_in_utc_time +from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.typing import HomeAssistantType -from homeassistant.util.async_ import run_coroutine_threadsafe -import homeassistant.util.dt as dt_util + _LOGGER = logging.getLogger(__name__) @@ -65,54 +64,49 @@ def discover_devices(device_id: int) -> List[Tuple[str, str]]: return result -def see_device(see, mac: str, device_name: str, rssi=None) -> None: +def see_device(hass: HomeAssistantType, async_see, mac: str, device_name: str, rssi=None) -> None: """Mark a device as seen.""" attributes = {} if rssi is not None: attributes["rssi"] = rssi - see( + + hass.async_create_task(async_see( mac=f"{BT_PREFIX}{mac}", host_name=device_name, attributes=attributes, source_type=SOURCE_TYPE_BLUETOOTH, - ) + )) -def get_tracking_devices(hass: HomeAssistantType) -> Tuple[Set[str], Set[str]]: +async def get_tracking_devices(hass: HomeAssistantType) -> Tuple[Set[str], Set[str]]: """ Load all known devices. We just need the devices so set consider_home and home range to 0 """ yaml_path: str = hass.config.path(YAML_DEVICES) - devices_to_track: Set[str] = set() - devices_to_not_track: Set[str] = set() - - for device in run_coroutine_threadsafe( - async_load_config(yaml_path, hass, 0), hass.loop - ).result(): - # Check if device is a valid bluetooth device - if not is_bluetooth_device(device): - continue - - normalized_mac: str = device.mac[3:] - if device.track: - devices_to_track.add(normalized_mac) - else: - devices_to_not_track.add(normalized_mac) + + devices = await async_load_config(yaml_path, hass, 0) + bluetooth_devices = [device for device in devices if is_bluetooth_device(device)] + + devices_to_track: Set[str] = {device.mac[3:] for device in bluetooth_devices if device.track} + devices_to_not_track: Set[str] = {device.mac[3:] for device in bluetooth_devices if not device.track} return devices_to_track, devices_to_not_track -def setup_scanner(hass: HomeAssistantType, config: dict, see, discovery_info=None): +async def async_setup_scanner(hass: HomeAssistantType, config: dict, async_see, discovery_info=None): """Set up the Bluetooth Scanner.""" device_id: int = config.get(CONF_DEVICE_ID) - devices_to_track, devices_to_not_track = get_tracking_devices(hass) + interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL) + request_rssi = config.get(CONF_REQUEST_RSSI, False) # If track new devices is true discover new devices on startup. track_new: bool = config.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) _LOGGER.debug("Tracking new devices = %s", track_new) + devices_to_track, devices_to_not_track = await get_tracking_devices(hass) + if not devices_to_track and not track_new: _LOGGER.debug("No Bluetooth devices to track and not tracking new devices") @@ -120,21 +114,13 @@ def setup_scanner(hass: HomeAssistantType, config: dict, see, discovery_info=Non for mac, device_name in discover_devices(device_id): if mac not in devices_to_track and mac not in devices_to_not_track: devices_to_track.add(mac) - see_device(see, mac, device_name) + see_device(hass, async_see, mac, device_name) - interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL) - - request_rssi = config.get(CONF_REQUEST_RSSI, False) if request_rssi: _LOGGER.debug("Detecting RSSI for devices") - def update_bluetooth(_): - """Update Bluetooth and set timer for the next update.""" - update_bluetooth_once() - track_point_in_utc_time(hass, update_bluetooth, dt_util.utcnow() + interval) - - def update_bluetooth_once(): - """Lookup Bluetooth device and update status.""" + async def update_bluetooth(): + """Lookup Bluetooth devices and update status.""" try: if track_new: for mac, device_name in discover_devices(device_id): @@ -144,24 +130,28 @@ def update_bluetooth_once(): for mac in devices_to_track: _LOGGER.debug("Scanning %s", mac) device_name = bluetooth.lookup_name(mac, timeout=5) + if device_name is None: + # Could not lookup device name + continue + rssi = None if request_rssi: client = BluetoothRSSI(mac) rssi = client.request_rssi() client.close() - if device_name is None: - # Could not lookup device name - continue - see_device(see, mac, device_name, rssi) + + see_device(hass, async_see, mac, device_name, rssi) except bluetooth.BluetoothError: _LOGGER.exception("Error looking up Bluetooth device") - def handle_update_bluetooth(call): + async def handle_update_bluetooth(call): """Update bluetooth devices on demand.""" - update_bluetooth_once() - update_bluetooth(dt_util.utcnow()) + await update_bluetooth() + + hass.async_create_task(update_bluetooth()) + async_track_time_interval(hass, update_bluetooth, interval) - hass.services.register(DOMAIN, "bluetooth_tracker_update", handle_update_bluetooth) + hass.services.async_register(DOMAIN, "bluetooth_tracker_update", handle_update_bluetooth) return True From 8da6554ef2b93693447f152576f954a1f2f20494 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 01:24:00 +0300 Subject: [PATCH 02/13] WIP --- .../bluetooth_tracker/device_tracker.py | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index 2bbfcd39325ce0..df03e0b658b407 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -64,18 +64,22 @@ def discover_devices(device_id: int) -> List[Tuple[str, str]]: return result -def see_device(hass: HomeAssistantType, async_see, mac: str, device_name: str, rssi=None) -> None: +def see_device( + hass: HomeAssistantType, async_see, mac: str, device_name: str, rssi=None +) -> None: """Mark a device as seen.""" attributes = {} if rssi is not None: attributes["rssi"] = rssi - hass.async_create_task(async_see( - mac=f"{BT_PREFIX}{mac}", - host_name=device_name, - attributes=attributes, - source_type=SOURCE_TYPE_BLUETOOTH, - )) + hass.async_create_task( + async_see( + mac=f"{BT_PREFIX}{mac}", + host_name=device_name, + attributes=attributes, + source_type=SOURCE_TYPE_BLUETOOTH, + ) + ) async def get_tracking_devices(hass: HomeAssistantType) -> Tuple[Set[str], Set[str]]: @@ -88,17 +92,23 @@ async def get_tracking_devices(hass: HomeAssistantType) -> Tuple[Set[str], Set[s devices = await async_load_config(yaml_path, hass, 0) bluetooth_devices = [device for device in devices if is_bluetooth_device(device)] - - devices_to_track: Set[str] = {device.mac[3:] for device in bluetooth_devices if device.track} - devices_to_not_track: Set[str] = {device.mac[3:] for device in bluetooth_devices if not device.track} + + devices_to_track: Set[str] = { + device.mac[3:] for device in bluetooth_devices if device.track + } + devices_to_not_track: Set[str] = { + device.mac[3:] for device in bluetooth_devices if not device.track + } return devices_to_track, devices_to_not_track -async def async_setup_scanner(hass: HomeAssistantType, config: dict, async_see, discovery_info=None): +async def async_setup_scanner( + hass: HomeAssistantType, config: dict, async_see, discovery_info=None +): """Set up the Bluetooth Scanner.""" device_id: int = config.get(CONF_DEVICE_ID) - interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL) + interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL) request_rssi = config.get(CONF_REQUEST_RSSI, False) # If track new devices is true discover new devices on startup. @@ -139,7 +149,7 @@ async def update_bluetooth(): client = BluetoothRSSI(mac) rssi = client.request_rssi() client.close() - + see_device(hass, async_see, mac, device_name, rssi) except bluetooth.BluetoothError: _LOGGER.exception("Error looking up Bluetooth device") @@ -148,10 +158,12 @@ async def handle_update_bluetooth(call): """Update bluetooth devices on demand.""" await update_bluetooth() - + hass.async_create_task(update_bluetooth()) async_track_time_interval(hass, update_bluetooth, interval) - hass.services.async_register(DOMAIN, "bluetooth_tracker_update", handle_update_bluetooth) + hass.services.async_register( + DOMAIN, "bluetooth_tracker_update", handle_update_bluetooth + ) return True From 2c9009d43d9d745b65f7aab0c330498518624b57 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 01:26:05 +0300 Subject: [PATCH 03/13] WIP --- homeassistant/components/bluetooth_tracker/device_tracker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index df03e0b658b407..b776bab811d796 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -154,7 +154,7 @@ async def update_bluetooth(): except bluetooth.BluetoothError: _LOGGER.exception("Error looking up Bluetooth device") - async def handle_update_bluetooth(call): + async def handle_manual_update_bluetooth(call): """Update bluetooth devices on demand.""" await update_bluetooth() @@ -163,7 +163,7 @@ async def handle_update_bluetooth(call): async_track_time_interval(hass, update_bluetooth, interval) hass.services.async_register( - DOMAIN, "bluetooth_tracker_update", handle_update_bluetooth + DOMAIN, "bluetooth_tracker_update", handle_manual_update_bluetooth ) return True From 5d807f2ff22fd2b90b36df4382db447e98993286 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 01:57:34 +0300 Subject: [PATCH 04/13] Fix callback --- homeassistant/components/bluetooth_tracker/device_tracker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index b776bab811d796..6f82f3b8f7cce0 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -129,7 +129,7 @@ async def async_setup_scanner( if request_rssi: _LOGGER.debug("Detecting RSSI for devices") - async def update_bluetooth(): + async def update_bluetooth(now=None): """Lookup Bluetooth devices and update status.""" try: if track_new: From 038dd9f74eaf7490ea9a89f9b88036bbedf28763 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 02:21:01 +0300 Subject: [PATCH 05/13] Fix tracked devices --- homeassistant/components/bluetooth_tracker/device_tracker.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index 6f82f3b8f7cce0..6b683a854505ef 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -124,6 +124,8 @@ async def async_setup_scanner( for mac, device_name in discover_devices(device_id): if mac not in devices_to_track and mac not in devices_to_not_track: devices_to_track.add(mac) + + if mac in devices_to_track: see_device(hass, async_see, mac, device_name) if request_rssi: From c9e72f18261714d0d2751c5fc14b5caccbcdae0b Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 07:50:25 +0300 Subject: [PATCH 06/13] Perform synchornized updates --- .../bluetooth_tracker/device_tracker.py | 60 ++++++++++++------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index 6b683a854505ef..c84b308d70b80b 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -1,4 +1,5 @@ """Tracking for bluetooth devices.""" +import asyncio import logging from typing import List, Set, Tuple @@ -110,6 +111,7 @@ async def async_setup_scanner( device_id: int = config.get(CONF_DEVICE_ID) interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL) request_rssi = config.get(CONF_REQUEST_RSSI, False) + update_bluetooth_lock = asyncio.Lock() # If track new devices is true discover new devices on startup. track_new: bool = config.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) @@ -131,30 +133,44 @@ async def async_setup_scanner( if request_rssi: _LOGGER.debug("Detecting RSSI for devices") + def perform_bluetooth_update(): + if track_new: + for mac, device_name in discover_devices(device_id): + if mac not in devices_to_track and mac not in devices_to_not_track: + devices_to_track.add(mac) + + for mac in devices_to_track: + _LOGGER.debug("Scanning %s", mac) + device_name = bluetooth.lookup_name(mac, timeout=5) + if device_name is None: + # Could not lookup device name + continue + + rssi = None + if request_rssi: + client = BluetoothRSSI(mac) + rssi = client.request_rssi() + client.close() + + see_device(hass, async_see, mac, device_name, rssi) + async def update_bluetooth(now=None): """Lookup Bluetooth devices and update status.""" - try: - if track_new: - for mac, device_name in discover_devices(device_id): - if mac not in devices_to_track and mac not in devices_to_not_track: - devices_to_track.add(mac) - - for mac in devices_to_track: - _LOGGER.debug("Scanning %s", mac) - device_name = bluetooth.lookup_name(mac, timeout=5) - if device_name is None: - # Could not lookup device name - continue - - rssi = None - if request_rssi: - client = BluetoothRSSI(mac) - rssi = client.request_rssi() - client.close() - - see_device(hass, async_see, mac, device_name, rssi) - except bluetooth.BluetoothError: - _LOGGER.exception("Error looking up Bluetooth device") + + # If an update is in progress, we don't do anything + if update_bluetooth_lock.locked(): + _LOGGER.warning( + "Updating %s took longer than the scheduled update of interval %s", + DOMAIN, + interval, + ) + return + + async with update_bluetooth_lock: + try: + perform_bluetooth_update() + except bluetooth.BluetoothError: + _LOGGER.exception("Error looking up Bluetooth device") async def handle_manual_update_bluetooth(call): """Update bluetooth devices on demand.""" From 0f11d6102151dc2be6bc31440d678c57a01f16ed Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 07:59:44 +0300 Subject: [PATCH 07/13] Add doc --- homeassistant/components/bluetooth_tracker/device_tracker.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index c84b308d70b80b..9b85499cd71e1e 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -134,6 +134,8 @@ async def async_setup_scanner( _LOGGER.debug("Detecting RSSI for devices") def perform_bluetooth_update(): + """Discover Bluetooth devices and update status.""" + if track_new: for mac, device_name in discover_devices(device_id): if mac not in devices_to_track and mac not in devices_to_not_track: From d55dc5567f0ca360e15018f36996054ee42be8f2 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 16:33:35 +0300 Subject: [PATCH 08/13] Run in executor --- .../bluetooth_tracker/device_tracker.py | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index 9b85499cd71e1e..0935d571437759 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -65,7 +65,7 @@ def discover_devices(device_id: int) -> List[Tuple[str, str]]: return result -def see_device( +async def see_device( hass: HomeAssistantType, async_see, mac: str, device_name: str, rssi=None ) -> None: """Mark a device as seen.""" @@ -73,7 +73,7 @@ def see_device( if rssi is not None: attributes["rssi"] = rssi - hass.async_create_task( + await hass.async_create_task( async_see( mac=f"{BT_PREFIX}{mac}", host_name=device_name, @@ -128,37 +128,43 @@ async def async_setup_scanner( devices_to_track.add(mac) if mac in devices_to_track: - see_device(hass, async_see, mac, device_name) + await see_device(hass, async_see, mac, device_name) if request_rssi: _LOGGER.debug("Detecting RSSI for devices") - def perform_bluetooth_update(): + async def perform_bluetooth_update(): """Discover Bluetooth devices and update status.""" - - if track_new: - for mac, device_name in discover_devices(device_id): - if mac not in devices_to_track and mac not in devices_to_not_track: - devices_to_track.add(mac) - - for mac in devices_to_track: - _LOGGER.debug("Scanning %s", mac) - device_name = bluetooth.lookup_name(mac, timeout=5) - if device_name is None: - # Could not lookup device name - continue - - rssi = None - if request_rssi: - client = BluetoothRSSI(mac) - rssi = client.request_rssi() - client.close() - - see_device(hass, async_see, mac, device_name, rssi) + _LOGGER.debug("Performing Bluetooth devices discovery and update") + try: + if track_new: + for mac, device_name in discover_devices(device_id): + if mac not in devices_to_track and mac not in devices_to_not_track: + devices_to_track.add(mac) + + for mac in devices_to_track: + _LOGGER.debug("Scanning %s", mac) + device_name = bluetooth.lookup_name(mac, timeout=5) + if device_name is None: + # Could not lookup device name + continue + + rssi = None + if request_rssi: + client = BluetoothRSSI(mac) + rssi = client.request_rssi() + client.close() + + await see_device(hass, async_see, mac, device_name, rssi) + + except bluetooth.BluetoothError: + _LOGGER.exception("Error looking up Bluetooth device") async def update_bluetooth(now=None): """Lookup Bluetooth devices and update status.""" + _LOGGER.debug("Preparing to update Bluetooth devices") + # If an update is in progress, we don't do anything if update_bluetooth_lock.locked(): _LOGGER.warning( @@ -169,10 +175,7 @@ async def update_bluetooth(now=None): return async with update_bluetooth_lock: - try: - perform_bluetooth_update() - except bluetooth.BluetoothError: - _LOGGER.exception("Error looking up Bluetooth device") + await hass.async_add_executor_job(perform_bluetooth_update) async def handle_manual_update_bluetooth(call): """Update bluetooth devices on demand.""" From 8f2b78b46c82b012b2ca4013b407beaaf37a2141 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 17:42:43 +0300 Subject: [PATCH 09/13] Improve execution --- .../bluetooth_tracker/device_tracker.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index 0935d571437759..2630f5980048c1 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -1,7 +1,7 @@ """Tracking for bluetooth devices.""" import asyncio import logging -from typing import List, Set, Tuple +from typing import List, Set, Tuple, Optional # pylint: disable=import-error import bluetooth @@ -104,6 +104,12 @@ async def get_tracking_devices(hass: HomeAssistantType) -> Tuple[Set[str], Set[s return devices_to_track, devices_to_not_track +def lookup_name(mac: str) -> Optional[str]: + """Lookup a Bluetooth device name.""" + _LOGGER.debug("Scanning %s", mac) + return bluetooth.lookup_name(mac, timeout=5) + + async def async_setup_scanner( hass: HomeAssistantType, config: dict, async_see, discovery_info=None ): @@ -123,7 +129,8 @@ async def async_setup_scanner( _LOGGER.debug("No Bluetooth devices to track and not tracking new devices") if track_new: - for mac, device_name in discover_devices(device_id): + devices = await hass.async_add_executor_job(discover_devices, device_id) + for mac, device_name in devices: if mac not in devices_to_track and mac not in devices_to_not_track: devices_to_track.add(mac) @@ -138,13 +145,13 @@ async def perform_bluetooth_update(): _LOGGER.debug("Performing Bluetooth devices discovery and update") try: if track_new: - for mac, device_name in discover_devices(device_id): + devices = await hass.async_add_executor_job(discover_devices, device_id) + for mac, device_name in devices: if mac not in devices_to_track and mac not in devices_to_not_track: devices_to_track.add(mac) for mac in devices_to_track: - _LOGGER.debug("Scanning %s", mac) - device_name = bluetooth.lookup_name(mac, timeout=5) + device_name = await hass.async_add_executor_job(lookup_name, mac) if device_name is None: # Could not lookup device name continue @@ -152,7 +159,7 @@ async def perform_bluetooth_update(): rssi = None if request_rssi: client = BluetoothRSSI(mac) - rssi = client.request_rssi() + rssi = await hass.async_add_executor_job(client.request_rssi) client.close() await see_device(hass, async_see, mac, device_name, rssi) @@ -175,7 +182,7 @@ async def update_bluetooth(now=None): return async with update_bluetooth_lock: - await hass.async_add_executor_job(perform_bluetooth_update) + await perform_bluetooth_update() async def handle_manual_update_bluetooth(call): """Update bluetooth devices on demand.""" From 9e1615b7db0e7555c3a76e4791a4dea598d52c92 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 17:53:33 +0300 Subject: [PATCH 10/13] Improve execution --- .../components/bluetooth_tracker/device_tracker.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index 2630f5980048c1..cf6526f0a5a72a 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -121,7 +121,7 @@ async def async_setup_scanner( # If track new devices is true discover new devices on startup. track_new: bool = config.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) - _LOGGER.debug("Tracking new devices = %s", track_new) + _LOGGER.debug("Tracking new devices is set to %s", track_new) devices_to_track, devices_to_not_track = await get_tracking_devices(hass) @@ -142,6 +142,7 @@ async def async_setup_scanner( async def perform_bluetooth_update(): """Discover Bluetooth devices and update status.""" + _LOGGER.debug("Performing Bluetooth devices discovery and update") try: if track_new: @@ -170,13 +171,10 @@ async def perform_bluetooth_update(): async def update_bluetooth(now=None): """Lookup Bluetooth devices and update status.""" - _LOGGER.debug("Preparing to update Bluetooth devices") - # If an update is in progress, we don't do anything if update_bluetooth_lock.locked(): - _LOGGER.warning( - "Updating %s took longer than the scheduled update of interval %s", - DOMAIN, + _LOGGER.info( + "Previous execution of update_bluetooth is taking longer than the scheduled update of interval %s", interval, ) return From 59b897e2185385e586c3fe22e9696c9005ab1571 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 19:01:40 +0300 Subject: [PATCH 11/13] Don't create a redundant task --- .../components/bluetooth_tracker/device_tracker.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index cf6526f0a5a72a..faac32e1129a88 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -73,13 +73,11 @@ async def see_device( if rssi is not None: attributes["rssi"] = rssi - await hass.async_create_task( - async_see( - mac=f"{BT_PREFIX}{mac}", - host_name=device_name, - attributes=attributes, - source_type=SOURCE_TYPE_BLUETOOTH, - ) + await async_see( + mac=f"{BT_PREFIX}{mac}", + host_name=device_name, + attributes=attributes, + source_type=SOURCE_TYPE_BLUETOOTH, ) From a6b59a1e4da284c55f95d452afa50b41b74890c3 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 20:27:59 +0300 Subject: [PATCH 12/13] Optimize see_device to run concurrently --- .../bluetooth_tracker/device_tracker.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index faac32e1129a88..fb0cf44db7246f 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -128,12 +128,17 @@ async def async_setup_scanner( if track_new: devices = await hass.async_add_executor_job(discover_devices, device_id) + + tasks = [] for mac, device_name in devices: if mac not in devices_to_track and mac not in devices_to_not_track: devices_to_track.add(mac) if mac in devices_to_track: - await see_device(hass, async_see, mac, device_name) + tasks.append(see_device(hass, async_see, mac, device_name)) + + if tasks: + await asyncio.wait(tasks) if request_rssi: _LOGGER.debug("Detecting RSSI for devices") @@ -142,6 +147,8 @@ async def perform_bluetooth_update(): """Discover Bluetooth devices and update status.""" _LOGGER.debug("Performing Bluetooth devices discovery and update") + tasks = [] + try: if track_new: devices = await hass.async_add_executor_job(discover_devices, device_id) @@ -161,7 +168,10 @@ async def perform_bluetooth_update(): rssi = await hass.async_add_executor_job(client.request_rssi) client.close() - await see_device(hass, async_see, mac, device_name, rssi) + tasks.append(see_device(hass, async_see, mac, device_name, rssi)) + + if tasks: + await asyncio.wait(tasks) except bluetooth.BluetoothError: _LOGGER.exception("Error looking up Bluetooth device") @@ -171,7 +181,7 @@ async def update_bluetooth(now=None): # If an update is in progress, we don't do anything if update_bluetooth_lock.locked(): - _LOGGER.info( + _LOGGER.debug( "Previous execution of update_bluetooth is taking longer than the scheduled update of interval %s", interval, ) From 8336a68a093d1041052db029fec16adfc28a3cd5 Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Fri, 13 Sep 2019 21:00:08 +0300 Subject: [PATCH 13/13] Remove redundant initialization scan --- .../components/bluetooth_tracker/device_tracker.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/homeassistant/components/bluetooth_tracker/device_tracker.py b/homeassistant/components/bluetooth_tracker/device_tracker.py index fb0cf44db7246f..6a26775b0a8ac7 100644 --- a/homeassistant/components/bluetooth_tracker/device_tracker.py +++ b/homeassistant/components/bluetooth_tracker/device_tracker.py @@ -126,20 +126,6 @@ async def async_setup_scanner( if not devices_to_track and not track_new: _LOGGER.debug("No Bluetooth devices to track and not tracking new devices") - if track_new: - devices = await hass.async_add_executor_job(discover_devices, device_id) - - tasks = [] - for mac, device_name in devices: - if mac not in devices_to_track and mac not in devices_to_not_track: - devices_to_track.add(mac) - - if mac in devices_to_track: - tasks.append(see_device(hass, async_see, mac, device_name)) - - if tasks: - await asyncio.wait(tasks) - if request_rssi: _LOGGER.debug("Detecting RSSI for devices")