diff --git a/custom_components/tapo/__init__.py b/custom_components/tapo/__init__.py index 171e90f..a5d73b9 100755 --- a/custom_components/tapo/__init__.py +++ b/custom_components/tapo/__init__.py @@ -41,10 +41,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): (await api.get_device_info()).map(lambda x: DeviceInfo(**x)).get_or_raise() ) if get_short_model(state.model) in SUPPORTED_HUB_DEVICE_MODEL: - scan_interval = entry.data.get(CONF_SCAN_INTERVAL) + scan_interval_millis = entry.data.get(CONF_SCAN_INTERVAL) * 1000 hub = TapoHub( entry, - HubDevice(api, subscription_polling_interval_millis=scan_interval), + HubDevice( + api, subscription_polling_interval_millis=scan_interval_millis + ), ) return await hub.initialize_hub(hass) else: diff --git a/custom_components/tapo/hub/tapo_hub.py b/custom_components/tapo/hub/tapo_hub.py index fd1b04f..7c02af4 100644 --- a/custom_components/tapo/hub/tapo_hub.py +++ b/custom_components/tapo/hub/tapo_hub.py @@ -1,3 +1,4 @@ +import logging from dataclasses import dataclass from datetime import timedelta from typing import List @@ -18,6 +19,8 @@ from homeassistant.helpers.device_registry import DeviceEntry from homeassistant.helpers.device_registry import DeviceRegistry from plugp100.api.hub.hub_device import HubDevice +from plugp100.api.hub.hub_device_tracker import DeviceAdded +from plugp100.api.hub.hub_device_tracker import HubDeviceEvent from plugp100.api.hub.s200b_device import S200ButtonDevice from plugp100.api.hub.switch_child_device import SwitchChildDevice from plugp100.api.hub.t100_device import T100MotionSensor @@ -26,6 +29,8 @@ from plugp100.responses.device_state import DeviceInfo from plugp100.responses.hub_childs.hub_child_base_info import HubChildBaseInfo +_LOGGER = logging.getLogger(__name__) + @dataclass class TapoHub: @@ -51,7 +56,6 @@ async def initialize_hub(self, hass: HomeAssistant): hw_version=device_info.hardware_version, ) - # TODO: TIPS: attach to hub coordinator to handle device removal device_list = ( (await self.hub.get_children()).get_or_else([]).get_children_base_info() ) @@ -66,6 +70,21 @@ async def initialize_hub(self, hass: HomeAssistant): ), child_coordinators=child_coordinators, ) + + # TODO: refactory with add_device and remove_device methods + initial_device_ids = list(map(lambda x: x.device_id, device_list)) + + async def _handle_child_device_event(event: HubDeviceEvent): + _LOGGER.info("Detected child association change %s", str(event)) + if event.device_id not in initial_device_ids: + await hass.config_entries.async_reload(self.entry.entry_id) + elif event is DeviceAdded: + initial_device_ids.remove(event.device_id) + + self.entry.async_on_unload( + self.hub.subscribe_device_association(_handle_child_device_event) + ) + await hass.config_entries.async_forward_entry_setups(self.entry, HUB_PLATFORMS) return True @@ -76,14 +95,14 @@ async def setup_child_devices( device_list: list[HubChildBaseInfo], ): knwon_children = [ - self.add_child_device(registry, device_state) + self.add_child_device(registry, device_state).id for device_state in device_list ] # delete device which is no longer available to hub for device in dr.async_entries_for_config_entry(registry, self.entry.entry_id): # avoid delete hub device which has a connection - if device not in knwon_children and device.connections is []: + if device.id not in knwon_children and len(device.connections) == 0: registry.async_remove_device(device.id) async def setup_child_coordinators(