diff --git a/custom_components/tapo/__init__.py b/custom_components/tapo/__init__.py index ca84a1a..6f6ca7d 100755 --- a/custom_components/tapo/__init__.py +++ b/custom_components/tapo/__init__.py @@ -13,7 +13,6 @@ from custom_components.tapo.errors import DeviceNotSupported from custom_components.tapo.hub.tapo_hub import TapoHub from custom_components.tapo.setup_helpers import setup_tapo_device, setup_tapo_hub -from custom_components.tapo.tapo_device import TapoDevice from .const import DEFAULT_POLLING_RATE_S, DOMAIN, HUB_PLATFORMS, PLATFORMS @@ -51,6 +50,13 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry): config_entry.version = 2 hass.config_entries.async_update_entry(config_entry, data=new) + elif config_entry.version == 2: + new_data = {**config_entry.data} + scan_interval = new_data.pop(CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S) + config_entry.version = 3 + hass.config_entries.async_update_entry( + config_entry, data=new_data, options={CONF_SCAN_INTERVAL: scan_interval} + ) _LOGGER.info("Migration to version %s successful", config_entry.version) diff --git a/custom_components/tapo/config_flow.py b/custom_components/tapo/config_flow.py index e01339d..66308c8 100755 --- a/custom_components/tapo/config_flow.py +++ b/custom_components/tapo/config_flow.py @@ -27,7 +27,6 @@ from custom_components.tapo.errors import CannotConnect, InvalidAuth, InvalidHost from custom_components.tapo.helpers import ( get_short_model, - merge_data_options, value_or_raise, ) @@ -69,7 +68,7 @@ class FirstStepData: class TapoConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle a config flow for tapo.""" - VERSION = 2 + VERSION = 3 CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL def __init__(self) -> None: @@ -86,27 +85,27 @@ async def async_step_user( if user_input is not None: try: - if not user_input[CONF_HOST]: - raise InvalidHost api = await self._try_setup_api(user_input) - unique_data = await self._get_first_data_from_api(api) - unique_id = unique_data.device_id - await self.async_set_unique_id(unique_id) + device_data = await self._get_first_data_from_api(api) + device_id = device_data.device_id + await self.async_set_unique_id(device_id) self._abort_if_unique_id_configured() - self.hass.data[DOMAIN][f"{unique_id}_api"] = api + self.hass.data[DOMAIN][f"{device_id}_api"] = api - if get_short_model(unique_data.model) == SUPPORTED_HUB_DEVICE_MODEL: + if get_short_model(device_data.model) == SUPPORTED_HUB_DEVICE_MODEL: return self.async_create_entry( - title=f"Tapo Hub {unique_data.nickname}", + title=f"Tapo Hub {device_data.nickname}", data={"is_hub": True, **user_input}, + options={CONF_SCAN_INTERVAL: DEFAULT_POLLING_RATE_S}, ) elif user_input.get(CONF_ADVANCED_SETTINGS, False): - self.first_step_data = FirstStepData(unique_data, user_input) + self.first_step_data = FirstStepData(device_data, user_input) return await self.async_step_advanced_config() else: return self.async_create_entry( - title=unique_data.nickname, + title=device_data.nickname, data=user_input, + options={CONF_SCAN_INTERVAL: DEFAULT_POLLING_RATE_S}, ) except InvalidAuth as error: errors["base"] = "invalid_auth" @@ -143,10 +142,8 @@ async def async_step_advanced_config( polling_rate = user_input.get(CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S) return self.async_create_entry( title=self.first_step_data.state.nickname, - data={ - CONF_SCAN_INTERVAL: polling_rate, - **self.first_step_data.user_input, - }, + data=self.first_step_data.user_input, + options={CONF_SCAN_INTERVAL: polling_rate}, ) else: return self.async_show_form( @@ -168,6 +165,8 @@ async def _get_first_data_from_api(self, api: TapoClient) -> DeviceInfo: async def _try_setup_api( self, user_input: Optional[dict[str, Any]] = None ) -> TapoClient: + if not user_input[CONF_HOST]: + raise InvalidHost try: session = async_create_clientsession(self.hass) client = TapoClient( @@ -198,7 +197,6 @@ async def async_step_init( self, user_input: dict[str, Any] | None = None ) -> data_entry_flow.FlowResult: """Manage the options.""" - entry_data = merge_data_options(self.config_entry) if user_input is not None: return self.async_create_entry(title="", data=user_input) schema = vol.Schema( @@ -206,7 +204,9 @@ async def async_step_init( vol.Optional( CONF_SCAN_INTERVAL, description="Polling rate in seconds (e.g. 0.5 seconds means 500ms)", - default=entry_data.get(CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S), + default=self.config_entry.options.get( + CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S + ), ): vol.All(vol.Coerce(float), vol.Clamp(min=1)), } ) diff --git a/custom_components/tapo/helpers.py b/custom_components/tapo/helpers.py index 35d94a1..5d6eea0 100644 --- a/custom_components/tapo/helpers.py +++ b/custom_components/tapo/helpers.py @@ -1,6 +1,5 @@ -from typing import Any, TypeVar, Union +from typing import TypeVar, Union -from homeassistant.config_entries import ConfigEntry from plugp100.common.functional.either import Either T = TypeVar("T") @@ -20,10 +19,3 @@ def clamp(value, min_value, max_value): def get_short_model(model: str) -> str: return model.lower().split(maxsplit=1)[0] - - -def merge_data_options(entry: ConfigEntry) -> dict[str, Any]: - data = dict(entry.data) - if entry.options: - data.update(entry.options) - return data diff --git a/custom_components/tapo/hub/siren.py b/custom_components/tapo/hub/siren.py index 34c6722..0ddb54d 100644 --- a/custom_components/tapo/hub/siren.py +++ b/custom_components/tapo/hub/siren.py @@ -24,7 +24,9 @@ async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_devices: AddEntitiesCallback ): data = cast(HassTapoDeviceData, hass.data[DOMAIN][entry.entry_id]) - available_tones = (await data.coordinator.device.get_supported_alarm_tones()).tones + available_tones = value_or_raise( + await data.coordinator.device.get_supported_alarm_tones() + ).tones async_add_devices([HubSiren(data.coordinator, available_tones)], True) diff --git a/custom_components/tapo/hub/tapo_hub.py b/custom_components/tapo/hub/tapo_hub.py index 3c576ff..d36cc31 100644 --- a/custom_components/tapo/hub/tapo_hub.py +++ b/custom_components/tapo/hub/tapo_hub.py @@ -21,7 +21,7 @@ class TapoHub: async def initialize_hub(self, hass: HomeAssistant): polling_rate = timedelta( - seconds=self.entry.data.get(CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S) + seconds=self.entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S) ) value_or_raise(await self.hub.login()) hub_coordinator = TapoHubCoordinator(hass, self.hub, polling_rate) diff --git a/custom_components/tapo/manifest.json b/custom_components/tapo/manifest.json index cf69c9b..e9e1b2c 100755 --- a/custom_components/tapo/manifest.json +++ b/custom_components/tapo/manifest.json @@ -7,7 +7,7 @@ "documentation": "https://github.com/petretiandrea/home-assistant-tapo-p100", "issue_tracker": "https://github.com/petretiandrea/home-assistant-tapo-p100/issues", "requirements": [ - "plugp100==3.2.0" + "plugp100==3.4.0" ], "dependencies": [], "integration_type": "hub", diff --git a/custom_components/tapo/tapo_device.py b/custom_components/tapo/tapo_device.py index 2229809..4f24af3 100644 --- a/custom_components/tapo/tapo_device.py +++ b/custom_components/tapo/tapo_device.py @@ -1,6 +1,5 @@ from dataclasses import dataclass from datetime import timedelta -from typing import Any, Dict from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_SCAN_INTERVAL @@ -24,7 +23,7 @@ class TapoDevice: async def initialize_device(self, hass: HomeAssistant) -> bool: polling_rate = timedelta( - seconds=self.entry.data.get(CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S) + seconds=self.entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_POLLING_RATE_S) ) host = self.entry.data.get(CONF_HOST) coordinator = await create_coordinator(hass, self.client, host, polling_rate) diff --git a/requirements_dev.txt b/requirements_dev.txt index fba9c4e..797d2bc 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,2 +1,2 @@ homeassistant==2022.12.8 -plugp100==3.2.0 \ No newline at end of file +plugp100==3.4.0 \ No newline at end of file