diff --git a/CHANGELOG.md b/CHANGELOG.md index 49fda9922..25b3e0ef0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Changelog -## Ongoing +## v0.34.5 +- Adam: return the control_state for each thermostat/location. - Bugfix: correct removal of obsolete `outdoor_air_temperature` sensor. ## v0.34.4 diff --git a/fixtures/adam_heatpump_cooling/all_data.json b/fixtures/adam_heatpump_cooling/all_data.json index f0868d427..4ccc7281e 100644 --- a/fixtures/adam_heatpump_cooling/all_data.json +++ b/fixtures/adam_heatpump_cooling/all_data.json @@ -42,6 +42,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -151,6 +152,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -227,6 +229,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -354,6 +357,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -386,6 +390,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -417,6 +422,7 @@ "ca79d23ae0094120b877558734cff85c": { "active_preset": "away", "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "thermostat", "location": "fa5fa6b34f6b40a0972988b20e888ed4", "mode": "auto", @@ -440,6 +446,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -472,6 +479,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -505,6 +513,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -537,6 +546,7 @@ "active_preset": "away", "available": true, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -570,7 +580,7 @@ "cooling_present": true, "gateway_id": "7d97fc3117784cfdafe347bcedcbbbcb", "heater_id": "0ca13e8176204ca7bf6f09de59f81c83", - "item_count": 403, + "item_count": 413, "notifications": {}, "smile_name": "Adam" } diff --git a/fixtures/adam_jip/all_data.json b/fixtures/adam_jip/all_data.json index c8fe1f195..37566e1d3 100644 --- a/fixtures/adam_jip/all_data.json +++ b/fixtures/adam_jip/all_data.json @@ -4,6 +4,7 @@ "active_preset": "no_frost", "available": true, "available_schedules": ["None"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -99,6 +100,7 @@ "active_preset": "home", "available": true, "available_schedules": ["None"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -155,6 +157,7 @@ "active_preset": "home", "available": true, "available_schedules": ["None"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -265,6 +268,7 @@ "active_preset": "home", "available": true, "available_schedules": ["None"], + "control_state": "off", "dev_class": "zone_thermometer", "firmware": "2020-09-01T02:00:00+02:00", "hardware": "1", @@ -300,7 +304,7 @@ "cooling_present": false, "gateway_id": "b5c2386c6f6342669e50fe49dd05b188", "heater_id": "e4684553153b44afbef2200885f379dc", - "item_count": 215, + "item_count": 219, "notifications": {}, "smile_name": "Adam" } diff --git a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json index d7fa788fa..af973f178 100644 --- a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json +++ b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json @@ -64,6 +64,7 @@ "ca79d23ae0094120b877558734cff85c": { "active_preset": "away", "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "thermostat", "location": "fa5fa6b34f6b40a0972988b20e888ed4", "mode": "auto", @@ -88,7 +89,7 @@ "cooling_present": true, "gateway_id": "7d97fc3117784cfdafe347bcedcbbbcb", "heater_id": "0ca13e8176204ca7bf6f09de59f81c83", - "item_count": 53, + "item_count": 54, "notifications": {}, "smile_name": "Adam" } diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 186462b7f..364dcc2ee 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -127,6 +127,7 @@ "ad4838d7d35c4d6ea796ee12ae5aedf8": { "active_preset": "asleep", "available_schedules": ["Weekschema", "Badkamer", "Test"], + "control_state": "heating", "dev_class": "thermostat", "location": "f2bf9048bef64cc5b6d5110154e33c81", "mode": "auto", @@ -169,6 +170,7 @@ "active_preset": "home", "available": true, "available_schedules": ["Weekschema", "Badkamer", "Test"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -215,7 +217,7 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 143, + "item_count": 145, "notifications": {}, "smile_name": "Adam" } diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index 26b06baec..2e1063d14 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -103,6 +103,7 @@ "active_preset": "home", "available": true, "available_schedules": ["Weekschema", "Badkamer", "Test"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -149,7 +150,7 @@ "cooling_present": true, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 143, + "item_count": 145, "notifications": {}, "smile_name": "Adam" } diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index 0230628a9..f7fbaac2f 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -125,6 +125,7 @@ "active_preset": "home", "available": true, "available_schedules": ["Weekschema", "Badkamer", "Test"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -171,7 +172,7 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 143, + "item_count": 145, "notifications": {}, "smile_name": "Adam" } diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 7c7623b02..a817aa33a 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -231,6 +231,11 @@ def _device_data_climate( device_data["select_schedule"] = sel_schedule self._count += 2 + # Control_state, only for Adam master thermostats + if ctrl_state := self._control_state(loc_id): + device_data["control_state"] = ctrl_state + self._count += 1 + # Operation modes: auto, heat, heat_cool, cool and off device_data["mode"] = "auto" self._count += 1 diff --git a/plugwise/helper.py b/plugwise/helper.py index 495519aae..8d146c18d 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -669,6 +669,21 @@ def _match_locations(self) -> dict[str, ThermoLoc]: return matched_locations + def _control_state(self, loc_id: str) -> str | bool: + """Helper-function for _device_data_adam(). + + Adam: find the thermostat control_state of a location, from DOMAIN_OBJECTS. + Represents the heating/cooling demand-state of the local master thermostat. + Note: heating or cooling can still be active when the setpoint has been reached. + """ + locator = f'location[@id="{loc_id}"]' + if (location := self._domain_objects.find(locator)) is not None: + locator = './actuator_functionalities/thermostat_functionality[type="thermostat"]/control_state' + if (ctrl_state := location.find(locator)) is not None: + return str(ctrl_state.text) + + return False + def _presets_legacy(self) -> dict[str, list[float]]: """Helper-function for presets() - collect Presets for a legacy Anna.""" presets: dict[str, list[float]] = {} diff --git a/pyproject.toml b/pyproject.toml index 3888513ea..ca6d6dc55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "0.34.4" +version = "0.34.5" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" diff --git a/tests/test_smile.py b/tests/test_smile.py index 1ce051a25..3ae64fdb3 100644 --- a/tests/test_smile.py +++ b/tests/test_smile.py @@ -1764,6 +1764,7 @@ async def test_connect_adam_plus_anna_new(self): "active_preset": "asleep", "available_schedules": ["Weekschema", "Badkamer", "Test"], "select_schedule": "Weekschema", + "control_state": "heating", "mode": "auto", "sensors": {"temperature": 18.1, "setpoint": 18.5}, }, @@ -1856,6 +1857,7 @@ async def test_connect_adam_plus_anna_new(self): "active_preset": "home", "available_schedules": ["Weekschema", "Badkamer", "Test"], "select_schedule": "Badkamer", + "control_state": "off", "mode": "auto", "sensors": {"temperature": 17.9, "setpoint": 15.0, "battery": 56}, }, @@ -1957,7 +1959,7 @@ async def test_connect_adam_plus_anna_new(self): assert smile.gateway_id == "da224107914542988a88561b4452b0f6" assert smile._last_active["f2bf9048bef64cc5b6d5110154e33c81"] == "Weekschema" assert smile._last_active["f871b8c4d63549319221e294e4f88074"] == "Badkamer" - assert smile.device_items == 143 + assert smile.device_items == 145 assert smile.device_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", @@ -2951,6 +2953,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3046,6 +3049,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3110,6 +3114,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3221,6 +3226,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3247,6 +3253,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3272,6 +3279,7 @@ async def test_adam_heatpump_cooling(self): "ca79d23ae0094120b877558734cff85c": { "active_preset": "away", "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "thermostat", "location": "fa5fa6b34f6b40a0972988b20e888ed4", "mode": "auto", @@ -3295,6 +3303,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3321,6 +3330,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3348,6 +3358,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3374,6 +3385,7 @@ async def test_adam_heatpump_cooling(self): "active_preset": "away", "available": True, "available_schedules": ["Opstaan weekdag", "Werkdag schema", "Weekend"], + "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -3432,7 +3444,7 @@ async def test_adam_heatpump_cooling(self): assert ( smile._last_active["5cc21042f87f4b4c94ccb5537c47a53f"] == "Werkdag schema" ) - assert smile.device_items == 403 + assert smile.device_items == 413 await smile.close_connection() await self.disconnect(server, client) @@ -3494,6 +3506,7 @@ async def test_adam_plus_jip(self): "active_preset": "home", "available_schedules": ["None"], "select_schedule": "None", + "control_state": "off", "mode": "heat", "sensors": {"temperature": 30.0, "setpoint": 13.0, "battery": 80}, }, @@ -3517,6 +3530,7 @@ async def test_adam_plus_jip(self): "active_preset": "no_frost", "available_schedules": ["None"], "select_schedule": "None", + "control_state": "off", "mode": "heat", "sensors": {"temperature": 24.2, "setpoint": 13.0, "battery": 92}, }, @@ -3557,6 +3571,7 @@ async def test_adam_plus_jip(self): "active_preset": "home", "available_schedules": ["None"], "select_schedule": "None", + "control_state": "off", "mode": "heat", "sensors": {"temperature": 30.0, "setpoint": 13.0, "battery": 79}, }, @@ -3580,6 +3595,7 @@ async def test_adam_plus_jip(self): "active_preset": "home", "available_schedules": ["None"], "select_schedule": "None", + "control_state": "off", "mode": "heat", "sensors": { "temperature": 27.4, @@ -3676,7 +3692,7 @@ async def test_adam_plus_jip(self): assert smile._last_active["06aecb3d00354375924f50c47af36bd2"] is None assert smile._last_active["d27aede973b54be484f6842d1b2802ad"] is None assert smile._last_active["13228dab8ce04617af318a2888b3c548"] is None - assert smile.device_items == 215 + assert smile.device_items == 219 # Negative test result = await self.tinker_thermostat( @@ -4239,7 +4255,7 @@ async def test_connect_adam_onoff_cooling_fake_firmware(self): assert smile.smile_type == "thermostat" await self.device_test(smile, "2022-01-02 00:00:01", testdata) - assert smile.device_items == 53 + assert smile.device_items == 54 assert smile._cooling_present assert smile._cooling_enabled