From 51908ab674342c660c1d361d5e38c4821573ce96 Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Sat, 17 Aug 2024 07:51:42 +0200 Subject: [PATCH 1/8] Reorganized constants Moved device specific constants from const.py to device_map.py. --- custom_components/dantherm/button.py | 3 +- custom_components/dantherm/const.py | 546 ----------------------- custom_components/dantherm/cover.py | 3 +- custom_components/dantherm/device.py | 8 +- custom_components/dantherm/device_map.py | 546 +++++++++++++++++++++++ custom_components/dantherm/number.py | 3 +- custom_components/dantherm/select.py | 3 +- custom_components/dantherm/sensor.py | 3 +- custom_components/dantherm/switch.py | 3 +- 9 files changed, 562 insertions(+), 556 deletions(-) create mode 100644 custom_components/dantherm/device_map.py diff --git a/custom_components/dantherm/button.py b/custom_components/dantherm/button.py index b5b9697..84f6efa 100644 --- a/custom_components/dantherm/button.py +++ b/custom_components/dantherm/button.py @@ -5,8 +5,9 @@ from homeassistant.components.button import ButtonEntity from homeassistant.core import HomeAssistant -from .const import BUTTONS, DOMAIN, DanthermButtonEntityDescription +from .const import DOMAIN from .device import DanthermEntity, Device +from .device_map import BUTTONS, DanthermButtonEntityDescription _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/dantherm/const.py b/custom_components/dantherm/const.py index 5509d69..06d8332 100644 --- a/custom_components/dantherm/const.py +++ b/custom_components/dantherm/const.py @@ -1,552 +1,6 @@ """The constants.""" -from dataclasses import dataclass -from enum import Enum -from typing import Any, Final - -from homeassistant.components.button import ButtonEntityDescription -from homeassistant.components.cover import ( - CoverDeviceClass, - CoverEntityDescription, - CoverEntityFeature, -) -from homeassistant.components.number import ( - NumberDeviceClass, - NumberEntityDescription, - NumberMode, -) -from homeassistant.components.select import SelectEntityDescription -from homeassistant.components.sensor import ( - SensorDeviceClass, - SensorEntityDescription, - SensorStateClass, -) -from homeassistant.components.switch import SwitchDeviceClass, SwitchEntityDescription -from homeassistant.const import EntityCategory - DOMAIN = "dantherm" DEFAULT_NAME = "Dantherm" DEFAULT_SCAN_INTERVAL = 10 DEFAULT_PORT = 502 - - -DEVICE_TYPES = { - 1: "WG200", - 2: "WG300", - 3: "WG500", - 4: "HCC 2", - 5: "HCC 2 ALU", - 6: "HCV300 ALU", - 7: "HCV500 ALU", - 8: "HCV700 ALU", - 9: "HCV400 P2", - 10: "HCV400 E1", - 11: "HCV400 P1", - 12: "HCC 2 E1", - 21: "RCV320 P2", - 26: "RCV320 P1", -} - - -class ComponentClass(int): - """Danterm components.""" - - FP1 = 0x0001 - Week = 0x0002 - Bypass = 0x0004 - LRSwitch = 0x0008 - Internal_preheater = 0x0010 - Servo_flow = 0x0020 - RH_Senser = 0x0040 - VOC_sensor = 0x0080 - Ext_Override = 0x0100 - HAC1 = 0x0200 - HRC2 = 0x0400 - PC_Tool = 0x0800 - Apps = 0x1000 - ZeegBee = 0x2000 - DI1_Override = 0x4000 - DI2_Override = 0x8000 - - -class DataClass(Enum): - """Dantherm modbus data class.""" - - Int8 = 1 - UInt8 = 2 - Int16 = 3 - UInt16 = 4 - Int32 = 5 - UInt32 = 6 - UInt64 = 7 - Float32 = 8 - - -class CurrentUnitMode(int): - """Dantherm current unit mode class.""" - - Standby = 0 - Manual = 1 - Automatic = 2 - WeekProgram = 3 - Away = 5 - Summer = 6 - Fireplace = 9 - Night = 16 - - -class ActiveUnitMode(int): - """Dantherm active unit mode class.""" - - Automatic = 0x0002 - Manuel = 0x0004 - WeekProgram = 0x0008 - - Away = StartAway = 0x0010 - EndAway = 0x8010 - - Night = NightEnable = 0x0020 - NightDisable = 0x8020 - - Fireplace = StartFireplace = 0x0040 - EndFireplace = 0x8040 - - ManuelBypass = SelectManuelBypass = 0x0080 - DeselectManuelBypass = 0x8080 - - Summer = StartSummer = 0x0800 - EndSummer = 0x8800 - - -STATE_STANDBY: Final = "standby" -STATE_AUTOMATIC: Final = "automatic" -STATE_MANUAL: Final = "manual" -STATE_WEEKPROGRAM: Final = "week_program" -STATE_AWAY: Final = "away" -STATE_SUMMER: Final = "summer" -STATE_FIREPLACE: Final = "fireplace" -STATE_NIGHT: Final = "night" - - -class BypassDamperState(int): - """Dantherm bypass damper state class.""" - - InProgress = 1 - Opening = 64 - Opened = 255 - Closing = 32 - Closed = 0 - - -@dataclass -class DanthermButtonEntityDescription(ButtonEntityDescription): - """Dantherm Button Entity Description.""" - - data_setaddress: int | None = None - data_setclass: DataClass | None = None - state: int = None - state_entity: str | None = None - - data_address: int | None = None - data_exclude_if: Any | None = None - data_exclude_if_above: int | None = None - data_exclude_if_below: int | None = None - data_class: DataClass = DataClass.UInt16 - - component_class: ComponentClass = None - - -@dataclass -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 - state_stop: int = None - - data_address: int | None = None - data_getinternal: str | None = None - data_entity: str | None = None - data_exclude_if: Any | None = None - data_exclude_if_above: int | None = None - data_exclude_if_below: int | None = None - data_class: DataClass = DataClass.UInt16 - state_opening: int = None - state_opened: int = None - state_closing: int = None - state_closed: int = None - - component_class: ComponentClass = None - - -@dataclass -class DanthermNumberEntityDescription(NumberEntityDescription): - """Dantherm Number Entity Description.""" - - data_setaddress: int | None = None - data_setinternal: str | None = None - data_setclass: DataClass | None = None - - data_address: int | None = None - data_getinternal: str | None = None - data_entity: str | None = None - data_exclude_if: Any | None = None - data_exclude_if_above: int | None = None - data_exclude_if_below: int | None = None - data_class: DataClass = DataClass.UInt16 - - component_class: ComponentClass = None - - -@dataclass -class DanthermSelectEntityDescription(SelectEntityDescription): - """Dantherm Select Entity Description.""" - - data_setaddress: int | None = None - data_setinternal: str | None = None - data_setclass: DataClass | None = None - - data_address: int | None = None - data_getinternal: str | None = None - data_entity: str | None = None - data_bitwise_and: int | None = None - data_exclude_if: Any | None = None - data_exclude_if_above: int | None = None - data_exclude_if_below: int | None = None - data_class: DataClass = DataClass.UInt16 - - component_class: ComponentClass = None - - -@dataclass -class DanthermSensorEntityDescription(SensorEntityDescription): - """Dantherm Sensor Entity Description.""" - - icon_zero: str | None = None - data_address: int | None = None - data_getinternal: str | None = None - data_precision: int | None = None - data_scale: int | None = None - data_exclude_if: Any | None = None - data_exclude_if_above: int | None = None - data_exclude_if_below: int | None = None - data_entity: str | None = None - data_class: DataClass = DataClass.UInt16 - - component_class: ComponentClass = None - - -@dataclass -class DanthermSwitchEntityDescription(SwitchEntityDescription): - """Dantherm Switch Entity Description.""" - - data_setaddress: int | None = None - data_setinternal: str | None = None - data_getinternal: str | None = None - state_seton: int = None - state_setoff: int = None - data_setclass: DataClass | None = None - - state_suspend_for: int | None = None - state_on: int = None - icon_on: str = None - state_off: int = None - icon_off: str = None - - data_address: int | None = None - data_entity: str | None = None - data_exclude_if: Any | None = None - data_exclude_if_above: int | None = None - data_exclude_if_below: int | None = None - data_class: DataClass = DataClass.UInt16 - - component_class: ComponentClass = None - - -BUTTONS: tuple[DanthermButtonEntityDescription, ...] = ( - DanthermButtonEntityDescription( - key="filter_reset", - data_setaddress=558, - state=1, - data_class=DataClass.UInt32, - ), - DanthermButtonEntityDescription( - key="alarm_reset", - data_setaddress=514, - state_entity="alarm", - data_class=DataClass.UInt32, - ), -) - -COVERS: tuple[DanthermCoverEntityDescription, ...] = ( - DanthermCoverEntityDescription( - key="bypass_damper", - supported_features=CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE, - data_setinternal="set_bypass_damper", - data_getinternal="get_bypass_damper", - state_opening=BypassDamperState.Opening, - state_opened=BypassDamperState.Opened, - state_closing=BypassDamperState.Closing, - state_closed=BypassDamperState.Closed, - component_class=ComponentClass.Bypass, - device_class=CoverDeviceClass.DAMPER, - ), -) - -NUMBERS: tuple[DanthermNumberEntityDescription, ...] = ( - DanthermNumberEntityDescription( - key="filter_lifetime", - icon="mdi:air-filter", - data_setinternal="set_filter_lifetime", - data_getinternal="get_filter_lifetime", - native_max_value=360, - native_min_value=0, - device_class=NumberDeviceClass.DURATION, - native_unit_of_measurement="d", - mode=NumberMode.BOX, - entity_category=EntityCategory.CONFIG, - ), -) - -SELECTS: tuple[DanthermSelectEntityDescription, ...] = ( - DanthermSelectEntityDescription( - key="operation_selection", - icon="mdi:state-machine", - data_setinternal="set_operation_selection", - data_getinternal="get_operation_selection", - options=[ - "standby", - "automatic", - "manual", - "week_program", - "away", - "summer", - "fireplace", - "night", - ], - ), - DanthermSelectEntityDescription( - key="fan_level_selection", - data_setinternal="set_fan_level", - data_getinternal="get_fan_level", - options=["0", "1", "2", "3", "4"], - ), - DanthermSelectEntityDescription( - key="week_program_selection", - icon="mdi:clock-edit-outline", - data_address=466, - data_class=DataClass.UInt32, - options=["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], - component_class=ComponentClass.Week, - entity_category=EntityCategory.CONFIG, - ), -) - -SENSORS: tuple[DanthermSensorEntityDescription, ...] = ( - DanthermSensorEntityDescription( - key="operation_mode", - data_getinternal="get_current_unit_mode", - entity_category=EntityCategory.DIAGNOSTIC, - ), - DanthermSensorEntityDescription( - key="alarm", - icon="mdi:alert-circle-outline", - icon_zero="mdi:alert-circle-check-outline", - data_getinternal="get_alarm", - ), - DanthermSensorEntityDescription( - key="fan_level", - data_getinternal="get_fan_level", - ), - DanthermSensorEntityDescription( - key="fan1_speed", - icon="mdi:fan", - icon_zero="mdi:fan-off", - data_class=DataClass.Float32, - data_address=100, - native_unit_of_measurement="rpm", - data_precision=0, - state_class=SensorStateClass.MEASUREMENT, - entity_registry_visible_default=True, - entity_registry_enabled_default=False, - ), - DanthermSensorEntityDescription( - key="fan2_speed", - icon="mdi:fan", - icon_zero="mdi:fan-off", - data_class=DataClass.Float32, - data_address=102, - native_unit_of_measurement="rpm", - data_precision=0, - state_class=SensorStateClass.MEASUREMENT, - entity_registry_visible_default=True, - entity_registry_enabled_default=False, - ), - DanthermSensorEntityDescription( - key="humidity", - data_address=196, - data_exclude_if=0, - data_class=DataClass.UInt32, - native_unit_of_measurement="%", - device_class=SensorDeviceClass.HUMIDITY, - state_class=SensorStateClass.MEASUREMENT, - component_class=ComponentClass.RH_Senser, - ), - DanthermSensorEntityDescription( - key="air_quality", - data_address=430, - data_exclude_if=0, - data_class=DataClass.UInt32, - native_unit_of_measurement="ppm", - device_class=SensorDeviceClass.AQI, - state_class=SensorStateClass.MEASUREMENT, - component_class=ComponentClass.VOC_sensor, - ), - DanthermSensorEntityDescription( - key="exhaust_temperature", - data_class=DataClass.Float32, - data_address=138, - data_precision=1, - native_unit_of_measurement="°C", - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - ), - DanthermSensorEntityDescription( - key="extract_temperature", - data_class=DataClass.Float32, - data_address=136, - data_precision=1, - native_unit_of_measurement="°C", - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - ), - DanthermSensorEntityDescription( - key="supply_temperature", - data_class=DataClass.Float32, - data_address=134, - data_precision=1, - native_unit_of_measurement="°C", - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - ), - DanthermSensorEntityDescription( - key="outdoor_temperature", - data_class=DataClass.Float32, - data_address=132, - data_precision=1, - native_unit_of_measurement="°C", - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - ), - DanthermSensorEntityDescription( - key="room_temperature", - data_class=DataClass.Float32, - data_address=140, - data_precision=1, - data_exclude_if_above=70, - data_exclude_if_below=-40, - native_unit_of_measurement="°C", - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - entity_registry_visible_default=True, - entity_registry_enabled_default=False, - component_class=ComponentClass.HRC2, - ), - DanthermSensorEntityDescription( - key="filter_remain", - icon="mdi:air-filter", - data_getinternal="get_filter_remain", - native_unit_of_measurement="d", - suggested_display_precision=0, - suggested_unit_of_measurement="d", - device_class=SensorDeviceClass.DURATION, - ), - DanthermSensorEntityDescription( - key="work_time", - icon="mdi:progress-clock", - data_class=DataClass.UInt32, - data_address=624, - native_unit_of_measurement="h", - suggested_display_precision=0, - suggested_unit_of_measurement="h", - device_class=SensorDeviceClass.DURATION, - entity_category=EntityCategory.DIAGNOSTIC, - entity_registry_visible_default=True, - entity_registry_enabled_default=False, - ), - DanthermSensorEntityDescription( - key="internal_preheater_dutycycle", - icon="mdi:heating-coil", - data_address=160, - data_class=DataClass.UInt32, - device_class=NumberDeviceClass.POWER_FACTOR, - native_unit_of_measurement="%", - entity_registry_visible_default=True, - entity_registry_enabled_default=False, - component_class=ComponentClass.Internal_preheater, - ), -) - -SWITCHES: tuple[DanthermSwitchEntityDescription, ...] = ( - DanthermSwitchEntityDescription( - key="away_mode", - data_setinternal="set_active_unit_mode", - data_getinternal="get_away_mode", - state_suspend_for=30, - state_on=ActiveUnitMode.StartAway, - icon_on="mdi:bag-suitcase-outline", - state_off=ActiveUnitMode.EndAway, - icon_off="mdi:bag-suitcase-off-outline", - device_class=SwitchDeviceClass.SWITCH, - ), - DanthermSwitchEntityDescription( - key="night_mode", - data_setinternal="set_active_unit_mode", - data_getinternal="get_active_unit_mode", - state_suspend_for=30, - state_on=ActiveUnitMode.NightEnable, - icon_on="mdi:sleep", - state_off=ActiveUnitMode.NightDisable, - icon_off="mdi:sleep-off", - device_class=SwitchDeviceClass.SWITCH, - entity_category=EntityCategory.CONFIG, - ), - DanthermSwitchEntityDescription( - key="fireplace_mode", - data_setinternal="set_active_unit_mode", - data_getinternal="get_fireplace_mode", - state_suspend_for=30, - state_seton=ActiveUnitMode.StartFireplace, - icon_on="mdi:fireplace", - state_setoff=ActiveUnitMode.EndFireplace, - icon_off="mdi:fireplace-off", - device_class=SwitchDeviceClass.SWITCH, - ), - DanthermSwitchEntityDescription( - key="manual_bypass_mode", - data_setinternal="set_active_unit_mode", - data_getinternal="get_active_unit_mode", - state_suspend_for=30, - state_on=ActiveUnitMode.SelectManuelBypass, - icon_on="mdi:hand-back-right-outline", - state_off=ActiveUnitMode.DeselectManuelBypass, - icon_off="mdi:hand-back-right-off-outline", - component_class=ComponentClass.Bypass, - device_class=SwitchDeviceClass.SWITCH, - ), - DanthermSwitchEntityDescription( - key="summer_mode", - data_setinternal="set_active_unit_mode", - data_getinternal="get_summer_mode", - state_suspend_for=30, - state_seton=ActiveUnitMode.StartSummer, - icon_on="mdi:weather-sunny", - state_setoff=ActiveUnitMode.EndSummer, - icon_off="mdi:weather-sunny-off", - device_class=SwitchDeviceClass.SWITCH, - ), -) diff --git a/custom_components/dantherm/cover.py b/custom_components/dantherm/cover.py index 84606cd..e7eaf8e 100644 --- a/custom_components/dantherm/cover.py +++ b/custom_components/dantherm/cover.py @@ -7,8 +7,9 @@ from homeassistant.const import STATE_CLOSED, STATE_CLOSING, STATE_OPEN, STATE_OPENING from homeassistant.core import HomeAssistant -from .const import COVERS, DOMAIN, DanthermCoverEntityDescription +from .const import DOMAIN from .device import DanthermEntity, Device +from .device_map import COVERS, DanthermCoverEntityDescription _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/dantherm/device.py b/custom_components/dantherm/device.py index 412efd1..b803035 100644 --- a/custom_components/dantherm/device.py +++ b/custom_components/dantherm/device.py @@ -13,9 +13,9 @@ from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.event import async_track_time_interval -from .const import ( +from .const import DEFAULT_NAME, DOMAIN +from .device_map import ( DEVICE_TYPES, - DOMAIN, STATE_AUTOMATIC, STATE_AWAY, STATE_FIREPLACE, @@ -89,7 +89,7 @@ def device_info(self): (DOMAIN, unique_id), }, "name": self._device.get_device_name, - "manufacturer": "Dantherm", + "manufacturer": DEFAULT_NAME, "model": self._device.get_device_type, "sw_version": self._device.get_device_fw_version, "serial_number": self._device.get_device_serial_number, @@ -168,7 +168,7 @@ async def setup(self): result = await self._read_holding_uint32(610) if result is None: - raise ValueError("Dantherm unit probably not responding") + raise ValueError(f"{DEFAULT_NAME} unit probably not responding") self._device_installed_components = result & 0xFFFF _LOGGER.debug( diff --git a/custom_components/dantherm/device_map.py b/custom_components/dantherm/device_map.py new file mode 100644 index 0000000..72f0915 --- /dev/null +++ b/custom_components/dantherm/device_map.py @@ -0,0 +1,546 @@ +"""The device mapping.""" + +from dataclasses import dataclass +from enum import Enum +from typing import Any, Final + +from homeassistant.components.button import ButtonEntityDescription +from homeassistant.components.cover import ( + CoverDeviceClass, + CoverEntityDescription, + CoverEntityFeature, +) +from homeassistant.components.number import ( + NumberDeviceClass, + NumberEntityDescription, + NumberMode, +) +from homeassistant.components.select import SelectEntityDescription +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntityDescription, + SensorStateClass, +) +from homeassistant.components.switch import SwitchDeviceClass, SwitchEntityDescription +from homeassistant.const import EntityCategory + +DEVICE_TYPES = { + 1: "WG200", + 2: "WG300", + 3: "WG500", + 4: "HCC 2", + 5: "HCC 2 ALU", + 6: "HCV300 ALU", + 7: "HCV500 ALU", + 8: "HCV700 ALU", + 9: "HCV400 P2", + 10: "HCV400 E1", + 11: "HCV400 P1", + 12: "HCC 2 E1", + 21: "RCV320 P2", + 26: "RCV320 P1", +} + + +class ComponentClass(int): + """Danterm components.""" + + FP1 = 0x0001 + Week = 0x0002 + Bypass = 0x0004 + LRSwitch = 0x0008 + Internal_preheater = 0x0010 + Servo_flow = 0x0020 + RH_Senser = 0x0040 + VOC_sensor = 0x0080 + Ext_Override = 0x0100 + HAC1 = 0x0200 + HRC2 = 0x0400 + PC_Tool = 0x0800 + Apps = 0x1000 + ZeegBee = 0x2000 + DI1_Override = 0x4000 + DI2_Override = 0x8000 + + +class DataClass(Enum): + """Dantherm modbus data class.""" + + Int8 = 1 + UInt8 = 2 + Int16 = 3 + UInt16 = 4 + Int32 = 5 + UInt32 = 6 + UInt64 = 7 + Float32 = 8 + + +class CurrentUnitMode(int): + """Dantherm current unit mode class.""" + + Standby = 0 + Manual = 1 + Automatic = 2 + WeekProgram = 3 + Away = 5 + Summer = 6 + Fireplace = 9 + Night = 16 + + +class ActiveUnitMode(int): + """Dantherm active unit mode class.""" + + Automatic = 0x0002 + Manuel = 0x0004 + WeekProgram = 0x0008 + + Away = StartAway = 0x0010 + EndAway = 0x8010 + + Night = NightEnable = 0x0020 + NightDisable = 0x8020 + + Fireplace = StartFireplace = 0x0040 + EndFireplace = 0x8040 + + ManuelBypass = SelectManuelBypass = 0x0080 + DeselectManuelBypass = 0x8080 + + Summer = StartSummer = 0x0800 + EndSummer = 0x8800 + + +STATE_STANDBY: Final = "standby" +STATE_AUTOMATIC: Final = "automatic" +STATE_MANUAL: Final = "manual" +STATE_WEEKPROGRAM: Final = "week_program" +STATE_AWAY: Final = "away" +STATE_SUMMER: Final = "summer" +STATE_FIREPLACE: Final = "fireplace" +STATE_NIGHT: Final = "night" + + +class BypassDamperState(int): + """Dantherm bypass damper state class.""" + + InProgress = 1 + Opening = 64 + Opened = 255 + Closing = 32 + Closed = 0 + + +@dataclass +class DanthermButtonEntityDescription(ButtonEntityDescription): + """Dantherm Button Entity Description.""" + + data_setaddress: int | None = None + data_setclass: DataClass | None = None + state: int = None + state_entity: str | None = None + + data_address: int | None = None + data_exclude_if: Any | None = None + data_exclude_if_above: int | None = None + data_exclude_if_below: int | None = None + data_class: DataClass = DataClass.UInt16 + + component_class: ComponentClass = None + + +@dataclass +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 + state_stop: int = None + + data_address: int | None = None + data_getinternal: str | None = None + data_entity: str | None = None + data_exclude_if: Any | None = None + data_exclude_if_above: int | None = None + data_exclude_if_below: int | None = None + data_class: DataClass = DataClass.UInt16 + state_opening: int = None + state_opened: int = None + state_closing: int = None + state_closed: int = None + + component_class: ComponentClass = None + + +@dataclass +class DanthermNumberEntityDescription(NumberEntityDescription): + """Dantherm Number Entity Description.""" + + data_setaddress: int | None = None + data_setinternal: str | None = None + data_setclass: DataClass | None = None + + data_address: int | None = None + data_getinternal: str | None = None + data_entity: str | None = None + data_exclude_if: Any | None = None + data_exclude_if_above: int | None = None + data_exclude_if_below: int | None = None + data_class: DataClass = DataClass.UInt16 + + component_class: ComponentClass = None + + +@dataclass +class DanthermSelectEntityDescription(SelectEntityDescription): + """Dantherm Select Entity Description.""" + + data_setaddress: int | None = None + data_setinternal: str | None = None + data_setclass: DataClass | None = None + + data_address: int | None = None + data_getinternal: str | None = None + data_entity: str | None = None + data_bitwise_and: int | None = None + data_exclude_if: Any | None = None + data_exclude_if_above: int | None = None + data_exclude_if_below: int | None = None + data_class: DataClass = DataClass.UInt16 + + component_class: ComponentClass = None + + +@dataclass +class DanthermSensorEntityDescription(SensorEntityDescription): + """Dantherm Sensor Entity Description.""" + + icon_zero: str | None = None + data_address: int | None = None + data_getinternal: str | None = None + data_precision: int | None = None + data_scale: int | None = None + data_exclude_if: Any | None = None + data_exclude_if_above: int | None = None + data_exclude_if_below: int | None = None + data_entity: str | None = None + data_class: DataClass = DataClass.UInt16 + + component_class: ComponentClass = None + + +@dataclass +class DanthermSwitchEntityDescription(SwitchEntityDescription): + """Dantherm Switch Entity Description.""" + + data_setaddress: int | None = None + data_setinternal: str | None = None + data_getinternal: str | None = None + state_seton: int = None + state_setoff: int = None + data_setclass: DataClass | None = None + + state_suspend_for: int | None = None + state_on: int = None + icon_on: str = None + state_off: int = None + icon_off: str = None + + data_address: int | None = None + data_entity: str | None = None + data_exclude_if: Any | None = None + data_exclude_if_above: int | None = None + data_exclude_if_below: int | None = None + data_class: DataClass = DataClass.UInt16 + + component_class: ComponentClass = None + + +BUTTONS: tuple[DanthermButtonEntityDescription, ...] = ( + DanthermButtonEntityDescription( + key="filter_reset", + data_setaddress=558, + state=1, + data_class=DataClass.UInt32, + ), + DanthermButtonEntityDescription( + key="alarm_reset", + data_setaddress=514, + state_entity="alarm", + data_class=DataClass.UInt32, + ), +) + +COVERS: tuple[DanthermCoverEntityDescription, ...] = ( + DanthermCoverEntityDescription( + key="bypass_damper", + supported_features=CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE, + data_setinternal="set_bypass_damper", + data_getinternal="get_bypass_damper", + state_opening=BypassDamperState.Opening, + state_opened=BypassDamperState.Opened, + state_closing=BypassDamperState.Closing, + state_closed=BypassDamperState.Closed, + component_class=ComponentClass.Bypass, + device_class=CoverDeviceClass.DAMPER, + ), +) + +NUMBERS: tuple[DanthermNumberEntityDescription, ...] = ( + DanthermNumberEntityDescription( + key="filter_lifetime", + icon="mdi:air-filter", + data_setinternal="set_filter_lifetime", + data_getinternal="get_filter_lifetime", + native_max_value=360, + native_min_value=0, + device_class=NumberDeviceClass.DURATION, + native_unit_of_measurement="d", + mode=NumberMode.BOX, + entity_category=EntityCategory.CONFIG, + ), +) + +SELECTS: tuple[DanthermSelectEntityDescription, ...] = ( + DanthermSelectEntityDescription( + key="operation_selection", + icon="mdi:state-machine", + data_setinternal="set_operation_selection", + data_getinternal="get_operation_selection", + options=[ + "standby", + "automatic", + "manual", + "week_program", + "away", + "summer", + "fireplace", + "night", + ], + ), + DanthermSelectEntityDescription( + key="fan_level_selection", + data_setinternal="set_fan_level", + data_getinternal="get_fan_level", + options=["0", "1", "2", "3", "4"], + ), + DanthermSelectEntityDescription( + key="week_program_selection", + icon="mdi:clock-edit-outline", + data_address=466, + data_class=DataClass.UInt32, + options=["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], + component_class=ComponentClass.Week, + entity_category=EntityCategory.CONFIG, + ), +) + +SENSORS: tuple[DanthermSensorEntityDescription, ...] = ( + DanthermSensorEntityDescription( + key="operation_mode", + data_getinternal="get_current_unit_mode", + entity_category=EntityCategory.DIAGNOSTIC, + ), + DanthermSensorEntityDescription( + key="alarm", + icon="mdi:alert-circle-outline", + icon_zero="mdi:alert-circle-check-outline", + data_getinternal="get_alarm", + ), + DanthermSensorEntityDescription( + key="fan_level", + data_getinternal="get_fan_level", + ), + DanthermSensorEntityDescription( + key="fan1_speed", + icon="mdi:fan", + icon_zero="mdi:fan-off", + data_class=DataClass.Float32, + data_address=100, + native_unit_of_measurement="rpm", + data_precision=0, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + ), + DanthermSensorEntityDescription( + key="fan2_speed", + icon="mdi:fan", + icon_zero="mdi:fan-off", + data_class=DataClass.Float32, + data_address=102, + native_unit_of_measurement="rpm", + data_precision=0, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + ), + DanthermSensorEntityDescription( + key="humidity", + data_address=196, + data_exclude_if=0, + data_class=DataClass.UInt32, + native_unit_of_measurement="%", + device_class=SensorDeviceClass.HUMIDITY, + state_class=SensorStateClass.MEASUREMENT, + component_class=ComponentClass.RH_Senser, + ), + DanthermSensorEntityDescription( + key="air_quality", + data_address=430, + data_exclude_if=0, + data_class=DataClass.UInt32, + native_unit_of_measurement="ppm", + device_class=SensorDeviceClass.AQI, + state_class=SensorStateClass.MEASUREMENT, + component_class=ComponentClass.VOC_sensor, + ), + DanthermSensorEntityDescription( + key="exhaust_temperature", + data_class=DataClass.Float32, + data_address=138, + data_precision=1, + native_unit_of_measurement="°C", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + DanthermSensorEntityDescription( + key="extract_temperature", + data_class=DataClass.Float32, + data_address=136, + data_precision=1, + native_unit_of_measurement="°C", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + DanthermSensorEntityDescription( + key="supply_temperature", + data_class=DataClass.Float32, + data_address=134, + data_precision=1, + native_unit_of_measurement="°C", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + DanthermSensorEntityDescription( + key="outdoor_temperature", + data_class=DataClass.Float32, + data_address=132, + data_precision=1, + native_unit_of_measurement="°C", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + DanthermSensorEntityDescription( + key="room_temperature", + data_class=DataClass.Float32, + data_address=140, + data_precision=1, + data_exclude_if_above=70, + data_exclude_if_below=-40, + native_unit_of_measurement="°C", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + component_class=ComponentClass.HRC2, + ), + DanthermSensorEntityDescription( + key="filter_remain", + icon="mdi:air-filter", + data_getinternal="get_filter_remain", + native_unit_of_measurement="d", + suggested_display_precision=0, + suggested_unit_of_measurement="d", + device_class=SensorDeviceClass.DURATION, + ), + DanthermSensorEntityDescription( + key="work_time", + icon="mdi:progress-clock", + data_class=DataClass.UInt32, + data_address=624, + native_unit_of_measurement="h", + suggested_display_precision=0, + suggested_unit_of_measurement="h", + device_class=SensorDeviceClass.DURATION, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + ), + DanthermSensorEntityDescription( + key="internal_preheater_dutycycle", + icon="mdi:heating-coil", + data_address=160, + data_class=DataClass.UInt32, + device_class=NumberDeviceClass.POWER_FACTOR, + native_unit_of_measurement="%", + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + component_class=ComponentClass.Internal_preheater, + ), +) + +SWITCHES: tuple[DanthermSwitchEntityDescription, ...] = ( + DanthermSwitchEntityDescription( + key="away_mode", + data_setinternal="set_active_unit_mode", + data_getinternal="get_away_mode", + state_suspend_for=30, + state_on=ActiveUnitMode.StartAway, + icon_on="mdi:bag-suitcase-outline", + state_off=ActiveUnitMode.EndAway, + icon_off="mdi:bag-suitcase-off-outline", + device_class=SwitchDeviceClass.SWITCH, + ), + DanthermSwitchEntityDescription( + key="night_mode", + data_setinternal="set_active_unit_mode", + data_getinternal="get_active_unit_mode", + state_suspend_for=30, + state_on=ActiveUnitMode.NightEnable, + icon_on="mdi:sleep", + state_off=ActiveUnitMode.NightDisable, + icon_off="mdi:sleep-off", + device_class=SwitchDeviceClass.SWITCH, + entity_category=EntityCategory.CONFIG, + ), + DanthermSwitchEntityDescription( + key="fireplace_mode", + data_setinternal="set_active_unit_mode", + data_getinternal="get_fireplace_mode", + state_suspend_for=30, + state_seton=ActiveUnitMode.StartFireplace, + icon_on="mdi:fireplace", + state_setoff=ActiveUnitMode.EndFireplace, + icon_off="mdi:fireplace-off", + device_class=SwitchDeviceClass.SWITCH, + ), + DanthermSwitchEntityDescription( + key="manual_bypass_mode", + data_setinternal="set_active_unit_mode", + data_getinternal="get_active_unit_mode", + state_suspend_for=30, + state_on=ActiveUnitMode.SelectManuelBypass, + icon_on="mdi:hand-back-right-outline", + state_off=ActiveUnitMode.DeselectManuelBypass, + icon_off="mdi:hand-back-right-off-outline", + component_class=ComponentClass.Bypass, + device_class=SwitchDeviceClass.SWITCH, + ), + DanthermSwitchEntityDescription( + key="summer_mode", + data_setinternal="set_active_unit_mode", + data_getinternal="get_summer_mode", + state_suspend_for=30, + state_seton=ActiveUnitMode.StartSummer, + icon_on="mdi:weather-sunny", + state_setoff=ActiveUnitMode.EndSummer, + icon_off="mdi:weather-sunny-off", + device_class=SwitchDeviceClass.SWITCH, + ), +) diff --git a/custom_components/dantherm/number.py b/custom_components/dantherm/number.py index ce4e21e..8646142 100644 --- a/custom_components/dantherm/number.py +++ b/custom_components/dantherm/number.py @@ -5,8 +5,9 @@ from homeassistant.components.number import NumberEntity from homeassistant.core import HomeAssistant -from .const import DOMAIN, NUMBERS, DanthermNumberEntityDescription +from .const import DOMAIN from .device import DanthermEntity, Device +from .device_map import NUMBERS, DanthermNumberEntityDescription _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/dantherm/select.py b/custom_components/dantherm/select.py index 0d3c076..5d247a5 100644 --- a/custom_components/dantherm/select.py +++ b/custom_components/dantherm/select.py @@ -5,8 +5,9 @@ from homeassistant.components.select import SelectEntity from homeassistant.core import HomeAssistant -from .const import DOMAIN, SELECTS, DanthermSelectEntityDescription +from .const import DOMAIN from .device import DanthermEntity, Device +from .device_map import SELECTS, DanthermSelectEntityDescription _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/dantherm/sensor.py b/custom_components/dantherm/sensor.py index 6737bf9..8fd2fed 100644 --- a/custom_components/dantherm/sensor.py +++ b/custom_components/dantherm/sensor.py @@ -5,8 +5,9 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.core import HomeAssistant -from .const import DOMAIN, SENSORS, DanthermSensorEntityDescription +from .const import DOMAIN from .device import DanthermEntity, Device +from .device_map import SENSORS, DanthermSensorEntityDescription _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/dantherm/switch.py b/custom_components/dantherm/switch.py index a8bf44d..2435134 100644 --- a/custom_components/dantherm/switch.py +++ b/custom_components/dantherm/switch.py @@ -6,8 +6,9 @@ from homeassistant.components.switch import SwitchEntity from homeassistant.core import HomeAssistant -from .const import DOMAIN, SWITCHES, DanthermSwitchEntityDescription +from .const import DOMAIN from .device import DanthermEntity, Device +from .device_map import SWITCHES, DanthermSwitchEntityDescription _LOGGER = logging.getLogger(__name__) From bb74140747ed0113af82889871a5782acb145505 Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Sat, 17 Aug 2024 07:58:14 +0200 Subject: [PATCH 2/8] Removed dantherm from translations --- custom_components/dantherm/translations/da.json | 4 ++-- custom_components/dantherm/translations/en.json | 4 ++-- custom_components/dantherm/translations/fr.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_components/dantherm/translations/da.json b/custom_components/dantherm/translations/da.json index fe98cfa..c9a081c 100644 --- a/custom_components/dantherm/translations/da.json +++ b/custom_components/dantherm/translations/da.json @@ -2,9 +2,9 @@ "config": { "step": { "user": { - "title": "Dantherm modbus forbindelse", + "title": "Modbus forbindelse", "data": { - "host": "Indtast ip-adresse til din Dantherm enhed", + "host": "Indtast ip-adresse til din enhed", "name": "Indtast prefix til din enheds entiteter", "port": "Indtast TCP port der skal forbindes til på din enhed", "scan_interval": "Indtast opdateringsfrekvens for modbus registere i sekunder" diff --git a/custom_components/dantherm/translations/en.json b/custom_components/dantherm/translations/en.json index 088280a..5e12c1a 100644 --- a/custom_components/dantherm/translations/en.json +++ b/custom_components/dantherm/translations/en.json @@ -2,9 +2,9 @@ "config": { "step": { "user": { - "title": "Dantherm modbus-connection", + "title": "Modbus-connection", "data": { - "host": "Enter ip-address of your Dantherm unit", + "host": "Enter ip-address of your unit", "name": "Enter prefix for the device entities", "port": "Enter TCP port on which to connect to the device", "scan_interval": "Enter polling frequency of the modbus registers in seconds" diff --git a/custom_components/dantherm/translations/fr.json b/custom_components/dantherm/translations/fr.json index 17485f5..24feff1 100644 --- a/custom_components/dantherm/translations/fr.json +++ b/custom_components/dantherm/translations/fr.json @@ -2,7 +2,7 @@ "config": { "step": { "user": { - "title": "Connexion modbus Dantherm", + "title": "Connexion Modbus", "data": { "host": "Adresse IP de la VMC", "name": "Préfixe à utiliser pour les entités", From 5f6cccae26fa154d4036816e2274eaecc180d7be Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Sun, 18 Aug 2024 06:57:24 +0200 Subject: [PATCH 3/8] Removed dantherm from translations --- custom_components/dantherm/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/dantherm/translations/en.json b/custom_components/dantherm/translations/en.json index 5e12c1a..eb82946 100644 --- a/custom_components/dantherm/translations/en.json +++ b/custom_components/dantherm/translations/en.json @@ -2,7 +2,7 @@ "config": { "step": { "user": { - "title": "Modbus-connection", + "title": "Modbus connection", "data": { "host": "Enter ip-address of your unit", "name": "Enter prefix for the device entities", From 6ae6e77410a0c3773a6e844f6339b318f83b0fec Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Sun, 18 Aug 2024 09:34:58 +0200 Subject: [PATCH 4/8] Added bypass manual duration and temperature limits --- custom_components/dantherm/device_map.py | 46 +++++++++++++++++++ custom_components/dantherm/number.py | 2 +- .../dantherm/translations/da.json | 5 +- .../dantherm/translations/en.json | 5 +- .../dantherm/translations/fr.json | 5 +- 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/custom_components/dantherm/device_map.py b/custom_components/dantherm/device_map.py index 72f0915..657a2f8 100644 --- a/custom_components/dantherm/device_map.py +++ b/custom_components/dantherm/device_map.py @@ -187,6 +187,7 @@ class DanthermNumberEntityDescription(NumberEntityDescription): data_address: int | None = None data_getinternal: str | None = None + data_precision: int | None = None data_entity: str | None = None data_exclude_if: Any | None = None data_exclude_if_above: int | None = None @@ -304,6 +305,51 @@ class DanthermSwitchEntityDescription(SwitchEntityDescription): mode=NumberMode.BOX, entity_category=EntityCategory.CONFIG, ), + DanthermNumberEntityDescription( + key="bypass_minimum_temperature", + data_address=444, + native_max_value=15, + native_min_value=12, + data_class=DataClass.Float32, + device_class=NumberDeviceClass.TEMPERATURE, + native_unit_of_measurement="°C", + data_precision=1, + mode=NumberMode.SLIDER, + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + component_class=ComponentClass.Bypass, + ), + DanthermNumberEntityDescription( + key="bypass_maximum_temperature", + data_address=446, + native_max_value=27, + native_min_value=21, + data_class=DataClass.Float32, + device_class=NumberDeviceClass.TEMPERATURE, + native_unit_of_measurement="°C", + data_precision=1, + mode=NumberMode.SLIDER, + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + component_class=ComponentClass.Bypass, + ), + DanthermNumberEntityDescription( + key="manual_bypass_duration", + data_address=264, + native_max_value=480, + native_min_value=60, + data_class=DataClass.UInt32, + device_class=NumberDeviceClass.DURATION, + native_unit_of_measurement="min", + native_step=15, + mode=NumberMode.SLIDER, + entity_registry_visible_default=True, + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + component_class=ComponentClass.Bypass, + ), ) SELECTS: tuple[DanthermSelectEntityDescription, ...] = ( diff --git a/custom_components/dantherm/number.py b/custom_components/dantherm/number.py index 8646142..4d27cab 100644 --- a/custom_components/dantherm/number.py +++ b/custom_components/dantherm/number.py @@ -53,7 +53,7 @@ async def async_set_native_value(self, value: int) -> None: await getattr(self._device, self.entity_description.data_setinternal)(value) else: await self._device.write_holding_registers( - description=self.entity_description + description=self.entity_description, value=value ) async def async_update(self) -> None: diff --git a/custom_components/dantherm/translations/da.json b/custom_components/dantherm/translations/da.json index c9a081c..dcb4bff 100644 --- a/custom_components/dantherm/translations/da.json +++ b/custom_components/dantherm/translations/da.json @@ -27,7 +27,10 @@ "bypass_damper": { "name": "Bypass spjæld"} }, "number": { - "filter_lifetime": { "name": "Filter livstid" } + "filter_lifetime": { "name": "Filter livstid" }, + "bypass_minimum_temperature": { "name": "Bypass minimum temperatur" }, + "bypass_maximum_temperature": { "name": "Bypass maximum temperatur" }, + "manual_bypass_duration": { "name": "Manuel bypass varighed" } }, "select": { "operation_selection": { diff --git a/custom_components/dantherm/translations/en.json b/custom_components/dantherm/translations/en.json index eb82946..f3b89b8 100644 --- a/custom_components/dantherm/translations/en.json +++ b/custom_components/dantherm/translations/en.json @@ -27,7 +27,10 @@ "bypass_damper": { "name": "Bypass Damper" } }, "number": { - "filter_lifetime": { "name": "Filter Lifetime" } + "filter_lifetime": { "name": "Filter Lifetime" }, + "bypass_minimum_temperature": { "name": "Bypass Minimum Temperature" }, + "bypass_maximum_temperature": { "name": "Bypass Maxumum Temperature" }, + "manual_bypass_duration": { "name": "Manual Bypass Duration" } }, "select": { "operation_selection": { diff --git a/custom_components/dantherm/translations/fr.json b/custom_components/dantherm/translations/fr.json index 24feff1..07c3979 100644 --- a/custom_components/dantherm/translations/fr.json +++ b/custom_components/dantherm/translations/fr.json @@ -27,7 +27,10 @@ "bypass_damper": { "name": "Bypass" } }, "number": { - "filter_lifetime": { "name": "Durée de vie filtre" } + "filter_lifetime": { "name": "Durée de vie filtre" }, + "bypass_minimum_temperature": { "name": "Bypass température minimale" }, + "bypass_maximum_temperature": { "name": "Bypass température maximale" }, + "manual_bypass_duration": { "name": "Durée du bypass manuel" } }, "select": { "operation_selection": { From 64b6956cfe1b8c402ac6102ba0e58ee455f414ef Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Mon, 19 Aug 2024 11:10:45 +0200 Subject: [PATCH 5/8] Update README.md --- README.md | 59 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index fe1141f..05d4e00 100644 --- a/README.md +++ b/README.md @@ -17,35 +17,38 @@ Known supported units: ### Controls and sensors -| key | description | -| :--------------------- | :------------------------------------ | -| operation_selection | Mode of operation selection | -| fan_level_selection | Fan level selection | -| week_program_selection | Week program selection\* | -| bypass_damper | Bypass damper cover\* | -| filter_lifetime | Input filter lifetime box | -| operation_mode | Operation mode sensor | -| alarm | Alarm sensor | -| fan_level | Fan level sensor | -| fan1_speed | Fan 1 speed sensor | -| fan2_speed | Fan 2 speed sensor | -| humidity | Humidity sensor\* | -| air_quality | Air quality sensor\* | -| exhaust_temperature | Exhaust temperature sensor | -| extract_temperature | Extract temperature sensor | -| supply_temperature | Supply temperature sensor | -| outdoor_temperature | Outdoor temperature sensor | -| room_temperature | Room temperature sensor\* † | -| filter_remain | Remaining filter time sensor | -| work_time | Work time sensor | +| key | description | +| :--------------------------- | :------------------------------------ | +| operation_selection | Mode of operation selection | +| fan_level_selection | Fan level selection | +| week_program_selection | Week program selection\* | +| bypass_damper | Bypass damper cover\* | +| filter_lifetime | Input filter lifetime box | +| bypass_minimum_temperature | Bypass minimum temperature slider | +| bypass_maximum_temperature | Bypass maximum temperature slider | +| manual_bypass_duration | Manual bypass duration slider\* † | +| operation_mode | Operation mode sensor | +| alarm | Alarm sensor | +| fan_level | Fan level sensor | +| fan1_speed | Fan 1 speed sensor | +| fan2_speed | Fan 2 speed sensor | +| humidity | Humidity sensor\* | +| air_quality | Air quality sensor\* | +| exhaust_temperature | Exhaust temperature sensor | +| extract_temperature | Extract temperature sensor | +| supply_temperature | Supply temperature sensor | +| outdoor_temperature | Outdoor temperature sensor | +| room_temperature | Room temperature sensor\* † | +| filter_remain | Remaining filter time sensor | +| work_time | Work time sensor | | internal_preheater_dutycycle | Preheater power dutycycle\* † | -| away_mode | Away mode switch | -| night_mode | Night mode switch | -| fireplace_mode | Fireplace mode switch | -| manual_bypass_mode | Manual bypass mode switch\* | -| summer_mode | Summer mode switch | -| filter_reset | Reset remain filter time button | -| alarm_reset | Reset alarm button | +| away_mode | Away mode switch | +| night_mode | Night mode switch | +| fireplace_mode | Fireplace mode switch | +| manual_bypass_mode | Manual bypass mode switch\* | +| summer_mode | Summer mode switch | +| filter_reset | Reset remain filter time button | +| alarm_reset | Reset alarm button | _\* Some of the entities may not install due to lack of support or installation in the particular unit._ From 9c9ab6a1357cae6518966870cec2e47bfeed6c73 Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:06:29 +0200 Subject: [PATCH 6/8] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 05d4e00..0d2cae8 100644 --- a/README.md +++ b/README.md @@ -375,8 +375,8 @@ The trademark "Dantherm" is owned by Dantherm Group A/S, a leading supplier of c All product names, trademarks, and registered trademarks mentioned in this repository are the property of their respective owners. -I am not affiliated with Dantherm, except as an owner of one of their units, the HCV400 P2. +#### I am not affiliated with Dantherm, except as an owner of one of their units, the HCV400 P2. -The author does not guarantee the functionality of this integration and is not responsible for any damage. +### The author does not guarantee the functionality of this integration and is not responsible for any damage. -Tvalley71 +_Tvalley71_ From 366f287a751119bda746cc6b67006337e79adc6e Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:10:53 +0200 Subject: [PATCH 7/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d2cae8..63e4b8c 100644 --- a/README.md +++ b/README.md @@ -366,7 +366,7 @@ Alert chip displaying any current alert along with its descriptions. A hold acti Here are some examples of badges added to the dashboard. The pop-up that appears when clicking on a badge will vary depending on the selected entities, either displaying information or enabling manipulation of the Dantherm unit. -![Skærmbillede badge example](https://github.com/user-attachments/assets/77ae39a9-edb2-4648-bb88-feac6a997087) +![Skærmbillede badge example](https://github.com/user-attachments/assets/bbaac388-0e40-48cf-a0d1-7b42fb5a4234) ## Disclaimer From dc2c6d2cdfd8b4e07afe058de68fe77444f0301e Mon Sep 17 00:00:00 2001 From: Tvalley71 <83084467+Tvalley71@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:24:07 +0200 Subject: [PATCH 8/8] Moved DEVICE_TYPES to const.py --- custom_components/dantherm/const.py | 17 +++++++++++++++++ custom_components/dantherm/device.py | 3 +-- custom_components/dantherm/device_map.py | 17 ----------------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/custom_components/dantherm/const.py b/custom_components/dantherm/const.py index 06d8332..fd3b984 100644 --- a/custom_components/dantherm/const.py +++ b/custom_components/dantherm/const.py @@ -4,3 +4,20 @@ DEFAULT_NAME = "Dantherm" DEFAULT_SCAN_INTERVAL = 10 DEFAULT_PORT = 502 + +DEVICE_TYPES = { + 1: "WG200", + 2: "WG300", + 3: "WG500", + 4: "HCC 2", + 5: "HCC 2 ALU", + 6: "HCV300 ALU", + 7: "HCV500 ALU", + 8: "HCV700 ALU", + 9: "HCV400 P2", + 10: "HCV400 E1", + 11: "HCV400 P1", + 12: "HCC 2 E1", + 21: "RCV320 P2", + 26: "RCV320 P1", +} diff --git a/custom_components/dantherm/device.py b/custom_components/dantherm/device.py index b803035..75b22c6 100644 --- a/custom_components/dantherm/device.py +++ b/custom_components/dantherm/device.py @@ -13,9 +13,8 @@ from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.event import async_track_time_interval -from .const import DEFAULT_NAME, DOMAIN +from .const import DEFAULT_NAME, DEVICE_TYPES, DOMAIN from .device_map import ( - DEVICE_TYPES, STATE_AUTOMATIC, STATE_AWAY, STATE_FIREPLACE, diff --git a/custom_components/dantherm/device_map.py b/custom_components/dantherm/device_map.py index 657a2f8..6050c46 100644 --- a/custom_components/dantherm/device_map.py +++ b/custom_components/dantherm/device_map.py @@ -24,23 +24,6 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntityDescription from homeassistant.const import EntityCategory -DEVICE_TYPES = { - 1: "WG200", - 2: "WG300", - 3: "WG500", - 4: "HCC 2", - 5: "HCC 2 ALU", - 6: "HCV300 ALU", - 7: "HCV500 ALU", - 8: "HCV700 ALU", - 9: "HCV400 P2", - 10: "HCV400 E1", - 11: "HCV400 P1", - 12: "HCC 2 E1", - 21: "RCV320 P2", - 26: "RCV320 P1", -} - class ComponentClass(int): """Danterm components."""