Homee: fix cover if it has no up/down attribute (#135563)

This commit is contained in:
Markus Adrario 2025-01-17 14:51:18 +00:00 committed by GitHub
parent c651e2b3c3
commit 734d1898cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 23 deletions

View File

@ -29,7 +29,7 @@ OPEN_CLOSE_ATTRIBUTES = [
POSITION_ATTRIBUTES = [AttributeType.POSITION, AttributeType.SHUTTER_SLAT_POSITION] POSITION_ATTRIBUTES = [AttributeType.POSITION, AttributeType.SHUTTER_SLAT_POSITION]
def get_open_close_attribute(node: HomeeNode) -> HomeeAttribute: def get_open_close_attribute(node: HomeeNode) -> HomeeAttribute | None:
"""Return the attribute used for opening/closing the cover.""" """Return the attribute used for opening/closing the cover."""
# We assume, that no device has UP_DOWN and OPEN_CLOSE, but only one of them. # We assume, that no device has UP_DOWN and OPEN_CLOSE, but only one of them.
if (open_close := node.get_attribute_by_type(AttributeType.UP_DOWN)) is None: if (open_close := node.get_attribute_by_type(AttributeType.UP_DOWN)) is None:
@ -39,12 +39,12 @@ def get_open_close_attribute(node: HomeeNode) -> HomeeAttribute:
def get_cover_features( def get_cover_features(
node: HomeeNode, open_close_attribute: HomeeAttribute node: HomeeNode, open_close_attribute: HomeeAttribute | None
) -> CoverEntityFeature: ) -> CoverEntityFeature:
"""Determine the supported cover features of a homee node based on the available attributes.""" """Determine the supported cover features of a homee node based on the available attributes."""
features = CoverEntityFeature(0) features = CoverEntityFeature(0)
if open_close_attribute.editable: if (open_close_attribute is not None) and open_close_attribute.editable:
features |= ( features |= (
CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE | CoverEntityFeature.STOP CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE | CoverEntityFeature.STOP
) )
@ -111,8 +111,11 @@ class HomeeCover(HomeeNodeEntity, CoverEntity):
node, self._open_close_attribute node, self._open_close_attribute
) )
self._attr_device_class = get_device_class(node) self._attr_device_class = get_device_class(node)
self._attr_unique_id = (
self._attr_unique_id = f"{self._attr_unique_id}-{self._open_close_attribute.id}" f"{self._attr_unique_id}-{self._open_close_attribute.id}"
if self._open_close_attribute is not None
else f"{self._attr_unique_id}-0"
)
@property @property
def current_cover_position(self) -> int | None: def current_cover_position(self) -> int | None:
@ -194,6 +197,7 @@ class HomeeCover(HomeeNodeEntity, CoverEntity):
async def async_open_cover(self, **kwargs: Any) -> None: async def async_open_cover(self, **kwargs: Any) -> None:
"""Open the cover.""" """Open the cover."""
assert self._open_close_attribute is not None
if not self._open_close_attribute.is_reversed: if not self._open_close_attribute.is_reversed:
await self.async_set_value(self._open_close_attribute, 0) await self.async_set_value(self._open_close_attribute, 0)
else: else:
@ -201,6 +205,7 @@ class HomeeCover(HomeeNodeEntity, CoverEntity):
async def async_close_cover(self, **kwargs: Any) -> None: async def async_close_cover(self, **kwargs: Any) -> None:
"""Close cover.""" """Close cover."""
assert self._open_close_attribute is not None
if not self._open_close_attribute.is_reversed: if not self._open_close_attribute.is_reversed:
await self.async_set_value(self._open_close_attribute, 1) await self.async_set_value(self._open_close_attribute, 1)
else: else:
@ -217,11 +222,12 @@ class HomeeCover(HomeeNodeEntity, CoverEntity):
homee_max = attribute.maximum homee_max = attribute.maximum
homee_position = (position / 100) * (homee_max - homee_min) + homee_min homee_position = (position / 100) * (homee_max - homee_min) + homee_min
await self.async_set_value(AttributeType.POSITION, homee_position) await self.async_set_value(attribute, homee_position)
async def async_stop_cover(self, **kwargs: Any) -> None: async def async_stop_cover(self, **kwargs: Any) -> None:
"""Stop the cover.""" """Stop the cover."""
await self.async_set_value(self._open_close_attribute, 2) if self._open_close_attribute is not None:
await self.async_set_value(self._open_close_attribute, 2)
async def async_open_cover_tilt(self, **kwargs: Any) -> None: async def async_open_cover_tilt(self, **kwargs: Any) -> None:
"""Open the cover tilt.""" """Open the cover tilt."""
@ -229,9 +235,9 @@ class HomeeCover(HomeeNodeEntity, CoverEntity):
AttributeType.SLAT_ROTATION_IMPULSE AttributeType.SLAT_ROTATION_IMPULSE
) )
if not slat_attribute.is_reversed: if not slat_attribute.is_reversed:
await self.async_set_value(AttributeType.SLAT_ROTATION_IMPULSE, 2) await self.async_set_value(slat_attribute, 2)
else: else:
await self.async_set_value(AttributeType.SLAT_ROTATION_IMPULSE, 1) await self.async_set_value(slat_attribute, 1)
async def async_close_cover_tilt(self, **kwargs: Any) -> None: async def async_close_cover_tilt(self, **kwargs: Any) -> None:
"""Close the cover tilt.""" """Close the cover tilt."""
@ -239,9 +245,9 @@ class HomeeCover(HomeeNodeEntity, CoverEntity):
AttributeType.SLAT_ROTATION_IMPULSE AttributeType.SLAT_ROTATION_IMPULSE
) )
if not slat_attribute.is_reversed: if not slat_attribute.is_reversed:
await self.async_set_value(AttributeType.SLAT_ROTATION_IMPULSE, 1) await self.async_set_value(slat_attribute, 1)
else: else:
await self.async_set_value(AttributeType.SLAT_ROTATION_IMPULSE, 2) await self.async_set_value(slat_attribute, 2)
async def async_set_cover_tilt_position(self, **kwargs: Any) -> None: async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
"""Move the cover tilt to a specific position.""" """Move the cover tilt to a specific position."""
@ -256,6 +262,4 @@ class HomeeCover(HomeeNodeEntity, CoverEntity):
homee_max = attribute.maximum homee_max = attribute.maximum
homee_position = (position / 100) * (homee_max - homee_min) + homee_min homee_position = (position / 100) * (homee_max - homee_min) + homee_min
await self.async_set_value( await self.async_set_value(attribute, homee_position)
AttributeType.SHUTTER_SLAT_POSITION, homee_position
)

View File

@ -1,7 +1,7 @@
"""Base Entities for Homee integration.""" """Base Entities for Homee integration."""
from pyHomee.const import AttributeType, NodeProfile, NodeState from pyHomee.const import AttributeType, NodeProfile, NodeState
from pyHomee.model import HomeeNode from pyHomee.model import HomeeAttribute, HomeeNode
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
@ -69,16 +69,10 @@ class HomeeNodeEntity(Entity):
"""Check if an attribute of the given type exists.""" """Check if an attribute of the given type exists."""
return attribute_type in self._node.attribute_map return attribute_type in self._node.attribute_map
async def async_set_value(self, attribute_type: int, value: float) -> None: async def async_set_value(self, attribute: HomeeAttribute, value: float) -> None:
"""Set an attribute value on the homee node."""
await self.async_set_value_by_id(
self._node.get_attribute_by_type(attribute_type).id, value
)
async def async_set_value_by_id(self, attribute_id: int, value: float) -> None:
"""Set an attribute value on the homee node.""" """Set an attribute value on the homee node."""
homee = self._entry.runtime_data homee = self._entry.runtime_data
await homee.set_value(self._node.id, attribute_id, value) await homee.set_value(attribute.node_id, attribute.id, value)
def _on_node_updated(self, node: HomeeNode) -> None: def _on_node_updated(self, node: HomeeNode) -> None:
self.schedule_update_ha_state() self.schedule_update_ha_state()