From 4d6ddbabcadb3ba8915adb69cd3759145a5b365a Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Sun, 28 Apr 2024 14:15:59 +0200 Subject: [PATCH] Included cover Included cover for the bypass damper. The open and close buttons toggles the current state of the manual bypass. --- custom_components/dantherm/__init__.py | 2 +- custom_components/dantherm/const.py | 14 +-- custom_components/dantherm/cover.py | 116 ++++++++++++++----------- 3 files changed, 74 insertions(+), 58 deletions(-) diff --git a/custom_components/dantherm/__init__.py b/custom_components/dantherm/__init__.py index fdb33cd..a510016 100644 --- a/custom_components/dantherm/__init__.py +++ b/custom_components/dantherm/__init__.py @@ -31,7 +31,7 @@ ) PLATFORMS = [ - "button", + # "button", # left out for now "cover", "number", "select", diff --git a/custom_components/dantherm/const.py b/custom_components/dantherm/const.py index 1bef6a9..e322d66 100644 --- a/custom_components/dantherm/const.py +++ b/custom_components/dantherm/const.py @@ -5,7 +5,11 @@ from typing import Any from homeassistant.components.button import ButtonEntityDescription -from homeassistant.components.cover import CoverDeviceClass, CoverEntityDescription +from homeassistant.components.cover import ( + CoverDeviceClass, + CoverEntityDescription, + CoverEntityFeature, +) from homeassistant.components.number import ( NumberDeviceClass, NumberEntityDescription, @@ -95,7 +99,9 @@ class DanthermButtonEntityDescription(ButtonEntityDescription): class DanthermCoverEntityDescription(CoverEntityDescription): """Dantherm Cover Entity Description.""" + supported_features: CoverEntityFeature | None = None data_setaddress: int | None = None + data_setinternal: str | None = None data_setclass: DataClass | None = None state_open: int = None state_close: int = None @@ -201,10 +207,8 @@ class DanthermSwitchEntityDescription(SwitchEntityDescription): COVER_TYPES: dict[str, list[DanthermCoverEntityDescription]] = { "bypass_damper": DanthermCoverEntityDescription( key="bypass_damper", - data_setaddress=168, - data_setclass=DataClass.UInt16, - state_open=0x0080, - state_close=0x8080, + supported_features=CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE, + data_setinternal="set_bypass_damper", data_address=198, data_class=DataClass.UInt16, state_opening=64, diff --git a/custom_components/dantherm/cover.py b/custom_components/dantherm/cover.py index 27513c8..bab4a8a 100644 --- a/custom_components/dantherm/cover.py +++ b/custom_components/dantherm/cover.py @@ -5,14 +5,7 @@ from typing import Any from homeassistant.components.cover import CoverEntity, CoverEntityFeature -from homeassistant.const import ( - STATE_CLOSED, - STATE_CLOSING, - STATE_OPEN, - STATE_OPENING, - STATE_UNAVAILABLE, - STATE_UNKNOWN, -) +from homeassistant.const import STATE_CLOSED, STATE_CLOSING, STATE_OPEN, STATE_OPENING from homeassistant.core import HomeAssistant from .const import COVER_TYPES, DOMAIN, DanthermCoverEntityDescription @@ -49,46 +42,63 @@ def __init__( self.has_entity_name = True self.entity_description: DanthermCoverEntityDescription = description self._attr_supported_features = 0 - if description.state_open: - self._attr_supported_features |= CoverEntityFeature.OPEN - if description.state_close: - self._attr_supported_features |= CoverEntityFeature.CLOSE - if description.state_stop: - self._attr_supported_features |= CoverEntityFeature.STOP + if description.supported_features: + self._attr_supported_features = description.supported_features + else: + if description.state_open: + self._attr_supported_features |= CoverEntityFeature.OPEN + if description.state_close: + self._attr_supported_features |= CoverEntityFeature.CLOSE + if description.state_stop: + self._attr_supported_features |= CoverEntityFeature.STOP # states + self._attr_available = False self._attr_is_closed = False self._attr_is_closing = False self._attr_is_opening = False - self._attr_last_state: int = 0 - self._call_active = False async def async_open_cover(self, **kwargs: Any) -> None: """Open cover.""" - result = await self._device.write_holding_registers( - description=self.entity_description, - value=self.entity_description.state_open, - ) - self._attr_available = result is not None - self.async_update_ha_state(True) + + if self.entity_description.data_setinternal: + await getattr(self._device, self.entity_description.data_setinternal)( + CoverEntityFeature.OPEN + ) + else: + await self._device.write_holding_registers( + description=self.entity_description, + value=self.entity_description.state_open, + ) + # await self.async_update_ha_state(True) async def async_close_cover(self, **kwargs: Any) -> None: """Close cover.""" - result = await self._device.write_holding_registers( - description=self.entity_description, - value=self.entity_description.state_close, - ) - self._attr_available = result is not None - self.async_update_ha_state(True) + + if self.entity_description.data_setinternal: + await getattr(self._device, self.entity_description.data_setinternal)( + CoverEntityFeature.CLOSE + ) + else: + await self._device.write_holding_registers( + description=self.entity_description, + value=self.entity_description.state_close, + ) + # await self.async_update_ha_state(True) async def async_stop_cover(self, **kwargs: Any) -> None: """Stop cover.""" - result = await self._device.write_holding_registers( - description=self.entity_description, - value=self.entity_description.state_stop, - ) - self._attr_available = result is not None - self.async_update_ha_state(True) + + if self.entity_description.data_setinternal: + await getattr(self._device, self.entity_description.data_setinternal)( + CoverEntityFeature.STOP + ) + else: + await self._device.write_holding_registers( + description=self.entity_description, + value=self.entity_description.state_stop, + ) + # await self.async_update_ha_state(True) @property def native_value(self): @@ -98,28 +108,30 @@ def native_value(self): async def async_update(self, now: datetime | None = None) -> None: """Update the state of the cover.""" - self._attr_last_state = STATE_UNKNOWN result = await self._device.read_holding_registers( description=self.entity_description ) if result is None: self._attr_available = False - elif result == self.entity_description.state_closed: - self._attr_state = STATE_CLOSED - self._attr_is_closed = True - self._attr_is_closing = False - self._attr_is_opening = False - elif result == self.entity_description.state_closing: - self._attr_state = STATE_CLOSING - self._attr_is_closing = True - elif result == self.entity_description.state_opening: - self._attr_state = STATE_OPENING - self._attr_is_opening = True - elif result == self.entity_description.state_open: - self._attr_state = STATE_OPEN - self._attr_is_closed = False - self._attr_is_closing = False - self._attr_is_opening = False else: - self._attr_state = STATE_UNAVAILABLE + self._attr_available = True + + if result == self.entity_description.state_closed: + self._attr_state = STATE_CLOSED + self._attr_is_closed = True + self._attr_is_closing = False + self._attr_is_opening = False + elif result == self.entity_description.state_closing: + self._attr_state = STATE_CLOSING + self._attr_is_closing = True + self._attr_is_opening = False + elif result == self.entity_description.state_opening: + self._attr_state = STATE_OPENING + self._attr_is_opening = True + self._attr_is_closing = False + elif result == self.entity_description.state_opened: + self._attr_state = STATE_OPEN + self._attr_is_closed = False + self._attr_is_closing = False + self._attr_is_opening = False