Handle module errors more robustly and add query params to light preset and transition (#1036)

Ensures that all modules try to access their data in `_post_update_hook` in a safe manner and disable themselves if there's an error.
Also adds parameters to get_preset_rules and get_on_off_gradually_info to fix issues with recent firmware updates.
[#1033](https://github.com/python-kasa/python-kasa/issues/1033)
This commit is contained in:
Steven B
2024-07-04 08:02:50 +01:00
committed by GitHub
parent 9cffbe9e48
commit 905a14895d
17 changed files with 206 additions and 30 deletions

View File

@@ -177,11 +177,20 @@ class SmartDevice(Device):
self._children[info["device_id"]]._update_internal_state(info)
# Call handle update for modules that want to update internal data
for module in self._modules.values():
module._post_update_hook()
errors = []
for module_name, module in self._modules.items():
if not self._handle_module_post_update_hook(module):
errors.append(module_name)
for error in errors:
self._modules.pop(error)
for child in self._children.values():
for child_module in child._modules.values():
child_module._post_update_hook()
errors = []
for child_module_name, child_module in child._modules.items():
if not self._handle_module_post_update_hook(child_module):
errors.append(child_module_name)
for error in errors:
child._modules.pop(error)
# We can first initialize the features after the first update.
# We make here an assumption that every device has at least a single feature.
@@ -190,6 +199,19 @@ class SmartDevice(Device):
_LOGGER.debug("Got an update: %s", self._last_update)
def _handle_module_post_update_hook(self, module: SmartModule) -> bool:
try:
module._post_update_hook()
return True
except Exception as ex:
_LOGGER.error(
"Error processing %s for device %s, module will be unavailable: %s",
module.name,
self.host,
ex,
)
return False
async def _initialize_modules(self):
"""Initialize modules based on component negotiation response."""
from .smartmodule import SmartModule