diff --git a/plugwise/constants.py b/plugwise/constants.py index 267f2cbdb..4673b6dd7 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -181,6 +181,7 @@ ), # Available with the Loria and Elga (newer Anna firmware) heatpumps "cooling_state": UOM(NONE), "domestic_hot_water_mode": DATA("select_dhw_mode", NONE), + "domestic_hot_water_comfort_mode": DATA("select_dhw_mode", NONE), "domestic_hot_water_setpoint": UOM(TEMP_CELSIUS), "domestic_hot_water_state": DATA("dhw_state", NONE), "domestic_hot_water_temperature": DATA("dhw_temperature", TEMP_CELSIUS), diff --git a/plugwise/helper.py b/plugwise/helper.py index 075f5b17d..b6f7645c8 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -242,9 +242,8 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree.Element) -> Munch appl := self._appl_heater_central_info(appl, appliance, False) ): # False means non-legacy entity return Munch() - self._dhw_allowed_modes = self._get_appl_actuator_modes( - appliance, "domestic_hot_water_mode_control_functionality" - ) + self._collect_dhw_modes(appliance) + return appl case _ as s if s.endswith("_plug"): # Collect info from plug-types (Plug, Aqara Smart Plug) @@ -265,6 +264,18 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree.Element) -> Munch case _: # pragma: no cover return Munch() + def _collect_dhw_modes(self, appliance: etree.Element) -> None: + """Collect the DHW modes.""" + # Collect the Loria dhw_modes + self._dhw_allowed_modes = self._get_appl_actuator_modes( + appliance, "domestic_hot_water_mode_control_functionality" + ) + # Collect the default dhw modes: comfort and off + if not self._dhw_allowed_modes: + self._get_toggle_state( + appliance, "domestic_hot_water_comfort_mode", "dhw_cm_switch", None + ) + def _appl_gateway_info(self, appl: Munch, appliance: etree.Element) -> Munch: """Helper-function for _appliance_info_finder().""" self._gateway_id = appl.entity_id @@ -351,7 +362,7 @@ def _get_measurement_data(self, entity_id: str, entity: GwEntityData) -> None: measurements = DEVICE_MEASUREMENTS if self._is_thermostat and entity_id == self.heater_id: measurements = HEATER_CENTRAL_MEASUREMENTS - # Show the allowed dhw_modes (Loria only) + # Show the available dhw_modes if self._dhw_allowed_modes: data["dhw_modes"] = self._dhw_allowed_modes # Counting of this item is done in _appliance_measurements() @@ -407,12 +418,14 @@ def _collect_appliance_data( if ( appliance := self._domain_objects.find(f'./appliance[@id="{entity_id}"]') ) is not None: + # Collect the cooling enabled toggle state + self._get_toggle_state( + appliance, "cooling_enabled", "cooling_ena_switch", data + ) + self._appliance_measurements(appliance, data, measurements) self._get_lock_state(appliance, data) - for toggle, name in TOGGLES.items(): - self._get_toggle_state(appliance, toggle, name, data) - if appliance.find("type").text in ACTUATOR_CLASSES: self._get_actuator_functionalities(appliance, entity, data) @@ -452,6 +465,7 @@ def _appliance_measurements( continue if new_name := getattr(attrs, ATTR_NAME, None): + old_measurement = measurement measurement = new_name match measurement: @@ -460,6 +474,10 @@ def _appliance_measurements( case "select_dhw_mode": if self._dhw_allowed_modes: data["select_dhw_mode"] = appl_p_loc.text + if old_measurement == "domestic_hot_water_comfort_mode": + data["select_dhw_mode"] = ( + "comfort" if appl_p_loc.text == "on" else "off" + ) common_match_cases(measurement, attrs, appl_p_loc, data) @@ -482,8 +500,12 @@ def _get_toggle_state( if xml.find("type").text == "heater_central": locator = f"./actuator_functionalities/toggle_functionality[type='{toggle}']/state" if (state := xml.find(locator)) is not None: - data["switches"][name] = state.text == "on" - self._count += 1 + match toggle: + case "cooling_enabled": + data["switches"][name] = state.text == "on" + self._count += 1 + case "domestic_hot_water_comfort_mode": + self._dhw_allowed_modes = ["comfort", "off"] def _get_plugwise_notifications(self) -> None: """Collect the Plugwise notifications.""" diff --git a/tests/data/adam/adam_bad_thermostat.json b/tests/data/adam/adam_bad_thermostat.json index 5554c02e1..16978a60c 100644 --- a/tests/data/adam/adam_bad_thermostat.json +++ b/tests/data/adam/adam_bad_thermostat.json @@ -7,6 +7,10 @@ "heating_state": false }, "dev_class": "heater_central", + "dhw_modes": [ + "comfort", + "off" + ], "location": "856285a783f24bf4b2573c8bc510eabf", "max_dhw_temperature": { "lower_bound": 0.0, @@ -23,6 +27,7 @@ "model": "Generic heater", "model_id": "1.1", "name": "OpenTherm", + "select_dhw_mode": "off", "sensors": { "dhw_temperature": 49.9, "intended_boiler_temperature": 0.0, @@ -31,9 +36,6 @@ "return_temperature": 33.0, "water_temperature": 20.9 }, - "switches": { - "dhw_cm_switch": false - }, "vendor": "WeHeat" }, "3ee6b9486cb04c258a3130fff2b144a4": { diff --git a/tests/data/adam/adam_heatpump_cooling.json b/tests/data/adam/adam_heatpump_cooling.json index 71bfad7e2..6c9f1fabe 100644 --- a/tests/data/adam/adam_heatpump_cooling.json +++ b/tests/data/adam/adam_heatpump_cooling.json @@ -44,6 +44,10 @@ }, "dev_class": "heater_central", "location": "eedadcb297564f1483faa509179aebed", + "dhw_modes": [ + "comfort", + "off" + ], "max_dhw_temperature": { "lower_bound": 40.0, "resolution": 0.01, @@ -59,6 +63,7 @@ "model": "Generic heater/cooler", "model_id": "17.1", "name": "OpenTherm", + "select_dhw_mode": "off", "sensors": { "dhw_temperature": 63.5, "intended_boiler_temperature": 0.0, @@ -68,9 +73,6 @@ "water_pressure": 2.0, "water_temperature": 24.5 }, - "switches": { - "dhw_cm_switch": true - }, "vendor": "Remeha B.V." }, "1053c8bbf8be43c6921742b146a625f1": { diff --git a/tests/data/adam/adam_jip.json b/tests/data/adam/adam_jip.json index a1136e3c9..3c10a4ca7 100644 --- a/tests/data/adam/adam_jip.json +++ b/tests/data/adam/adam_jip.json @@ -330,6 +330,10 @@ }, "dev_class": "heater_central", "location": "9e4433a9d69f40b3aefd15e74395eaec", + "dhw_modes": [ + "comfort", + "off" + ], "max_dhw_temperature": { "lower_bound": 40.0, "resolution": 0.01, @@ -345,6 +349,7 @@ "model": "Generic heater", "model_id": "10.20", "name": "OpenTherm", + "select_dhw_mode": "off", "sensors": { "intended_boiler_temperature": 0.0, "modulation_level": 0.0, @@ -352,9 +357,6 @@ "water_pressure": 1.4, "water_temperature": 37.3 }, - "switches": { - "dhw_cm_switch": false - }, "vendor": "Remeha B.V." }, "f61f1a2535f54f52ad006a3d18e459ca": { diff --git a/tests/data/adam/adam_onoff_cooling_fake_firmware.json b/tests/data/adam/adam_onoff_cooling_fake_firmware.json index f822e33d8..27d994a0e 100644 --- a/tests/data/adam/adam_onoff_cooling_fake_firmware.json +++ b/tests/data/adam/adam_onoff_cooling_fake_firmware.json @@ -9,6 +9,10 @@ }, "dev_class": "heater_central", "location": "eedadcb297564f1483faa509179aebed", + "dhw_modes": [ + "comfort", + "off" + ], "max_dhw_temperature": { "lower_bound": 40.0, "resolution": 0.01, @@ -23,6 +27,7 @@ }, "model": "Unknown", "name": "OnOff", + "select_dhw_mode": "comfort", "sensors": { "dhw_temperature": 63.5, "intended_boiler_temperature": 0.0, @@ -31,9 +36,6 @@ "return_temperature": 24.9, "water_pressure": 2.0, "water_temperature": 24.5 - }, - "switches": { - "dhw_cm_switch": true } }, "7d97fc3117784cfdafe347bcedcbbbcb": { diff --git a/tests/data/adam/adam_plus_anna.json b/tests/data/adam/adam_plus_anna.json index 8533e7468..d86a53176 100644 --- a/tests/data/adam/adam_plus_anna.json +++ b/tests/data/adam/adam_plus_anna.json @@ -35,6 +35,10 @@ }, "dev_class": "heater_central", "location": "07d618f0bb80412687f065b8698ce3e7", + "dhw_modes": [ + "comfort", + "off" + ], "maximum_boiler_temperature": { "lower_bound": 0.0, "resolution": 1.0, @@ -43,12 +47,10 @@ }, "model": "Generic heater", "name": "OpenTherm", + "select_dhw_mode": "off", "sensors": { "intended_boiler_temperature": 0.0, "water_temperature": 48.0 - }, - "switches": { - "dhw_cm_switch": false } }, "aa6b0002df0a46e1b1eb94beb61eddfe": { diff --git a/tests/data/adam/adam_plus_anna_new.json b/tests/data/adam/adam_plus_anna_new.json index 0c1057afc..d794d51cd 100644 --- a/tests/data/adam/adam_plus_anna_new.json +++ b/tests/data/adam/adam_plus_anna_new.json @@ -8,6 +8,10 @@ }, "dev_class": "heater_central", "location": "bc93488efab249e5bc54fd7e175a6f91", + "dhw_modes": [ + "comfort", + "off" + ], "maximum_boiler_temperature": { "lower_bound": 25.0, "resolution": 0.01, @@ -16,12 +20,10 @@ }, "model": "Generic heater", "name": "OpenTherm", + "select_dhw_mode": "off", "sensors": { "intended_boiler_temperature": 22.5, "water_temperature": 43.0 - }, - "switches": { - "dhw_cm_switch": false } }, "10016900610d4c7481df78c89606ef22": { diff --git a/tests/data/adam/adam_plus_anna_new_regulation_off.json b/tests/data/adam/adam_plus_anna_new_regulation_off.json index 4a0576d90..4f3130c05 100644 --- a/tests/data/adam/adam_plus_anna_new_regulation_off.json +++ b/tests/data/adam/adam_plus_anna_new_regulation_off.json @@ -8,6 +8,10 @@ }, "dev_class": "heater_central", "location": "bc93488efab249e5bc54fd7e175a6f91", + "dhw_modes": [ + "comfort", + "off" + ], "maximum_boiler_temperature": { "lower_bound": 25.0, "resolution": 0.01, @@ -16,12 +20,10 @@ }, "model": "Generic heater", "name": "OpenTherm", + "select_dhw_mode": "off", "sensors": { "intended_boiler_temperature": 0.0, "water_temperature": 30.0 - }, - "switches": { - "dhw_cm_switch": false } }, "10016900610d4c7481df78c89606ef22": { diff --git a/tests/test_adam.py b/tests/test_adam.py index b818713f1..98266c7cc 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -47,7 +47,7 @@ async def test_connect_adam_plus_anna_new(self): test_items = await self.device_test(api, "2025-10-12 00:00:01", testdata) assert api.gateway_id == "da224107914542988a88561b4452b0f6" - assert self.entity_items == 231 + assert self.entity_items == 232 assert test_items == self.entity_items assert self.entity_list == [ "da224107914542988a88561b4452b0f6",