Skip to content

Commit

Permalink
Refactor entity path (#1625)
Browse files Browse the repository at this point in the history
* Refactor entity path

* Rename payload methods

* Convert payload values to str

* Update pyproject.toml

* Update pyproject.toml
  • Loading branch information
SukramJ authored Aug 2, 2024
1 parent f89dc85 commit 3382828
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 27 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Version 2024.8.1(2024-08-02)

- Refactor entity path

# Version 2024.8.0(2024-08-01)

- Reduce data load, if only device description is updated
Expand Down
5 changes: 5 additions & 0 deletions hahomematic/platforms/custom/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ def is_valid(self) -> bool:
"""Return if the state is valid."""
return all(entity.is_valid for entity in self._relevant_entities)

@property
def path(self) -> str:
"""Return the path of the entity."""
return f"{self._base_path}".lower()

@property
def state_uncertain(self) -> bool:
"""Return, if the state is uncertain."""
Expand Down
12 changes: 11 additions & 1 deletion hahomematic/platforms/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from collections.abc import Callable, Mapping
from enum import Enum
from typing import Any


Expand Down Expand Up @@ -80,7 +81,16 @@ def _get_public_attributes_by_decorator(
if not y.startswith("_")
and isinstance(getattr(data_object.__class__, y), property_decorator)
]
return {x: getattr(data_object, x) for x in pub_attributes}
return {x: _get_text_value(getattr(data_object, x)) for x in pub_attributes}


def _get_text_value(value: Any) -> Any:
"""Convert value to text."""
if isinstance(value, (list, tuple, set)):
return tuple(_get_text_value(v) for v in value)
if isinstance(value, Enum):
return str(value)
return value


def get_public_attributes_for_config_property(data_object: Any) -> Mapping[str, Any]:
Expand Down
33 changes: 20 additions & 13 deletions hahomematic/platforms/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ def refreshed_at(self) -> datetime:
def name(self) -> str | None:
"""Return the name of the entity."""

@property
@abstractmethod
def path(self) -> str:
"""Return the path of the entity."""

@config_property
def platform(self) -> HmPlatform:
"""Return, the platform of the entity."""
Expand Down Expand Up @@ -248,6 +253,10 @@ def _set_refreshed_at(self, now: datetime = datetime.now()) -> None:
"""Set last_update to current datetime."""
self._refreshed_at = now

def __str__(self) -> str:
"""Provide some useful information."""
return f"path: {self.path}, name: {self.full_name}"


class BaseEntity(CallbackEntity, PayloadMixin):
"""Base class for regular entities."""
Expand Down Expand Up @@ -285,11 +294,6 @@ def __init__(
self._usage: EntityUsage = self._get_entity_usage()
self._entity_name_data: Final = self._get_entity_name()

@property
def address_path(self) -> str:
"""Return the address pass of the entity."""
return f"{self._platform}/{self._device.interface_id}/{self._unique_id}/"

@property
def available(self) -> bool:
"""Return the availability of the device."""
Expand All @@ -300,6 +304,11 @@ def base_channel_no(self) -> int | None:
"""Return the base channel no of the entity."""
return self._device.get_sub_device_channel(channel_no=self._channel_no)

@property
def _base_path(self) -> str:
"""Return the base path of the entity."""
return f"{self._device.device_address}/{self._channel_no}/{self._platform}"

@config_property
def channel_address(self) -> str:
"""Return the channel_address of the entity."""
Expand Down Expand Up @@ -378,13 +387,6 @@ def _get_entity_name(self) -> EntityNameData:
def _get_entity_usage(self) -> EntityUsage:
"""Generate the usage for the entity."""

def __str__(self) -> str:
"""Provide some useful information."""
return (
f"address_path: {self.address_path}, type: {self._device.device_type}, "
f"name: {self.full_name}"
)


class BaseParameterEntity[
ParameterT: GenericParameterType,
Expand Down Expand Up @@ -506,6 +508,11 @@ def paramset_key(self) -> str:
"""Return paramset_key name."""
return self._paramset_key

@property
def path(self) -> str:
"""Return the path of the entity."""
return f"{self._base_path}/{self._parameter}".lower()

@config_property
def raw_unit(self) -> str | None:
"""Return raw unit value."""
Expand Down Expand Up @@ -586,7 +593,7 @@ def unit(self) -> str | None:
"""Return unit value."""
return self._unit

@value_property
@config_property
def values(self) -> tuple[str, ...] | None:
"""Return the values."""
return self._values
Expand Down
5 changes: 5 additions & 0 deletions hahomematic/platforms/hub/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ def name(self) -> str | None:
"""Return the name of the entity."""
return self._name

@property
def path(self) -> str:
"""Return the path of the entity."""
return f"{self.central.name}/{self.platform}".lower()


class GenericSystemVariable(GenericHubEntity):
"""Class for a HomeMatic system variable."""
Expand Down
8 changes: 4 additions & 4 deletions hahomematic/platforms/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ class PayloadMixin:
"""Mixin to add payload methods to class."""

@property
def config_payload(self) -> Mapping[str, Any]:
"""Return the config payload."""
def payload_config(self) -> Mapping[str, Any]:
"""Return the payload config."""
return get_public_attributes_for_config_property(data_object=self)

@property
def value_payload(self) -> Mapping[str, Any]:
"""Return the value payload."""
def payload_value(self) -> Mapping[str, Any]:
"""Return the payload value."""
return get_public_attributes_for_value_property(data_object=self)


Expand Down
5 changes: 5 additions & 0 deletions hahomematic/platforms/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ def firmware_update_state(self) -> str | None:
"""Latest version available for install."""
return self._device.firmware_update_state

@property
def path(self) -> str:
"""Return the path of the entity."""
return f"{self._device.device_address}/{HmPlatform.UPDATE}".lower()

def register_entity_updated_callback(self, cb: Callable, custom_id: str) -> CALLBACK_TYPE:
"""Register update callback."""
if custom_id != DEFAULT_CUSTOM_ID:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "hahomematic"
version = "2024.8.0"
version = "2024.8.1"
license = {text = "MIT License"}
description = "Homematic interface for Home Assistant running on Python 3."
readme = "README.md"
Expand Down
10 changes: 2 additions & 8 deletions tests/test_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ async def test_custom_entity_callback(
cb=device_removed_mock
)
assert switch.value is None
assert (
str(switch) == "address_path: switch/CentralTest-BidCos-RF/vcu2128127_4/, "
"type: HmIP-BSM, name: HmIP-BSM_VCU2128127"
)
assert str(switch) == "path: vcu2128127/4/switch, name: HmIP-BSM_VCU2128127"
await central.event(const.INTERFACE_ID, "VCU2128127:4", "STATE", 1)
assert switch.value is True
await central.event(const.INTERFACE_ID, "VCU2128127:4", "STATE", 0)
Expand Down Expand Up @@ -115,10 +112,7 @@ async def test_generic_entity_callback(
switch.register_entity_updated_callback(cb=device_updated_mock, custom_id="some_id")
switch.register_device_removed_callback(cb=device_removed_mock)
assert switch.value is None
assert (
str(switch) == "address_path: switch/CentralTest-BidCos-RF/vcu2128127_4_state/, "
"type: HmIP-BSM, name: HmIP-BSM_VCU2128127 State ch4"
)
assert str(switch) == "path: vcu2128127/4/switch/state, name: HmIP-BSM_VCU2128127 State ch4"
await central.event(const.INTERFACE_ID, "VCU2128127:4", "STATE", 1)
assert switch.value is True
await central.event(const.INTERFACE_ID, "VCU2128127:4", "STATE", 0)
Expand Down

0 comments on commit 3382828

Please sign in to comment.