From ced70971cb013565a4099e7e5a57ff92313f72cc Mon Sep 17 00:00:00 2001 From: regevbr Date: Thu, 14 Mar 2024 00:11:56 +0200 Subject: [PATCH 1/7] fix setting attribute changes state to None --- custom_components/zha_toolkit/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/custom_components/zha_toolkit/utils.py b/custom_components/zha_toolkit/utils.py index c24fd54..09c9454 100644 --- a/custom_components/zha_toolkit/utils.py +++ b/custom_components/zha_toolkit/utils.py @@ -356,7 +356,11 @@ def set_state( # entity_id, key, value, stateAttrs) if key is not None: stateAttrs[key] = value - value = None + if stateObj is not None: + # Copy existing state, to update selected item + value = stateObj.state + else: + value = None # LOGGER.debug("entity:%s key:%s value:%s attrs:%s", # entity_id, key, value, stateAttrs) From 4c4284a00fa17e5f45f513b8d25c4bfdd82a0f4b Mon Sep 17 00:00:00 2001 From: Ben Schumacher Date: Thu, 9 May 2024 08:13:46 -0600 Subject: [PATCH 2/7] Fix for blocking call issue --- custom_components/zha_toolkit/default.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/custom_components/zha_toolkit/default.py b/custom_components/zha_toolkit/default.py index c94df12..4e68c58 100644 --- a/custom_components/zha_toolkit/default.py +++ b/custom_components/zha_toolkit/default.py @@ -1,7 +1,14 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, final + import importlib import logging import sys +if TYPE_CHECKING: + from types import ModuleType + LOGGER = logging.getLogger(__name__) @@ -27,13 +34,16 @@ async def default(app, listener, ieee, cmd, data, service, params, event_data): module_name = cmd[0] cmd = cmd[1] - LOGGER.debug( - f"Trying to import {package_name}.{module_name} to call {cmd}" - ) - m = importlib.import_module(f".{module_name}", package=package_name) + def _reload_command_module() -> ModuleType: + LOGGER.debug( + f"Trying to import {package_name}.{module_name} to call {cmd}" + ) + m = importlib.import_module(f".{module_name}", package=package_name) - importlib.reload(m) + importlib.reload(m) + return m + m = await listener.hass.async_add_import_executor_job(_reload_command_module) # Get handler (cmd) in loaded module. handler = getattr(m, cmd) # Call the handler From a9b37ca24435de081b797e42fbf9afdb8a002dbb Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Sat, 4 May 2024 02:05:19 +0200 Subject: [PATCH 3/7] Test that app has ota and ota has listeners for OTA operations Apparently in some situations they're absent. Let's guard against them. Closes issue #225 --- custom_components/zha_toolkit/ota.py | 40 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/custom_components/zha_toolkit/ota.py b/custom_components/zha_toolkit/ota.py index 9fae296..073d2d4 100644 --- a/custom_components/zha_toolkit/ota.py +++ b/custom_components/zha_toolkit/ota.py @@ -158,28 +158,34 @@ async def download_sonoff_ota(listener, ota_dir): async def download_zigpy_ota(app, listener): LOGGER.debug("Zigpy download procedure starting") - for _, (ota, _) in app.ota._listeners.items(): - if isinstance(ota, zigpy.ota.provider.FileStore): - # Skip files provider - continue - await ota.refresh_firmware_list() - for image_key, image in ota._cache.items(): - url = getattr(image, "url", None) - LOGGER.error("Try getting %r, %r, %r", image_key, url, image) - try: - img = await app.ota.get_ota_image( - image_key.manufacturer_id, image_key.image_type, model=None - ) - LOGGER.info("Got image %r", getattr(img, "header", None)) - except Exception as e: - LOGGER.error("%r while getting %r - %s", e, image_key, url) + if hasattr(app, 'ota') and hasattr(app.ota, '_listeners'): + for _, (ota, _) in app.ota._listeners.items(): + if isinstance(ota, zigpy.ota.provider.FileStore): + # Skip files provider + continue + await ota.refresh_firmware_list() + for image_key, image in ota._cache.items(): + url = getattr(image, "url", None) + LOGGER.error("Try getting %r, %r, %r", image_key, url, image) + try: + img = await app.ota.get_ota_image( + image_key.manufacturer_id, image_key.image_type, model=None + ) + LOGGER.info("Got image %r", getattr(img, "header", None)) + except Exception as e: + LOGGER.error("%r while getting %r - %s", e, image_key, url) + else: + LOGGER.warning("Could not get ota object for download_zigpy_ota, try again") async def ota_update_images( app, listener, ieee, cmd, data, service, params, event_data ): - for _, (ota, _) in app.ota._listeners.items(): - await ota.refresh_firmware_list() + if hasattr(app, 'ota') and hasattr(app.ota, '_listeners'): + for _, (ota, _) in app.ota._listeners.items(): + await ota.refresh_firmware_list() + else: + LOGGER.warning("Could not get ota object for ota_update_images, try again") async def ota_notify( From 224e665390769c3cf1280e0e6fba492d46626006 Mon Sep 17 00:00:00 2001 From: Derek Frankhouser Date: Mon, 10 Jun 2024 21:17:38 -0400 Subject: [PATCH 4/7] remove direct refs to homeassistant.helpers when HA >= 2024.6 Closes #229 Apprach taken from https://github.com/custom-components/ble_monitor/commit/a95ae14a2146ff6db009ef428e8aeb5733c47238 --- custom_components/zha_toolkit/utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/custom_components/zha_toolkit/utils.py b/custom_components/zha_toolkit/utils.py index 09c9454..d738ca6 100644 --- a/custom_components/zha_toolkit/utils.py +++ b/custom_components/zha_toolkit/utils.py @@ -34,6 +34,9 @@ # pylint: disable=ungrouped-imports from homeassistant.helpers.json import save_json +if parse_version(HA_VERSION) >= parse_version("2024.6"): + from homeassistant.helpers import device_registry as dr, entity_registry as er + if typing.TYPE_CHECKING: VERSION_TIME: float = 0.0 VERSION: str = "Unknown" @@ -286,6 +289,8 @@ async def get_ieee(app, listener, ref): else get_hass(listener).helpers.entity_registry.async_get( get_hass(listener) ) + if not is_ha_ge("2024.6") + else er.async_get(get_hass(listener)) ) device_registry = ( @@ -297,6 +302,8 @@ async def get_ieee(app, listener, ref): else get_hass(listener).helpers.device_registry.async_get( get_hass(listener) ) + if not is_ha_ge("2024.6") + else dr.async_get(get_hass(listener)) ) registry_device = device_registry.async_get(ref) From 00eb4925337ab7071dcf444ec3dce2266a6877a8 Mon Sep 17 00:00:00 2001 From: mdeweerd Date: Tue, 30 Jul 2024 19:23:16 +0200 Subject: [PATCH 5/7] Apply pre-commit/black --- custom_components/zha_toolkit/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/zha_toolkit/utils.py b/custom_components/zha_toolkit/utils.py index d738ca6..e3d0307 100644 --- a/custom_components/zha_toolkit/utils.py +++ b/custom_components/zha_toolkit/utils.py @@ -35,7 +35,8 @@ from homeassistant.helpers.json import save_json if parse_version(HA_VERSION) >= parse_version("2024.6"): - from homeassistant.helpers import device_registry as dr, entity_registry as er + from homeassistant.helpers import device_registry as dr + from homeassistant.helpers import entity_registry as er if typing.TYPE_CHECKING: VERSION_TIME: float = 0.0 From 58169f59ec5dbb092a93eb9cdc5c8be45650a456 Mon Sep 17 00:00:00 2001 From: mdeweerd Date: Tue, 30 Jul 2024 19:27:18 +0200 Subject: [PATCH 6/7] Apply black/flake (pre-commit) --- custom_components/zha_toolkit/default.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/custom_components/zha_toolkit/default.py b/custom_components/zha_toolkit/default.py index 4e68c58..ad1bab7 100644 --- a/custom_components/zha_toolkit/default.py +++ b/custom_components/zha_toolkit/default.py @@ -1,10 +1,9 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, final - import importlib import logging import sys +from typing import TYPE_CHECKING if TYPE_CHECKING: from types import ModuleType @@ -43,7 +42,9 @@ def _reload_command_module() -> ModuleType: importlib.reload(m) return m - m = await listener.hass.async_add_import_executor_job(_reload_command_module) + m = await listener.hass.async_add_import_executor_job( + _reload_command_module + ) # Get handler (cmd) in loaded module. handler = getattr(m, cmd) # Call the handler From b8903f96efb7b31b429fb4bcba5df836a6bc5ee9 Mon Sep 17 00:00:00 2001 From: mdeweerd Date: Tue, 30 Jul 2024 19:40:00 +0200 Subject: [PATCH 7/7] Apply formatting tools (black) with pre-commit --- custom_components/zha_toolkit/ota.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/custom_components/zha_toolkit/ota.py b/custom_components/zha_toolkit/ota.py index 073d2d4..3f5f16b 100644 --- a/custom_components/zha_toolkit/ota.py +++ b/custom_components/zha_toolkit/ota.py @@ -158,7 +158,7 @@ async def download_sonoff_ota(listener, ota_dir): async def download_zigpy_ota(app, listener): LOGGER.debug("Zigpy download procedure starting") - if hasattr(app, 'ota') and hasattr(app.ota, '_listeners'): + if hasattr(app, "ota") and hasattr(app.ota, "_listeners"): for _, (ota, _) in app.ota._listeners.items(): if isinstance(ota, zigpy.ota.provider.FileStore): # Skip files provider @@ -169,23 +169,29 @@ async def download_zigpy_ota(app, listener): LOGGER.error("Try getting %r, %r, %r", image_key, url, image) try: img = await app.ota.get_ota_image( - image_key.manufacturer_id, image_key.image_type, model=None + image_key.manufacturer_id, + image_key.image_type, + model=None, ) LOGGER.info("Got image %r", getattr(img, "header", None)) except Exception as e: LOGGER.error("%r while getting %r - %s", e, image_key, url) else: - LOGGER.warning("Could not get ota object for download_zigpy_ota, try again") + LOGGER.warning( + "Could not get ota object for download_zigpy_ota, try again" + ) async def ota_update_images( app, listener, ieee, cmd, data, service, params, event_data ): - if hasattr(app, 'ota') and hasattr(app.ota, '_listeners'): + if hasattr(app, "ota") and hasattr(app.ota, "_listeners"): for _, (ota, _) in app.ota._listeners.items(): await ota.refresh_firmware_list() else: - LOGGER.warning("Could not get ota object for ota_update_images, try again") + LOGGER.warning( + "Could not get ota object for ota_update_images, try again" + ) async def ota_notify(