Skip to content

Commit a3dc5ef

Browse files
committed
Add entity "DHW thermal desinfection day"
1 parent 11685a3 commit a3dc5ef

File tree

2 files changed

+143
-2
lines changed

2 files changed

+143
-2
lines changed

custom_components/luxtronik/const.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
Platform.UPDATE,
3333
Platform.WATER_HEATER,
3434
Platform.CLIMATE,
35+
Platform.SELECT,
3536
]
3637
UPDATE_INTERVAL_FAST: Final = timedelta(seconds=10)
3738
UPDATE_INTERVAL_NORMAL: Final = timedelta(minutes=1)
@@ -86,7 +87,7 @@ class UnitOfVolumeFlowRateExt(StrEnum):
8687
class DeviceKey(StrEnum):
8788
"""Device keys."""
8889

89-
heatpump: Final = "heatpump"
90+
heatpump: Final = "heatpump"
9091
heating: Final = "heating"
9192
domestic_water: Final = "domestic_water"
9293
cooling: Final = "cooling"
@@ -272,6 +273,39 @@ class LuxSwitchoffReason(Enum):
272273
LUX_MODELS_OTHER = ["CB", "CI", "CN", "CS"]
273274
# endregion Lux Definitions
274275

276+
277+
class LuxDaySelectorParameter(StrEnum):
278+
"""Luxtronik parameters for day selector (TDI activation per weekday)."""
279+
280+
MONDAY: Final = "parameters.ID_Einst_BwTDI_akt_MO"
281+
TUESDAY: Final = "parameters.ID_Einst_BwTDI_akt_DI"
282+
WEDNESDAY: Final = "parameters.ID_Einst_BwTDI_akt_MI"
283+
THURSDAY: Final = "parameters.ID_Einst_BwTDI_akt_DO"
284+
FRIDAY: Final = "parameters.ID_Einst_BwTDI_akt_FR"
285+
SATURDAY: Final = "parameters.ID_Einst_BwTDI_akt_SA"
286+
SUNDAY: Final = "parameters.ID_Einst_BwTDI_akt_SO"
287+
288+
DAY_NAME_TO_PARAM: Final[dict[str, LuxDaySelectorParameter]] = {
289+
"Monday": LuxDaySelectorParameter.MONDAY,
290+
"Tuesday": LuxDaySelectorParameter.TUESDAY,
291+
"Wednesday": LuxDaySelectorParameter.WEDNESDAY,
292+
"Thursday": LuxDaySelectorParameter.THURSDAY,
293+
"Friday": LuxDaySelectorParameter.FRIDAY,
294+
"Saturday": LuxDaySelectorParameter.SATURDAY,
295+
"Sunday": LuxDaySelectorParameter.SUNDAY,
296+
}
297+
298+
DAY_SELECTOR_OPTIONS: Final[list[str]] = [
299+
"None",
300+
"Monday",
301+
"Tuesday",
302+
"Wednesday",
303+
"Thursday",
304+
"Friday",
305+
"Saturday",
306+
"Sunday",
307+
]
308+
275309
# region Lux parameters
276310

277311

@@ -805,7 +839,7 @@ class SensorKey(StrEnum):
805839
PUMP_VENT_HUP = "pump_vent_hup"
806840
PUMP_VENT_TIMER_H = "pump_vent_timer_h"
807841
PUMP_VENT_ACTIVE = "pump_vent_active"
808-
842+
THERMAL_DESINFECTION_DAY = "thermal_desinfection_day"
809843

810844
# endregion Keys
811845

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"""Support for Luxtronik selectors"""
2+
3+
from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT, BinarySensorEntity
4+
from homeassistant.components.select import SelectEntity
5+
from homeassistant.config_entries import ConfigEntry
6+
from homeassistant.core import HomeAssistant
7+
from homeassistant.exceptions import ConfigEntryNotReady
8+
from homeassistant.helpers.entity import EntityCategory
9+
from homeassistant.helpers.entity_platform import AddEntitiesCallback
10+
11+
12+
from .base import LuxtronikEntity
13+
from .common import get_sensor_data
14+
from .const import (
15+
DAY_SELECTOR_OPTIONS,
16+
DOMAIN,
17+
CONF_COORDINATOR,
18+
CONF_HA_SENSOR_PREFIX,
19+
LuxDaySelectorParameter,
20+
DAY_NAME_TO_PARAM,
21+
DeviceKey,
22+
SensorKey as SK
23+
)
24+
from .coordinator import LuxtronikCoordinator
25+
from .model import LuxtronikEntityDescription
26+
27+
28+
async def async_setup_entry(
29+
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
30+
) -> None:
31+
"""Set up Luxtronik Select entities"""
32+
33+
data = hass.data.get(DOMAIN, {}).get(entry.entry_id)
34+
if not data or CONF_COORDINATOR not in data:
35+
raise ConfigEntryNotReady
36+
37+
coordinator: LuxtronikCoordinator = data[CONF_COORDINATOR]
38+
39+
# Ensure coordinator has valid data before adding entities
40+
if not coordinator.last_update_success:
41+
raise ConfigEntryNotReady
42+
43+
description = LuxtronikEntityDescription(
44+
key=SK.THERMAL_DESINFECTION_DAY,
45+
name="Thermal Desinfection Day",
46+
device_key=DeviceKey.domestic_water,
47+
luxtronik_key=LuxDaySelectorParameter.MONDAY, # Just one valid key for metadata
48+
)
49+
async_add_entities([LuxtronikThermalDesinfectionDaySelector(entry, coordinator,description, description.device_key)], True)
50+
51+
52+
class LuxtronikThermalDesinfectionDaySelector(LuxtronikEntity, SelectEntity):
53+
"""Luxtronik Thermal Desinfection Day Selector Entity."""
54+
def __init__(
55+
self,
56+
entry: ConfigEntry,
57+
coordinator: LuxtronikCoordinator,
58+
description: LuxtronikEntityDescription,
59+
device_info_ident: DeviceKey,
60+
):
61+
# No description needed for this custom entity
62+
63+
super().__init__(
64+
coordinator=coordinator,
65+
description=description,
66+
device_info_ident=device_info_ident,
67+
)
68+
69+
self._attr_name = "Thermal Desinfection Day"
70+
self._attr_options = DAY_SELECTOR_OPTIONS
71+
self._attr_current_option = "None"
72+
self._attr_entity_category = EntityCategory.CONFIG
73+
self._attr_icon = "mdi:calendar"
74+
self.coordinator = coordinator
75+
76+
prefix = entry.data[CONF_HA_SENSOR_PREFIX]
77+
self.entity_id = ENTITY_ID_FORMAT.format(f"{prefix}_thermal_desinfection_day")
78+
self._attr_unique_id = self.entity_id
79+
80+
async def async_select_option(self, option: str) -> None:
81+
"""Handle selection of a new day."""
82+
self._attr_current_option = option
83+
current_data = self.coordinator.data
84+
85+
for day, param_enum in DAY_NAME_TO_PARAM.items():
86+
param = param_enum.value
87+
desired_value = 1 if day == option else 0
88+
current_value = int(get_sensor_data(current_data, param))
89+
90+
if current_value != desired_value:
91+
await self.coordinator.async_write(param, desired_value)
92+
93+
self.async_write_ha_state()
94+
95+
async def async_update(self) -> None:
96+
"""Read current day from heat pump and update selected option."""
97+
data = self.coordinator.data
98+
selected_day = "None"
99+
100+
for day, param_enum in DAY_NAME_TO_PARAM.items():
101+
param = param_enum.value
102+
value = get_sensor_data(data, param)
103+
if str(value) == "1":
104+
selected_day = day
105+
break
106+
107+
self._attr_current_option = selected_day

0 commit comments

Comments
 (0)