diff --git a/homeassistant/components/smarla/__init__.py b/homeassistant/components/smarla/__init__.py index 137fcf62b82..d005f0020fb 100644 --- a/homeassistant/components/smarla/__init__.py +++ b/homeassistant/components/smarla/__init__.py @@ -7,9 +7,6 @@ from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryError from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity import Entity -from homeassistant.helpers.typing import ConfigType from .const import DOMAIN, HOST, PLATFORMS @@ -18,11 +15,6 @@ CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) type FederwiegeConfigEntry = ConfigEntry[Federwiege] -async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: - """Set up this integration using YAML is not supported.""" - return True - - async def async_setup_entry(hass: HomeAssistant, entry: FederwiegeConfigEntry) -> bool: """Set up this integration using UI.""" if hass.data.get(DOMAIN) is None: @@ -68,24 +60,3 @@ async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: """Reload config entry.""" await async_unload_entry(hass, entry) await async_setup_entry(hass, entry) - - -class SmarlaBaseEntity(Entity): - """Common Base Entity class for defining Smarla device.""" - - def __init__( - self, - federwiege: Federwiege, - ) -> None: - """Initialise the entity.""" - super().__init__() - - self._attr_has_entity_name = True - - self._attr_device_info = DeviceInfo( - identifiers={(DOMAIN, federwiege.serial_number)}, - name="Federwiege", - model="Smarla", - manufacturer="Swing2Sleep", - serial_number=federwiege.serial_number, - ) diff --git a/homeassistant/components/smarla/config_flow.py b/homeassistant/components/smarla/config_flow.py index 37eb3900945..fbfe0e9299c 100644 --- a/homeassistant/components/smarla/config_flow.py +++ b/homeassistant/components/smarla/config_flow.py @@ -2,6 +2,8 @@ from __future__ import annotations +from typing import Any + from pysmarlaapi import Connection import voluptuous as vol @@ -19,7 +21,9 @@ class SmarlaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_PUSH - async def async_step_user(self, user_input=None) -> config_entries.ConfigFlowResult: + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> config_entries.ConfigFlowResult: """Handle the initial step.""" if user_input is None: return self.async_show_form( @@ -27,18 +31,20 @@ class SmarlaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): data_schema=STEP_USER_DATA_SCHEMA, ) - errors = {} + errors: dict[str, str] = {} try: info = await self.validate_input(user_input) + except InvalidAuth: + errors["base"] = "invalid_auth" + except InvalidToken: + errors["base"] = "invalid_token" + + if not errors: return self.async_create_entry( title=info["title"], data={CONF_ACCESS_TOKEN: info.get(CONF_ACCESS_TOKEN)}, ) - except InvalidAuth: - errors["base"] = "invalid_auth" - except ValueError: - errors["base"] = "invalid_token" return self.async_show_form( step_id="user", @@ -46,12 +52,15 @@ class SmarlaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): errors=errors, ) - async def validate_input(self, data): + async def validate_input(self, data: dict[str, Any]): """Validate the user input allows us to connect. Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user. """ - conn = Connection(url=HOST, token_b64=data[CONF_ACCESS_TOKEN]) + try: + conn = Connection(url=HOST, token_b64=data[CONF_ACCESS_TOKEN]) + except ValueError as e: + raise InvalidToken from e await self.async_set_unique_id(conn.token.serialNumber) self._abort_if_unique_id_configured() @@ -67,3 +76,7 @@ class SmarlaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): class InvalidAuth(exceptions.HomeAssistantError): """Error to indicate there is invalid auth.""" + + +class InvalidToken(exceptions.HomeAssistantError): + """Error to indicate there is an invalid token.""" diff --git a/homeassistant/components/smarla/entity.py b/homeassistant/components/smarla/entity.py new file mode 100644 index 00000000000..fb28d55bdf2 --- /dev/null +++ b/homeassistant/components/smarla/entity.py @@ -0,0 +1,29 @@ +"""Common base for entities.""" + +from pysmarlaapi import Federwiege + +from homeassistant.helpers.device_registry import DeviceInfo +from homeassistant.helpers.entity import Entity + +from .const import DOMAIN + + +class SmarlaBaseEntity(Entity): + """Common Base Entity class for defining Smarla device.""" + + def __init__( + self, + federwiege: Federwiege, + ) -> None: + """Initialise the entity.""" + super().__init__() + + self._attr_has_entity_name = True + + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, federwiege.serial_number)}, + name="Federwiege", + model="Smarla", + manufacturer="Swing2Sleep", + serial_number=federwiege.serial_number, + ) diff --git a/homeassistant/components/smarla/number.py b/homeassistant/components/smarla/number.py index a177759f3bc..8f8d2ec82c2 100644 --- a/homeassistant/components/smarla/number.py +++ b/homeassistant/components/smarla/number.py @@ -1,6 +1,7 @@ """Support for the Swing2Sleep Smarla number entities.""" from dataclasses import dataclass +from typing import Any from pysmarlaapi import Federwiege @@ -12,7 +13,8 @@ from homeassistant.components.number import ( from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import FederwiegeConfigEntry, SmarlaBaseEntity +from . import FederwiegeConfigEntry +from .entity import SmarlaBaseEntity @dataclass(frozen=True, kw_only=True) @@ -45,7 +47,7 @@ async def async_setup_entry( """Set up the Smarla numbers from config entry.""" federwiege = config_entry.runtime_data - entities: list[SmarlaNumber] = [] + entities: list[NumberEntity] = [] for desc in NUMBER_TYPES: entity = SmarlaNumber(federwiege, desc) @@ -57,7 +59,7 @@ async def async_setup_entry( class SmarlaNumber(SmarlaBaseEntity, NumberEntity): """Representation of Smarla number.""" - async def on_change(self, value): + async def on_change(self, value: Any): """Notify ha when state changes.""" self.async_write_ha_state() diff --git a/homeassistant/components/smarla/sensor.py b/homeassistant/components/smarla/sensor.py index 35041748eec..1af4aa04a22 100644 --- a/homeassistant/components/smarla/sensor.py +++ b/homeassistant/components/smarla/sensor.py @@ -1,6 +1,7 @@ """Support for the Swing2Sleep Smarla sensor entities.""" from dataclasses import dataclass +from typing import Any from pysmarlaapi import Federwiege @@ -13,7 +14,8 @@ from homeassistant.const import UnitOfLength, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import FederwiegeConfigEntry, SmarlaBaseEntity +from . import FederwiegeConfigEntry +from .entity import SmarlaBaseEntity @dataclass(frozen=True, kw_only=True) @@ -72,7 +74,7 @@ async def async_setup_entry( """Set up the Smarla sensors from config entry.""" federwiege = config_entry.runtime_data - entities: list[SmarlaSensor] = [] + entities: list[SensorEntity] = [] for desc in NUMBER_TYPES: entity = SmarlaSensor(federwiege, desc) @@ -84,7 +86,7 @@ async def async_setup_entry( class SmarlaSensor(SmarlaBaseEntity, SensorEntity): """Representation of Smarla sensor.""" - async def on_change(self, value): + async def on_change(self, value: Any): """Notify ha when state changes.""" self.async_write_ha_state() diff --git a/homeassistant/components/smarla/switch.py b/homeassistant/components/smarla/switch.py index 1397ee33581..9eeb4008ff6 100644 --- a/homeassistant/components/smarla/switch.py +++ b/homeassistant/components/smarla/switch.py @@ -9,7 +9,8 @@ from homeassistant.components.switch import SwitchEntity, SwitchEntityDescriptio from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from . import FederwiegeConfigEntry, SmarlaBaseEntity +from . import FederwiegeConfigEntry +from .entity import SmarlaBaseEntity @dataclass(frozen=True, kw_only=True) @@ -44,7 +45,7 @@ async def async_setup_entry( """Set up the Smarla switches from config entry.""" federwiege = config_entry.runtime_data - entities: list[SmarlaSwitch] = [] + entities: list[SwitchEntity] = [] for desc in NUMBER_TYPES: entity = SmarlaSwitch(federwiege, desc) @@ -56,7 +57,7 @@ async def async_setup_entry( class SmarlaSwitch(SmarlaBaseEntity, SwitchEntity): """Representation of Smarla switch.""" - async def on_change(self, value): + async def on_change(self, value: Any): """Notify ha when state changes.""" self.async_write_ha_state()