From 85f5750d31696290dbb8a499b49a77bc7624f98c Mon Sep 17 00:00:00 2001 From: SukramJ Date: Mon, 20 May 2024 16:32:04 +0200 Subject: [PATCH] Use PEP 695 typing pt2 (#1565) * Use PEP 695 typing pt2 * Use PEP 695 typing pt3 * Update number.py * Fixes * Refactor number preparation --- hahomematic/platforms/custom/climate.py | 22 +++--- hahomematic/platforms/custom/cover.py | 20 +++--- hahomematic/platforms/custom/entity.py | 3 +- hahomematic/platforms/custom/light.py | 14 ++-- hahomematic/platforms/custom/lock.py | 18 +++-- hahomematic/platforms/custom/siren.py | 4 +- hahomematic/platforms/decorators.py | 11 ++- hahomematic/platforms/entity.py | 28 ++++---- .../platforms/generic/binary_sensor.py | 6 +- hahomematic/platforms/generic/entity.py | 14 ++-- hahomematic/platforms/generic/number.py | 68 +++++++++++-------- hahomematic/platforms/generic/sensor.py | 10 +-- hahomematic/platforms/generic/switch.py | 4 +- hahomematic/platforms/support.py | 4 +- 14 files changed, 125 insertions(+), 101 deletions(-) diff --git a/hahomematic/platforms/custom/climate.py b/hahomematic/platforms/custom/climate.py index 2cef7d5a..bb7137c7 100644 --- a/hahomematic/platforms/custom/climate.py +++ b/hahomematic/platforms/custom/climate.py @@ -107,10 +107,12 @@ class BaseClimateEntity(CustomEntity): def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() - self._e_humidity: HmSensor = self._get_entity(field=Field.HUMIDITY, entity_type=HmSensor) + self._e_humidity: HmSensor[int | None] = self._get_entity( + field=Field.HUMIDITY, entity_type=HmSensor[int | None] + ) self._e_setpoint: HmFloat = self._get_entity(field=Field.SETPOINT, entity_type=HmFloat) - self._e_temperature: HmSensor = self._get_entity( - field=Field.TEMPERATURE, entity_type=HmSensor + self._e_temperature: HmSensor[float | None] = self._get_entity( + field=Field.TEMPERATURE, entity_type=HmSensor[float | None] ) self._e_temperature_maximum: HmFloat = self._get_entity( field=Field.TEMPERATURE_MAXIMUM, entity_type=HmFloat @@ -141,17 +143,17 @@ def max_temp(self) -> float: """Return the maximum temperature.""" if self._e_temperature_maximum.value is not None: return float(self._e_temperature_maximum.value) - return self._e_setpoint.max + return self._e_setpoint.max # type: ignore[no-any-return] @value_property def current_humidity(self) -> int | None: """Return the current humidity.""" - return self._e_humidity.value # type: ignore[no-any-return] + return self._e_humidity.value @value_property def current_temperature(self) -> float | None: """Return current temperature.""" - return self._e_temperature.value # type: ignore[no-any-return] + return self._e_temperature.value @value_property def target_temperature(self) -> float | None: @@ -273,11 +275,11 @@ def _init_entity_fields(self) -> None: self._e_lowering_mode: HmAction = self._get_entity( field=Field.LOWERING_MODE, entity_type=HmAction ) - self._e_control_mode: HmSensor = self._get_entity( - field=Field.CONTROL_MODE, entity_type=HmSensor + self._e_control_mode: HmSensor[str | None] = self._get_entity( + field=Field.CONTROL_MODE, entity_type=HmSensor[str | None] ) - self._e_valve_state: HmSensor = self._get_entity( - field=Field.VALVE_STATE, entity_type=HmSensor + self._e_valve_state: HmSensor[int | None] = self._get_entity( + field=Field.VALVE_STATE, entity_type=HmSensor[int | None] ) @value_property diff --git a/hahomematic/platforms/custom/cover.py b/hahomematic/platforms/custom/cover.py index a6bc847f..19ed3792 100644 --- a/hahomematic/platforms/custom/cover.py +++ b/hahomematic/platforms/custom/cover.py @@ -98,11 +98,13 @@ def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() self._command_processing_lock = asyncio.Lock() - self._e_direction: HmSensor = self._get_entity(field=Field.DIRECTION, entity_type=HmSensor) + self._e_direction: HmSensor[str | None] = self._get_entity( + field=Field.DIRECTION, entity_type=HmSensor[str | None] + ) self._e_level: HmFloat = self._get_entity(field=Field.LEVEL, entity_type=HmFloat) self._e_stop: HmAction = self._get_entity(field=Field.STOP, entity_type=HmAction) - self._e_channel_level: HmSensor = self._get_entity( - field=Field.CHANNEL_LEVEL, entity_type=HmSensor + self._e_channel_level: HmSensor[float | None] = self._get_entity( + field=Field.CHANNEL_LEVEL, entity_type=HmSensor[float | None] ) @property @@ -238,8 +240,8 @@ class CeBlind(CeCover): def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() - self._e_channel_level_2: HmSensor = self._get_entity( - field=Field.CHANNEL_LEVEL_2, entity_type=HmSensor + self._e_channel_level_2: HmSensor[float | None] = self._get_entity( + field=Field.CHANNEL_LEVEL_2, entity_type=HmSensor[float | None] ) self._e_level_2: HmFloat = self._get_entity(field=Field.LEVEL_2, entity_type=HmFloat) self._e_combined: HmAction = self._get_entity( @@ -468,13 +470,15 @@ class CeGarage(CustomEntity): def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() - self._e_door_state: HmSensor = self._get_entity( - field=Field.DOOR_STATE, entity_type=HmSensor + self._e_door_state: HmSensor[str | None] = self._get_entity( + field=Field.DOOR_STATE, entity_type=HmSensor[str | None] ) self._e_door_command: HmAction = self._get_entity( field=Field.DOOR_COMMAND, entity_type=HmAction ) - self._e_section: HmSensor = self._get_entity(field=Field.SECTION, entity_type=HmSensor) + self._e_section: HmSensor[str | None] = self._get_entity( + field=Field.SECTION, entity_type=HmSensor[str | None] + ) @value_property def current_position(self) -> int | None: diff --git a/hahomematic/platforms/custom/entity.py b/hahomematic/platforms/custom/entity.py index 73fe76c1..62e66a38 100644 --- a/hahomematic/platforms/custom/entity.py +++ b/hahomematic/platforms/custom/entity.py @@ -281,7 +281,8 @@ def _get_entity[_EntityT: hmge.GenericEntity]( ) -> _EntityT: """Get entity.""" if entity := self._data_entities.get(field): - if not isinstance(entity, entity_type): + if type(entity).__name__ != entity_type.__name__: + # not isinstance(entity, entity_type): # does not work with generic type _LOGGER.debug( # pragma: no cover "GET_ENTITY: type mismatch for requested sub entity: " "expected: %s, but is %s for field name %s of entity %s", diff --git a/hahomematic/platforms/custom/light.py b/hahomematic/platforms/custom/light.py index 1b395f04..2fb99439 100644 --- a/hahomematic/platforms/custom/light.py +++ b/hahomematic/platforms/custom/light.py @@ -144,8 +144,8 @@ def _init_entity_fields(self) -> None: OnTimeMixin.__init__(self) super()._init_entity_fields() self._e_level: HmFloat = self._get_entity(field=Field.LEVEL, entity_type=HmFloat) - self._e_channel_level: HmSensor = self._get_entity( - field=Field.CHANNEL_LEVEL, entity_type=HmSensor + self._e_channel_level: HmSensor[float | None] = self._get_entity( + field=Field.CHANNEL_LEVEL, entity_type=HmSensor[float | None] ) self._e_on_time_value: HmAction = self._get_entity( field=Field.ON_TIME_VALUE, entity_type=HmAction @@ -437,8 +437,8 @@ class CeIpRGBWLight(CeDimmer): def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() - self._e_activity_state: HmSensor = self._get_entity( - field=Field.DIRECTION, entity_type=HmSensor + self._e_activity_state: HmSensor[str | None] = self._get_entity( + field=Field.DIRECTION, entity_type=HmSensor[str | None] ) self._e_color_temperature_kelvin: HmInteger = self._get_entity( field=Field.COLOR_TEMPERATURE, entity_type=HmInteger @@ -708,14 +708,14 @@ def color_name(self) -> str | None: @value_property def channel_color_name(self) -> str | None: """Return the name of the channel color.""" - return self._e_channel_color.value # type: ignore[no-any-return] + return self._e_channel_color.value def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() self._e_color: HmSelect = self._get_entity(field=Field.COLOR, entity_type=HmSelect) - self._e_channel_color: HmSensor = self._get_entity( - field=Field.CHANNEL_COLOR, entity_type=HmSensor + self._e_channel_color: HmSensor[str | None] = self._get_entity( + field=Field.CHANNEL_COLOR, entity_type=HmSensor[str | None] ) self._e_on_time_unit: HmAction = self._get_entity( field=Field.ON_TIME_UNIT, entity_type=HmAction diff --git a/hahomematic/platforms/custom/lock.py b/hahomematic/platforms/custom/lock.py index 9baceb6f..b4514944 100644 --- a/hahomematic/platforms/custom/lock.py +++ b/hahomematic/platforms/custom/lock.py @@ -98,18 +98,20 @@ class CeIpLock(BaseLock): def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() - self._e_lock_state: HmSensor = self._get_entity( - field=Field.LOCK_STATE, entity_type=HmSensor + self._e_lock_state: HmSensor[str | None] = self._get_entity( + field=Field.LOCK_STATE, entity_type=HmSensor[str | None] ) self._e_lock_target_level: HmAction = self._get_entity( field=Field.LOCK_TARGET_LEVEL, entity_type=HmAction ) - self._e_direction: HmSensor = self._get_entity(field=Field.DIRECTION, entity_type=HmSensor) + self._e_direction: HmSensor[str | None] = self._get_entity( + field=Field.DIRECTION, entity_type=HmSensor[str | None] + ) @value_property def is_locked(self) -> bool: """Return true if lock is on.""" - return self._e_lock_state.value == LockState.LOCKED # type: ignore[no-any-return] + return self._e_lock_state.value == LockState.LOCKED @value_property def is_locking(self) -> bool | None: @@ -158,8 +160,12 @@ def _init_entity_fields(self) -> None: super()._init_entity_fields() self._e_state: HmSwitch = self._get_entity(field=Field.STATE, entity_type=HmSwitch) self._e_open: HmAction = self._get_entity(field=Field.OPEN, entity_type=HmAction) - self._e_direction: HmSensor = self._get_entity(field=Field.DIRECTION, entity_type=HmSensor) - self._e_error: HmSensor = self._get_entity(field=Field.ERROR, entity_type=HmSensor) + self._e_direction: HmSensor[str | None] = self._get_entity( + field=Field.DIRECTION, entity_type=HmSensor[str | None] + ) + self._e_error: HmSensor[str | None] = self._get_entity( + field=Field.ERROR, entity_type=HmSensor[str | None] + ) @value_property def is_locked(self) -> bool: diff --git a/hahomematic/platforms/custom/siren.py b/hahomematic/platforms/custom/siren.py index 0686c2e1..a94038c2 100644 --- a/hahomematic/platforms/custom/siren.py +++ b/hahomematic/platforms/custom/siren.py @@ -188,8 +188,8 @@ class CeIpSirenSmoke(BaseSiren): def _init_entity_fields(self) -> None: """Init the entity fields.""" super()._init_entity_fields() - self._e_smoke_detector_alarm_status: HmSensor = self._get_entity( - field=Field.SMOKE_DETECTOR_ALARM_STATUS, entity_type=HmSensor + self._e_smoke_detector_alarm_status: HmSensor[str | None] = self._get_entity( + field=Field.SMOKE_DETECTOR_ALARM_STATUS, entity_type=HmSensor[str | None] ) self._e_smoke_detector_command: HmAction = self._get_entity( field=Field.SMOKE_DETECTOR_COMMAND, entity_type=HmAction diff --git a/hahomematic/platforms/decorators.py b/hahomematic/platforms/decorators.py index aaf2f2e0..4a518513 100644 --- a/hahomematic/platforms/decorators.py +++ b/hahomematic/platforms/decorators.py @@ -3,14 +3,11 @@ from __future__ import annotations from collections.abc import Callable, Mapping -from typing import Any, Generic, TypeVar - -_GETTER = TypeVar("_GETTER") -_SETTER = TypeVar("_SETTER") +from typing import Any # pylint: disable=invalid-name -class generic_property(Generic[_GETTER, _SETTER], property): +class generic_property[_GETTER, _SETTER](property): """Generic property implementation.""" fget: Callable[[Any], _GETTER] | None @@ -64,12 +61,12 @@ def __delete__(self, __obj: Any) -> None: # pylint: disable=invalid-name -class config_property(generic_property[_GETTER, _SETTER], property): +class config_property[_GETTER, _SETTER](generic_property[_GETTER, _SETTER]): """Decorate to mark own config properties.""" # pylint: disable=invalid-name -class value_property(generic_property[_GETTER, _SETTER], property): +class value_property[_GETTER, _SETTER](generic_property[_GETTER, _SETTER]): """Decorate to mark own value properties.""" diff --git a/hahomematic/platforms/entity.py b/hahomematic/platforms/entity.py index 96c0c6bf..ef375846 100644 --- a/hahomematic/platforms/entity.py +++ b/hahomematic/platforms/entity.py @@ -8,7 +8,7 @@ from functools import partial, wraps from inspect import getfullargspec import logging -from typing import Any, Final, Generic, TypeVar, cast +from typing import Any, Final, cast import voluptuous as vol @@ -43,6 +43,7 @@ from hahomematic.platforms.decorators import config_property, value_property from hahomematic.platforms.support import ( EntityNameData, + GenericParameterType, PayloadMixin, convert_value, generate_channel_unique_id, @@ -385,11 +386,10 @@ def __str__(self) -> str: ) -InputParameterT = TypeVar("InputParameterT", bool, int, float, str, int | float | str, None) -ParameterT = TypeVar("ParameterT", bool, int, float, str, int | str, None) - - -class BaseParameterEntity(Generic[ParameterT, InputParameterT], BaseEntity): +class BaseParameterEntity[ + ParameterT: GenericParameterType, + InputParameterT: GenericParameterType, +](BaseEntity): """Base class for stateless entities.""" def __init__( @@ -423,8 +423,8 @@ def __init__( custom_only=True, ) ) - self._value: ParameterT | None = None - self._old_value: ParameterT | None = None + self._value: ParameterT = None # type: ignore[assignment] + self._old_value: ParameterT = None # type: ignore[assignment] self._last_updated: datetime = INIT_DATETIME self._last_refreshed: datetime = INIT_DATETIME self._state_uncertain: bool = True @@ -542,15 +542,15 @@ def last_refreshed(self) -> datetime: return self._last_refreshed @property - def unconfirmed_last_value_send(self) -> ParameterT | None: + def unconfirmed_last_value_send(self) -> ParameterT: """Return the unconfirmed value send for the entity.""" return cast( - ParameterT | None, + ParameterT, self._client.last_value_send_cache.get_last_value_send(entity_key=self.entity_key), ) @property - def old_value(self) -> ParameterT | None: + def old_value(self) -> ParameterT: """Return the old value of the entity.""" return self._old_value @@ -565,7 +565,7 @@ def state_uncertain(self) -> bool: return self._state_uncertain @value_property - def value(self) -> ParameterT | None: + def value(self) -> ParameterT: """Return the value of the entity.""" return self._value @@ -679,14 +679,14 @@ async def load_entity_value(self, call_source: CallSource, direct_call: bool = F ) ) - def write_value(self, value: Any) -> tuple[ParameterT | None, ParameterT | None]: + def write_value(self, value: Any) -> tuple[ParameterT, ParameterT]: """Update value of the entity.""" old_value = self._value if value == NO_CACHE_ENTRY: if self.last_refreshed != INIT_DATETIME: self._state_uncertain = True self.fire_entity_updated_callback() - return (old_value, None) + return (old_value, None) # type: ignore[return-value] new_value = self._convert_value(value) if old_value == new_value: diff --git a/hahomematic/platforms/generic/binary_sensor.py b/hahomematic/platforms/generic/binary_sensor.py index ddc61a05..0583da8d 100644 --- a/hahomematic/platforms/generic/binary_sensor.py +++ b/hahomematic/platforms/generic/binary_sensor.py @@ -11,7 +11,7 @@ from hahomematic.platforms.generic.entity import GenericEntity -class HmBinarySensor(GenericEntity[bool, bool]): +class HmBinarySensor(GenericEntity[bool | None, bool]): """ Implementation of a binary_sensor. @@ -24,5 +24,5 @@ class HmBinarySensor(GenericEntity[bool, bool]): def value(self) -> bool | None: # type: ignore[override] """Return the value of the entity.""" if self._value is not None: - return self._value - return self._default + return self._value # type: ignore[no-any-return] + return self._default # type: ignore[no-any-return] diff --git a/hahomematic/platforms/generic/entity.py b/hahomematic/platforms/generic/entity.py index fecdc650..40aa0f81 100644 --- a/hahomematic/platforms/generic/entity.py +++ b/hahomematic/platforms/generic/entity.py @@ -9,12 +9,14 @@ from hahomematic.const import CallSource, EntityUsage, HomematicEventType, Parameter, ParamsetKey from hahomematic.platforms import device as hmd, entity as hme from hahomematic.platforms.decorators import config_property -from hahomematic.platforms.support import EntityNameData, get_entity_name +from hahomematic.platforms.support import EntityNameData, GenericParameterType, get_entity_name _LOGGER: Final = logging.getLogger(__name__) -class GenericEntity(hme.BaseParameterEntity[hme.ParameterT, hme.InputParameterT]): +class GenericEntity[ParameterT: GenericParameterType, InputParameterT: GenericParameterType]( + hme.BaseParameterEntity +): """Base class for generic entities.""" _validate_state_change: bool = True @@ -84,7 +86,7 @@ async def event(self, value: Any) -> None: async def send_value( self, - value: hme.InputParameterT, + value: InputParameterT, collector: hme.CallParameterCollector | None = None, collector_order: int = 50, do_validate: bool = True, @@ -117,8 +119,8 @@ async def send_value( ) def _prepare_value_for_sending( - self, value: hme.InputParameterT, do_validate: bool = True - ) -> hme.ParameterT: + self, value: InputParameterT, do_validate: bool = True + ) -> ParameterT: """Prepare value, if required, before send.""" return value # type: ignore[return-value] @@ -147,7 +149,7 @@ def _get_entity_usage(self) -> EntityUsage: else EntityUsage.ENTITY ) - def is_state_change(self, value: hme.ParameterT) -> bool: + def is_state_change(self, value: ParameterT) -> bool: """ Check if the state/value changes. diff --git a/hahomematic/platforms/generic/number.py b/hahomematic/platforms/generic/number.py index 6595b7f6..796e46d0 100644 --- a/hahomematic/platforms/generic/number.py +++ b/hahomematic/platforms/generic/number.py @@ -7,11 +7,13 @@ from __future__ import annotations from hahomematic.const import HmPlatform -from hahomematic.platforms.entity import ParameterT +from hahomematic.platforms.decorators import value_property from hahomematic.platforms.generic.entity import GenericEntity -class BaseNumber(GenericEntity[ParameterT, int | float | str]): +class BaseNumber[NumberParameterT: int | float | None]( + GenericEntity[NumberParameterT, int | float | str] +): """ Implementation of a number. @@ -20,8 +22,25 @@ class BaseNumber(GenericEntity[ParameterT, int | float | str]): _platform = HmPlatform.NUMBER + def _prepare_number_for_sending( + self, value: int | float | str, type_converter: type, do_validate: bool = True + ) -> NumberParameterT: + """Prepare value before sending.""" + if not do_validate or ( + value is not None + and isinstance(value, int | float) + and self._min <= type_converter(value) <= self._max + ): + return type_converter(value) # type: ignore[no-any-return] + if self._special and isinstance(value, str) and value in self._special: + return type_converter(self._special[value]) # type: ignore[no-any-return] + raise ValueError( + f"NUMBER failed: Invalid value: {value} (min: {self._min}, " + f"max: {self._max}, special:{self._special})" + ) -class HmFloat(BaseNumber[float]): + +class HmFloat(BaseNumber[float | None]): """ Implementation of a Float. @@ -30,23 +49,19 @@ class HmFloat(BaseNumber[float]): def _prepare_value_for_sending( self, value: int | float | str, do_validate: bool = True - ) -> float: + ) -> float | None: """Prepare value before sending.""" - if not do_validate or ( - value is not None - and isinstance(value, int | float) - and self._min <= float(value) <= self._max - ): - return float(value) - if self._special and isinstance(value, str) and value in self._special: - return float(self._special[value]) - raise ValueError( - f"NUMBER.FLOAT failed: Invalid value: {value} (min: {self._min}, " - f"max: {self._max}, special:{self._special})" + return self._prepare_number_for_sending( + value=value, type_converter=float, do_validate=do_validate ) + @value_property + def value(self) -> float | None: # type: ignore[override] + """Return the value of the entity.""" + return self._value # type: ignore[no-any-return] + -class HmInteger(BaseNumber[int]): +class HmInteger(BaseNumber[int | None]): """ Implementation of an Integer. @@ -55,18 +70,13 @@ class HmInteger(BaseNumber[int]): def _prepare_value_for_sending( self, value: int | float | str, do_validate: bool = True - ) -> int: + ) -> int | None: """Prepare value before sending.""" - if not do_validate or ( - value is not None - and isinstance(value, int | float) - and self._min <= int(value) <= self._max - ): - return int(value) - if self._special and isinstance(value, str) and value in self._special: - return int(self._special[value]) - - raise ValueError( - f"NUMBER.INT failed: Invalid value: {value} (min: {self._min}, " - f"max: {self._max}, special:{self._special})" + return self._prepare_number_for_sending( + value=value, type_converter=int, do_validate=do_validate ) + + @value_property + def value(self) -> int | None: # type: ignore[override] + """Return the value of the entity.""" + return self._value # type: ignore[no-any-return] diff --git a/hahomematic/platforms/generic/sensor.py b/hahomematic/platforms/generic/sensor.py index 6a03798f..dcb31fe1 100644 --- a/hahomematic/platforms/generic/sensor.py +++ b/hahomematic/platforms/generic/sensor.py @@ -18,7 +18,7 @@ _LOGGER: Final = logging.getLogger(__name__) -class HmSensor(GenericEntity[Any, None]): +class HmSensor[SensorT: float | int | str | None](GenericEntity[SensorT, None]): """ Implementation of a sensor. @@ -28,15 +28,15 @@ class HmSensor(GenericEntity[Any, None]): _platform = HmPlatform.SENSOR @value_property - def value(self) -> Any: + def value(self) -> SensorT: # type: ignore[override] """Return the value.""" if ( value := get_value_from_value_list(value=self._value, value_list=self.values) ) is not None: - return value + return value # type: ignore[return-value] if convert_func := self._get_converter_func(): - return convert_func(self._value) - return self._value + return convert_func(self._value) # type: ignore[no-any-return] + return self._value # type: ignore[no-any-return] def _get_converter_func(self) -> Any: """Return a converter based on sensor.""" diff --git a/hahomematic/platforms/generic/switch.py b/hahomematic/platforms/generic/switch.py index a6c30208..2d57eb71 100644 --- a/hahomematic/platforms/generic/switch.py +++ b/hahomematic/platforms/generic/switch.py @@ -16,7 +16,7 @@ _PARAM_ON_TIME: Final = "ON_TIME" -class HmSwitch(GenericEntity[bool, bool]): +class HmSwitch(GenericEntity[bool | None, bool]): """ Implementation of a switch. @@ -30,7 +30,7 @@ def value(self) -> bool | None: # type: ignore[override] """Get the value of the entity.""" if self._type == ParameterType.ACTION: return False - return self._value + return self._value # type: ignore[no-any-return] async def turn_on( self, collector: CallParameterCollector | None = None, on_time: float | None = None diff --git a/hahomematic/platforms/support.py b/hahomematic/platforms/support.py index 7a9dced8..e66de6c4 100644 --- a/hahomematic/platforms/support.py +++ b/hahomematic/platforms/support.py @@ -6,7 +6,7 @@ from datetime import datetime from enum import StrEnum import logging -from typing import Any, Final +from typing import Any, Final, TypeAlias from hahomematic import central as hmcu, support as hms from hahomematic.const import ( @@ -28,6 +28,8 @@ _LOGGER: Final = logging.getLogger(__name__) +GenericParameterType: TypeAlias = bool | int | float | str | None + # dict with binary_sensor relevant value lists and the corresponding TRUE value _BINARY_SENSOR_TRUE_VALUE_DICT_FOR_VALUE_LIST: Final[Mapping[tuple[str, ...], str]] = { ("CLOSED", "OPEN"): "OPEN",