Skip to content

Commit

Permalink
Use PEP 695 typing pt2 (#1565)
Browse files Browse the repository at this point in the history
* Use PEP 695 typing pt2

* Use PEP 695 typing pt3

* Update number.py

* Fixes

* Refactor number preparation
  • Loading branch information
SukramJ authored May 20, 2024
1 parent 32103a5 commit 85f5750
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 101 deletions.
22 changes: 12 additions & 10 deletions hahomematic/platforms/custom/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
20 changes: 12 additions & 8 deletions hahomematic/platforms/custom/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion hahomematic/platforms/custom/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
14 changes: 7 additions & 7 deletions hahomematic/platforms/custom/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 12 additions & 6 deletions hahomematic/platforms/custom/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions hahomematic/platforms/custom/siren.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 4 additions & 7 deletions hahomematic/platforms/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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."""


Expand Down
28 changes: 14 additions & 14 deletions hahomematic/platforms/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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__(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions hahomematic/platforms/generic/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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]
14 changes: 8 additions & 6 deletions hahomematic/platforms/generic/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]

Expand Down Expand Up @@ -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.
Expand Down
Loading

0 comments on commit 85f5750

Please sign in to comment.