From e0baec6b60ae7cafd52ad7534197859ce41d2f9a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 16:25:29 +0100 Subject: [PATCH 001/106] Adapt to several primary thermostats --- plugwise/helper.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 67a123887..513ab34ec 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -801,7 +801,7 @@ def _scan_thermostats(self) -> None: self._thermo_locs = self._match_locations() thermo_matching: dict[str, int] = { - "thermostat": 3, + "thermostat": 2, "zone_thermometer": 2, "zone_thermostat": 2, "thermostatic_radiator_valve": 1, @@ -828,7 +828,7 @@ def _match_locations(self) -> dict[str, ThermoLoc]: for appliance_details in self.gw_devices.values(): if appliance_details["location"] == location_id: location_details.update( - {"primary": None, "primary_prio": 0, "secondary": set()} + {"primary": set(), "primary_prio": 0, "secondary": set()} ) matched_locations[location_id] = location_details @@ -844,6 +844,8 @@ def _rank_thermostat( """Helper-function for _scan_thermostats(). Rank the thermostat based on appliance_details: primary or secondary. + Note: there can be several primary thermostats, then the lowest reported + temperature of a location is used as the reported value. """ appl_class = appliance_details["dev_class"] appl_d_loc = appliance_details["location"] @@ -851,12 +853,12 @@ def _rank_thermostat( # Pre-elect new primary if thermo_matching[appl_class] > self._thermo_locs[loc_id]["primary_prio"]: # Demote former primary - if (tl_primary:= self._thermo_locs[loc_id]["primary"]) is not None: + if (tl_primary:= self._thermo_locs[loc_id]["primary"]): self._thermo_locs[loc_id]["secondary"].add(tl_primary) # Crown primary self._thermo_locs[loc_id]["primary_prio"] = thermo_matching[appl_class] - self._thermo_locs[loc_id]["primary"] = appliance_id + self._thermo_locs[loc_id]["primary"].add(appliance_id) else: self._thermo_locs[loc_id]["secondary"].add(appliance_id) From 86bca9aa13dec879ed88ea02d51a21b3497bf420 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 16:42:21 +0100 Subject: [PATCH 002/106] Add comment --- plugwise/helper.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugwise/helper.py b/plugwise/helper.py index 513ab34ec..dd8068cd0 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -818,6 +818,11 @@ def _scan_thermostats(self) -> None: if "secondary" in tl_loc_id and dev_id in tl_loc_id["secondary"]: device["dev_class"] = "thermo_sensor" + # All thermostat appliances can keep their device_class but must not become climate-entities in HA. + # For each _thermo_loc a special climate-device must be created, with setpoint and temperature taken from the thermostat appliance with the lowest reported temperature. + # Also the corresponding device_id must be available, and updated, as an attribute. + # And the other attributes must be taken from the _thermo_loc. + def _match_locations(self) -> dict[str, ThermoLoc]: """Helper-function for _scan_thermostats(). From e95b8abdebb3bb845e0262b42df1e28d02edac7a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 17:23:50 +0100 Subject: [PATCH 003/106] Debug --- plugwise/helper.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugwise/helper.py b/plugwise/helper.py index dd8068cd0..0e5244053 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -799,6 +799,7 @@ def _scan_thermostats(self) -> None: the result to update the device_class of secondary thermostats. """ self._thermo_locs = self._match_locations() + LOGGER.debug("HOI 1 thermo_locs: %s", self._thermo_locs) thermo_matching: dict[str, int] = { "thermostat": 2, @@ -811,6 +812,7 @@ def _scan_thermostats(self) -> None: for dev_id, device in self.gw_devices.items(): self._rank_thermostat(thermo_matching, loc_id, dev_id, device) + LOGGER.debug("HOI 2 thermo_locs: %s", self._thermo_locs) # Update secondary thermostat class where needed for dev_id, device in self.gw_devices.items(): if (loc_id := device["location"]) in self._thermo_locs: From 2cc41a1bfb1b641f409b0ea8f14529dae80aad84 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 17:35:20 +0100 Subject: [PATCH 004/106] Optimize --- plugwise/helper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 0e5244053..3cb5e4769 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -866,9 +866,10 @@ def _rank_thermostat( # Crown primary self._thermo_locs[loc_id]["primary_prio"] = thermo_matching[appl_class] self._thermo_locs[loc_id]["primary"].add(appliance_id) - else: self._thermo_locs[loc_id]["secondary"].add(appliance_id) + else: + self._thermo_locs.pop(loc_id) def _control_state(self, loc_id: str) -> str | bool: """Helper-function for _device_data_adam(). From 9b766e0a05eeeea11e9d68ef74eb60eb673f745c Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 17:43:45 +0100 Subject: [PATCH 005/106] Clean up non-thermostat locations --- plugwise/helper.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 3cb5e4769..f268da32d 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -812,6 +812,10 @@ def _scan_thermostats(self) -> None: for dev_id, device in self.gw_devices.items(): self._rank_thermostat(thermo_matching, loc_id, dev_id, device) + for loc_id, loc_data in list(self._thermo_locs.items()): + if loc_data["primary_prio"] == 0: + self._thermo_locs.pop(loc_id) + LOGGER.debug("HOI 2 thermo_locs: %s", self._thermo_locs) # Update secondary thermostat class where needed for dev_id, device in self.gw_devices.items(): @@ -868,8 +872,6 @@ def _rank_thermostat( self._thermo_locs[loc_id]["primary"].add(appliance_id) else: self._thermo_locs[loc_id]["secondary"].add(appliance_id) - else: - self._thermo_locs.pop(loc_id) def _control_state(self, loc_id: str) -> str | bool: """Helper-function for _device_data_adam(). From e1c5be4ea10efefcc8b4b6409c36ff94fc127791 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 17:55:19 +0100 Subject: [PATCH 006/106] Debug more --- plugwise/helper.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugwise/helper.py b/plugwise/helper.py index f268da32d..6964fd24b 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -865,6 +865,8 @@ def _rank_thermostat( if thermo_matching[appl_class] > self._thermo_locs[loc_id]["primary_prio"]: # Demote former primary if (tl_primary:= self._thermo_locs[loc_id]["primary"]): + LOGGER.debug("HOI 3 tl_primary: %s", tl_primary) + LOGGER.debug("HOI 4 secondary: %s", self._thermo_locs[loc_id]["secondary"]) self._thermo_locs[loc_id]["secondary"].add(tl_primary) # Crown primary From e23bfe4483f98ffa4ae6ada479b323e8598ac741 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 18:10:29 +0100 Subject: [PATCH 007/106] Try --- plugwise/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 6964fd24b..5e5d0a273 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -867,7 +867,7 @@ def _rank_thermostat( if (tl_primary:= self._thermo_locs[loc_id]["primary"]): LOGGER.debug("HOI 3 tl_primary: %s", tl_primary) LOGGER.debug("HOI 4 secondary: %s", self._thermo_locs[loc_id]["secondary"]) - self._thermo_locs[loc_id]["secondary"].add(tl_primary) + self._thermo_locs[loc_id]["secondary"].update(tl_primary) # Crown primary self._thermo_locs[loc_id]["primary_prio"] = thermo_matching[appl_class] From 7b07220161c3163fe2a701dc6e0d0d845dad758e Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 18:12:26 +0100 Subject: [PATCH 008/106] Full output --- scripts/tests_and_coverage.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index 580482c44..04c9f46eb 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -31,7 +31,8 @@ set +u if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "test_and_coverage" ] ; then # Python tests (rerun with debug if failures) - PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ + # PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || + PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ fi if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "linting" ] ; then From 14cd5b41765d4bb5bcb97b273c3618a382898716 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 19:00:07 +0100 Subject: [PATCH 009/106] Add climate "devices", remove debugging --- plugwise/helper.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 5e5d0a273..62788684c 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -799,7 +799,6 @@ def _scan_thermostats(self) -> None: the result to update the device_class of secondary thermostats. """ self._thermo_locs = self._match_locations() - LOGGER.debug("HOI 1 thermo_locs: %s", self._thermo_locs) thermo_matching: dict[str, int] = { "thermostat": 2, @@ -813,16 +812,16 @@ def _scan_thermostats(self) -> None: self._rank_thermostat(thermo_matching, loc_id, dev_id, device) for loc_id, loc_data in list(self._thermo_locs.items()): - if loc_data["primary_prio"] == 0: - self._thermo_locs.pop(loc_id) - - LOGGER.debug("HOI 2 thermo_locs: %s", self._thermo_locs) - # Update secondary thermostat class where needed - for dev_id, device in self.gw_devices.items(): - if (loc_id := device["location"]) in self._thermo_locs: - tl_loc_id = self._thermo_locs[loc_id] - if "secondary" in tl_loc_id and dev_id in tl_loc_id["secondary"]: - device["dev_class"] = "thermo_sensor" + if loc_data["primary_prio"] != 0: + self.gw_devices.update( + { + loc_id: { + "dev_class": "climate", + "name": loc_data["name"], + "devices": loc_data["primary"] + } + } + ) # All thermostat appliances can keep their device_class but must not become climate-entities in HA. # For each _thermo_loc a special climate-device must be created, with setpoint and temperature taken from the thermostat appliance with the lowest reported temperature. @@ -865,8 +864,6 @@ def _rank_thermostat( if thermo_matching[appl_class] > self._thermo_locs[loc_id]["primary_prio"]: # Demote former primary if (tl_primary:= self._thermo_locs[loc_id]["primary"]): - LOGGER.debug("HOI 3 tl_primary: %s", tl_primary) - LOGGER.debug("HOI 4 secondary: %s", self._thermo_locs[loc_id]["secondary"]) self._thermo_locs[loc_id]["secondary"].update(tl_primary) # Crown primary From 1e5dde45c13a67f229269a92749d2ce65fd4bf07 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 14 Nov 2024 19:07:54 +0100 Subject: [PATCH 010/106] Debug --- plugwise/smile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugwise/smile.py b/plugwise/smile.py index 9a725a470..d64af2f9d 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -17,6 +17,7 @@ DOMAIN_OBJECTS, GATEWAY_REBOOT, LOCATIONS, + LOGGER, MAX_SETPOINT, MIN_SETPOINT, NOTIFICATIONS, @@ -120,6 +121,7 @@ def get_all_devices(self) -> None: self.gw_devices.update(group_data) # Collect the remaining data for all devices + LOGGER.debug("HOI all_devices: %s", self.gw_devices) self._all_device_data() async def async_update(self) -> PlugwiseData: From 38bdd1a54fad888faf1d00bd8631d54c533a8a63 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 17:27:54 +0100 Subject: [PATCH 011/106] Reworking --- fixtures/adam_plus_anna_new/all_data.json | 52 +---------------------- plugwise/__init__.py | 2 +- plugwise/constants.py | 41 +++++++++++------- plugwise/data.py | 52 ++++++++++++++--------- plugwise/helper.py | 40 +++++++++++++---- plugwise/smile.py | 9 +++- tests/test_init.py | 1 + 7 files changed, 101 insertions(+), 96 deletions(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 4727e8967..9e7317229 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -42,7 +42,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "f871b8c4d63549319221e294e4f88074", @@ -145,39 +145,15 @@ "zigbee_mac_address": "000D6F000D13CB6F" }, "ad4838d7d35c4d6ea796ee12ae5aedf8": { - "active_preset": "home", - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], - "climate_mode": "auto", - "control_state": "heating", "dev_class": "thermostat", "location": "f2bf9048bef64cc5b6d5110154e33c81", "model": "ThermoTouch", "model_id": "143.1", "name": "Anna", - "preset_modes": [ - "no_frost", - "asleep", - "vacation", - "home", - "away" - ], - "select_schedule": "Weekschema", "sensors": { "setpoint": 18.5, "temperature": 18.4 }, - "thermostat": { - "lower_bound": 1.0, - "resolution": 0.01, - "setpoint": 18.5, - "upper_bound": 35.0 - }, "vendor": "Plugwise" }, "da224107914542988a88561b4452b0f6": { @@ -212,20 +188,10 @@ "zigbee_mac_address": "000D6F000D5A168D" }, "e2f4322d57924fa090fbbc48b3a140dc": { - "active_preset": "home", "available": true, - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], "binary_sensors": { "low_battery": true }, - "climate_mode": "auto", - "control_state": "preheating", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -233,14 +199,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Lisa Badkamer", - "preset_modes": [ - "no_frost", - "asleep", - "vacation", - "home", - "away" - ], - "select_schedule": "Badkamer", "sensors": { "battery": 14, "setpoint": 18.0, @@ -252,12 +210,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "000D6F000C869B61" }, @@ -278,7 +230,7 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 165, + "item_count": 150, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 0d7bf6609..e17d0ecab 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -308,7 +308,7 @@ def get_all_devices(self) -> None: async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" - data = PlugwiseData({}, {}) + data = PlugwiseData({}, {}, {}) try: data = await self._smile_api.async_update() self.gateway_id = data.gateway["gateway_id"] diff --git a/plugwise/constants.py b/plugwise/constants.py index 3830e5d45..ffcb83257 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -144,6 +144,11 @@ "relay": UOM(NONE), } +# Climate related measurements +CLIMATE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = { + "temperature": UOM(TEMP_CELSIUS), # HA Core thermostat current_temperature +} + # Heater Central related measurements HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, DATA | UOM]] = { "boiler_state": DATA( @@ -492,7 +497,7 @@ class ThermoLoc(TypedDict, total=False): """Thermo Location class.""" name: str - primary: str | None + primary: set[str] primary_prio: int secondary: set[str] @@ -508,6 +513,25 @@ class ActuatorData(TypedDict, total=False): upper_bound: float +class ClimateData(TypedDict, total=False): + """The Climate Data class, covering the collected and ordered output-data per location.""" + + dev_class: str + name: str + members: dict[str, str] # TODO complete + climate_mode: str + # Extra for Adam Master Thermostats + control_state: str | bool + # Presets: + active_preset: str | None + preset_modes: list[str] | None + # Schedules: + available_schedules: list[str] + select_schedule: str + + thermostat: ActuatorData + + class DeviceData(TypedDict, total=False): """The Device Data class, covering the collected and ordered output-data per device.""" @@ -544,19 +568,6 @@ class DeviceData(TypedDict, total=False): select_gateway_mode: str select_regulation_mode: str - # Master Thermostats - # Presets: - active_preset: str | None - preset_modes: list[str] | None - # Schedules: - available_schedules: list[str] - last_used: str | None - select_schedule: str - - climate_mode: str - # Extra for Adam Master Thermostats - control_state: str | bool - # Dict-types binary_sensors: SmileBinarySensors max_dhw_temperature: ActuatorData @@ -564,7 +575,6 @@ class DeviceData(TypedDict, total=False): sensors: SmileSensors switches: SmileSwitches temperature_offset: ActuatorData - thermostat: ActuatorData @dataclass @@ -572,4 +582,5 @@ class PlugwiseData: """Plugwise data provided as output.""" gateway: GatewayData + climates: dict[str, ClimateData] devices: dict[str, DeviceData] diff --git a/plugwise/data.py b/plugwise/data.py index f23812b0c..ca7b9e254 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -9,6 +9,7 @@ from plugwise.constants import ( ADAM, ANNA, + LOGGER, MAX_SETPOINT, MIN_SETPOINT, NONE, @@ -35,6 +36,7 @@ def _all_device_data(self) -> None: Collect data for each device and add to self.gw_data and self.gw_devices. """ self._update_gw_devices() + self._update_climates() self.gw_data.update( { "gateway_id": self.gateway_id, @@ -49,6 +51,15 @@ def _all_device_data(self) -> None: {"heater_id": self._heater_id, "cooling_present": self._cooling_present} ) + def _update_climates(self) -> None: + """Helper-function for _all_device_data() and async_update(). + + Collect data for each climate-location and add to self.climate_data. + """ + for location_id, climate in self.climate_data.items(): + data = self._get_location_data(location_id) + climate.update(data) + def _update_gw_devices(self) -> None: """Helper-function for _all_device_data() and async_update(). @@ -140,10 +151,27 @@ def _update_for_cooling(self, device: DeviceData) -> None: sensors["setpoint_high"] = temp_dict["setpoint_high"] self._count += 2 - def _get_device_data(self, dev_id: str) -> DeviceData: + + def _get_location_data(self, loc_id: str) -> DeviceData: """Helper-function for _all_device_data() and async_update(). - Provide device-data, based on Location ID (= dev_id), from APPLIANCES. + Provide device-data, based on Location ID (= loc_id). + """ + climate = self.climate_data[loc_id] + data = self._get_climate_data(loc_id) + if ctrl_state := self._control_state(loc_id): + data["control_state"] = ctrl_state + self._count += 1 + + # Thermostat data (presets, temperatures etc) + self._device_data_climate(loc_id, climate, data) + + return data + + def _get_device_data(self, dev_id: str) -> DeviceData: + """Helper-function for _update_gw_devices() and async_update(). + + Provide device-data, based on appliance_id ()= dev_id). """ device = self.gw_devices[dev_id] data = self._get_measurement_data(dev_id) @@ -162,13 +190,7 @@ def _get_device_data(self, dev_id: str) -> DeviceData: # Switching groups data self._device_data_switching_group(device, data) # Adam data - self._device_data_adam(device, data) - # Skip obtaining data for (Adam) secondary thermostats - if device["dev_class"] not in ZONE_THERMOSTATS: - return data - - # Thermostat data (presets, temperatures etc) - self._device_data_climate(device, data) + self._device_data_adam(dev_id, device, data) return data @@ -187,7 +209,7 @@ def _check_availability( if message in msg: data["available"] = False - def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None: + def _device_data_adam(self, loc_id: str, device: DeviceData, data: DeviceData) -> None: """Helper-function for _get_device_data(). Determine Adam heating-status for on-off heating via valves, @@ -211,20 +233,12 @@ def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None: data["gateway_modes"] = self._gw_allowed_modes self._count += 1 - # Control_state, only available for Adam primary thermostats - if device["dev_class"] in ZONE_THERMOSTATS: - loc_id = device["location"] - if ctrl_state := self._control_state(loc_id): - data["control_state"] = ctrl_state - self._count += 1 - def _device_data_climate(self, device: DeviceData, data: DeviceData) -> None: + def _device_data_climate(self, loc_id: str, device: DeviceData, data: DeviceData) -> None: """Helper-function for _get_device_data(). Determine climate-control device data. """ - loc_id = device["location"] - # Presets data["preset_modes"] = None data["active_preset"] = None diff --git a/plugwise/helper.py b/plugwise/helper.py index 62788684c..45af110fa 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -15,6 +15,7 @@ ADAM, ANNA, ATTR_NAME, + CLIMATE_MEASUREMENTS, DATA, DEVICE_MEASUREMENTS, DHW_SETPOINT, @@ -35,6 +36,7 @@ ActuatorData, ActuatorDataType, ActuatorType, + ClimateData, DeviceData, GatewayData, SensorType, @@ -248,6 +250,7 @@ def __init__(self) -> None: self._cooling_enabled = False self.gateway_id: str + self.climate_data: ClimateData = {} self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} self.loc_data: dict[str, ThermoLoc] @@ -480,6 +483,22 @@ def _get_appliances_with_offset_functionality(self) -> list[str]: return therm_list + def _get_climate_data(self, loc_id: str) -> ClimateData: + """Helper-function for smile.py: _get_device_data(). + + Collect the location-data based on location id. + """ + data: ClimateData = {"sensors": {}} + climate = self.climate_data[loc_id] + measurements = CLIMATE_MEASUREMENTS + if ( + location := self._domain_objects.find(f'./location[@id="{loc_id}"]') + ) is not None: + self._appliance_measurements(location, data, measurements) + self._get_actuator_functionalities(location, climate, data) + + return data + def _get_measurement_data(self, dev_id: str) -> DeviceData: """Helper-function for smile.py: _get_device_data(). @@ -619,11 +638,14 @@ def _appliance_measurements( appl_i_loc.text, ENERGY_WATT_HOUR ) - self._count += len(data["binary_sensors"]) - self._count += len(data["sensors"]) - self._count += len(data["switches"]) + if data.get("binary_sensors"): + self._count += len(data["binary_sensors"]) - 1 + if data.get("sensors"): + self._count += len(data["sensors"]) -1 + if data.get("switches"): + self._count += len(data["switches"]) -1 # Don't count the above top-level dicts, only the remaining single items - self._count += len(data) - 3 + #self._count += len(data) - 3 def _get_toggle_state( self, xml: etree, toggle: str, name: ToggleNameType, data: DeviceData @@ -660,9 +682,9 @@ def _get_actuator_functionalities( """Helper-function for _get_measurement_data().""" for item in ACTIVE_ACTUATORS: # Skip max_dhw_temperature, not initially valid, - # skip thermostat for thermo_sensors + # skip thermostat for all but climates if item == "max_dhw_temperature" or ( - item == "thermostat" and device["dev_class"] == "thermo_sensor" + item == "thermostat" and device["dev_class"] != "climate" ): continue @@ -813,12 +835,12 @@ def _scan_thermostats(self) -> None: for loc_id, loc_data in list(self._thermo_locs.items()): if loc_data["primary_prio"] != 0: - self.gw_devices.update( + self.climate_data.update( { loc_id: { "dev_class": "climate", "name": loc_data["name"], - "devices": loc_data["primary"] + "members": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} } } ) @@ -864,7 +886,7 @@ def _rank_thermostat( if thermo_matching[appl_class] > self._thermo_locs[loc_id]["primary_prio"]: # Demote former primary if (tl_primary:= self._thermo_locs[loc_id]["primary"]): - self._thermo_locs[loc_id]["secondary"].update(tl_primary) + self._thermo_locs[loc_id]["secondary"].add(tl_primary) # Crown primary self._thermo_locs[loc_id]["primary_prio"] = thermo_matching[appl_class] diff --git a/plugwise/smile.py b/plugwise/smile.py index d64af2f9d..2b7c1fa8f 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -23,6 +23,7 @@ NOTIFICATIONS, OFF, RULES, + ClimateData, DeviceData, GatewayData, PlugwiseData, @@ -121,11 +122,11 @@ def get_all_devices(self) -> None: self.gw_devices.update(group_data) # Collect the remaining data for all devices - LOGGER.debug("HOI all_devices: %s", self.gw_devices) self._all_device_data() async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" + self.climate_data: ClimateData = {} self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} try: @@ -141,7 +142,11 @@ async def async_update(self) -> PlugwiseData: except KeyError as err: raise DataMissingError("No Plugwise data received") from err - return PlugwiseData(self.gw_data, self.gw_devices) + return PlugwiseData( + gateway=self.gw_data, + climates=self.climate_data, + devices=self.gw_devices, + ) ######################################################################################################## ### API Set and HA Service-related Functions ### diff --git a/tests/test_init.py b/tests/test_init.py index 179db8025..068f54c61 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -596,6 +596,7 @@ async def device_test( _LOGGER.info("Gateway id = %s", data.gateway["gateway_id"]) _LOGGER.info("Hostname = %s", smile.smile_hostname) _LOGGER.info("Gateway data = %s", data.gateway) + _LOGGER.info("Climate data = %s", data.climates) _LOGGER.info("Device list = %s", data.devices) self.show_setup(location_list, data.devices) From b1e016dd4b570e095fc67c0d1a904e4813595d45 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 17:46:33 +0100 Subject: [PATCH 012/106] Rename to zone --- plugwise/constants.py | 18 +++++++++++------- plugwise/data.py | 16 ++++++++-------- plugwise/helper.py | 25 ++++++++++--------------- plugwise/smile.py | 6 +++--- tests/test_init.py | 4 ++-- 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/plugwise/constants.py b/plugwise/constants.py index ffcb83257..a82e13dee 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -144,11 +144,6 @@ "relay": UOM(NONE), } -# Climate related measurements -CLIMATE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = { - "temperature": UOM(TEMP_CELSIUS), # HA Core thermostat current_temperature -} - # Heater Central related measurements HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, DATA | UOM]] = { "boiler_state": DATA( @@ -195,6 +190,14 @@ "outdoor_temperature", ) +# Zone/climate related measurements +ZONE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = { + "electricity_consumed": UOM(POWER_WATT), + "electricity_produced": UOM(POWER_WATT), + "relay": UOM(NONE), + "temperature": UOM(TEMP_CELSIUS), # HA Core thermostat current_temperature +} + # Literals SMILE_P1 = "Smile P1" POWER = "power" @@ -513,7 +516,7 @@ class ActuatorData(TypedDict, total=False): upper_bound: float -class ClimateData(TypedDict, total=False): +class ZoneData(TypedDict, total=False): """The Climate Data class, covering the collected and ordered output-data per location.""" dev_class: str @@ -529,6 +532,7 @@ class ClimateData(TypedDict, total=False): available_schedules: list[str] select_schedule: str + sensors: SmileSensors thermostat: ActuatorData @@ -582,5 +586,5 @@ class PlugwiseData: """Plugwise data provided as output.""" gateway: GatewayData - climates: dict[str, ClimateData] devices: dict[str, DeviceData] + zones: dict[str, ZoneData] diff --git a/plugwise/data.py b/plugwise/data.py index ca7b9e254..fa6008069 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -36,7 +36,7 @@ def _all_device_data(self) -> None: Collect data for each device and add to self.gw_data and self.gw_devices. """ self._update_gw_devices() - self._update_climates() + self._update_zones() self.gw_data.update( { "gateway_id": self.gateway_id, @@ -51,14 +51,14 @@ def _all_device_data(self) -> None: {"heater_id": self._heater_id, "cooling_present": self._cooling_present} ) - def _update_climates(self) -> None: + def _update_zones(self) -> None: """Helper-function for _all_device_data() and async_update(). - Collect data for each climate-location and add to self.climate_data. + Collect data for each zone/location and add to self.zone_data. """ - for location_id, climate in self.climate_data.items(): + for location_id, zone in self.zone_data.items(): data = self._get_location_data(location_id) - climate.update(data) + zone.update(data) def _update_gw_devices(self) -> None: """Helper-function for _all_device_data() and async_update(). @@ -157,14 +157,14 @@ def _get_location_data(self, loc_id: str) -> DeviceData: Provide device-data, based on Location ID (= loc_id). """ - climate = self.climate_data[loc_id] - data = self._get_climate_data(loc_id) + zone = self.zone_data[loc_id] + data = self._get_zone_data(loc_id) if ctrl_state := self._control_state(loc_id): data["control_state"] = ctrl_state self._count += 1 # Thermostat data (presets, temperatures etc) - self._device_data_climate(loc_id, climate, data) + self._device_data_climate(loc_id, zone, data) return data diff --git a/plugwise/helper.py b/plugwise/helper.py index 45af110fa..799fba980 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -15,7 +15,6 @@ ADAM, ANNA, ATTR_NAME, - CLIMATE_MEASUREMENTS, DATA, DEVICE_MEASUREMENTS, DHW_SETPOINT, @@ -33,15 +32,16 @@ THERMOSTAT_CLASSES, TOGGLES, UOM, + ZONE_MEASUREMENTS, ActuatorData, ActuatorDataType, ActuatorType, - ClimateData, DeviceData, GatewayData, SensorType, ThermoLoc, ToggleNameType, + ZoneData, ) from plugwise.exceptions import ( ConnectionFailedError, @@ -250,7 +250,6 @@ def __init__(self) -> None: self._cooling_enabled = False self.gateway_id: str - self.climate_data: ClimateData = {} self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} self.loc_data: dict[str, ThermoLoc] @@ -263,6 +262,7 @@ def __init__(self) -> None: self.smile_type: str self.smile_zigbee_mac_address: str | None self.therms_with_offset_func: list[str] = [] + self.zone_data: ZoneData = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -483,19 +483,19 @@ def _get_appliances_with_offset_functionality(self) -> list[str]: return therm_list - def _get_climate_data(self, loc_id: str) -> ClimateData: + def _get_zone_data(self, loc_id: str) -> ZoneData: """Helper-function for smile.py: _get_device_data(). Collect the location-data based on location id. """ - data: ClimateData = {"sensors": {}} - climate = self.climate_data[loc_id] - measurements = CLIMATE_MEASUREMENTS + data: ZoneData = {"sensors": {}} + zone = self.zone_data[loc_id] + measurements = ZONE_MEASUREMENTS if ( location := self._domain_objects.find(f'./location[@id="{loc_id}"]') ) is not None: self._appliance_measurements(location, data, measurements) - self._get_actuator_functionalities(location, climate, data) + self._get_actuator_functionalities(location, zone, data) return data @@ -682,7 +682,7 @@ def _get_actuator_functionalities( """Helper-function for _get_measurement_data().""" for item in ACTIVE_ACTUATORS: # Skip max_dhw_temperature, not initially valid, - # skip thermostat for all but climates + # skip thermostat for all but zones with thermostats if item == "max_dhw_temperature" or ( item == "thermostat" and device["dev_class"] != "climate" ): @@ -835,7 +835,7 @@ def _scan_thermostats(self) -> None: for loc_id, loc_data in list(self._thermo_locs.items()): if loc_data["primary_prio"] != 0: - self.climate_data.update( + self.zone_data.update( { loc_id: { "dev_class": "climate", @@ -845,11 +845,6 @@ def _scan_thermostats(self) -> None: } ) - # All thermostat appliances can keep their device_class but must not become climate-entities in HA. - # For each _thermo_loc a special climate-device must be created, with setpoint and temperature taken from the thermostat appliance with the lowest reported temperature. - # Also the corresponding device_id must be available, and updated, as an attribute. - # And the other attributes must be taken from the _thermo_loc. - def _match_locations(self) -> dict[str, ThermoLoc]: """Helper-function for _scan_thermostats(). diff --git a/plugwise/smile.py b/plugwise/smile.py index 2b7c1fa8f..51a963671 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -23,11 +23,11 @@ NOTIFICATIONS, OFF, RULES, - ClimateData, DeviceData, GatewayData, PlugwiseData, ThermoLoc, + ZoneData, ) from plugwise.data import SmileData from plugwise.exceptions import ConnectionFailedError, DataMissingError, PlugwiseError @@ -126,9 +126,9 @@ def get_all_devices(self) -> None: async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" - self.climate_data: ClimateData = {} self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} + self.zone_data: ZoneData = {} try: await self.full_update_device() self.get_all_devices() @@ -144,8 +144,8 @@ async def async_update(self) -> PlugwiseData: return PlugwiseData( gateway=self.gw_data, - climates=self.climate_data, devices=self.gw_devices, + zones=self.zone_data, ) ######################################################################################################## diff --git a/tests/test_init.py b/tests/test_init.py index 068f54c61..f183d57ae 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -584,7 +584,7 @@ async def device_test( if "cooling_state" in heat_cooler["binary_sensors"]: self._cooling_active = heat_cooler["binary_sensors"]["cooling_state"] - self._write_json("all_data", {"gateway": data.gateway, "devices": data.devices}) + self._write_json("all_data", {"gateway": data.gateway, "devices": data.devices, "zones": data.zones}) if "FIXTURES" in os.environ: _LOGGER.info("Skipping tests: Requested fixtures only") # pragma: no cover @@ -596,7 +596,7 @@ async def device_test( _LOGGER.info("Gateway id = %s", data.gateway["gateway_id"]) _LOGGER.info("Hostname = %s", smile.smile_hostname) _LOGGER.info("Gateway data = %s", data.gateway) - _LOGGER.info("Climate data = %s", data.climates) + _LOGGER.info("Zone data = %s", data.zones) _LOGGER.info("Device list = %s", data.devices) self.show_setup(location_list, data.devices) From 29037afd9a0555e84bbc3d876623c54e96c8cc71 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 17:58:42 +0100 Subject: [PATCH 013/106] Save updated fixture --- fixtures/adam_plus_anna_new/all_data.json | 84 ++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 9e7317229..3d891c503 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -230,9 +230,91 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 150, + "item_count": 152, "notifications": {}, "reboot": true, "smile_name": "Adam" + }, + "zones": { + "f2bf9048bef64cc5b6d5110154e33c81": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "heating", + "dev_class": "climate", + "members": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] + }, + "name": "Living room", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Weekschema", + "sensors": { + "electricity_consumed": 149.9, + "electricity_produced": 0.0, + "temperature": 18.4 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 18.5, + "upper_bound": 35.0 + } + }, + "f871b8c4d63549319221e294e4f88074": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "preheating", + "dev_class": "climate", + "members": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] + }, + "name": "Bathroom", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Badkamer", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + } + } } } From b8b98d051a49e54e457c398b65f4db7f431e2a83 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 18:02:28 +0100 Subject: [PATCH 014/106] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6d3133e8..42438d887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Ongoing + +- Implement collection of zone data: Plugwise thermostat representations are zone/location-based. + ## v1.5.2 - Bugfix for Adam: improve recognition of unknown zigbee devices. From 023f755920a8edab01316b0273d193e7703ef45e Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 18:03:01 +0100 Subject: [PATCH 015/106] Bump to v1.6.0a0 test-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ebc2b3cde..8f5321a83 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.5.2" +version = "1.6.0a0 license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From e1d9a525d348134bc31566d5e5040e8ef6849062 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 18:05:15 +0100 Subject: [PATCH 016/106] Fix typo --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8f5321a83..b3cc31547 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.6.0a0 +version = "1.6.0a0" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From e6d8297cf6d458ed8981e2a50539c3381fc217d9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 17:06:27 +0000 Subject: [PATCH 017/106] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugwise/data.py | 2 -- plugwise/helper.py | 2 +- plugwise/smile.py | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/plugwise/data.py b/plugwise/data.py index fa6008069..a2a56c434 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -9,12 +9,10 @@ from plugwise.constants import ( ADAM, ANNA, - LOGGER, MAX_SETPOINT, MIN_SETPOINT, NONE, OFF, - ZONE_THERMOSTATS, ActuatorData, DeviceData, ) diff --git a/plugwise/helper.py b/plugwise/helper.py index 799fba980..7d5c82727 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -490,7 +490,7 @@ def _get_zone_data(self, loc_id: str) -> ZoneData: """ data: ZoneData = {"sensors": {}} zone = self.zone_data[loc_id] - measurements = ZONE_MEASUREMENTS + measurements = ZONE_MEASUREMENTS if ( location := self._domain_objects.find(f'./location[@id="{loc_id}"]') ) is not None: diff --git a/plugwise/smile.py b/plugwise/smile.py index 51a963671..a37b4a189 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -17,7 +17,6 @@ DOMAIN_OBJECTS, GATEWAY_REBOOT, LOCATIONS, - LOGGER, MAX_SETPOINT, MIN_SETPOINT, NOTIFICATIONS, From 739fa334eb7c1b66a567f19b024e22b0fac0174a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 18:10:34 +0100 Subject: [PATCH 018/106] Fix comment --- plugwise/helper.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 7d5c82727..a1606c703 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -871,8 +871,7 @@ def _rank_thermostat( """Helper-function for _scan_thermostats(). Rank the thermostat based on appliance_details: primary or secondary. - Note: there can be several primary thermostats, then the lowest reported - temperature of a location is used as the reported value. + Note: there can be several primary and secondary thermostats. """ appl_class = appliance_details["dev_class"] appl_d_loc = appliance_details["location"] From efb081d4cbca881bb3d3263cd27ecf4eefa292c8 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 18:12:26 +0100 Subject: [PATCH 019/106] Delete unused function-argument --- plugwise/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/data.py b/plugwise/data.py index a2a56c434..a5159d753 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -207,7 +207,7 @@ def _check_availability( if message in msg: data["available"] = False - def _device_data_adam(self, loc_id: str, device: DeviceData, data: DeviceData) -> None: + def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None: """Helper-function for _get_device_data(). Determine Adam heating-status for on-off heating via valves, From 6c8b6b020e375b79b2a6fba7a4f429f0f9401e72 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 18:13:48 +0100 Subject: [PATCH 020/106] Update typing --- plugwise/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/constants.py b/plugwise/constants.py index a82e13dee..35237429c 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -521,7 +521,7 @@ class ZoneData(TypedDict, total=False): dev_class: str name: str - members: dict[str, str] # TODO complete + members: dict[str, set[str]] climate_mode: str # Extra for Adam Master Thermostats control_state: str | bool From a7fe140a42b967d5f60dc0e37d7ceab64054c56c Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 16 Nov 2024 18:16:43 +0100 Subject: [PATCH 021/106] Fix function-argument use --- plugwise/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/data.py b/plugwise/data.py index a5159d753..266893ffe 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -188,7 +188,7 @@ def _get_device_data(self, dev_id: str) -> DeviceData: # Switching groups data self._device_data_switching_group(device, data) # Adam data - self._device_data_adam(dev_id, device, data) + self._device_data_adam(device, data) return data From a44531bd0e941c5ce6097dcd4ca0371d25ecdcd3 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 17 Nov 2024 08:57:40 +0100 Subject: [PATCH 022/106] Start adapting legacy --- plugwise/legacy/smile.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index a1813105a..6338ac130 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -23,6 +23,7 @@ GatewayData, PlugwiseData, ThermoLoc, + ZoneData, ) from plugwise.exceptions import ConnectionFailedError, PlugwiseError from plugwise.legacy.data import SmileLegacyData @@ -120,6 +121,7 @@ async def async_update(self) -> PlugwiseData: ) self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} + self.zones: dict[str, ZoneData] = {} await self.full_update_device() self.get_all_devices() # Otherwise perform an incremental update @@ -134,7 +136,11 @@ async def async_update(self) -> PlugwiseData: self._update_gw_devices() self._previous_day_number = day_number - return PlugwiseData(self.gw_data, self.gw_devices) + return PlugwiseData( + gateway=self.gw_data, + devices=self.gw_devices, + zones=self.zone_data, + ) ######################################################################################################## ### API Set and HA Service-related Functions ### From 3efafca9ffdcee41ceef16c420ceb8b7d77caf39 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 17 Nov 2024 09:01:41 +0100 Subject: [PATCH 023/106] Limit test-cases for now --- tests/test_adam.py | 249 -------------------- tests/test_anna.py | 439 ----------------------------------- tests/test_legacy_anna.py | 30 --- tests/test_legacy_p1.py | 33 --- tests/test_legacy_stretch.py | 64 ----- tests/test_p1.py | 48 ---- 6 files changed, 863 deletions(-) diff --git a/tests/test_adam.py b/tests/test_adam.py index 2a2f95116..614e4a16e 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -164,252 +164,3 @@ async def test_connect_adam_plus_anna_new(self): await smile.close_connection() await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_adam_zone_per_device(self): - """Test an extensive setup of Adam with a zone per device.""" - self.smile_setup = "adam_zone_per_device" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="3.0.15", - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile.gateway_id == "fe799307f1624099878210aa0b9f1475" - assert smile._last_active["12493538af164a409c6a1c79e38afe1c"] == BADKAMER_SCHEMA - assert smile._last_active["c50f167537524366a5af7aa3942feb1e"] == GF7_WOONKAMER - assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE - assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA - assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA - assert self.device_items == 340 - - assert "af82e4ccf9c548528166d38e560662a4" in self.notifications - await smile.delete_notification() - - result = await self.tinker_thermostat( - smile, "c50f167537524366a5af7aa3942feb1e", good_schedules=[GF7_WOONKAMER] - ) - assert result - result = await self.tinker_thermostat( - smile, "82fa13f017d240daa0d0ea1775420f24", good_schedules=[CV_JESSIE] - ) - assert result - switch_change = await self.tinker_switch( - smile, "675416a629f343c495449970e2ca37b5" - ) - assert not switch_change - - reboot = await self.tinker_reboot(smile) - assert reboot - - await smile.close_connection() - await self.disconnect(server, client) - - server, smile, client = await self.connect_wrapper(raise_timeout=True) - await self.device_test(smile, "2022-05-16 00:00:01", testdata, skip_testing=True) - result = await self.tinker_thermostat( - smile, - "c50f167537524366a5af7aa3942feb1e", - good_schedules=[GF7_WOONKAMER], - unhappy=True, - ) - assert result - result = await self.tinker_thermostat( - smile, - "82fa13f017d240daa0d0ea1775420f24", - good_schedules=[CV_JESSIE], - unhappy=True, - ) - assert result - - tinkered = await self.tinker_max_boiler_temp(smile, unhappy=True) - assert not tinkered - - try: - await smile.delete_notification() - notification_deletion = False # pragma: no cover - except pw_exceptions.ConnectionFailedError: - notification_deletion = True - assert notification_deletion - - reboot = await self.tinker_reboot(smile, unhappy=True) - assert reboot - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_adam_multiple_devices_per_zone(self): - """Test an extensive setup of Adam with multiple devices per zone.""" - self.smile_setup = "adam_multiple_devices_per_zone" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="3.0.15", - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile._last_active["12493538af164a409c6a1c79e38afe1c"] == BADKAMER_SCHEMA - assert smile._last_active["c50f167537524366a5af7aa3942feb1e"] == GF7_WOONKAMER - assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE - assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA - assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA - assert self.device_items == 340 - - assert "af82e4ccf9c548528166d38e560662a4" in self.notifications - - result = await self.tinker_thermostat( - smile, "c50f167537524366a5af7aa3942feb1e", good_schedules=[GF7_WOONKAMER] - ) - assert result - result = await self.tinker_thermostat( - smile, "82fa13f017d240daa0d0ea1775420f24", good_schedules=[CV_JESSIE] - ) - assert result - switch_change = await self.tinker_switch( - smile, "675416a629f343c495449970e2ca37b5" - ) - assert not switch_change - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_adam_heatpump_cooling(self): - """Test Adam with heatpump in cooling mode and idle.""" - self.smile_setup = "adam_heatpump_cooling" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - - await self.device_test(smile, "2022-01-02 00:00:01", testdata) - assert smile._last_active["b52908550469425b812c87f766fe5303"] == WERKDAG_SCHEMA - assert smile._last_active["20e735858f8146cead98b873177a4f99"] == WERKDAG_SCHEMA - assert smile._last_active["e39529c79ab54fda9bed26cfc0447546"] == WERKDAG_SCHEMA - assert smile._last_active["9a27714b970547ee9a6bdadc2b815ad5"] == WERKDAG_SCHEMA - assert smile._last_active["93ac3f7bf25342f58cbb77c4a99ac0b3"] == WERKDAG_SCHEMA - assert smile._last_active["fa5fa6b34f6b40a0972988b20e888ed4"] == WERKDAG_SCHEMA - assert smile._last_active["04b15f6e884448288f811d29fb7b1b30"] == WERKDAG_SCHEMA - assert smile._last_active["a562019b0b1f47a4bde8ebe3dbe3e8a9"] == WERKDAG_SCHEMA - assert smile._last_active["8cf650a4c10c44819e426bed406aec34"] == WERKDAG_SCHEMA - assert smile._last_active["5cc21042f87f4b4c94ccb5537c47a53f"] == WERKDAG_SCHEMA - assert self.device_items == 439 - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_adam_onoff_cooling_fake_firmware(self): - """Test an Adam with a fake OnOff cooling device in cooling mode.""" - self.smile_setup = "adam_onoff_cooling_fake_firmware" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version=None, - ) - - await self.device_test(smile, "2022-01-02 00:00:01", testdata) - assert self.device_items == 58 - assert self.cooling_present - # assert self._cooling_enabled - no cooling_enabled indication present - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_adam_plus_anna(self): - """Test Adam (firmware 3.0) with Anna setup.""" - self.smile_setup = "adam_plus_anna" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="3.0.15", - ) - - await self.device_test(smile, "2020-03-22 00:00:01", testdata) - assert smile.gateway_id == "b128b4bbbd1f47e9bf4d756e8fb5ee94" - assert smile._last_active["009490cc2f674ce6b576863fbb64f867"] == "Weekschema" - assert self.device_items == 73 - assert "6fb89e35caeb4b1cb275184895202d84" in self.notifications - - result = await self.tinker_thermostat( - smile, "009490cc2f674ce6b576863fbb64f867", good_schedules=["Weekschema"] - ) - assert result - switch_change = await self.tinker_switch( - smile, "aa6b0002df0a46e1b1eb94beb61eddfe" - ) - assert switch_change - await smile.close_connection() - await self.disconnect(server, client) - - server, smile, client = await self.connect_wrapper(raise_timeout=True) - await self.device_test(smile, "2020-03-22 00:00:01", testdata, skip_testing=True) - result = await self.tinker_thermostat( - smile, - "009490cc2f674ce6b576863fbb64f867", - good_schedules=["Weekschema"], - unhappy=True, - ) - assert result - switch_change = await self.tinker_switch( - smile, "aa6b0002df0a46e1b1eb94beb61eddfe", unhappy=True - ) - assert switch_change - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_adam_plus_jip(self): - """Test Adam with Jip setup.""" - self.smile_setup = "adam_jip" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - - await self.device_test(smile, "2021-06-20 00:00:01", testdata) - assert smile.gateway_id == "b5c2386c6f6342669e50fe49dd05b188" - assert smile._last_active["d58fec52899f4f1c92e4f8fad6d8c48c"] is None - assert smile._last_active["06aecb3d00354375924f50c47af36bd2"] is None - assert smile._last_active["d27aede973b54be484f6842d1b2802ad"] is None - assert smile._last_active["13228dab8ce04617af318a2888b3c548"] is None - assert self.device_items == 228 - - # Negative test - result = await self.tinker_thermostat( - smile, - "13228dab8ce04617af318a2888b3c548", - schedule_on=False, - good_schedules=[None], - ) - assert result - - result = await self.tinker_thermostat_schedule( - smile, - "13228dab8ce04617af318a2888b3c548", - "off", - good_schedules=[None], - ) - assert result - await smile.close_connection() - await self.disconnect(server, client) diff --git a/tests/test_anna.py b/tests/test_anna.py index e260f95e0..516c379b6 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -87,442 +87,3 @@ async def test_connect_anna_v4(self): await smile.close_connection() await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_v4_dhw(self): - """Test an Anna firmware 4 setup for domestic hot water.""" - self.smile_setup = "anna_v4_dhw" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.0.15", - ) - - await self.device_test(smile, "2020-04-05 00:00:01", testdata) - assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard" - assert self.device_items == 58 - assert not self.notifications - - result = await self.tinker_thermostat( - smile, - "eb5309212bf5407bb143e5bfa3b18aee", - schedule_on=False, - good_schedules=["Standaard", "Thuiswerken"], - ) - assert result - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_v4_no_tag(self): - """Test an Anna firmware 4 setup - missing tag (issue).""" - testdata = { - # Anna - "01b85360fdd243d0aaad4d6ac2a5ba7e": { - "active_preset": "home", - } - } - self.smile_setup = "anna_v4_no_tag" - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.0.15", - ) - - await self.device_test(smile, "2020-04-05 00:00:01", testdata) - assert self.device_items == 58 - - result = await self.tinker_thermostat( - smile, - "eb5309212bf5407bb143e5bfa3b18aee", - schedule_on=False, - good_schedules=["Standaard", "Thuiswerken"], - ) - assert result - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_without_boiler_fw441(self): - """Test an Anna with firmware 4.4, without a boiler.""" - self.smile_setup = "anna_without_boiler_fw441" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.4.1", - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile._last_active["c34c6864216446528e95d88985e714cc"] == "Normaal" - assert self.device_items == 39 - assert not self.notifications - - result = await self.tinker_thermostat( - smile, "c34c6864216446528e95d88985e714cc", good_schedules=["Normaal"] - ) - assert result - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_heatpump_heating(self): - """Test an Anna with Elga, cooling-mode off, in heating mode.""" - - self.smile_setup = "anna_heatpump_heating" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.0.15", - ) - - await self.device_test(smile, "2020-04-12 00:00:01", testdata) - assert smile.gateway_id == "015ae9ea3f964e668e490fa39da3870b" - assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" - assert self.device_items == 67 - assert not self.notifications - assert self.cooling_present - assert not self._cooling_enabled - assert not self._cooling_active - - with pytest.raises(pw_exceptions.PlugwiseError) as exc: - await self.tinker_thermostat( - smile, - "c784ee9fdab44e1395b8dee7d7a497d5", - good_schedules=[ - "standaard", - ], - ) - _LOGGER.debug( - "ERROR raised setting good schedule standaard: %s", exc.value - ) # pragma: no cover - - # Now change some data and change directory reading xml from - # emulating reading newer dataset after an update_interval, - # set testday to Monday to force an incremental update - testdata_updated = self.load_testdata( - SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA" - ) - - self.smile_setup = "updated/anna_heatpump_heating" - await self.device_test( - smile, "2020-04-13 00:00:01", testdata_updated, initialize=False - ) - assert self.device_items == 64 - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_heatpump_cooling(self): - """Test an Anna with Elga setup in cooling mode. - - This test also covers the situation that the operation-mode it switched - from heating to cooling due to the outdoor temperature rising above the - cooling_activation_outdoor_temperature threshold. - """ - self.smile_setup = "anna_heatpump_cooling" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.0.15", - ) - - await self.device_test(smile, "2020-04-19 00:00:01", testdata) - assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" - assert self.device_items == 64 - assert self.cooling_present - assert not self.notifications - - assert self._cooling_enabled - assert self._cooling_active - - with pytest.raises(pw_exceptions.PlugwiseError) as exc: - await self.tinker_thermostat( - smile, - "c784ee9fdab44e1395b8dee7d7a497d5", - good_schedules=[ - "standaard", - ], - ) - _LOGGER.debug( - "ERROR raised good schedule to standaard: %s", exc.value - ) # pragma: no cover - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_heatpump_cooling_fake_firmware(self): - """Test an Anna with a fake Loria/Thermastate setup in cooling mode. - - The Anna + Elga firmware has been amended with the point_log cooling_enabled and - gateway/features/cooling keys. - This test also covers the situation that the operation-mode it switched - from heating to cooling due to the outdoor temperature rising above the - cooling_activation_outdoor_temperature threshold. - """ - self.smile_setup = "anna_heatpump_cooling_fake_firmware" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.10.10", - ) - - await self.device_test(smile, "2020-04-19 00:00:01", testdata) - assert self.device_items == 64 - assert self.cooling_present - assert self._cooling_enabled - assert self._cooling_active - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_elga_no_cooling(self): - """Test an Anna with Elga, cooling-mode not used, in heating mode.""" - - self.smile_setup = "anna_elga_no_cooling" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.0.15", - ) - - await self.device_test(smile, "2020-04-12 00:00:01", testdata) - assert smile.gateway_id == "015ae9ea3f964e668e490fa39da3870b" - assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" - assert self.device_items == 63 - assert not self.notifications - assert not self.cooling_present - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_elga_2(self): - """Test a 2nd Anna with Elga setup, cooling off, in idle mode (with missing outdoor temperature - solved).""" - self.smile_setup = "anna_elga_2" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.2.1", - ) - - await self.device_test(smile, "2022-03-13 00:00:01", testdata) - assert ( - smile._last_active["d3ce834534114348be628b61b26d9220"] - == THERMOSTAT_SCHEDULE - ) - assert self.device_items == 63 - assert smile.gateway_id == "fb49af122f6e4b0f91267e1cf7666d6f" - assert self.cooling_present - assert not self._cooling_enabled - assert not self.notifications - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_elga_2_schedule_off(self): - """Test Anna with Elga setup, cooling off, in idle mode, modified to schedule off.""" - self.smile_setup = "anna_elga_2_schedule_off" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - await self.device_test(smile, "2022-03-13 00:00:01", testdata) - assert ( - smile._last_active["d3ce834534114348be628b61b26d9220"] - == THERMOSTAT_SCHEDULE - ) - assert self.cooling_present - assert not self._cooling_enabled - assert self.device_items == 63 - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_elga_2_cooling(self): - """Test a 2nd Anna with Elga setup with cooling active. - - This testcase also covers testing of the generation of a cooling-based - schedule, opposite the generation of a heating-based schedule. - """ - self.smile_setup = "anna_elga_2_cooling" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="4.2.1", - ) - - await self.device_test(smile, "2022-03-10 00:00:01", testdata) - assert ( - smile._last_active["d3ce834534114348be628b61b26d9220"] - == THERMOSTAT_SCHEDULE - ) - assert self.device_items == 63 - assert not self.notifications - - assert self.cooling_present - assert self._cooling_enabled - assert self._cooling_active - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_loria_heating_idle(self): - """Test an Anna with a Loria in heating mode - state idle.""" - self.smile_setup = "anna_loria_heating_idle" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version=None, - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter" - assert self.device_items == 66 - assert self.cooling_present - assert not self._cooling_enabled - - switch_change = await self.tinker_switch( - smile, - "bfb5ee0a88e14e5f97bfa725a760cc49", - model="cooling_ena_switch", - ) - assert switch_change - - with pytest.raises(pw_exceptions.PlugwiseError) as exc: - await self.tinker_thermostat( - smile, - "15da035090b847e7a21f93e08c015ebc", - good_schedules=[ - "Winter", - ], - ) - _LOGGER.debug( - "ERROR raised setting to schedule Winter: %s", exc.value - ) # pragma: no cover - - with pytest.raises(pw_exceptions.PlugwiseError) as exc: - await self.tinker_thermostat_temp( - smile, - "15da035090b847e7a21f93e08c015ebc", - block_cooling=True, - ) - _LOGGER.debug( - "ERROR raised setting block cooling: %s", exc.value - ) # pragma: no cover - - tinkered = await self.tinker_dhw_mode(smile) - assert not tinkered - - await smile.close_connection() - await self.disconnect(server, client) - - server, smile, client = await self.connect_wrapper(raise_timeout=True) - await self.device_test(smile, "2022-05-16 00:00:01", testdata, skip_testing=True) - - tinkered = await self.tinker_dhw_mode(smile, unhappy=True) - assert tinkered - - await smile.close_connection() - await self.disconnect(server, client) - - - @pytest.mark.asyncio - async def test_connect_anna_loria_cooling_active(self): - """Test an Anna with a Loria in heating mode - state idle.""" - self.smile_setup = "anna_loria_cooling_active" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version=None, - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter" - assert self.device_items == 66 - assert self.cooling_present - assert self._cooling_enabled - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_anna_loria_driessens(self): - """Test an Anna with a Loria in heating mode - state idle.""" - self.smile_setup = "anna_loria_driessens" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version=None, - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.device_items == 66 - assert self.cooling_present - assert not self._cooling_enabled - - await smile.close_connection() - await self.disconnect(server, client) diff --git a/tests/test_legacy_anna.py b/tests/test_legacy_anna.py index 2475aff83..6963aee30 100644 --- a/tests/test_legacy_anna.py +++ b/tests/test_legacy_anna.py @@ -44,33 +44,3 @@ async def test_connect_legacy_anna(self): assert result await smile.close_connection() await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_legacy_anna_2(self): - """Test another legacy Anna device.""" - self.smile_setup = "legacy_anna_2" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_legacy_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_version="1.8.22", - smile_legacy=True, - ) - - await self.device_test(smile, "2020-05-03 00:00:01", testdata) - - assert smile.gateway_id == "be81e3f8275b4129852c4d8d550ae2eb" - assert self.device_items == 43 - - result = await self.tinker_legacy_thermostat(smile) - assert result - - result = await self.tinker_legacy_thermostat_schedule(smile, "on") - assert result - - await smile.close_connection() - await self.disconnect(server, client) diff --git a/tests/test_legacy_p1.py b/tests/test_legacy_p1.py index 99b1277db..6432216ad 100644 --- a/tests/test_legacy_p1.py +++ b/tests/test_legacy_p1.py @@ -34,36 +34,3 @@ async def test_connect_smile_p1_v2(self): await smile.close_connection() await self.disconnect(server, client) - @pytest.mark.asyncio - async def test_connect_smile_p1_v2_2(self): - """Test another legacy P1 device.""" - self.smile_setup = "smile_p1_v2_2" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_legacy_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_type="power", - smile_version="2.5.9", - smile_legacy=True, - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.device_items == 26 - - # Now change some data and change directory reading xml from - # emulating reading newer dataset after an update_interval - testdata_updated = self.load_testdata( - SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA" - ) - self.smile_setup = "updated/smile_p1_v2_2" - await self.device_test( - smile, "2022-05-16 00:00:01", testdata_updated, initialize=False - ) - - await smile.close_connection() - await self.disconnect(server, client) - diff --git a/tests/test_legacy_stretch.py b/tests/test_legacy_stretch.py index c88be6f1a..d38415776 100644 --- a/tests/test_legacy_stretch.py +++ b/tests/test_legacy_stretch.py @@ -50,67 +50,3 @@ async def test_connect_stretch_v31(self): await smile.close_connection() await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_stretch_v23(self): - """Test a legacy Stretch with firmware 2.3 setup.""" - self.smile_setup = "stretch_v23" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_legacy_wrapper(stretch=True) - assert smile.smile_hostname == "stretch000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_type="stretch", - smile_version="2.3.12", - smile_legacy=True, - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.device_items == 243 - - switch_change = await self.tinker_switch( - smile, "2587a7fcdd7e482dab03fda256076b4b" - ) - assert switch_change - switch_change = await self.tinker_switch( - smile, - "f7b145c8492f4dd7a4de760456fdef3e", - ["407aa1c1099d463c9137a3a9eda787fd"], - ) - assert switch_change - - await smile.close_connection() - await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_stretch_v27_no_domain(self): - """Test a legacy Stretch with firmware 2.7 setup, with no domain_objects.""" - # testdata dictionary with key ctrl_id_dev_id => keys:values - self.smile_setup = "stretch_v27_no_domain" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_legacy_wrapper(stretch=True) - assert smile.smile_hostname == "stretch000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_type="stretch", - smile_version="2.7.18", - smile_legacy=True, - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.device_items == 190 - _LOGGER.info(" # Assert no master thermostat") - - switch_change = await self.tinker_switch( - smile, "8b8d14b242e24cd789743c828b9a2ea9" - ) - assert switch_change - - await smile.close_connection() - await self.disconnect(server, client) diff --git a/tests/test_p1.py b/tests/test_p1.py index 4bec2f54b..5d3f1840a 100644 --- a/tests/test_p1.py +++ b/tests/test_p1.py @@ -10,30 +10,6 @@ class TestPlugwiseP1(TestPlugwise): # pylint: disable=attribute-defined-outside-init """Tests for P1.""" - @pytest.mark.asyncio - async def test_connect_p1v4(self): - """Test a P1 firmware 4 setup.""" - self.smile_setup = "p1v4" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_type="power", - smile_version="4.1.1", - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile.gateway_id == "a455b61e52394b2db5081ce025a430f3" - assert self.device_items == 30 - assert "97a04c0c263049b29350a660b4cdd01e" in self.notifications - - await smile.close_connection() - await self.disconnect(server, client) - @pytest.mark.asyncio async def test_connect_p1v4_442_single(self): """Test a P1 firmware 4.4 single-phase setup.""" @@ -67,27 +43,3 @@ async def test_connect_p1v4_442_single(self): await smile.close_connection() await self.disconnect(server, client) - - @pytest.mark.asyncio - async def test_connect_p1v4_442_triple(self): - """Test a P1 firmware 4 3-phase setup.""" - self.smile_setup = "p1v4_442_triple" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_type="power", - smile_version="4.4.2", - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile.gateway_id == "03e65b16e4b247a29ae0d75a78cb492e" - assert self.device_items == 41 - assert self.notifications - - await smile.close_connection() - await self.disconnect(server, client) From 2092e4f4b98dba15f7da9f2e2f6f3cb94925c0c8 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 17 Nov 2024 09:04:17 +0100 Subject: [PATCH 024/106] Update test-jsons --- fixtures/anna_v4/all_data.json | 11 +- plugwise/data.py | 13 +- plugwise/helper.py | 8 +- tests/data/adam/adam_plus_anna_new.json | 528 ++++++++++-------- .../adam/adam_plus_anna_new_UPDATED_DATA.json | 6 +- tests/data/anna/anna_v4.json | 167 +++--- tests/test_adam.py | 2 +- tests/test_anna.py | 2 +- tests/test_init.py | 139 +++-- 9 files changed, 516 insertions(+), 360 deletions(-) diff --git a/fixtures/anna_v4/all_data.json b/fixtures/anna_v4/all_data.json index a9c312534..7bb23b0d8 100644 --- a/fixtures/anna_v4/all_data.json +++ b/fixtures/anna_v4/all_data.json @@ -33,12 +33,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 4.0, - "resolution": 0.1, - "setpoint": 20.5, - "upper_bound": 30.0 - }, "vendor": "Plugwise" }, "0466eae8520144c78afb29628384edeb": { @@ -99,9 +93,10 @@ "cooling_present": false, "gateway_id": "0466eae8520144c78afb29628384edeb", "heater_id": "cd0e6156b1f04d5f952349ffbe397481", - "item_count": 58, + "item_count": 50, "notifications": {}, "reboot": true, "smile_name": "Smile Anna" - } + }, + "zones": {} } diff --git a/plugwise/data.py b/plugwise/data.py index 266893ffe..5896c8170 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -34,7 +34,8 @@ def _all_device_data(self) -> None: Collect data for each device and add to self.gw_data and self.gw_devices. """ self._update_gw_devices() - self._update_zones() + if self.smile(ADAM): + self._update_zones() self.gw_data.update( { "gateway_id": self.gateway_id, @@ -190,6 +191,10 @@ def _get_device_data(self, dev_id: str) -> DeviceData: # Adam data self._device_data_adam(device, data) + # Thermostat data for Anna (presets, temperatures etc) + if self.smile(ANNA) and device["dev_class"] == "thermostat": + self._device_data_climate(dev_id, device, data) + return data def _check_availability( @@ -232,11 +237,15 @@ def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None: self._count += 1 - def _device_data_climate(self, loc_id: str, device: DeviceData, data: DeviceData) -> None: + def _device_data_climate(self, location_id: str, device: DeviceData, data: DeviceData) -> None: """Helper-function for _get_device_data(). Determine climate-control device data. """ + loc_id = location_id + if (dev_loc := device.get("location")) is not None: + loc_id = dev_loc + # Presets data["preset_modes"] = None data["active_preset"] = None diff --git a/plugwise/helper.py b/plugwise/helper.py index a1606c703..d510b0c6f 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -855,7 +855,7 @@ def _match_locations(self) -> dict[str, ThermoLoc]: for appliance_details in self.gw_devices.values(): if appliance_details["location"] == location_id: location_details.update( - {"primary": set(), "primary_prio": 0, "secondary": set()} + {"primary": [], "primary_prio": 0, "secondary": []} ) matched_locations[location_id] = location_details @@ -880,13 +880,13 @@ def _rank_thermostat( if thermo_matching[appl_class] > self._thermo_locs[loc_id]["primary_prio"]: # Demote former primary if (tl_primary:= self._thermo_locs[loc_id]["primary"]): - self._thermo_locs[loc_id]["secondary"].add(tl_primary) + self._thermo_locs[loc_id]["secondary"].append(tl_primary) # Crown primary self._thermo_locs[loc_id]["primary_prio"] = thermo_matching[appl_class] - self._thermo_locs[loc_id]["primary"].add(appliance_id) + self._thermo_locs[loc_id]["primary"].append(appliance_id) else: - self._thermo_locs[loc_id]["secondary"].add(appliance_id) + self._thermo_locs[loc_id]["secondary"].append(appliance_id) def _control_state(self, loc_id: str) -> str | bool: """Helper-function for _device_data_adam(). diff --git a/tests/data/adam/adam_plus_anna_new.json b/tests/data/adam/adam_plus_anna_new.json index 41c0b575a..3d891c503 100644 --- a/tests/data/adam/adam_plus_anna_new.json +++ b/tests/data/adam/adam_plus_anna_new.json @@ -1,242 +1,320 @@ { - "da224107914542988a88561b4452b0f6": { - "binary_sensors": { - "plugwise_notification": false + "devices": { + "056ee145a816487eaa69243c3280f8bf": { + "available": true, + "binary_sensors": { + "dhw_state": false, + "flame_state": true, + "heating_state": true + }, + "dev_class": "heater_central", + "location": "bc93488efab249e5bc54fd7e175a6f91", + "maximum_boiler_temperature": { + "lower_bound": 25.0, + "resolution": 0.01, + "setpoint": 50.0, + "upper_bound": 95.0 + }, + "model": "Generic heater", + "name": "OpenTherm", + "sensors": { + "intended_boiler_temperature": 23.9, + "water_temperature": 30.0 + }, + "switches": { + "dhw_cm_switch": false + } }, - "dev_class": "gateway", - "firmware": "3.7.8", - "gateway_modes": ["away", "full", "vacation"], - "hardware": "AME Smile 2.0 board", - "location": "bc93488efab249e5bc54fd7e175a6f91", - "mac_address": "012345679891", - "model": "Gateway", - "model_id": "smile_open_therm", - "name": "Adam", - "regulation_modes": ["bleeding_hot", "bleeding_cold", "off", "heating"], - "select_gateway_mode": "full", - "select_regulation_mode": "heating", - "sensors": { - "outdoor_temperature": 9.19 + "10016900610d4c7481df78c89606ef22": { + "available": true, + "dev_class": "valve_actuator_plug", + "location": "d9786723dbcf4f19b5c629a54629f9c7", + "model_id": "TS0011", + "name": "Aanvoer water afsluiter (nous lz3)", + "switches": { + "relay": false + }, + "vendor": "_TZ3000_abjodzas", + "zigbee_mac_address": "A4C13862AF9917B1" }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000D5A168D" - }, - "056ee145a816487eaa69243c3280f8bf": { - "available": true, - "binary_sensors": { - "dhw_state": false, - "flame_state": true, - "heating_state": true - }, - "dev_class": "heater_central", - "location": "bc93488efab249e5bc54fd7e175a6f91", - "maximum_boiler_temperature": { - "lower_bound": 25.0, - "resolution": 0.01, - "setpoint": 50.0, - "upper_bound": 95.0 - }, - "model": "Generic heater", - "name": "OpenTherm", - "sensors": { - "intended_boiler_temperature": 23.9, - "water_temperature": 30.0 - }, - "switches": { - "dhw_cm_switch": false - } - }, - "1772a4ea304041adb83f357b751341ff": { - "available": true, - "binary_sensors": { - "low_battery": false - }, - "dev_class": "thermo_sensor", - "firmware": "2020-11-04T01:00:00+01:00", - "hardware": "1", - "location": "f871b8c4d63549319221e294e4f88074", - "model": "Tom/Floor", - "model_id": "106-03", - "name": "Tom Badkamer", - "sensors": { - "battery": 99, - "setpoint": 18.0, - "temperature": 17.6, - "temperature_difference": -0.2, - "valve_position": 100 - }, - "temperature_offset": { - "lower_bound": -2.0, - "resolution": 0.1, - "setpoint": 0.1, - "upper_bound": 2.0 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000C8FF5EE" - }, - "2568cc4b9c1e401495d4741a5f89bee1": { - "available": true, - "dev_class": "hometheater_plug", - "firmware": "2020-11-10T01:00:00+01:00", - "location": "f2bf9048bef64cc5b6d5110154e33c81", - "model": "Plug", - "model_id": "160-01", - "name": "Plug MediaTV", - "sensors": { - "electricity_consumed": 14.8, - "electricity_consumed_interval": 3.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "1772a4ea304041adb83f357b751341ff": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2020-11-04T01:00:00+01:00", + "hardware": "1", + "location": "f871b8c4d63549319221e294e4f88074", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Tom Badkamer", + "sensors": { + "battery": 99, + "setpoint": 18.0, + "temperature": 17.6, + "temperature_difference": -0.2, + "valve_position": 100 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.1, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000C8FF5EE" }, - "switches": { - "lock": true, - "relay": true + "2568cc4b9c1e401495d4741a5f89bee1": { + "available": true, + "dev_class": "hometheater_plug", + "firmware": "2020-11-10T01:00:00+01:00", + "location": "f2bf9048bef64cc5b6d5110154e33c81", + "model": "Plug", + "model_id": "160-01", + "name": "Plug MediaTV", + "sensors": { + "electricity_consumed": 14.8, + "electricity_consumed_interval": 3.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000D13CCFD" }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000D13CCFD" - }, - "29542b2b6a6a4169acecc15c72a599b8": { - "available": true, - "dev_class": "computer_desktop_plug", - "firmware": "2020-11-10T01:00:00+01:00", - "location": "f2bf9048bef64cc5b6d5110154e33c81", - "model": "Plug", - "model_id": "160-01", - "name": "Plug Werkplek", - "sensors": { - "electricity_consumed": 91.3, - "electricity_consumed_interval": 23.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "29542b2b6a6a4169acecc15c72a599b8": { + "available": true, + "dev_class": "computer_desktop_plug", + "firmware": "2020-11-10T01:00:00+01:00", + "location": "f2bf9048bef64cc5b6d5110154e33c81", + "model": "Plug", + "model_id": "160-01", + "name": "Plug Werkplek", + "sensors": { + "electricity_consumed": 91.3, + "electricity_consumed_interval": 23.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000D13CA9A" }, - "switches": { - "lock": false, - "relay": true + "67d73d0bd469422db25a618a5fb8eeb0": { + "available": true, + "dev_class": "heater_central_plug", + "location": "b4f211175e124df59603412bafa77a34", + "model": "Aqara Smart Plug", + "model_id": "lumi.plug.maeu01", + "name": "SmartPlug Floor 0", + "sensors": { + "electricity_consumed_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "LUMI", + "zigbee_mac_address": "54EF4410002C97F2" }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000D13CA9A" - }, - "67d73d0bd469422db25a618a5fb8eeb0": { - "available": true, - "dev_class": "heater_central_plug", - "location": "b4f211175e124df59603412bafa77a34", - "model": "Aqara Smart Plug", - "model_id": "lumi.plug.maeu01", - "name": "SmartPlug Floor 0", - "sensors": { - "electricity_consumed_interval": 0.0 + "854f8a9b0e7e425db97f1f110e1ce4b3": { + "available": true, + "dev_class": "central_heating_pump_plug", + "firmware": "2020-11-10T01:00:00+01:00", + "location": "f2bf9048bef64cc5b6d5110154e33c81", + "model": "Plug", + "model_id": "160-01", + "name": "Plug Vloerverwarming", + "sensors": { + "electricity_consumed": 43.8, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000D13CB6F" }, - "switches": { - "lock": false, - "relay": true + "ad4838d7d35c4d6ea796ee12ae5aedf8": { + "dev_class": "thermostat", + "location": "f2bf9048bef64cc5b6d5110154e33c81", + "model": "ThermoTouch", + "model_id": "143.1", + "name": "Anna", + "sensors": { + "setpoint": 18.5, + "temperature": 18.4 + }, + "vendor": "Plugwise" }, - "vendor": "LUMI", - "zigbee_mac_address": "54EF4410002C97F2" - }, - "854f8a9b0e7e425db97f1f110e1ce4b3": { - "available": true, - "dev_class": "central_heating_pump_plug", - "firmware": "2020-11-10T01:00:00+01:00", - "location": "f2bf9048bef64cc5b6d5110154e33c81", - "model": "Plug", - "model_id": "160-01", - "name": "Plug Vloerverwarming", - "sensors": { - "electricity_consumed": 43.8, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "da224107914542988a88561b4452b0f6": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "3.7.8", + "gateway_modes": [ + "away", + "full", + "vacation" + ], + "hardware": "AME Smile 2.0 board", + "location": "bc93488efab249e5bc54fd7e175a6f91", + "mac_address": "012345679891", + "model": "Gateway", + "model_id": "smile_open_therm", + "name": "Adam", + "regulation_modes": [ + "bleeding_hot", + "bleeding_cold", + "off", + "heating" + ], + "select_gateway_mode": "full", + "select_regulation_mode": "heating", + "sensors": { + "outdoor_temperature": 9.19 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000D5A168D" }, - "switches": { - "relay": true + "e2f4322d57924fa090fbbc48b3a140dc": { + "available": true, + "binary_sensors": { + "low_battery": true + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "f871b8c4d63549319221e294e4f88074", + "model": "Lisa", + "model_id": "158-01", + "name": "Lisa Badkamer", + "sensors": { + "battery": 14, + "setpoint": 18.0, + "temperature": 16.5 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000C869B61" }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000D13CB6F" + "e8ef2a01ed3b4139a53bf749204fe6b4": { + "dev_class": "switching", + "members": [ + "2568cc4b9c1e401495d4741a5f89bee1", + "29542b2b6a6a4169acecc15c72a599b8" + ], + "model": "Switchgroup", + "name": "Test", + "switches": { + "relay": true + } + } }, - "ad4838d7d35c4d6ea796ee12ae5aedf8": { - "active_preset": "home", - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], - "control_state": "heating", - "dev_class": "thermostat", - "location": "f2bf9048bef64cc5b6d5110154e33c81", - "climate_mode": "auto", - "model": "ThermoTouch", - "model_id": "143.1", - "name": "Anna", - "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"], - "select_schedule": "Weekschema", - "sensors": { - "setpoint": 18.5, - "temperature": 18.4 - }, - "thermostat": { - "lower_bound": 1.0, - "resolution": 0.01, - "setpoint": 18.5, - "upper_bound": 35.0 - }, - "vendor": "Plugwise" + "gateway": { + "cooling_present": false, + "gateway_id": "da224107914542988a88561b4452b0f6", + "heater_id": "056ee145a816487eaa69243c3280f8bf", + "item_count": 152, + "notifications": {}, + "reboot": true, + "smile_name": "Adam" }, - "e2f4322d57924fa090fbbc48b3a140dc": { - "active_preset": "home", - "available": true, - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], - "binary_sensors": { - "low_battery": true - }, - "control_state": "preheating", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "f871b8c4d63549319221e294e4f88074", - "climate_mode": "auto", - "model": "Lisa", - "model_id": "158-01", - "name": "Lisa Badkamer", - "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"], - "select_schedule": "Badkamer", - "sensors": { - "battery": 14, - "setpoint": 18.0, - "temperature": 16.5 - }, - "temperature_offset": { - "lower_bound": -2.0, - "resolution": 0.1, - "setpoint": 0.0, - "upper_bound": 2.0 + "zones": { + "f2bf9048bef64cc5b6d5110154e33c81": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "heating", + "dev_class": "climate", + "members": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] + }, + "name": "Living room", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Weekschema", + "sensors": { + "electricity_consumed": 149.9, + "electricity_produced": 0.0, + "temperature": 18.4 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 18.5, + "upper_bound": 35.0 + } }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.0, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000C869B61" - }, - "e8ef2a01ed3b4139a53bf749204fe6b4": { - "dev_class": "switching", - "members": [ - "2568cc4b9c1e401495d4741a5f89bee1", - "29542b2b6a6a4169acecc15c72a599b8" - ], - "model": "Switchgroup", - "name": "Test", - "switches": { - "relay": true + "f871b8c4d63549319221e294e4f88074": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "preheating", + "dev_class": "climate", + "members": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] + }, + "name": "Bathroom", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Badkamer", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + } } } } diff --git a/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json index 1ff5bd24f..65bbf87d9 100644 --- a/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json +++ b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json @@ -4,9 +4,6 @@ "lock": true } }, - "ad4838d7d35c4d6ea796ee12ae5aedf8": { - "climate_mode": "off" - }, "29542b2b6a6a4169acecc15c72a599b8": { "switches": { "relay": false, @@ -29,8 +26,7 @@ "e2f4322d57924fa090fbbc48b3a140dc": { "binary_sensors": { "low_battery": true - }, - "climate_mode": "off" + } }, "da224107914542988a88561b4452b0f6": { "binary_sensors": { diff --git a/tests/data/anna/anna_v4.json b/tests/data/anna/anna_v4.json index dbd089643..7bb23b0d8 100644 --- a/tests/data/anna/anna_v4.json +++ b/tests/data/anna/anna_v4.json @@ -1,79 +1,102 @@ { - "cd0e6156b1f04d5f952349ffbe397481": { - "dev_class": "heater_central", - "location": "94c107dc6ac84ed98e9f68c0dd06bf71", - "model": "Generic heater", - "model_id": "2.32", - "name": "OpenTherm", - "vendor": "Bosch Thermotechniek B.V.", - "maximum_boiler_temperature": { - "setpoint": 70.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1 + "devices": { + "01b85360fdd243d0aaad4d6ac2a5ba7e": { + "active_preset": "home", + "available_schedules": [ + "Standaard", + "Thuiswerken", + "off" + ], + "climate_mode": "heat", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "eb5309212bf5407bb143e5bfa3b18aee", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "vacation", + "no_frost", + "away", + "asleep", + "home" + ], + "select_schedule": "off", + "sensors": { + "illuminance": 60.0, + "setpoint": 20.5, + "temperature": 20.6 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise" }, - "max_dhw_temperature": { - "setpoint": 60.0, - "lower_bound": 30.0, - "upper_bound": 60.0, - "resolution": 0.01 + "0466eae8520144c78afb29628384edeb": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.0.15", + "hardware": "AME Smile 2.0 board", + "location": "94c107dc6ac84ed98e9f68c0dd06bf71", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 7.44 + }, + "vendor": "Plugwise" }, - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": true, - "flame_state": false - }, - "sensors": { - "water_temperature": 45.0, - "intended_boiler_temperature": 39.9, - "modulation_level": 0, - "return_temperature": 32.0, - "water_pressure": 2.2 - }, - "switches": { - "dhw_cm_switch": false + "cd0e6156b1f04d5f952349ffbe397481": { + "available": true, + "binary_sensors": { + "dhw_state": false, + "flame_state": false, + "heating_state": true + }, + "dev_class": "heater_central", + "location": "94c107dc6ac84ed98e9f68c0dd06bf71", + "max_dhw_temperature": { + "lower_bound": 30.0, + "resolution": 0.01, + "setpoint": 60.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 70.0, + "upper_bound": 100.0 + }, + "model": "Generic heater", + "model_id": "2.32", + "name": "OpenTherm", + "sensors": { + "intended_boiler_temperature": 39.9, + "modulation_level": 0.0, + "return_temperature": 32.0, + "water_pressure": 2.2, + "water_temperature": 45.0 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Bosch Thermotechniek B.V." } }, - "01b85360fdd243d0aaad4d6ac2a5ba7e": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "eb5309212bf5407bb143e5bfa3b18aee", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 20.5, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 - }, - "preset_modes": ["vacation", "no_frost", "away", "asleep", "home"], - "active_preset": "home", - "available_schedules": ["Standaard", "Thuiswerken", "off"], - "select_schedule": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 20.6, - "setpoint": 20.5, - "illuminance": 60.0 - } + "gateway": { + "cooling_present": false, + "gateway_id": "0466eae8520144c78afb29628384edeb", + "heater_id": "cd0e6156b1f04d5f952349ffbe397481", + "item_count": 50, + "notifications": {}, + "reboot": true, + "smile_name": "Smile Anna" }, - "0466eae8520144c78afb29628384edeb": { - "dev_class": "gateway", - "firmware": "4.0.15", - "hardware": "AME Smile 2.0 board", - "location": "94c107dc6ac84ed98e9f68c0dd06bf71", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false - }, - "sensors": { - "outdoor_temperature": 7.44 - } - } + "zones": {} } diff --git a/tests/test_adam.py b/tests/test_adam.py index 614e4a16e..d3335d651 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -36,7 +36,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 self.device_items == 165 + assert self.device_items == 152 assert self.device_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", diff --git a/tests/test_anna.py b/tests/test_anna.py index 516c379b6..bb2fb449b 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -30,7 +30,7 @@ async def test_connect_anna_v4(self): await self.device_test(smile, "2020-04-05 00:00:01", testdata) assert smile.gateway_id == "0466eae8520144c78afb29628384edeb" assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard" - assert self.device_items == 58 + assert self.device_items == 60 assert not self.notifications assert not self.cooling_present diff --git a/tests/test_init.py b/tests/test_init.py index f183d57ae..4f0dfa0e7 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -603,51 +603,106 @@ async def device_test( if skip_testing: return - # Perform tests and asserts - tests = 0 - asserts = 0 - for testdevice, measurements in testdata.items(): - tests += 1 - assert testdevice in data.devices - asserts += 1 - for dev_id, details in data.devices.items(): - if testdevice == dev_id: - _LOGGER.info( - "%s", - "- Testing data for device {} ({})".format( - details["name"], dev_id - ), - ) - _LOGGER.info(" + Device data: %s", details) - for measure_key, measure_assert in measurements.items(): + # Perform tests and asserts in two steps: devices and zones + for header, data_dict in testdata.items(): + # Test devices + if header != "devices": + continue + + tests = 0 + asserts = 0 + for testdevice, measurements in data_dict.items(): + tests += 1 + assert testdevice in data.devices + asserts += 1 + for dev_id, details in data.devices.items(): + if testdevice == dev_id: + _LOGGER.info( + "%s", + "- Testing data for device {} ({})".format( + details["name"], dev_id + ), + ) + _LOGGER.info(" + Device data: %s", details) + for measure_key, measure_assert in measurements.items(): + _LOGGER.info( + "%s", + f" + Testing {measure_key}/{type(measure_key)} with {details[measure_key]}/{type(details[measure_key])} (should be {measure_assert}/{type(measure_assert)} )", + ) + tests += 1 + if ( + measure_key in bsw_list + or measure_key in pw_constants.ACTIVE_ACTUATORS + ): + tests -= 1 + for key_1, val_1 in measure_assert.items(): + tests += 1 + for key_2, val_2 in details[measure_key].items(): + if key_1 != key_2: + continue + + _LOGGER.info( + "%s", + f" + Testing {key_1} ({val_1} should be {val_2})", + ) + assert val_1 == val_2 + asserts += 1 + else: + assert details[measure_key] == measure_assert + asserts += 1 + + assert tests == asserts + _LOGGER.debug("Number of device test-assert: %s", asserts) + + for header, data_dict in testdata.items(): + # Test zones + if header != "zones": + continue + + tests = 0 + asserts = 0 + for testzone, measurements in data_dict.items(): + tests += 1 + assert testzone in data.zones + asserts += 1 + for loc_id, details in data.zones.items(): + if testzone == loc_id: _LOGGER.info( "%s", - f" + Testing {measure_key}/{type(measure_key)} with {details[measure_key]}/{type(details[measure_key])} (should be {measure_assert}/{type(measure_assert)} )", + "- Testing data for zone {} ({})".format( + details["name"], loc_id + ), ) - tests += 1 - if ( - measure_key in bsw_list - or measure_key in pw_constants.ACTIVE_ACTUATORS - ): - tests -= 1 - for key_1, val_1 in measure_assert.items(): - tests += 1 - for key_2, val_2 in details[measure_key].items(): - if key_1 != key_2: - continue - - _LOGGER.info( - "%s", - f" + Testing {key_1} ({val_1} should be {val_2})", - ) - assert val_1 == val_2 - asserts += 1 - else: - assert details[measure_key] == measure_assert - asserts += 1 - - assert tests == asserts - _LOGGER.debug("Number of test-assert: %s", asserts) + _LOGGER.info(" + Zone data: %s", details) + for measure_key, measure_assert in measurements.items(): + _LOGGER.info( + "%s", + f" + Testing {measure_key}/{type(measure_key)} with {details[measure_key]}/{type(details[measure_key])} (should be {measure_assert}/{type(measure_assert)} )", + ) + tests += 1 + if ( + measure_key in bsw_list + or measure_key in pw_constants.ACTIVE_ACTUATORS + ): + tests -= 1 + for key_1, val_1 in measure_assert.items(): + tests += 1 + for key_2, val_2 in details[measure_key].items(): + if key_1 != key_2: + continue + + _LOGGER.info( + "%s", + f" + Testing {key_1} ({val_1} should be {val_2})", + ) + assert val_1 == val_2 + asserts += 1 + else: + assert details[measure_key] == measure_assert + asserts += 1 + + assert tests == asserts + _LOGGER.debug("Number of zone test-assert: %s", asserts) # pragma warning restore S3776 From 558889c0bd62cd5f3c63e0c2ee8ad9082c71e134 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 17 Nov 2024 09:51:56 +0000 Subject: [PATCH 025/106] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_anna.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_anna.py b/tests/test_anna.py index bb2fb449b..772e80256 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -2,7 +2,7 @@ import pytest -from .test_init import _LOGGER, TestPlugwise, pw_exceptions +from .test_init import _LOGGER, TestPlugwise SMILE_TYPE = "anna" # Reoccuring constants From 187cfd4c23596f851dfcdb5a41a0c27f9b729d9a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 17 Nov 2024 12:40:32 +0100 Subject: [PATCH 026/106] Fixes-updates --- fixtures/adam_plus_anna_new/all_data.json | 2 +- fixtures/anna_v4/all_data.json | 8 +- fixtures/legacy_anna/all_data.json | 3 +- fixtures/p1v4_442_single/all_data.json | 3 +- fixtures/smile_p1_v2/all_data.json | 3 +- fixtures/stretch_v31/all_data.json | 3 +- plugwise/data.py | 2 +- plugwise/helper.py | 13 +- plugwise/legacy/helper.py | 2 + plugwise/legacy/smile.py | 2 +- scripts/manual_fixtures.py | 8 +- tests/data/anna/anna_v4.json | 8 +- tests/test_adam.py | 2 +- tests/test_anna.py | 2 +- tests/test_init.py | 145 ++++++++-------------- 15 files changed, 91 insertions(+), 115 deletions(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 3d891c503..75519525c 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -230,7 +230,7 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 152, + "item_count": 173, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/fixtures/anna_v4/all_data.json b/fixtures/anna_v4/all_data.json index 7bb23b0d8..d07563397 100644 --- a/fixtures/anna_v4/all_data.json +++ b/fixtures/anna_v4/all_data.json @@ -33,6 +33,12 @@ "setpoint": 0.0, "upper_bound": 2.0 }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 20.5, + "upper_bound": 30.0 + }, "vendor": "Plugwise" }, "0466eae8520144c78afb29628384edeb": { @@ -93,7 +99,7 @@ "cooling_present": false, "gateway_id": "0466eae8520144c78afb29628384edeb", "heater_id": "cd0e6156b1f04d5f952349ffbe397481", - "item_count": 50, + "item_count": 58, "notifications": {}, "reboot": true, "smile_name": "Smile Anna" diff --git a/fixtures/legacy_anna/all_data.json b/fixtures/legacy_anna/all_data.json index 2b0a27182..3adbdc056 100644 --- a/fixtures/legacy_anna/all_data.json +++ b/fixtures/legacy_anna/all_data.json @@ -70,5 +70,6 @@ "heater_id": "04e4cbfe7f4340f090f85ec3b9e6a950", "item_count": 41, "smile_name": "Smile Anna" - } + }, + "zones": {} } diff --git a/fixtures/p1v4_442_single/all_data.json b/fixtures/p1v4_442_single/all_data.json index 3ea4bb01b..5e2abe64b 100644 --- a/fixtures/p1v4_442_single/all_data.json +++ b/fixtures/p1v4_442_single/all_data.json @@ -47,5 +47,6 @@ "notifications": {}, "reboot": true, "smile_name": "Smile P1" - } + }, + "zones": {} } diff --git a/fixtures/smile_p1_v2/all_data.json b/fixtures/smile_p1_v2/all_data.json index 5d970d401..304624603 100644 --- a/fixtures/smile_p1_v2/all_data.json +++ b/fixtures/smile_p1_v2/all_data.json @@ -37,5 +37,6 @@ "gateway_id": "aaaa0000aaaa0000aaaa0000aaaa00aa", "item_count": 26, "smile_name": "Smile P1" - } + }, + "zones": {} } diff --git a/fixtures/stretch_v31/all_data.json b/fixtures/stretch_v31/all_data.json index a875324fc..49b42fb3f 100644 --- a/fixtures/stretch_v31/all_data.json +++ b/fixtures/stretch_v31/all_data.json @@ -137,5 +137,6 @@ "gateway_id": "0000aaaa0000aaaa0000aaaa0000aa00", "item_count": 83, "smile_name": "Stretch" - } + }, + "zones": {} } diff --git a/plugwise/data.py b/plugwise/data.py index 5896c8170..059d1e274 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -148,7 +148,7 @@ def _update_for_cooling(self, device: DeviceData) -> None: sensors.pop("setpoint") sensors["setpoint_low"] = temp_dict["setpoint_low"] sensors["setpoint_high"] = temp_dict["setpoint_high"] - self._count += 2 + self._count += 2 # add 4, remove 2 def _get_location_data(self, loc_id: str) -> DeviceData: diff --git a/plugwise/helper.py b/plugwise/helper.py index d510b0c6f..33eb6e667 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -639,13 +639,13 @@ def _appliance_measurements( ) if data.get("binary_sensors"): - self._count += len(data["binary_sensors"]) - 1 + self._count += len(data["binary_sensors"]) if data.get("sensors"): - self._count += len(data["sensors"]) -1 + self._count += len(data["sensors"]) if data.get("switches"): - self._count += len(data["switches"]) -1 + self._count += len(data["switches"]) # Don't count the above top-level dicts, only the remaining single items - #self._count += len(data) - 3 + self._count += len(data) - 3 def _get_toggle_state( self, xml: etree, toggle: str, name: ToggleNameType, data: DeviceData @@ -684,7 +684,9 @@ def _get_actuator_functionalities( # Skip max_dhw_temperature, not initially valid, # skip thermostat for all but zones with thermostats if item == "max_dhw_temperature" or ( - item == "thermostat" and device["dev_class"] != "climate" + item == "thermostat" and ( + device["dev_class"] != "climate" if self.smile(ADAM) else device["dev_class"] != "thermostat" + ) ): continue @@ -844,6 +846,7 @@ def _scan_thermostats(self) -> None: } } ) + self._count += 3 def _match_locations(self) -> dict[str, ThermoLoc]: """Helper-function for _scan_thermostats(). diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index a9a62cb88..6a47a110e 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -33,6 +33,7 @@ GatewayData, SensorType, ThermoLoc, + ZoneData, ) from plugwise.util import ( common_match_cases, @@ -89,6 +90,7 @@ def __init__(self) -> None: self.smile_name: str self.smile_type: str self.smile_zigbee_mac_address: str | None + self.zone_data: ZoneData = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 6338ac130..d2713165a 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -121,7 +121,7 @@ async def async_update(self) -> PlugwiseData: ) self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} - self.zones: dict[str, ZoneData] = {} + self.zone_data: dict[str, ZoneData] = {} await self.full_update_device() self.get_all_devices() # Otherwise perform an incremental update diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 1ec96d80d..459696a22 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -74,7 +74,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling["devices"].pop("10016900610d4c7481df78c89606ef22") # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["thermostat"][ +m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ "setpoint" ] = 23.5 @@ -115,7 +115,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: ] = 21.6 # Go for e2f4 -m_adam_cooling["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["thermostat"][ +m_adam_cooling["zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 25.0 m_adam_cooling["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ @@ -163,7 +163,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_heating["gateway"]["cooling_present"] = False # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["thermostat"][ +m_adam_heating["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ "setpoint" ] = 20.0 @@ -187,7 +187,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: ] = 18.6 # Go for e2f4 -m_adam_heating["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["thermostat"][ +m_adam_heating["zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 15.0 diff --git a/tests/data/anna/anna_v4.json b/tests/data/anna/anna_v4.json index 7bb23b0d8..d07563397 100644 --- a/tests/data/anna/anna_v4.json +++ b/tests/data/anna/anna_v4.json @@ -33,6 +33,12 @@ "setpoint": 0.0, "upper_bound": 2.0 }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 20.5, + "upper_bound": 30.0 + }, "vendor": "Plugwise" }, "0466eae8520144c78afb29628384edeb": { @@ -93,7 +99,7 @@ "cooling_present": false, "gateway_id": "0466eae8520144c78afb29628384edeb", "heater_id": "cd0e6156b1f04d5f952349ffbe397481", - "item_count": 50, + "item_count": 58, "notifications": {}, "reboot": true, "smile_name": "Smile Anna" diff --git a/tests/test_adam.py b/tests/test_adam.py index d3335d651..3f686dc2d 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -36,7 +36,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 self.device_items == 152 + assert self.device_items == 173 assert self.device_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", diff --git a/tests/test_anna.py b/tests/test_anna.py index 772e80256..b69965c29 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -30,7 +30,7 @@ async def test_connect_anna_v4(self): await self.device_test(smile, "2020-04-05 00:00:01", testdata) assert smile.gateway_id == "0466eae8520144c78afb29628384edeb" assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard" - assert self.device_items == 60 + assert self.device_items == 58 assert not self.notifications assert not self.cooling_present diff --git a/tests/test_init.py b/tests/test_init.py index 4f0dfa0e7..5ae05e0e9 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -546,7 +546,52 @@ async def device_test( skip_testing=False, ): """Perform basic device tests.""" - bsw_list = ["binary_sensors", "central", "climate", "sensors", "switches"] + + def test_and_assert(test_dict, data, header): + """Test-and-assert helper-function.""" + tests = 0 + asserts = 0 + bsw_list = ["binary_sensors", "central", "climate", "sensors", "switches"] + for testitem, measurements in test_dict.items(): + tests += 1 + assert testitem in data + asserts += 1 + for data_id, details in data.items(): + if testitem == data_id: + _LOGGER.info( + "%s", + f"- Testing data for {header} {details['name']} ({data_id})", + ) + _LOGGER.info("%s", f" + {header} data: {details}") + for measure_key, measure_assert in measurements.items(): + _LOGGER.info( + "%s", + f" + Testing {measure_key}/{type(measure_key)} with {details[measure_key]}/{type(details[measure_key])} (should be {measure_assert}/{type(measure_assert)} )", + ) + tests += 1 + if ( + measure_key in bsw_list + or measure_key in pw_constants.ACTIVE_ACTUATORS + ): + tests -= 1 + for key_1, val_1 in measure_assert.items(): + tests += 1 + for key_2, val_2 in details[measure_key].items(): + if key_1 != key_2: + continue + + _LOGGER.info( + "%s", + f" + Testing {key_1} ({val_1} should be {val_2})", + ) + assert val_1 == val_2 + asserts += 1 + else: + assert details[measure_key] == measure_assert + asserts += 1 + + assert tests == asserts + _LOGGER.debug("Number of zone test-assert: %s", asserts) # pragma warning disable S3776 @@ -606,103 +651,13 @@ async def device_test( # Perform tests and asserts in two steps: devices and zones for header, data_dict in testdata.items(): # Test devices - if header != "devices": - continue - - tests = 0 - asserts = 0 - for testdevice, measurements in data_dict.items(): - tests += 1 - assert testdevice in data.devices - asserts += 1 - for dev_id, details in data.devices.items(): - if testdevice == dev_id: - _LOGGER.info( - "%s", - "- Testing data for device {} ({})".format( - details["name"], dev_id - ), - ) - _LOGGER.info(" + Device data: %s", details) - for measure_key, measure_assert in measurements.items(): - _LOGGER.info( - "%s", - f" + Testing {measure_key}/{type(measure_key)} with {details[measure_key]}/{type(details[measure_key])} (should be {measure_assert}/{type(measure_assert)} )", - ) - tests += 1 - if ( - measure_key in bsw_list - or measure_key in pw_constants.ACTIVE_ACTUATORS - ): - tests -= 1 - for key_1, val_1 in measure_assert.items(): - tests += 1 - for key_2, val_2 in details[measure_key].items(): - if key_1 != key_2: - continue - - _LOGGER.info( - "%s", - f" + Testing {key_1} ({val_1} should be {val_2})", - ) - assert val_1 == val_2 - asserts += 1 - else: - assert details[measure_key] == measure_assert - asserts += 1 - - assert tests == asserts - _LOGGER.debug("Number of device test-assert: %s", asserts) + if header == "devices": + test_and_assert(data_dict, data.devices, header) for header, data_dict in testdata.items(): # Test zones - if header != "zones": - continue - - tests = 0 - asserts = 0 - for testzone, measurements in data_dict.items(): - tests += 1 - assert testzone in data.zones - asserts += 1 - for loc_id, details in data.zones.items(): - if testzone == loc_id: - _LOGGER.info( - "%s", - "- Testing data for zone {} ({})".format( - details["name"], loc_id - ), - ) - _LOGGER.info(" + Zone data: %s", details) - for measure_key, measure_assert in measurements.items(): - _LOGGER.info( - "%s", - f" + Testing {measure_key}/{type(measure_key)} with {details[measure_key]}/{type(details[measure_key])} (should be {measure_assert}/{type(measure_assert)} )", - ) - tests += 1 - if ( - measure_key in bsw_list - or measure_key in pw_constants.ACTIVE_ACTUATORS - ): - tests -= 1 - for key_1, val_1 in measure_assert.items(): - tests += 1 - for key_2, val_2 in details[measure_key].items(): - if key_1 != key_2: - continue - - _LOGGER.info( - "%s", - f" + Testing {key_1} ({val_1} should be {val_2})", - ) - assert val_1 == val_2 - asserts += 1 - else: - assert details[measure_key] == measure_assert - asserts += 1 - - assert tests == asserts - _LOGGER.debug("Number of zone test-assert: %s", asserts) + if header == "zones": + test_and_assert(data_dict, data.zones, header) # pragma warning restore S3776 From 9eb0018602ae0b01beb2b4574d21216706f80e69 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 17 Nov 2024 17:43:00 +0100 Subject: [PATCH 027/106] Save updated fixtures --- fixtures/m_adam_cooling/all_data.json | 129 +++++++++++++++++--------- fixtures/m_adam_heating/all_data.json | 128 ++++++++++++++++--------- 2 files changed, 166 insertions(+), 91 deletions(-) diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index 90d9ab8d9..f7003b051 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -31,7 +31,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "f871b8c4d63549319221e294e4f88074", @@ -54,15 +54,7 @@ "zigbee_mac_address": "000D6F000C8FF5EE" }, "ad4838d7d35c4d6ea796ee12ae5aedf8": { - "active_preset": "home", "available": true, - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], "climate_mode": "cool", "control_state": "cooling", "dev_class": "thermostat", @@ -70,24 +62,11 @@ "model": "ThermoTouch", "model_id": "143.1", "name": "Anna", - "preset_modes": [ - "no_frost", - "asleep", - "vacation", - "home", - "away" - ], "select_schedule": "off", "sensors": { "setpoint": 23.5, "temperature": 25.8 }, - "thermostat": { - "lower_bound": 1.0, - "resolution": 0.01, - "setpoint": 23.5, - "upper_bound": 35.0 - }, "vendor": "Plugwise" }, "da224107914542988a88561b4452b0f6": { @@ -123,20 +102,10 @@ "zigbee_mac_address": "000D6F000D5A168D" }, "e2f4322d57924fa090fbbc48b3a140dc": { - "active_preset": "home", "available": true, - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], "binary_sensors": { "low_battery": true }, - "climate_mode": "auto", - "control_state": "preheating", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -144,14 +113,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Lisa Badkamer", - "preset_modes": [ - "no_frost", - "asleep", - "vacation", - "home", - "away" - ], - "select_schedule": "Badkamer", "sensors": { "battery": 14, "setpoint": 23.5, @@ -163,12 +124,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 25.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "000D6F000C869B61" }, @@ -193,5 +148,87 @@ "notifications": {}, "reboot": true, "smile_name": "Adam" + }, + "zones": { + "f2bf9048bef64cc5b6d5110154e33c81": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "heating", + "dev_class": "climate", + "members": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] + }, + "name": "Living room", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Weekschema", + "sensors": { + "electricity_consumed": 149.9, + "electricity_produced": 0.0, + "temperature": 18.4 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 23.5, + "upper_bound": 35.0 + } + }, + "f871b8c4d63549319221e294e4f88074": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "preheating", + "dev_class": "climate", + "members": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] + }, + "name": "Bathroom", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Badkamer", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 25.0, + "upper_bound": 99.9 + } + } } } diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index 7e6a5a103..aabc7d654 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -36,7 +36,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "f871b8c4d63549319221e294e4f88074", @@ -59,15 +59,7 @@ "zigbee_mac_address": "000D6F000C8FF5EE" }, "ad4838d7d35c4d6ea796ee12ae5aedf8": { - "active_preset": "home", "available": true, - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], "climate_mode": "heat", "control_state": "preheating", "dev_class": "thermostat", @@ -75,24 +67,11 @@ "model": "ThermoTouch", "model_id": "143.1", "name": "Anna", - "preset_modes": [ - "no_frost", - "asleep", - "vacation", - "home", - "away" - ], "select_schedule": "off", "sensors": { "setpoint": 20.0, "temperature": 19.1 }, - "thermostat": { - "lower_bound": 1.0, - "resolution": 0.01, - "setpoint": 20.0, - "upper_bound": 35.0 - }, "vendor": "Plugwise" }, "da224107914542988a88561b4452b0f6": { @@ -127,19 +106,10 @@ "zigbee_mac_address": "000D6F000D5A168D" }, "e2f4322d57924fa090fbbc48b3a140dc": { - "active_preset": "home", "available": true, - "available_schedules": [ - "Badkamer", - "Test", - "Vakantie", - "Weekschema", - "off" - ], "binary_sensors": { "low_battery": true }, - "climate_mode": "auto", "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", @@ -148,14 +118,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Lisa Badkamer", - "preset_modes": [ - "no_frost", - "asleep", - "vacation", - "home", - "away" - ], - "select_schedule": "Badkamer", "sensors": { "battery": 14, "setpoint": 15.0, @@ -167,12 +129,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 15.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "000D6F000C869B61" }, @@ -197,5 +153,87 @@ "notifications": {}, "reboot": true, "smile_name": "Adam" + }, + "zones": { + "f2bf9048bef64cc5b6d5110154e33c81": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "heating", + "dev_class": "climate", + "members": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] + }, + "name": "Living room", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Weekschema", + "sensors": { + "electricity_consumed": 149.9, + "electricity_produced": 0.0, + "temperature": 18.4 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 20.0, + "upper_bound": 35.0 + } + }, + "f871b8c4d63549319221e294e4f88074": { + "active_preset": "home", + "available_schedules": [ + "Badkamer", + "Test", + "Vakantie", + "Weekschema", + "off" + ], + "climate_mode": "auto", + "control_state": "preheating", + "dev_class": "climate", + "members": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] + }, + "name": "Bathroom", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "home", + "away" + ], + "select_schedule": "Badkamer", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 15.0, + "upper_bound": 99.9 + } + } } } From 824ca0a5765479442fdaab52d98524bcaf9005e9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 17 Nov 2024 17:51:16 +0100 Subject: [PATCH 028/106] Typing corrections --- plugwise/constants.py | 26 +++++++++++++++++++++++--- plugwise/data.py | 16 +++++++++++----- plugwise/helper.py | 2 +- plugwise/legacy/helper.py | 9 ++++++--- plugwise/smile.py | 2 +- plugwise/util.py | 3 ++- 6 files changed, 44 insertions(+), 14 deletions(-) diff --git a/plugwise/constants.py b/plugwise/constants.py index 35237429c..35efd5dba 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -500,9 +500,9 @@ class ThermoLoc(TypedDict, total=False): """Thermo Location class.""" name: str - primary: set[str] + primary: list[str] primary_prio: int - secondary: set[str] + secondary: list[str] class ActuatorData(TypedDict, total=False): @@ -516,12 +516,19 @@ class ActuatorData(TypedDict, total=False): upper_bound: float +class MemberData: + """ZoneData Member data class.""" + + primary: list[str] + secondary: list[str] + + class ZoneData(TypedDict, total=False): """The Climate Data class, covering the collected and ordered output-data per location.""" dev_class: str name: str - members: dict[str, set[str]] + members: dict[MemberData] climate_mode: str # Extra for Adam Master Thermostats control_state: str | bool @@ -572,6 +579,18 @@ class DeviceData(TypedDict, total=False): select_gateway_mode: str select_regulation_mode: str + # Single thermostat (Anna) + # Presets: + active_preset: str | None + preset_modes: list[str] | None + # Schedules: + available_schedules: list[str] + select_schedule: str + + climate_mode: str + # Extra for Adam Master Thermostats + control_state: str | bool + # Dict-types binary_sensors: SmileBinarySensors max_dhw_temperature: ActuatorData @@ -579,6 +598,7 @@ class DeviceData(TypedDict, total=False): sensors: SmileSensors switches: SmileSwitches temperature_offset: ActuatorData + thermostat: ActuatorData @dataclass diff --git a/plugwise/data.py b/plugwise/data.py index 059d1e274..3e10d3461 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -15,6 +15,7 @@ OFF, ActuatorData, DeviceData, + ZoneData, ) from plugwise.helper import SmileHelper from plugwise.util import remove_empty_platform_dicts @@ -151,7 +152,7 @@ def _update_for_cooling(self, device: DeviceData) -> None: self._count += 2 # add 4, remove 2 - def _get_location_data(self, loc_id: str) -> DeviceData: + def _get_location_data(self, loc_id: str) -> ZoneData: """Helper-function for _all_device_data() and async_update(). Provide device-data, based on Location ID (= loc_id). @@ -237,14 +238,19 @@ def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None: self._count += 1 - def _device_data_climate(self, location_id: str, device: DeviceData, data: DeviceData) -> None: + def _device_data_climate( + self, + location_id: str, + device: DeviceData | ZoneData, + data: DeviceData | ZoneData + ) -> None: """Helper-function for _get_device_data(). Determine climate-control device data. """ loc_id = location_id - if (dev_loc := device.get("location")) is not None: - loc_id = dev_loc + if device.get("location") is not None: + loc_id = device["location"] # Presets data["preset_modes"] = None @@ -285,7 +291,7 @@ def check_reg_mode(self, mode: str) -> bool: ) def _get_schedule_states_with_off( - self, location: str, schedules: list[str], selected: str, data: DeviceData + self, location: str, schedules: list[str], selected: str, data: DeviceData | ZoneData ) -> None: """Collect schedules with states for each thermostat. diff --git a/plugwise/helper.py b/plugwise/helper.py index 33eb6e667..61b8729b0 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -262,7 +262,7 @@ def __init__(self) -> None: self.smile_type: str self.smile_zigbee_mac_address: str | None self.therms_with_offset_func: list[str] = [] - self.zone_data: ZoneData = {} + self.zone_data: dict[str, ZoneData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 6a47a110e..af1f6304d 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -90,7 +90,7 @@ def __init__(self) -> None: self.smile_name: str self.smile_type: str self.smile_zigbee_mac_address: str | None - self.zone_data: ZoneData = {} + self.zone_data: dict[str, ZoneData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -336,7 +336,7 @@ def _power_data_from_modules(self) -> DeviceData: def _appliance_measurements( self, appliance: etree, - data: DeviceData, + data: DeviceData | ZoneData, measurements: dict[str, DATA | UOM], ) -> None: """Helper-function for _get_measurement_data() - collect appliance measurement data.""" @@ -368,7 +368,10 @@ def _appliance_measurements( self._count += len(data) - 3 def _get_actuator_functionalities( - self, xml: etree, device: DeviceData, data: DeviceData + self, + xml: etree, + device: DeviceData | ZoneData, + data: DeviceData | ZoneData ) -> None: """Helper-function for _get_measurement_data().""" for item in ACTIVE_ACTUATORS: diff --git a/plugwise/smile.py b/plugwise/smile.py index a37b4a189..66382a041 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -127,7 +127,7 @@ async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} - self.zone_data: ZoneData = {} + self.zone_data: dict[str, ZoneData] = {} try: await self.full_update_device() self.get_all_devices() diff --git a/plugwise/util.py b/plugwise/util.py index 5798feb28..16e0b532b 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -27,6 +27,7 @@ SensorType, SpecialType, SwitchType, + ZoneData, ) from defusedxml import ElementTree as etree @@ -122,7 +123,7 @@ def common_match_cases( measurement: str, attrs: DATA | UOM, location: etree, - data: DeviceData, + data: DeviceData | ZoneData, ) -> None: """Helper-function for common match-case execution.""" value = location.text in ("on", "true") From fb288880079faa4c86f091b9a7f9c217f074e25e Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 17 Nov 2024 19:58:02 +0100 Subject: [PATCH 029/106] Add local mypy testing --- plugwise/constants.py | 2 +- plugwise/helper.py | 5 +++-- scripts/tests_and_coverage.sh | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/plugwise/constants.py b/plugwise/constants.py index 35efd5dba..17808957e 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -528,7 +528,7 @@ class ZoneData(TypedDict, total=False): dev_class: str name: str - members: dict[MemberData] + members: dict[str, list[str]] climate_mode: str # Extra for Adam Master Thermostats control_state: str | bool diff --git a/plugwise/helper.py b/plugwise/helper.py index 61b8729b0..29d79caf0 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -882,8 +882,9 @@ def _rank_thermostat( # Pre-elect new primary if thermo_matching[appl_class] > self._thermo_locs[loc_id]["primary_prio"]: # Demote former primary - if (tl_primary:= self._thermo_locs[loc_id]["primary"]): - self._thermo_locs[loc_id]["secondary"].append(tl_primary) + if (tl_primary := self._thermo_locs[loc_id]["primary"]): + self._thermo_locs[loc_id]["secondary"] = tl_primary + self._thermo_locs[loc_id]["primary"] = [] # Crown primary self._thermo_locs[loc_id]["primary_prio"] = thermo_matching[appl_class] diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index 04c9f46eb..5195652c3 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -42,6 +42,9 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "linting" ] ; then echo "... pylint-ing ..." pylint plugwise/ tests/ + + echo "... mypy-ing ..." + mypy plugwise/ fi # As to not generated fixtures, leaving biome to re-do them From 4ab11c8167a971deb6e816770584d481be270127 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 08:14:39 +0100 Subject: [PATCH 030/106] Combine to DeviceZoneData --- plugwise/common.py | 18 +++++++++--------- plugwise/constants.py | 39 ++++++++------------------------------- plugwise/data.py | 21 ++++++++++----------- plugwise/helper.py | 37 ++++++++++++++++++------------------- plugwise/legacy/data.py | 6 +++--- plugwise/legacy/helper.py | 21 ++++++++++----------- plugwise/legacy/smile.py | 7 +++---- plugwise/smile.py | 7 +++---- plugwise/util.py | 7 +++---- 9 files changed, 67 insertions(+), 96 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index ee6c22e99..b068c9317 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -11,7 +11,7 @@ SPECIAL_PLUG_TYPES, SWITCH_GROUP_TYPES, ApplianceType, - DeviceData, + DeviceZoneData, ModelData, SensorType, ) @@ -40,7 +40,7 @@ def __init__(self) -> None: self._heater_id: str self._on_off_device: bool self._opentherm_device: bool - self.gw_devices: dict[str, DeviceData] + self.gw_devices: dict[str, DeviceZoneData] self.smile_name: str self.smile_type: str @@ -108,7 +108,7 @@ def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) return appl - def _collect_power_values(self, data: DeviceData, loc: Munch, tariff: str, legacy: bool = False) -> None: + def _collect_power_values(self, data: DeviceZoneData, loc: Munch, tariff: str, legacy: bool = False) -> None: """Something.""" for loc.peak_select in ("nl_peak", "nl_offpeak"): loc.locator = ( @@ -160,8 +160,8 @@ def _power_data_energy_diff( measurement: str, net_string: SensorType, f_val: float | int, - direct_data: DeviceData, - ) -> DeviceData: + direct_data: DeviceZoneData, + ) -> DeviceZoneData: """Calculate differential energy.""" if ( "electricity" in measurement @@ -208,7 +208,7 @@ def _create_gw_devices(self, appl: Munch) -> None: self._count += 1 def _device_data_switching_group( - self, device: DeviceData, data: DeviceData + self, device: DeviceZoneData, data: DeviceZoneData ) -> None: """Helper-function for _get_device_data(). @@ -222,12 +222,12 @@ def _device_data_switching_group( data["switches"]["relay"] = counter != 0 self._count += 1 - def _get_group_switches(self) -> dict[str, DeviceData]: + def _get_group_switches(self) -> dict[str, DeviceZoneData]: """Helper-function for smile.py: get_all_devices(). Collect switching- or pump-group info. """ - switch_groups: dict[str, DeviceData] = {} + switch_groups: dict[str, DeviceZoneData] = {} # P1 and Anna don't have switchgroups if self.smile_type == "power" or self.smile(ANNA): return switch_groups @@ -258,7 +258,7 @@ def _get_group_switches(self) -> dict[str, DeviceData]: return switch_groups - def _get_lock_state(self, xml: etree, data: DeviceData, stretch_v2: bool = False) -> None: + def _get_lock_state(self, xml: etree, data: DeviceZoneData, stretch_v2: bool = False) -> None: """Helper-function for _get_measurement_data(). Adam & Stretches: obtain the relay-switch lock state. diff --git a/plugwise/constants.py b/plugwise/constants.py index 17808957e..0449e9985 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -516,35 +516,11 @@ class ActuatorData(TypedDict, total=False): upper_bound: float -class MemberData: - """ZoneData Member data class.""" +class DeviceZoneData(TypedDict, total=False): + """The DeviceZone data class. - primary: list[str] - secondary: list[str] - - -class ZoneData(TypedDict, total=False): - """The Climate Data class, covering the collected and ordered output-data per location.""" - - dev_class: str - name: str - members: dict[str, list[str]] - climate_mode: str - # Extra for Adam Master Thermostats - control_state: str | bool - # Presets: - active_preset: str | None - preset_modes: list[str] | None - # Schedules: - available_schedules: list[str] - select_schedule: str - - sensors: SmileSensors - thermostat: ActuatorData - - -class DeviceData(TypedDict, total=False): - """The Device Data class, covering the collected and ordered output-data per device.""" + Covering the collected output-data per device or location. + """ # Appliance base data dev_class: str @@ -579,7 +555,8 @@ class DeviceData(TypedDict, total=False): select_gateway_mode: str select_regulation_mode: str - # Single thermostat (Anna) + # Thermostat-related + thermostats: dict[str, list[str]] # Presets: active_preset: str | None preset_modes: list[str] | None @@ -606,5 +583,5 @@ class PlugwiseData: """Plugwise data provided as output.""" gateway: GatewayData - devices: dict[str, DeviceData] - zones: dict[str, ZoneData] + devices: dict[str, DeviceZoneData] + zones: dict[str, DeviceZoneData] diff --git a/plugwise/data.py b/plugwise/data.py index 3e10d3461..6ffa4e437 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -14,8 +14,7 @@ NONE, OFF, ActuatorData, - DeviceData, - ZoneData, + DeviceZoneData, ) from plugwise.helper import SmileHelper from plugwise.util import remove_empty_platform_dicts @@ -108,7 +107,7 @@ def _detect_low_batteries(self) -> list[str]: return mac_address_list def _add_or_update_notifications( - self, device_id: str, device: DeviceData, data: DeviceData + self, device_id: str, device: DeviceZoneData, data: DeviceZoneData ) -> None: """Helper-function adding or updating the Plugwise notifications.""" if ( @@ -123,7 +122,7 @@ def _add_or_update_notifications( data["binary_sensors"]["plugwise_notification"] = bool(self._notifications) self._count += 1 - def _update_for_cooling(self, device: DeviceData) -> None: + def _update_for_cooling(self, device: DeviceZoneData) -> None: """Helper-function for adding/updating various cooling-related values.""" # For Anna and heating + cooling, replace setpoint with setpoint_high/_low if ( @@ -152,7 +151,7 @@ def _update_for_cooling(self, device: DeviceData) -> None: self._count += 2 # add 4, remove 2 - def _get_location_data(self, loc_id: str) -> ZoneData: + def _get_location_data(self, loc_id: str) -> DeviceZoneData: """Helper-function for _all_device_data() and async_update(). Provide device-data, based on Location ID (= loc_id). @@ -168,7 +167,7 @@ def _get_location_data(self, loc_id: str) -> ZoneData: return data - def _get_device_data(self, dev_id: str) -> DeviceData: + def _get_device_data(self, dev_id: str) -> DeviceZoneData: """Helper-function for _update_gw_devices() and async_update(). Provide device-data, based on appliance_id ()= dev_id). @@ -199,7 +198,7 @@ def _get_device_data(self, dev_id: str) -> DeviceData: return data def _check_availability( - self, device: DeviceData, dev_class: str, data: DeviceData, message: str + self, device: DeviceZoneData, dev_class: str, data: DeviceZoneData, message: str ) -> None: """Helper-function for _get_device_data(). @@ -213,7 +212,7 @@ def _check_availability( if message in msg: data["available"] = False - def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None: + def _device_data_adam(self, device: DeviceZoneData, data: DeviceZoneData) -> None: """Helper-function for _get_device_data(). Determine Adam heating-status for on-off heating via valves, @@ -241,8 +240,8 @@ def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None: def _device_data_climate( self, location_id: str, - device: DeviceData | ZoneData, - data: DeviceData | ZoneData + device: DeviceZoneData, + data: DeviceZoneData ) -> None: """Helper-function for _get_device_data(). @@ -291,7 +290,7 @@ def check_reg_mode(self, mode: str) -> bool: ) def _get_schedule_states_with_off( - self, location: str, schedules: list[str], selected: str, data: DeviceData | ZoneData + self, location: str, schedules: list[str], selected: str, data: DeviceZoneData ) -> None: """Collect schedules with states for each thermostat. diff --git a/plugwise/helper.py b/plugwise/helper.py index 29d79caf0..3e1b580e1 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -36,12 +36,11 @@ ActuatorData, ActuatorDataType, ActuatorType, - DeviceData, + DeviceZoneData, GatewayData, SensorType, ThermoLoc, ToggleNameType, - ZoneData, ) from plugwise.exceptions import ( ConnectionFailedError, @@ -251,7 +250,7 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceData] = {} + self.gw_devices: dict[str, DeviceZoneData] = {} self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None @@ -262,7 +261,7 @@ def __init__(self) -> None: self.smile_type: str self.smile_zigbee_mac_address: str | None self.therms_with_offset_func: list[str] = [] - self.zone_data: dict[str, ZoneData] = {} + self.zone_data: dict[str, DeviceZoneData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -483,12 +482,12 @@ def _get_appliances_with_offset_functionality(self) -> list[str]: return therm_list - def _get_zone_data(self, loc_id: str) -> ZoneData: + def _get_zone_data(self, loc_id: str) -> DeviceZoneData: """Helper-function for smile.py: _get_device_data(). Collect the location-data based on location id. """ - data: ZoneData = {"sensors": {}} + data: DeviceZoneData = {"sensors": {}} zone = self.zone_data[loc_id] measurements = ZONE_MEASUREMENTS if ( @@ -499,12 +498,12 @@ def _get_zone_data(self, loc_id: str) -> ZoneData: return data - def _get_measurement_data(self, dev_id: str) -> DeviceData: + def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: """Helper-function for smile.py: _get_device_data(). Collect the appliance-data based on device id. """ - data: DeviceData = {"binary_sensors": {}, "sensors": {}, "switches": {}} + data: DeviceZoneData = {"binary_sensors": {}, "sensors": {}, "switches": {}} # Get P1 smartmeter data from LOCATIONS device = self.gw_devices[dev_id] # !! DON'T CHANGE below two if-lines, will break stuff !! @@ -588,12 +587,12 @@ def _get_measurement_data(self, dev_id: str) -> DeviceData: return data - def _power_data_from_location(self, loc_id: str) -> DeviceData: + def _power_data_from_location(self, loc_id: str) -> DeviceZoneData: """Helper-function for smile.py: _get_device_data(). Collect the power-data based on Location ID, from LOCATIONS. """ - direct_data: DeviceData = {"sensors": {}} + direct_data: DeviceZoneData = {"sensors": {}} loc = Munch() log_list: list[str] = ["point_log", "cumulative_log", "interval_log"] t_string = "tariff" @@ -610,7 +609,7 @@ def _power_data_from_location(self, loc_id: str) -> DeviceData: def _appliance_measurements( self, appliance: etree, - data: DeviceData, + data: DeviceZoneData, measurements: dict[str, DATA | UOM], ) -> None: """Helper-function for _get_measurement_data() - collect appliance measurement data.""" @@ -648,7 +647,7 @@ def _appliance_measurements( self._count += len(data) - 3 def _get_toggle_state( - self, xml: etree, toggle: str, name: ToggleNameType, data: DeviceData + self, xml: etree, toggle: str, name: ToggleNameType, data: DeviceZoneData ) -> None: """Helper-function for _get_measurement_data(). @@ -677,7 +676,7 @@ def _get_plugwise_notifications(self) -> None: ) def _get_actuator_functionalities( - self, xml: etree, device: DeviceData, data: DeviceData + self, xml: etree, device: DeviceZoneData, data: DeviceZoneData ) -> None: """Helper-function for _get_measurement_data().""" for item in ACTIVE_ACTUATORS: @@ -732,7 +731,7 @@ def _get_actuator_functionalities( act_item = cast(ActuatorType, item) data[act_item] = temp_dict - def _get_regulation_mode(self, appliance: etree, data: DeviceData) -> None: + def _get_regulation_mode(self, appliance: etree, data: DeviceZoneData) -> None: """Helper-function for _get_measurement_data(). Collect the gateway regulation_mode. @@ -743,7 +742,7 @@ def _get_regulation_mode(self, appliance: etree, data: DeviceData) -> None: self._count += 1 self._cooling_enabled = data["select_regulation_mode"] == "cooling" - def _get_gateway_mode(self, appliance: etree, data: DeviceData) -> None: + def _get_gateway_mode(self, appliance: etree, data: DeviceZoneData) -> None: """Helper-function for _get_measurement_data(). Collect the gateway mode. @@ -766,7 +765,7 @@ def _object_value(self, obj_id: str, measurement: str) -> float | int | None: return val - def _process_c_heating_state(self, data: DeviceData) -> None: + def _process_c_heating_state(self, data: DeviceZoneData) -> None: """Helper-function for _get_measurement_data(). Process the central_heating_state value. @@ -794,7 +793,7 @@ def _process_c_heating_state(self, data: DeviceData) -> None: if self._elga: data["binary_sensors"]["heating_state"] = data["c_heating_state"] - def _cleanup_data(self, data: DeviceData) -> None: + def _cleanup_data(self, data: DeviceZoneData) -> None: """Helper-function for _get_measurement_data(). Clean up the data dict. @@ -842,7 +841,7 @@ def _scan_thermostats(self) -> None: loc_id: { "dev_class": "climate", "name": loc_data["name"], - "members": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} + "thermostats": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} } } ) @@ -869,7 +868,7 @@ def _rank_thermostat( thermo_matching: dict[str, int], loc_id: str, appliance_id: str, - appliance_details: DeviceData, + appliance_details: DeviceZoneData, ) -> None: """Helper-function for _scan_thermostats(). diff --git a/plugwise/legacy/data.py b/plugwise/legacy/data.py index ee16ddf10..52d877fd5 100644 --- a/plugwise/legacy/data.py +++ b/plugwise/legacy/data.py @@ -6,7 +6,7 @@ # Dict as class # Version detection -from plugwise.constants import NONE, OFF, DeviceData +from plugwise.constants import NONE, OFF, DeviceZoneData from plugwise.legacy.helper import SmileLegacyHelper from plugwise.util import remove_empty_platform_dicts @@ -46,7 +46,7 @@ def _update_gw_devices(self) -> None: device.update(data) remove_empty_platform_dicts(device) - def _get_device_data(self, dev_id: str) -> DeviceData: + def _get_device_data(self, dev_id: str) -> DeviceZoneData: """Helper-function for _all_device_data() and async_update(). Provide device-data, based on Location ID (= dev_id), from APPLIANCES. @@ -66,7 +66,7 @@ def _get_device_data(self, dev_id: str) -> DeviceData: return data - def _device_data_climate(self, device: DeviceData, data: DeviceData) -> None: + def _device_data_climate(self, device: DeviceZoneData, data: DeviceZoneData) -> None: """Helper-function for _get_device_data(). Determine climate-control device data. diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index af1f6304d..2ab76d269 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -29,11 +29,10 @@ ActuatorDataType, ActuatorType, ApplianceType, - DeviceData, + DeviceZoneData, GatewayData, SensorType, ThermoLoc, - ZoneData, ) from plugwise.util import ( common_match_cases, @@ -81,7 +80,7 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceData] = {} + self.gw_devices: dict[str, DeviceZoneData] = {} self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None @@ -90,7 +89,7 @@ def __init__(self) -> None: self.smile_name: str self.smile_type: str self.smile_zigbee_mac_address: str | None - self.zone_data: dict[str, ZoneData] = {} + self.zone_data: dict[str, DeviceZoneData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -268,12 +267,12 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: self._create_gw_devices(appl) - def _get_measurement_data(self, dev_id: str) -> DeviceData: + def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: """Helper-function for smile.py: _get_device_data(). Collect the appliance-data based on device id. """ - data: DeviceData = {"binary_sensors": {}, "sensors": {}, "switches": {}} + data: DeviceZoneData = {"binary_sensors": {}, "sensors": {}, "switches": {}} # Get P1 smartmeter data from LOCATIONS or MODULES device = self.gw_devices[dev_id] # !! DON'T CHANGE below two if-lines, will break stuff !! @@ -312,12 +311,12 @@ def _get_measurement_data(self, dev_id: str) -> DeviceData: return data - def _power_data_from_modules(self) -> DeviceData: + def _power_data_from_modules(self) -> DeviceZoneData: """Helper-function for smile.py: _get_device_data(). Collect the power-data from MODULES (P1 legacy only). """ - direct_data: DeviceData = {"sensors": {}} + direct_data: DeviceZoneData = {"sensors": {}} loc = Munch() mod_list: list[str] = ["interval_meter", "cumulative_meter", "point_meter"] t_string = "tariff_indicator" @@ -336,7 +335,7 @@ def _power_data_from_modules(self) -> DeviceData: def _appliance_measurements( self, appliance: etree, - data: DeviceData | ZoneData, + data: DeviceZoneData, measurements: dict[str, DATA | UOM], ) -> None: """Helper-function for _get_measurement_data() - collect appliance measurement data.""" @@ -370,8 +369,8 @@ def _appliance_measurements( def _get_actuator_functionalities( self, xml: etree, - device: DeviceData | ZoneData, - data: DeviceData | ZoneData + device: DeviceZoneData, + data: DeviceZoneData ) -> None: """Helper-function for _get_measurement_data().""" for item in ACTIVE_ACTUATORS: diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index d2713165a..d335391fe 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -19,11 +19,10 @@ OFF, REQUIRE_APPLIANCES, RULES, - DeviceData, + DeviceZoneData, GatewayData, PlugwiseData, ThermoLoc, - ZoneData, ) from plugwise.exceptions import ConnectionFailedError, PlugwiseError from plugwise.legacy.data import SmileLegacyData @@ -120,8 +119,8 @@ async def async_update(self) -> PlugwiseData: "Performing daily full-update, reload the Plugwise integration when a single entity becomes unavailable." ) self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceData] = {} - self.zone_data: dict[str, ZoneData] = {} + self.gw_devices: dict[str, DeviceZoneData] = {} + self.zone_data: dict[str, DeviceZoneData] = {} await self.full_update_device() self.get_all_devices() # Otherwise perform an incremental update diff --git a/plugwise/smile.py b/plugwise/smile.py index 66382a041..4a9862107 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -22,11 +22,10 @@ NOTIFICATIONS, OFF, RULES, - DeviceData, + DeviceZoneData, GatewayData, PlugwiseData, ThermoLoc, - ZoneData, ) from plugwise.data import SmileData from plugwise.exceptions import ConnectionFailedError, DataMissingError, PlugwiseError @@ -126,8 +125,8 @@ def get_all_devices(self) -> None: async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceData] = {} - self.zone_data: dict[str, ZoneData] = {} + self.gw_devices: dict[str, DeviceZoneData] = {} + self.zone_data: dict[str, DeviceZoneData] = {} try: await self.full_update_device() self.get_all_devices() diff --git a/plugwise/util.py b/plugwise/util.py index 16e0b532b..d14983160 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -22,12 +22,11 @@ TEMP_CELSIUS, UOM, BinarySensorType, - DeviceData, + DeviceZoneData, ModelData, SensorType, SpecialType, SwitchType, - ZoneData, ) from defusedxml import ElementTree as etree @@ -123,7 +122,7 @@ def common_match_cases( measurement: str, attrs: DATA | UOM, location: etree, - data: DeviceData | ZoneData, + data: DeviceZoneData, ) -> None: """Helper-function for common match-case execution.""" value = location.text in ("on", "true") @@ -203,7 +202,7 @@ def power_data_local_format( return format_measure(val, attrs_uom) -def remove_empty_platform_dicts(data: DeviceData) -> None: +def remove_empty_platform_dicts(data: DeviceZoneData) -> None: """Helper-function for removing any empty platform dicts.""" if not data["binary_sensors"]: data.pop("binary_sensors") From 690a29fc031a0965e263e1979bd74a476b41c28f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 08:24:54 +0100 Subject: [PATCH 031/106] Save updated --- fixtures/adam_plus_anna_new/all_data.json | 28 +++++++++++------------ fixtures/m_adam_cooling/all_data.json | 28 +++++++++++------------ fixtures/m_adam_heating/all_data.json | 28 +++++++++++------------ tests/data/adam/adam_plus_anna_new.json | 4 ++-- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 75519525c..74f455271 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -248,12 +248,6 @@ "climate_mode": "auto", "control_state": "heating", "dev_class": "climate", - "members": { - "primary": [ - "ad4838d7d35c4d6ea796ee12ae5aedf8" - ], - "secondary": [] - }, "name": "Living room", "preset_modes": [ "no_frost", @@ -273,6 +267,12 @@ "resolution": 0.01, "setpoint": 18.5, "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] } }, "f871b8c4d63549319221e294e4f88074": { @@ -287,14 +287,6 @@ "climate_mode": "auto", "control_state": "preheating", "dev_class": "climate", - "members": { - "primary": [ - "e2f4322d57924fa090fbbc48b3a140dc" - ], - "secondary": [ - "1772a4ea304041adb83f357b751341ff" - ] - }, "name": "Bathroom", "preset_modes": [ "no_frost", @@ -314,6 +306,14 @@ "resolution": 0.01, "setpoint": 18.0, "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] } } } diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index f7003b051..66b32ed94 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -162,12 +162,6 @@ "climate_mode": "auto", "control_state": "heating", "dev_class": "climate", - "members": { - "primary": [ - "ad4838d7d35c4d6ea796ee12ae5aedf8" - ], - "secondary": [] - }, "name": "Living room", "preset_modes": [ "no_frost", @@ -187,6 +181,12 @@ "resolution": 0.01, "setpoint": 23.5, "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] } }, "f871b8c4d63549319221e294e4f88074": { @@ -201,14 +201,6 @@ "climate_mode": "auto", "control_state": "preheating", "dev_class": "climate", - "members": { - "primary": [ - "e2f4322d57924fa090fbbc48b3a140dc" - ], - "secondary": [ - "1772a4ea304041adb83f357b751341ff" - ] - }, "name": "Bathroom", "preset_modes": [ "no_frost", @@ -228,6 +220,14 @@ "resolution": 0.01, "setpoint": 25.0, "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] } } } diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index aabc7d654..687076161 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -167,12 +167,6 @@ "climate_mode": "auto", "control_state": "heating", "dev_class": "climate", - "members": { - "primary": [ - "ad4838d7d35c4d6ea796ee12ae5aedf8" - ], - "secondary": [] - }, "name": "Living room", "preset_modes": [ "no_frost", @@ -192,6 +186,12 @@ "resolution": 0.01, "setpoint": 20.0, "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] } }, "f871b8c4d63549319221e294e4f88074": { @@ -206,14 +206,6 @@ "climate_mode": "auto", "control_state": "preheating", "dev_class": "climate", - "members": { - "primary": [ - "e2f4322d57924fa090fbbc48b3a140dc" - ], - "secondary": [ - "1772a4ea304041adb83f357b751341ff" - ] - }, "name": "Bathroom", "preset_modes": [ "no_frost", @@ -233,6 +225,14 @@ "resolution": 0.01, "setpoint": 15.0, "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] } } } diff --git a/tests/data/adam/adam_plus_anna_new.json b/tests/data/adam/adam_plus_anna_new.json index 3d891c503..5e874c623 100644 --- a/tests/data/adam/adam_plus_anna_new.json +++ b/tests/data/adam/adam_plus_anna_new.json @@ -248,7 +248,7 @@ "climate_mode": "auto", "control_state": "heating", "dev_class": "climate", - "members": { + "thermostats": { "primary": [ "ad4838d7d35c4d6ea796ee12ae5aedf8" ], @@ -287,7 +287,7 @@ "climate_mode": "auto", "control_state": "preheating", "dev_class": "climate", - "members": { + "thermostats": { "primary": [ "e2f4322d57924fa090fbbc48b3a140dc" ], From 61b36142b5b7786bf601f77036561c52dc3fb039 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 08:30:08 +0100 Subject: [PATCH 032/106] Remapped TRY302 to TRY203 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b3cc31547..104fd9ada 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -278,7 +278,7 @@ lint.select = [ "TID251", # Banned imports "TRY004", # Prefer TypeError exception for invalid type # "TRY200", # TRY200 has been remapped to B904 - "TRY302", # Remove exception handler; error is immediately re-raised + "TRY203", # Remove exception handler; error is immediately re-raised "UP", # pyupgrade "W", # pycodestyle ] From 0db9025e63124dc5d8e57a73404c67eb79a62446 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 09:12:33 +0100 Subject: [PATCH 033/106] Set asyncio_default_fixture_loop_scope --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 104fd9ada..6c9086030 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -169,6 +169,7 @@ overgeneral-exceptions = [ ] [tool.pytest.ini_options] +asyncio_default_fixture_loop_scope = "function" asyncio_mode = "strict" markers = [ # mark a test as a asynchronous io test. From d0f199a1289a640d907783fa0deee4205fc1e6e5 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 12:38:59 +0100 Subject: [PATCH 034/106] Improve --- plugwise/__init__.py | 2 +- plugwise/legacy/smile.py | 2 +- plugwise/smile.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index e17d0ecab..900ae4964 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -308,7 +308,7 @@ def get_all_devices(self) -> None: async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" - data = PlugwiseData({}, {}, {}) + data = PlugwiseData(devices={}, gateway={}, zones={}) try: data = await self._smile_api.async_update() self.gateway_id = data.gateway["gateway_id"] diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index d335391fe..e725f32b0 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -136,8 +136,8 @@ async def async_update(self) -> PlugwiseData: self._previous_day_number = day_number return PlugwiseData( - gateway=self.gw_data, devices=self.gw_devices, + gateway=self.gw_data, zones=self.zone_data, ) diff --git a/plugwise/smile.py b/plugwise/smile.py index 4a9862107..a47ae9d70 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -141,8 +141,8 @@ async def async_update(self) -> PlugwiseData: raise DataMissingError("No Plugwise data received") from err return PlugwiseData( - gateway=self.gw_data, devices=self.gw_devices, + gateway=self.gw_data, zones=self.zone_data, ) From 2a8b9824fcd54b3bfbfc8b85bf028ddb733ed6ee Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 15:34:05 +0100 Subject: [PATCH 035/106] More manual-fixture changes --- scripts/manual_fixtures.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 459696a22..43bd4af52 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -81,13 +81,13 @@ def json_writer(manual_name: str, all_data: dict) -> None: # Add new key available m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["available"] = True -m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"][ +m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ "select_schedule" ] = "off" -m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"][ +m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ "control_state" ] = "cooling" -m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["climate_mode"] = "cool" +m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" # (following diff, now 2954 is removed) # Remove device "29542b2b6a6a4169acecc15c72a599b8" from anywhere @@ -167,11 +167,11 @@ def json_writer(manual_name: str, all_data: dict) -> None: "setpoint" ] = 20.0 -m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"][ +m_adam_heating["zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ "control_state" ] = "preheating" -m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["climate_mode"] = "heat" +m_adam_heating["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" # Back at ad48 m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ From 79e5f5761d569aee8a18e76859b9f41505635a62 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 19:33:45 +0100 Subject: [PATCH 036/106] Rework to combined dev_zones dict --- plugwise/__init__.py | 4 +- plugwise/common.py | 18 ++++----- plugwise/constants.py | 3 +- plugwise/data.py | 86 ++++++++++++++++++++++--------------------- plugwise/helper.py | 30 +++++++-------- plugwise/smile.py | 15 ++++---- tests/test_init.py | 38 ++++++++----------- 7 files changed, 93 insertions(+), 101 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 900ae4964..8f6cfc3d5 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -302,13 +302,13 @@ async def full_update_device(self) -> None: """Helper-function used for testing.""" await self._smile_api.full_update_device() - def get_all_devices(self) -> None: + def get_all_device_zones(self) -> None: """Helper-function used for testing.""" self._smile_api.get_all_devices() async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" - data = PlugwiseData(devices={}, gateway={}, zones={}) + data = PlugwiseData(device_zones={}, gateway={}) try: data = await self._smile_api.async_update() self.gateway_id = data.gateway["gateway_id"] diff --git a/plugwise/common.py b/plugwise/common.py index b068c9317..d00d1f888 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -40,7 +40,7 @@ def __init__(self) -> None: self._heater_id: str self._on_off_device: bool self._opentherm_device: bool - self.gw_devices: dict[str, DeviceZoneData] + self.gw_device_zones: dict[str, DeviceZoneData] self.smile_name: str self.smile_type: str @@ -186,9 +186,9 @@ def _power_data_energy_diff( return direct_data - def _create_gw_devices(self, appl: Munch) -> None: - """Helper-function for creating/updating gw_devices.""" - self.gw_devices[appl.dev_id] = {"dev_class": appl.pwclass} + def _create_gw_device_zones(self, appl: Munch) -> None: + """Helper-function for creating/updating gw_device_zones.""" + self.gw_device_zones[appl.dev_id] = {"dev_class": appl.pwclass} self._count += 1 for key, value in { "available": appl.available, @@ -204,26 +204,26 @@ def _create_gw_devices(self, appl: Munch) -> None: }.items(): if value is not None or key == "location": appl_key = cast(ApplianceType, key) - self.gw_devices[appl.dev_id][appl_key] = value + self.gw_device_zones[appl.dev_id][appl_key] = value self._count += 1 def _device_data_switching_group( self, device: DeviceZoneData, data: DeviceZoneData ) -> None: - """Helper-function for _get_device_data(). + """Helper-function for _get_device_zone_data(). Determine switching group device data. """ if device["dev_class"] in SWITCH_GROUP_TYPES: counter = 0 for member in device["members"]: - if self.gw_devices[member]["switches"].get("relay"): + if self.gw_device_zones[member]["switches"].get("relay"): counter += 1 data["switches"]["relay"] = counter != 0 self._count += 1 def _get_group_switches(self) -> dict[str, DeviceZoneData]: - """Helper-function for smile.py: get_all_devices(). + """Helper-function for smile.py: get_all_device_zones(). Collect switching- or pump-group info. """ @@ -240,7 +240,7 @@ def _get_group_switches(self) -> dict[str, DeviceZoneData]: group_appliances = group.findall("appliances/appliance") for item in group_appliances: # Check if members are not orphaned - stretch - if item.attrib["id"] in self.gw_devices: + if item.attrib["id"] in self.gw_device_zones: members.append(item.attrib["id"]) if group_type in SWITCH_GROUP_TYPES and members: diff --git a/plugwise/constants.py b/plugwise/constants.py index 0449e9985..ccc192935 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -583,5 +583,4 @@ class PlugwiseData: """Plugwise data provided as output.""" gateway: GatewayData - devices: dict[str, DeviceZoneData] - zones: dict[str, DeviceZoneData] + device_zones: dict[str, DeviceZoneData] diff --git a/plugwise/data.py b/plugwise/data.py index 6ffa4e437..83084823e 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -28,14 +28,16 @@ def __init__(self) -> None: SmileHelper.__init__(self) - def _all_device_data(self) -> None: - """Helper-function for get_all_devices(). + def _all_device_zone_data(self) -> None: + """Helper-function for get_all_device_zones(). - Collect data for each device and add to self.gw_data and self.gw_devices. + Collect data for each device/zone and add to self.gw_data and self.gw_device_zones. """ - self._update_gw_devices() + self._update_gw_device_zones() if self.smile(ADAM): self._update_zones() + self.gw_device_zones.update(self.zone_data) + self.gw_data.update( { "gateway_id": self.gateway_id, @@ -51,7 +53,7 @@ def _all_device_data(self) -> None: ) def _update_zones(self) -> None: - """Helper-function for _all_device_data() and async_update(). + """Helper-function for _all_device_zone_data() and async_update(). Collect data for each zone/location and add to self.zone_data. """ @@ -59,31 +61,31 @@ def _update_zones(self) -> None: data = self._get_location_data(location_id) zone.update(data) - def _update_gw_devices(self) -> None: - """Helper-function for _all_device_data() and async_update(). + def _update_gw_device_zones(self) -> None: + """Helper-function for _all_device_zone_data() and async_update(). - Collect data for each device and add to self.gw_devices. + Collect data for each device and add to self.gw_device_zones. """ mac_list: list[str] = [] - for device_id, device in self.gw_devices.items(): - data = self._get_device_data(device_id) - if device_id == self.gateway_id: + for devzone_id, devzone in self.gw_device_zones.items(): + data = self._get_device_zone_data(devzone_id) + if devzone_id == self.gateway_id: mac_list = self._detect_low_batteries() - self._add_or_update_notifications(device_id, device, data) + self._add_or_update_notifications(devzone_id, devzone, data) - device.update(data) + devzone.update(data) is_battery_low = ( mac_list - and "low_battery" in device["binary_sensors"] - and device["zigbee_mac_address"] in mac_list - and device["dev_class"] in ("thermo_sensor", "thermostatic_radiator_valve", "zone_thermometer", "zone_thermostat") + and "low_battery" in devzone["binary_sensors"] + and devzone["zigbee_mac_address"] in mac_list + and devzone["dev_class"] in ("thermo_sensor", "thermostatic_radiator_valve", "zone_thermometer", "zone_thermostat") ) if is_battery_low: - device["binary_sensors"]["low_battery"] = True + devzone["binary_sensors"]["low_battery"] = True - self._update_for_cooling(device) + self._update_for_cooling(devzone) - remove_empty_platform_dicts(device) + remove_empty_platform_dicts(devzone) def _detect_low_batteries(self) -> list[str]: """Helper-function updating the low-battery binary_sensor status from a Battery-is-low message.""" @@ -107,31 +109,31 @@ def _detect_low_batteries(self) -> list[str]: return mac_address_list def _add_or_update_notifications( - self, device_id: str, device: DeviceZoneData, data: DeviceZoneData + self, devzone_id: str, devzone: DeviceZoneData, data: DeviceZoneData ) -> None: """Helper-function adding or updating the Plugwise notifications.""" if ( - device_id == self.gateway_id + devzone_id == self.gateway_id and ( self._is_thermostat or self.smile_type == "power" ) ) or ( - "binary_sensors" in device - and "plugwise_notification" in device["binary_sensors"] + "binary_sensors" in devzone + and "plugwise_notification" in devzone["binary_sensors"] ): data["binary_sensors"]["plugwise_notification"] = bool(self._notifications) self._count += 1 - def _update_for_cooling(self, device: DeviceZoneData) -> None: + def _update_for_cooling(self, devzone: DeviceZoneData) -> None: """Helper-function for adding/updating various cooling-related values.""" # For Anna and heating + cooling, replace setpoint with setpoint_high/_low if ( self.smile(ANNA) and self._cooling_present - and device["dev_class"] == "thermostat" + and devzone["dev_class"] == "thermostat" ): - thermostat = device["thermostat"] - sensors = device["sensors"] + thermostat = devzone["thermostat"] + sensors = devzone["sensors"] temp_dict: ActuatorData = { "setpoint_low": thermostat["setpoint"], "setpoint_high": MAX_SETPOINT, @@ -143,7 +145,7 @@ def _update_for_cooling(self, device: DeviceZoneData) -> None: } thermostat.pop("setpoint") temp_dict.update(thermostat) - device["thermostat"] = temp_dict + devzone["thermostat"] = temp_dict if "setpoint" in sensors: sensors.pop("setpoint") sensors["setpoint_low"] = temp_dict["setpoint_low"] @@ -152,7 +154,7 @@ def _update_for_cooling(self, device: DeviceZoneData) -> None: def _get_location_data(self, loc_id: str) -> DeviceZoneData: - """Helper-function for _all_device_data() and async_update(). + """Helper-function for _all_device_zone_data() and async_update(). Provide device-data, based on Location ID (= loc_id). """ @@ -163,16 +165,16 @@ def _get_location_data(self, loc_id: str) -> DeviceZoneData: self._count += 1 # Thermostat data (presets, temperatures etc) - self._device_data_climate(loc_id, zone, data) + self._devzone_data_climate(loc_id, zone, data) return data - def _get_device_data(self, dev_id: str) -> DeviceZoneData: + def _get_device_zone_data(self, dev_id: str) -> DeviceZoneData: """Helper-function for _update_gw_devices() and async_update(). - Provide device-data, based on appliance_id ()= dev_id). + Provide device-data, based on appliance_id (= dev_id). """ - device = self.gw_devices[dev_id] + device = self.gw_device_zones[dev_id] data = self._get_measurement_data(dev_id) # Check availability of wired-connected devices @@ -193,14 +195,14 @@ def _get_device_data(self, dev_id: str) -> DeviceZoneData: # Thermostat data for Anna (presets, temperatures etc) if self.smile(ANNA) and device["dev_class"] == "thermostat": - self._device_data_climate(dev_id, device, data) + self._devzone_data_climate(dev_id, device, data) return data def _check_availability( self, device: DeviceZoneData, dev_class: str, data: DeviceZoneData, message: str ) -> None: - """Helper-function for _get_device_data(). + """Helper-function for _get_device_zone_data(). Provide availability status for the wired-commected devices. """ @@ -213,7 +215,7 @@ def _check_availability( data["available"] = False def _device_data_adam(self, device: DeviceZoneData, data: DeviceZoneData) -> None: - """Helper-function for _get_device_data(). + """Helper-function for _get_device_zone_data(). Determine Adam heating-status for on-off heating via valves, available regulations_modes and thermostat control_states. @@ -237,19 +239,19 @@ def _device_data_adam(self, device: DeviceZoneData, data: DeviceZoneData) -> Non self._count += 1 - def _device_data_climate( + def _devzone_data_climate( self, location_id: str, - device: DeviceZoneData, + devzone: DeviceZoneData, data: DeviceZoneData ) -> None: - """Helper-function for _get_device_data(). + """Helper-function for _get_device_zone_data(). Determine climate-control device data. """ loc_id = location_id - if device.get("location") is not None: - loc_id = device["location"] + if devzone.get("location") is not None: + loc_id = devzone["location"] # Presets data["preset_modes"] = None @@ -284,7 +286,7 @@ def _device_data_climate( def check_reg_mode(self, mode: str) -> bool: """Helper-function for device_data_climate().""" - gateway = self.gw_devices[self.gateway_id] + gateway = self.gw_device_zones[self.gateway_id] return ( "regulation_modes" in gateway and gateway["select_regulation_mode"] == mode ) diff --git a/plugwise/helper.py b/plugwise/helper.py index 3e1b580e1..641bf1d3b 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -250,7 +250,7 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceZoneData] = {} + self.gw_device_zones: dict[str, DeviceZoneData] = {} self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None @@ -322,13 +322,13 @@ def _all_appliances(self) -> None: if appl.pwclass == "gateway" and self.smile_type == "power": appl.dev_id = appl.location - self._create_gw_devices(appl) + self._create_gw_device_zones(appl) # For P1 collect the connected SmartMeter info if self.smile_type == "power": self._p1_smartmeter_info_finder(appl) # P1: for gateway and smartmeter switch device_id - part 2 - for item in self.gw_devices: + for item in self.gw_device_zones: if item != self.gateway_id: self.gateway_id = item # Leave for-loop to avoid a 2nd device_id switch @@ -336,13 +336,13 @@ def _all_appliances(self) -> None: # Place the gateway and optional heater_central devices as 1st and 2nd for dev_class in ("heater_central", "gateway"): - for dev_id, device in dict(self.gw_devices).items(): + for dev_id, device in dict(self.gw_device_zones).items(): if device["dev_class"] == dev_class: tmp_device = device - self.gw_devices.pop(dev_id) - cleared_dict = self.gw_devices + self.gw_device_zones.pop(dev_id) + cleared_dict = self.gw_device_zones add_to_front = {dev_id: tmp_device} - self.gw_devices = {**add_to_front, **cleared_dict} + self.gw_device_zones = {**add_to_front, **cleared_dict} def _all_locations(self) -> None: """Collect all locations.""" @@ -378,7 +378,7 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: appl.vendor_name = module_data["vendor_name"] appl.zigbee_mac = None - self._create_gw_devices(appl) + self._create_gw_device_zones(appl) def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: """Collect info for all appliances found.""" @@ -483,7 +483,7 @@ def _get_appliances_with_offset_functionality(self) -> list[str]: return therm_list def _get_zone_data(self, loc_id: str) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_data(). + """Helper-function for smile.py: _get_device_zone_data(). Collect the location-data based on location id. """ @@ -499,13 +499,13 @@ def _get_zone_data(self, loc_id: str) -> DeviceZoneData: return data def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_data(). + """Helper-function for smile.py: _get_device_zone_data(). Collect the appliance-data based on device id. """ data: DeviceZoneData = {"binary_sensors": {}, "sensors": {}, "switches": {}} # Get P1 smartmeter data from LOCATIONS - device = self.gw_devices[dev_id] + device = self.gw_device_zones[dev_id] # !! DON'T CHANGE below two if-lines, will break stuff !! if self.smile_type == "power": if device["dev_class"] == "smartmeter": @@ -588,7 +588,7 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: return data def _power_data_from_location(self, loc_id: str) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_data(). + """Helper-function for smile.py: _get_device_zone_data(). Collect the power-data based on Location ID, from LOCATIONS. """ @@ -753,7 +753,7 @@ def _get_gateway_mode(self, appliance: etree, data: DeviceZoneData) -> None: self._count += 1 def _object_value(self, obj_id: str, measurement: str) -> float | int | None: - """Helper-function for smile.py: _get_device_data() and _device_data_anna(). + """Helper-function for smile.py: _get_device_zone_data() and _device_data_anna(). Obtain the value/state for the given object from a location in DOMAIN_OBJECTS """ @@ -831,7 +831,7 @@ def _scan_thermostats(self) -> None: } for loc_id in self._thermo_locs: - for dev_id, device in self.gw_devices.items(): + for dev_id, device in self.gw_device_zones.items(): self._rank_thermostat(thermo_matching, loc_id, dev_id, device) for loc_id, loc_data in list(self._thermo_locs.items()): @@ -854,7 +854,7 @@ def _match_locations(self) -> dict[str, ThermoLoc]: """ matched_locations: dict[str, ThermoLoc] = {} for location_id, location_details in self.loc_data.items(): - for appliance_details in self.gw_devices.values(): + for appliance_details in self.gw_device_zones.values(): if appliance_details["location"] == location_id: location_details.update( {"primary": [], "primary_prio": 0, "secondary": []} diff --git a/plugwise/smile.py b/plugwise/smile.py index a47ae9d70..5b5fc9b9a 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -99,7 +99,7 @@ async def full_update_device(self) -> None: self._domain_objects = await self.request(DOMAIN_OBJECTS) self._get_plugwise_notifications() - def get_all_devices(self) -> None: + def get_all_device_zones(self) -> None: """Determine the evices present from the obtained XML-data. Run this functions once to gather the initial device configuration, @@ -117,21 +117,21 @@ def get_all_devices(self) -> None: # Collect and add switching- and/or pump-group devices if group_data := self._get_group_switches(): - self.gw_devices.update(group_data) + self.gw_device_zones.update(group_data) # Collect the remaining data for all devices - self._all_device_data() + self._all_device_zone_data() async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceZoneData] = {} + self.gw_device_zones: dict[str, DeviceZoneData] = {} self.zone_data: dict[str, DeviceZoneData] = {} try: await self.full_update_device() - self.get_all_devices() + self.get_all_device_zones() if "heater_id" in self.gw_data: - heat_cooler = self.gw_devices[self.gw_data["heater_id"]] + heat_cooler = self.gw_device_zones[self.gw_data["heater_id"]] if ( "binary_sensors" in heat_cooler and "cooling_enabled" in heat_cooler["binary_sensors"] @@ -141,9 +141,8 @@ async def async_update(self) -> PlugwiseData: raise DataMissingError("No Plugwise data received") from err return PlugwiseData( - devices=self.gw_devices, + device_zones=self.gw_device_zones, gateway=self.gw_data, - zones=self.zone_data, ) ######################################################################################################## diff --git a/tests/test_init.py b/tests/test_init.py index 5ae05e0e9..63e2105f1 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -516,24 +516,24 @@ async def disconnect(cls, server, client): await server.close() @staticmethod - def show_setup(location_list, device_list): + def show_setup(location_list, device_zone_list): """Show informative outline of the setup.""" _LOGGER.info("This environment looks like:") for loc_id, loc_info in location_list.items(): _LOGGER.info( " --> Location: %s", "{} ({})".format(loc_info["name"], loc_id) ) - device_count = 0 - for dev_id, dev_info in device_list.items(): - if dev_info.get("location", "not_found") == loc_id: - device_count += 1 + devzone_count = 0 + for devzone_id, devzone_info in device_zone_list.items(): + if devzone_info.get("location", "not_found") == loc_id: + devzone_count += 1 _LOGGER.info( - " + Device: %s", + " + Device_Zone: %s", "{} ({} - {})".format( - dev_info["name"], dev_info["dev_class"], dev_id + devzone_info["name"], devzone_info["dev_class"], devzone_id ), ) - if device_count == 0: # pragma: no cover + if devzone_count == 0: # pragma: no cover _LOGGER.info(" ! no devices found in this location") @pytest.mark.asyncio @@ -602,7 +602,7 @@ def test_and_assert(test_dict, data, header): _LOGGER.info("Asserting testdata:") if smile.smile_legacy: await smile.full_update_device() - smile.get_all_devices() + smile.get_all_device_zones() data = await smile.async_update() assert smile._timeout == 30 else: @@ -622,42 +622,34 @@ def test_and_assert(test_dict, data, header): self._cooling_active = False self._cooling_enabled = False if "heater_id" in data.gateway: - heat_cooler = data.devices[data.gateway["heater_id"]] + heat_cooler = data.device_zones[data.gateway["heater_id"]] if "binary_sensors" in heat_cooler: if "cooling_enabled" in heat_cooler["binary_sensors"]: self._cooling_enabled = heat_cooler["binary_sensors"]["cooling_enabled"] if "cooling_state" in heat_cooler["binary_sensors"]: self._cooling_active = heat_cooler["binary_sensors"]["cooling_state"] - self._write_json("all_data", {"gateway": data.gateway, "devices": data.devices, "zones": data.zones}) + self._write_json("all_data", {"device_zones": data.device_zones, "gateway": data.gateway}) if "FIXTURES" in os.environ: _LOGGER.info("Skipping tests: Requested fixtures only") # pragma: no cover return # pragma: no cover - self.device_list = list(data.devices.keys()) + self.device_list = list(data.device_zones.keys()) location_list = smile.loc_data _LOGGER.info("Gateway id = %s", data.gateway["gateway_id"]) _LOGGER.info("Hostname = %s", smile.smile_hostname) _LOGGER.info("Gateway data = %s", data.gateway) - _LOGGER.info("Zone data = %s", data.zones) - _LOGGER.info("Device list = %s", data.devices) - self.show_setup(location_list, data.devices) + _LOGGER.info("Device_zone list = %s", data.device_zones) + self.show_setup(location_list, data.device_zones) if skip_testing: return # Perform tests and asserts in two steps: devices and zones for header, data_dict in testdata.items(): - # Test devices - if header == "devices": - test_and_assert(data_dict, data.devices, header) - - for header, data_dict in testdata.items(): - # Test zones - if header == "zones": - test_and_assert(data_dict, data.zones, header) + test_and_assert(data_dict, data.device_zones, header) # pragma warning restore S3776 From b1bb60540143a1dbc32e0d59fef6d3e5994343e5 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 20:00:57 +0100 Subject: [PATCH 037/106] Save updated fixture --- fixtures/adam_plus_anna_new/all_data.json | 24 +++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 74f455271..589ba8ae8 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { @@ -224,18 +224,7 @@ "switches": { "relay": true } - } - }, - "gateway": { - "cooling_present": false, - "gateway_id": "da224107914542988a88561b4452b0f6", - "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 173, - "notifications": {}, - "reboot": true, - "smile_name": "Adam" - }, - "zones": { + }, "f2bf9048bef64cc5b6d5110154e33c81": { "active_preset": "home", "available_schedules": [ @@ -316,5 +305,14 @@ ] } } + }, + "gateway": { + "cooling_present": false, + "gateway_id": "da224107914542988a88561b4452b0f6", + "heater_id": "056ee145a816487eaa69243c3280f8bf", + "item_count": 173, + "notifications": {}, + "reboot": true, + "smile_name": "Adam" } } From 847e49234597e262999026766c3135b1080729d9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 20:03:39 +0100 Subject: [PATCH 038/106] And generate related test-json --- tests/data/adam/adam_plus_anna_new.json | 43 +++++++++---------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/tests/data/adam/adam_plus_anna_new.json b/tests/data/adam/adam_plus_anna_new.json index 5e874c623..d67cf5763 100644 --- a/tests/data/adam/adam_plus_anna_new.json +++ b/tests/data/adam/adam_plus_anna_new.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { @@ -224,18 +224,7 @@ "switches": { "relay": true } - } - }, - "gateway": { - "cooling_present": false, - "gateway_id": "da224107914542988a88561b4452b0f6", - "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 152, - "notifications": {}, - "reboot": true, - "smile_name": "Adam" - }, - "zones": { + }, "f2bf9048bef64cc5b6d5110154e33c81": { "active_preset": "home", "available_schedules": [ @@ -248,12 +237,6 @@ "climate_mode": "auto", "control_state": "heating", "dev_class": "climate", - "thermostats": { - "primary": [ - "ad4838d7d35c4d6ea796ee12ae5aedf8" - ], - "secondary": [] - }, "name": "Living room", "preset_modes": [ "no_frost", @@ -273,6 +256,12 @@ "resolution": 0.01, "setpoint": 18.5, "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ad4838d7d35c4d6ea796ee12ae5aedf8" + ], + "secondary": [] } }, "f871b8c4d63549319221e294e4f88074": { @@ -287,14 +276,6 @@ "climate_mode": "auto", "control_state": "preheating", "dev_class": "climate", - "thermostats": { - "primary": [ - "e2f4322d57924fa090fbbc48b3a140dc" - ], - "secondary": [ - "1772a4ea304041adb83f357b751341ff" - ] - }, "name": "Bathroom", "preset_modes": [ "no_frost", @@ -314,6 +295,14 @@ "resolution": 0.01, "setpoint": 18.0, "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "e2f4322d57924fa090fbbc48b3a140dc" + ], + "secondary": [ + "1772a4ea304041adb83f357b751341ff" + ] } } } From 09cbd8d1d37cfff71cf2ae602e9e81d1482704db Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 Nov 2024 20:05:52 +0100 Subject: [PATCH 039/106] Save updated fixture and test-jsons --- fixtures/anna_v4/all_data.json | 5 +- .../adam/adam_plus_anna_new_UPDATED_DATA.json | 84 +++++++++-------- tests/data/anna/anna_v4.json | 14 +-- tests/data/anna/anna_v4_UPDATED_DATA.json | 94 ++++++++++--------- tests/test_adam.py | 2 + 5 files changed, 97 insertions(+), 102 deletions(-) diff --git a/fixtures/anna_v4/all_data.json b/fixtures/anna_v4/all_data.json index d07563397..0e3d52eba 100644 --- a/fixtures/anna_v4/all_data.json +++ b/fixtures/anna_v4/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ @@ -103,6 +103,5 @@ "notifications": {}, "reboot": true, "smile_name": "Smile Anna" - }, - "zones": {} + } } diff --git a/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json index 65bbf87d9..3748bb59c 100644 --- a/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json +++ b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json @@ -1,45 +1,47 @@ { - "67d73d0bd469422db25a618a5fb8eeb0": { - "switches": { - "lock": true - } - }, - "29542b2b6a6a4169acecc15c72a599b8": { - "switches": { - "relay": false, - "lock": false - } - }, - "2568cc4b9c1e401495d4741a5f89bee1": { - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0 + "device_zones": { + "67d73d0bd469422db25a618a5fb8eeb0": { + "switches": { + "lock": true + } }, - "switches": { - "relay": false, - "lock": false - } - }, - "1772a4ea304041adb83f357b751341ff": { - "available": false - }, - "e2f4322d57924fa090fbbc48b3a140dc": { - "binary_sensors": { - "low_battery": true - } - }, - "da224107914542988a88561b4452b0f6": { - "binary_sensors": { - "plugwise_notification": true - } - }, - "e8ef2a01ed3b4139a53bf749204fe6b4": { - "members": [ - "2568cc4b9c1e401495d4741a5f89bee1", - "29542b2b6a6a4169acecc15c72a599b8" - ], - "switches": { - "relay": false + "29542b2b6a6a4169acecc15c72a599b8": { + "switches": { + "relay": false, + "lock": false + } + }, + "2568cc4b9c1e401495d4741a5f89bee1": { + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0 + }, + "switches": { + "relay": false, + "lock": false + } + }, + "1772a4ea304041adb83f357b751341ff": { + "available": false + }, + "e2f4322d57924fa090fbbc48b3a140dc": { + "binary_sensors": { + "low_battery": true + } + }, + "da224107914542988a88561b4452b0f6": { + "binary_sensors": { + "plugwise_notification": true + } + }, + "e8ef2a01ed3b4139a53bf749204fe6b4": { + "members": [ + "2568cc4b9c1e401495d4741a5f89bee1", + "29542b2b6a6a4169acecc15c72a599b8" + ], + "switches": { + "relay": false + } } - } + } } diff --git a/tests/data/anna/anna_v4.json b/tests/data/anna/anna_v4.json index d07563397..581ef2ff0 100644 --- a/tests/data/anna/anna_v4.json +++ b/tests/data/anna/anna_v4.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ @@ -94,15 +94,5 @@ }, "vendor": "Bosch Thermotechniek B.V." } - }, - "gateway": { - "cooling_present": false, - "gateway_id": "0466eae8520144c78afb29628384edeb", - "heater_id": "cd0e6156b1f04d5f952349ffbe397481", - "item_count": 58, - "notifications": {}, - "reboot": true, - "smile_name": "Smile Anna" - }, - "zones": {} + } } diff --git a/tests/data/anna/anna_v4_UPDATED_DATA.json b/tests/data/anna/anna_v4_UPDATED_DATA.json index a80745221..17c2899bf 100644 --- a/tests/data/anna/anna_v4_UPDATED_DATA.json +++ b/tests/data/anna/anna_v4_UPDATED_DATA.json @@ -1,52 +1,54 @@ { - "cd0e6156b1f04d5f952349ffbe397481": { - "maximum_boiler_temperature": { - "setpoint": 69.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1.0 + "device_zones": { + "cd0e6156b1f04d5f952349ffbe397481": { + "maximum_boiler_temperature": { + "setpoint": 69.0, + "lower_bound": 0.0, + "upper_bound": 100.0, + "resolution": 1.0 + }, + "max_dhw_temperature": { + "setpoint": 59.0, + "lower_bound": 30.0, + "upper_bound": 60.0, + "resolution": 0.01 + }, + "binary_sensors": { + "dhw_state": false, + "heating_state": false, + "flame_state": false + }, + "sensors": { + "water_temperature": 51.0, + "intended_boiler_temperature": 0.0, + "modulation_level": 0, + "return_temperature": 41.0, + "water_pressure": 2.1 + }, + "switches": { + "dhw_cm_switch": true + } }, - "max_dhw_temperature": { - "setpoint": 59.0, - "lower_bound": 30.0, - "upper_bound": 60.0, - "resolution": 0.01 + "01b85360fdd243d0aaad4d6ac2a5ba7e": { + "thermostat": { + "setpoint": 19.5, + "lower_bound": 4.0, + "upper_bound": 30.0, + "resolution": 0.1 + }, + "active_preset": "away", + "select_schedule": "Standaard", + "climate_mode": "auto", + "sensors": { + "temperature": 19.5, + "setpoint": 19.5, + "illuminance": 39.5 + } }, - "binary_sensors": { - "dhw_state": false, - "heating_state": false, - "flame_state": false - }, - "sensors": { - "water_temperature": 51.0, - "intended_boiler_temperature": 0.0, - "modulation_level": 0, - "return_temperature": 41.0, - "water_pressure": 2.1 - }, - "switches": { - "dhw_cm_switch": true - } - }, - "01b85360fdd243d0aaad4d6ac2a5ba7e": { - "thermostat": { - "setpoint": 19.5, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 - }, - "active_preset": "away", - "select_schedule": "Standaard", - "climate_mode": "auto", - "sensors": { - "temperature": 19.5, - "setpoint": 19.5, - "illuminance": 39.5 - } - }, - "0466eae8520144c78afb29628384edeb": { - "sensors": { - "outdoor_temperature": 6.44 + "0466eae8520144c78afb29628384edeb": { + "sensors": { + "outdoor_temperature": 6.44 + } } } } diff --git a/tests/test_adam.py b/tests/test_adam.py index 3f686dc2d..6a38bfdfc 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -49,6 +49,8 @@ async def test_connect_adam_plus_anna_new(self): "854f8a9b0e7e425db97f1f110e1ce4b3", "2568cc4b9c1e401495d4741a5f89bee1", "e8ef2a01ed3b4139a53bf749204fe6b4", + "f2bf9048bef64cc5b6d5110154e33c81", + "f871b8c4d63549319221e294e4f88074", ] result = await self.tinker_thermostat( From 78adcab1bf56032283f1fd8feb32e8a6a8532b7f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 17:28:52 +0100 Subject: [PATCH 040/106] Fix legacy --- plugwise/legacy/data.py | 8 ++++---- plugwise/legacy/helper.py | 20 ++++++++++---------- plugwise/legacy/smile.py | 8 +++----- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/plugwise/legacy/data.py b/plugwise/legacy/data.py index 52d877fd5..896ea85ff 100644 --- a/plugwise/legacy/data.py +++ b/plugwise/legacy/data.py @@ -21,7 +21,7 @@ def __init__(self) -> None: def _all_device_data(self) -> None: """Helper-function for get_all_devices(). - Collect data for each device and add to self.gw_data and self.gw_devices. + Collect data for each device and add to self.gw_data and self.gw_device_zones. """ self._update_gw_devices() self.gw_data.update( @@ -39,9 +39,9 @@ def _all_device_data(self) -> None: def _update_gw_devices(self) -> None: """Helper-function for _all_device_data() and async_update(). - Collect data for each device and add to self.gw_devices. + Collect data for each device and add to self.gw_device_zones. """ - for device_id, device in self.gw_devices.items(): + for device_id, device in self.gw_device_zones.items(): data = self._get_device_data(device_id) device.update(data) remove_empty_platform_dicts(device) @@ -51,7 +51,7 @@ def _get_device_data(self, dev_id: str) -> DeviceZoneData: Provide device-data, based on Location ID (= dev_id), from APPLIANCES. """ - device = self.gw_devices[dev_id] + device = self.gw_device_zones[dev_id] data = self._get_measurement_data(dev_id) # Switching groups data diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 2ab76d269..42c0e1eb1 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -80,7 +80,7 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceZoneData] = {} + self.gw_device_zones: dict[str, DeviceZoneData] = {} self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None @@ -143,17 +143,17 @@ def _all_appliances(self) -> None: if appl.pwclass == "heater_central" and appl.dev_id != self._heater_id: continue # pragma: no cover - self._create_gw_devices(appl) + self._create_gw_device_zones(appl) # Place the gateway and optional heater_central devices as 1st and 2nd for dev_class in ("heater_central", "gateway"): - for dev_id, device in dict(self.gw_devices).items(): + for dev_id, device in dict(self.gw_device_zones).items(): if device["dev_class"] == dev_class: tmp_device = device - self.gw_devices.pop(dev_id) - cleared_dict = self.gw_devices + self.gw_device_zones.pop(dev_id) + cleared_dict = self.gw_device_zones add_to_front = {dev_id: tmp_device} - self.gw_devices = {**add_to_front, **cleared_dict} + self.gw_device_zones = {**add_to_front, **cleared_dict} def _all_locations(self) -> None: """Collect all locations.""" @@ -194,7 +194,7 @@ def _create_legacy_gateway(self) -> None: if self.smile_type == "power": self.gateway_id = FAKE_APPL - self.gw_devices[self.gateway_id] = {"dev_class": "gateway"} + self.gw_device_zones[self.gateway_id] = {"dev_class": "gateway"} self._count += 1 for key, value in { "firmware": str(self.smile_fw_version), @@ -207,7 +207,7 @@ def _create_legacy_gateway(self) -> None: }.items(): if value is not None: gw_key = cast(ApplianceType, key) - self.gw_devices[self.gateway_id][gw_key] = value + self.gw_device_zones[self.gateway_id][gw_key] = value self._count += 1 def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch: @@ -265,7 +265,7 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: location = self._locations.find(f'./location[@id="{loc_id}"]') appl = self._energy_device_info_finder(location, appl) - self._create_gw_devices(appl) + self._create_gw_device_zones(appl) def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: """Helper-function for smile.py: _get_device_data(). @@ -274,7 +274,7 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: """ data: DeviceZoneData = {"binary_sensors": {}, "sensors": {}, "switches": {}} # Get P1 smartmeter data from LOCATIONS or MODULES - device = self.gw_devices[dev_id] + device = self.gw_device_zones[dev_id] # !! DON'T CHANGE below two if-lines, will break stuff !! if self.smile_type == "power": if device["dev_class"] == "smartmeter": diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index e725f32b0..3c97e9f2e 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -102,7 +102,7 @@ def get_all_devices(self) -> None: # Collect and add switching- and/or pump-group devices if group_data := self._get_group_switches(): - self.gw_devices.update(group_data) + self.gw_device_zones.update(group_data) # Collect the remaining data for all devices self._all_device_data() @@ -119,8 +119,7 @@ async def async_update(self) -> PlugwiseData: "Performing daily full-update, reload the Plugwise integration when a single entity becomes unavailable." ) self.gw_data: GatewayData = {} - self.gw_devices: dict[str, DeviceZoneData] = {} - self.zone_data: dict[str, DeviceZoneData] = {} + self.gw_device_zones: dict[str, DeviceZoneData] = {} await self.full_update_device() self.get_all_devices() # Otherwise perform an incremental update @@ -136,9 +135,8 @@ async def async_update(self) -> PlugwiseData: self._previous_day_number = day_number return PlugwiseData( - devices=self.gw_devices, + device_zones=self.gw_device_zones, gateway=self.gw_data, - zones=self.zone_data, ) ######################################################################################################## From 7994d615fe51b1ae9041db71eb4a711aceeba618 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 17:41:38 +0100 Subject: [PATCH 041/106] Save updated legacy fixtures and test-jsons --- fixtures/legacy_anna/all_data.json | 5 +- fixtures/smile_p1_v2/all_data.json | 5 +- fixtures/stretch_v31/all_data.json | 5 +- tests/data/anna/legacy_anna.json | 114 +++++++------ tests/data/p1/smile_p1_v2.json | 62 +++---- tests/data/stretch/stretch_v31.json | 252 ++++++++++++++-------------- 6 files changed, 226 insertions(+), 217 deletions(-) diff --git a/fixtures/legacy_anna/all_data.json b/fixtures/legacy_anna/all_data.json index 3adbdc056..fa20bd587 100644 --- a/fixtures/legacy_anna/all_data.json +++ b/fixtures/legacy_anna/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "1.8.22", @@ -70,6 +70,5 @@ "heater_id": "04e4cbfe7f4340f090f85ec3b9e6a950", "item_count": 41, "smile_name": "Smile Anna" - }, - "zones": {} + } } diff --git a/fixtures/smile_p1_v2/all_data.json b/fixtures/smile_p1_v2/all_data.json index 304624603..571df9cd3 100644 --- a/fixtures/smile_p1_v2/all_data.json +++ b/fixtures/smile_p1_v2/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "938696c4bcdb4b8a9a595cb38ed43913": { "dev_class": "smartmeter", "location": "938696c4bcdb4b8a9a595cb38ed43913", @@ -37,6 +37,5 @@ "gateway_id": "aaaa0000aaaa0000aaaa0000aaaa00aa", "item_count": 26, "smile_name": "Smile P1" - }, - "zones": {} + } } diff --git a/fixtures/stretch_v31/all_data.json b/fixtures/stretch_v31/all_data.json index 49b42fb3f..0af1473c7 100644 --- a/fixtures/stretch_v31/all_data.json +++ b/fixtures/stretch_v31/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "3.1.11", @@ -137,6 +137,5 @@ "gateway_id": "0000aaaa0000aaaa0000aaaa0000aa00", "item_count": 83, "smile_name": "Stretch" - }, - "zones": {} + } } diff --git a/tests/data/anna/legacy_anna.json b/tests/data/anna/legacy_anna.json index 8e0a058ed..a6454ec27 100644 --- a/tests/data/anna/legacy_anna.json +++ b/tests/data/anna/legacy_anna.json @@ -1,59 +1,67 @@ { - "0000aaaa0000aaaa0000aaaa0000aa00": { - "dev_class": "gateway", - "firmware": "1.8.22", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "mac_address": "01:23:45:67:89:AB", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise" - }, - "0d266432d64443e283b5d708ae98b455": { - "dev_class": "thermostat", - "firmware": "2017-03-13T11:54:58+01:00", - "hardware": "6539-1301-500", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 20.5, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "device_zones": { + "0000aaaa0000aaaa0000aaaa0000aa00": { + "dev_class": "gateway", + "firmware": "1.8.22", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "mac_address": "01:23:45:67:89:AB", + "model": "Gateway", + "name": "Smile Anna", + "vendor": "Plugwise" }, - "preset_modes": ["away", "vacation", "asleep", "home", "no_frost"], - "active_preset": "home", - "climate_mode": "heat", - "sensors": { - "temperature": 20.4, - "illuminance": 150.8, - "setpoint": 20.5 - } - }, - "04e4cbfe7f4340f090f85ec3b9e6a950": { - "dev_class": "heater_central", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Generic heater", - "name": "OpenTherm", - "vendor": "Bosch Thermotechniek B.V.", - "maximum_boiler_temperature": { - "setpoint": 50.0, - "lower_bound": 50.0, - "upper_bound": 90.0, - "resolution": 1.0 - }, - "binary_sensors": { - "flame_state": true, - "heating_state": true + "04e4cbfe7f4340f090f85ec3b9e6a950": { + "binary_sensors": { + "flame_state": true, + "heating_state": true + }, + "dev_class": "heater_central", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "maximum_boiler_temperature": { + "lower_bound": 50.0, + "resolution": 1.0, + "setpoint": 50.0, + "upper_bound": 90.0 + }, + "model": "Generic heater", + "name": "OpenTherm", + "sensors": { + "dhw_temperature": 51.2, + "intended_boiler_temperature": 17.0, + "modulation_level": 0.0, + "return_temperature": 21.7, + "water_pressure": 1.2, + "water_temperature": 23.6 + }, + "vendor": "Bosch Thermotechniek B.V." }, - "sensors": { - "water_temperature": 23.6, - "dhw_temperature": 51.2, - "intended_boiler_temperature": 17.0, - "modulation_level": 0, - "return_temperature": 21.7, - "water_pressure": 1.2 + "0d266432d64443e283b5d708ae98b455": { + "active_preset": "home", + "climate_mode": "heat", + "dev_class": "thermostat", + "firmware": "2017-03-13T11:54:58+01:00", + "hardware": "6539-1301-500", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "away", + "vacation", + "asleep", + "home", + "no_frost" + ], + "sensors": { + "illuminance": 150.8, + "setpoint": 20.5, + "temperature": 20.4 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 20.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" } } } diff --git a/tests/data/p1/smile_p1_v2.json b/tests/data/p1/smile_p1_v2.json index 298fcfc1c..10c129e47 100644 --- a/tests/data/p1/smile_p1_v2.json +++ b/tests/data/p1/smile_p1_v2.json @@ -1,34 +1,36 @@ { - "aaaa0000aaaa0000aaaa0000aaaa00aa": { - "dev_class": "gateway", - "firmware": "2.5.9", - "location": "938696c4bcdb4b8a9a595cb38ed43913", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Smile P1", - "vendor": "Plugwise" - }, - "938696c4bcdb4b8a9a595cb38ed43913": { - "dev_class": "smartmeter", - "location": "938696c4bcdb4b8a9a595cb38ed43913", - "model": "Ene5\\T210-DESMR5.0", - "name": "P1", - "vendor": "Ene5\\T210-DESMR5.0", - "sensors": { - "net_electricity_point": 458.0, - "electricity_consumed_point": 458.0, - "net_electricity_cumulative": 1019.201, - "electricity_consumed_peak_cumulative": 1155.195, - "electricity_consumed_off_peak_cumulative": 1642.74, - "electricity_consumed_peak_interval": 250.0, - "electricity_consumed_off_peak_interval": 0.0, - "electricity_produced_point": 0.0, - "electricity_produced_peak_cumulative": 1296.136, - "electricity_produced_off_peak_cumulative": 482.598, - "electricity_produced_peak_interval": 0.0, - "electricity_produced_off_peak_interval": 0.0, - "gas_consumed_cumulative": 584.433, - "gas_consumed_interval": 0.016 + "device_zones": { + "938696c4bcdb4b8a9a595cb38ed43913": { + "dev_class": "smartmeter", + "location": "938696c4bcdb4b8a9a595cb38ed43913", + "model": "Ene5\\T210-DESMR5.0", + "name": "P1", + "sensors": { + "electricity_consumed_off_peak_cumulative": 1642.74, + "electricity_consumed_off_peak_interval": 0, + "electricity_consumed_peak_cumulative": 1155.195, + "electricity_consumed_peak_interval": 250, + "electricity_consumed_point": 458, + "electricity_produced_off_peak_cumulative": 482.598, + "electricity_produced_off_peak_interval": 0, + "electricity_produced_peak_cumulative": 1296.136, + "electricity_produced_peak_interval": 0, + "electricity_produced_point": 0, + "gas_consumed_cumulative": 584.433, + "gas_consumed_interval": 0.016, + "net_electricity_cumulative": 1019.201, + "net_electricity_point": 458 + }, + "vendor": "Ene5\\T210-DESMR5.0" + }, + "aaaa0000aaaa0000aaaa0000aaaa00aa": { + "dev_class": "gateway", + "firmware": "2.5.9", + "location": "938696c4bcdb4b8a9a595cb38ed43913", + "mac_address": "012345670001", + "model": "Gateway", + "name": "Smile P1", + "vendor": "Plugwise" } } } diff --git a/tests/data/stretch/stretch_v31.json b/tests/data/stretch/stretch_v31.json index 369300146..43f925648 100644 --- a/tests/data/stretch/stretch_v31.json +++ b/tests/data/stretch/stretch_v31.json @@ -1,134 +1,136 @@ { - "0000aaaa0000aaaa0000aaaa0000aa00": { - "dev_class": "gateway", - "firmware": "3.1.11", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "mac_address": "01:23:45:67:89:AB", - "model": "Gateway", - "name": "Stretch", - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670101" - }, - "5871317346d045bc9f6b987ef25ee638": { - "dev_class": "water_heater_vessel", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4028", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Boiler (1EB31)", - "zigbee_mac_address": "ABCD012345670A07", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 1.19, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "device_zones": { + "0000aaaa0000aaaa0000aaaa0000aa00": { + "dev_class": "gateway", + "firmware": "3.1.11", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "mac_address": "01:23:45:67:89:AB", + "model": "Gateway", + "name": "Stretch", + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" }, - "switches": { - "relay": true, - "lock": false - } - }, - "e1c884e7dede431dadee09506ec4f859": { - "dev_class": "refrigerator", - "firmware": "2011-06-27T10:47:37+02:00", - "hardware": "6539-0700-7330", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle+ type F", - "name": "Koelkast (92C4A)", - "zigbee_mac_address": "0123456789AB", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 50.5, - "electricity_consumed_interval": 0.08, - "electricity_produced": 0.0 + "059e4d03c7a34d278add5c7a4a781d19": { + "dev_class": "washingmachine", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Wasmachine (52AC1)", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" }, - "switches": { - "relay": true, - "lock": false - } - }, - "aac7b735042c4832ac9ff33aae4f453b": { - "dev_class": "dishwasher", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4022", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Vaatwasser (2a1ab)", - "zigbee_mac_address": "ABCD012345670A02", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.71, - "electricity_produced": 0.0 + "5871317346d045bc9f6b987ef25ee638": { + "dev_class": "water_heater_vessel", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4028", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Boiler (1EB31)", + "sensors": { + "electricity_consumed": 1.19, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" }, - "switches": { - "relay": true, - "lock": false - } - }, - "cfe95cf3de1948c0b8955125bf754614": { - "dev_class": "dryer", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Droger (52559)", - "zigbee_mac_address": "ABCD012345670A04", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "aac7b735042c4832ac9ff33aae4f453b": { + "dev_class": "dishwasher", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4022", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Vaatwasser (2a1ab)", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.71, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" }, - "switches": { - "relay": true, - "lock": false - } - }, - "059e4d03c7a34d278add5c7a4a781d19": { - "dev_class": "washingmachine", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Wasmachine (52AC1)", - "zigbee_mac_address": "ABCD012345670A01", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "cfe95cf3de1948c0b8955125bf754614": { + "dev_class": "dryer", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Droger (52559)", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A04" }, - "switches": { - "relay": true, - "lock": true - } - }, - "d950b314e9d8499f968e6db8d82ef78c": { - "dev_class": "report", - "model": "Switchgroup", - "name": "Stroomvreters", - "members": [ - "059e4d03c7a34d278add5c7a4a781d19", - "5871317346d045bc9f6b987ef25ee638", - "aac7b735042c4832ac9ff33aae4f453b", - "cfe95cf3de1948c0b8955125bf754614", - "e1c884e7dede431dadee09506ec4f859" - ], - "switches": { - "relay": true - } - }, - "d03738edfcc947f7b8f4573571d90d2d": { - "dev_class": "switching", - "model": "Switchgroup", - "name": "Schakel", - "members": [ - "059e4d03c7a34d278add5c7a4a781d19", - "cfe95cf3de1948c0b8955125bf754614" - ], - "switches": { - "relay": true + "d03738edfcc947f7b8f4573571d90d2d": { + "dev_class": "switching", + "members": [ + "059e4d03c7a34d278add5c7a4a781d19", + "cfe95cf3de1948c0b8955125bf754614" + ], + "model": "Switchgroup", + "name": "Schakel", + "switches": { + "relay": true + } + }, + "d950b314e9d8499f968e6db8d82ef78c": { + "dev_class": "report", + "members": [ + "059e4d03c7a34d278add5c7a4a781d19", + "5871317346d045bc9f6b987ef25ee638", + "aac7b735042c4832ac9ff33aae4f453b", + "cfe95cf3de1948c0b8955125bf754614", + "e1c884e7dede431dadee09506ec4f859" + ], + "model": "Switchgroup", + "name": "Stroomvreters", + "switches": { + "relay": true + } + }, + "e1c884e7dede431dadee09506ec4f859": { + "dev_class": "refrigerator", + "firmware": "2011-06-27T10:47:37+02:00", + "hardware": "6539-0700-7330", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle+ type F", + "name": "Koelkast (92C4A)", + "sensors": { + "electricity_consumed": 50.5, + "electricity_consumed_interval": 0.08, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "0123456789AB" } } } From 1e2a14aae99f8bd2b4dcf2bebe60a7f7df947287 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 17:51:57 +0100 Subject: [PATCH 042/106] More legacy fixes --- plugwise/__init__.py | 2 +- plugwise/legacy/smile.py | 6 +- .../stretch/stretch_v31_UPDATED_DATA.json | 76 ++++++++++--------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 8f6cfc3d5..2571881be 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -304,7 +304,7 @@ async def full_update_device(self) -> None: def get_all_device_zones(self) -> None: """Helper-function used for testing.""" - self._smile_api.get_all_devices() + self._smile_api.get_all_device_zones() async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 3c97e9f2e..3bd701b0e 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -91,8 +91,8 @@ async def full_update_device(self) -> None: if self.smile_type != "power": self._appliances = await self.request(APPLIANCES) - def get_all_devices(self) -> None: - """Determine the evices present from the obtained XML-data. + def get_all_device_zones(self) -> None: + """Determine the devices present from the obtained XML-data. Run this functions once to gather the initial device configuration, then regularly run async_update() to refresh the device data. @@ -121,7 +121,7 @@ async def async_update(self) -> PlugwiseData: self.gw_data: GatewayData = {} self.gw_device_zones: dict[str, DeviceZoneData] = {} await self.full_update_device() - self.get_all_devices() + self.get_all_device_zones() # Otherwise perform an incremental update else: self._domain_objects = await self.request(DOMAIN_OBJECTS) diff --git a/tests/data/stretch/stretch_v31_UPDATED_DATA.json b/tests/data/stretch/stretch_v31_UPDATED_DATA.json index 44a1049ef..0eff7c2ef 100644 --- a/tests/data/stretch/stretch_v31_UPDATED_DATA.json +++ b/tests/data/stretch/stretch_v31_UPDATED_DATA.json @@ -1,44 +1,46 @@ { - "aac7b735042c4832ac9ff33aae4f453b": { - "sensors": { - "electricity_consumed": 1000.0, - "electricity_consumed_interval": 20.7, - "electricity_produced": 0.0 + "device_zones": { + "aac7b735042c4832ac9ff33aae4f453b": { + "sensors": { + "electricity_consumed": 1000.0, + "electricity_consumed_interval": 20.7, + "electricity_produced": 0.0 + }, + "switches": { + "relay": true, + "lock": true + } }, - "switches": { - "relay": true, - "lock": true - } - }, - "cfe95cf3de1948c0b8955125bf754614": { - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "cfe95cf3de1948c0b8955125bf754614": { + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "relay": false, + "lock": false + } }, - "switches": { - "relay": false, - "lock": false - } - }, - "059e4d03c7a34d278add5c7a4a781d19": { - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "059e4d03c7a34d278add5c7a4a781d19": { + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "relay": false, + "lock": false + } }, - "switches": { - "relay": false, - "lock": false - } - }, - "d03738edfcc947f7b8f4573571d90d2d": { - "members": [ - "059e4d03c7a34d278add5c7a4a781d19", - "cfe95cf3de1948c0b8955125bf754614" - ], - "switches": { - "relay": false + "d03738edfcc947f7b8f4573571d90d2d": { + "members": [ + "059e4d03c7a34d278add5c7a4a781d19", + "cfe95cf3de1948c0b8955125bf754614" + ], + "switches": { + "relay": false + } } } } From b55d951f9becb42a9034baba55fda01caff794de Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 17:59:49 +0100 Subject: [PATCH 043/106] Save updated fixture and related test-jsons --- fixtures/p1v4_442_single/all_data.json | 5 +- tests/data/p1/p1v4_442_single.json | 78 ++++++++++--------- .../data/p1/p1v4_442_single_UPDATED_DATA.json | 32 ++++---- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/fixtures/p1v4_442_single/all_data.json b/fixtures/p1v4_442_single/all_data.json index 5e2abe64b..febf457fa 100644 --- a/fixtures/p1v4_442_single/all_data.json +++ b/fixtures/p1v4_442_single/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "device_zones": { "a455b61e52394b2db5081ce025a430f3": { "binary_sensors": { "plugwise_notification": false @@ -47,6 +47,5 @@ "notifications": {}, "reboot": true, "smile_name": "Smile P1" - }, - "zones": {} + } } diff --git a/tests/data/p1/p1v4_442_single.json b/tests/data/p1/p1v4_442_single.json index 92c645776..8f41b3f13 100644 --- a/tests/data/p1/p1v4_442_single.json +++ b/tests/data/p1/p1v4_442_single.json @@ -1,42 +1,44 @@ { - "a455b61e52394b2db5081ce025a430f3": { - "dev_class": "gateway", - "firmware": "4.4.2", - "hardware": "AME Smile 2.0 board", - "location": "a455b61e52394b2db5081ce025a430f3", - "mac_address": "012345670001", - "model": "Gateway", - "model_id": "smile", - "name": "Smile P1", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false - } - }, - "ba4de7613517478da82dd9b6abea36af": { - "dev_class": "smartmeter", - "location": "a455b61e52394b2db5081ce025a430f3", - "model": "KFM5KAIFA-METER", - "name": "P1", - "vendor": "SHENZHEN KAIFA TECHNOLOGY (CHENGDU) CO., LTD.", - "available": true, - "sensors": { - "net_electricity_point": 486.0, - "electricity_consumed_peak_point": 0.0, - "electricity_consumed_off_peak_point": 486.0, - "net_electricity_cumulative": 31610.031, - "electricity_consumed_peak_cumulative": 13966.608, - "electricity_consumed_off_peak_cumulative": 17643.423, - "electricity_consumed_peak_interval": 0.0, - "electricity_consumed_off_peak_interval": 15.0, - "electricity_produced_peak_point": 0.0, - "electricity_produced_off_peak_point": 0.0, - "electricity_produced_peak_cumulative": 0.0, - "electricity_produced_off_peak_cumulative": 0.0, - "electricity_produced_peak_interval": 0.0, - "electricity_produced_off_peak_interval": 0.0, - "electricity_phase_one_consumed": 486.0, - "electricity_phase_one_produced": 0.0 + "device_zones": { + "a455b61e52394b2db5081ce025a430f3": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.4.2", + "hardware": "AME Smile 2.0 board", + "location": "a455b61e52394b2db5081ce025a430f3", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile", + "name": "Smile P1", + "vendor": "Plugwise" + }, + "ba4de7613517478da82dd9b6abea36af": { + "available": true, + "dev_class": "smartmeter", + "location": "a455b61e52394b2db5081ce025a430f3", + "model": "KFM5KAIFA-METER", + "name": "P1", + "sensors": { + "electricity_consumed_off_peak_cumulative": 17643.423, + "electricity_consumed_off_peak_interval": 15, + "electricity_consumed_off_peak_point": 486, + "electricity_consumed_peak_cumulative": 13966.608, + "electricity_consumed_peak_interval": 0, + "electricity_consumed_peak_point": 0, + "electricity_phase_one_consumed": 486, + "electricity_phase_one_produced": 0, + "electricity_produced_off_peak_cumulative": 0.0, + "electricity_produced_off_peak_interval": 0, + "electricity_produced_off_peak_point": 0, + "electricity_produced_peak_cumulative": 0.0, + "electricity_produced_peak_interval": 0, + "electricity_produced_peak_point": 0, + "net_electricity_cumulative": 31610.031, + "net_electricity_point": 486 + }, + "vendor": "SHENZHEN KAIFA TECHNOLOGY \uff08CHENGDU\uff09 CO., LTD." } } } diff --git a/tests/data/p1/p1v4_442_single_UPDATED_DATA.json b/tests/data/p1/p1v4_442_single_UPDATED_DATA.json index 1033342ef..8db198157 100644 --- a/tests/data/p1/p1v4_442_single_UPDATED_DATA.json +++ b/tests/data/p1/p1v4_442_single_UPDATED_DATA.json @@ -1,19 +1,21 @@ { - "ba4de7613517478da82dd9b6abea36af": { - "sensors": { - "net_electricity_point": -2248.0, - "electricity_consumed_peak_point": 0.0, - "electricity_consumed_off_peak_point": 0.0, - "electricity_consumed_peak_interval": 0.0, - "electricity_consumed_off_peak_interval": 0.0, - "electricity_produced_peak_point": 2248.0, - "electricity_produced_off_peak_point": 0.0, - "electricity_produced_peak_cumulative": 6.543, - "electricity_produced_off_peak_cumulative": 0.0, - "electricity_produced_peak_interval": 1345.0, - "electricity_produced_off_peak_interval": 0.0, - "electricity_phase_one_consumed": 0.0, - "electricity_phase_one_produced": 1998.0 + "device_zones": { + "ba4de7613517478da82dd9b6abea36af": { + "sensors": { + "net_electricity_point": -2248.0, + "electricity_consumed_peak_point": 0.0, + "electricity_consumed_off_peak_point": 0.0, + "electricity_consumed_peak_interval": 0.0, + "electricity_consumed_off_peak_interval": 0.0, + "electricity_produced_peak_point": 2248.0, + "electricity_produced_off_peak_point": 0.0, + "electricity_produced_peak_cumulative": 6.543, + "electricity_produced_off_peak_cumulative": 0.0, + "electricity_produced_peak_interval": 1345.0, + "electricity_produced_off_peak_interval": 0.0, + "electricity_phase_one_consumed": 0.0, + "electricity_phase_one_produced": 1998.0 + } } } } From 1a3a9343a7321509a5f274f1a37de08b9ef0e501 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 18:01:59 +0100 Subject: [PATCH 044/106] Fix --- tests/test_adam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_adam.py b/tests/test_adam.py index 6a38bfdfc..ffe994d34 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -49,7 +49,7 @@ async def test_connect_adam_plus_anna_new(self): "854f8a9b0e7e425db97f1f110e1ce4b3", "2568cc4b9c1e401495d4741a5f89bee1", "e8ef2a01ed3b4139a53bf749204fe6b4", - "f2bf9048bef64cc5b6d5110154e33c81", + "f2bf9048bef64cc5b6d5110154e33c81", "f871b8c4d63549319221e294e4f88074", ] From bc3d9d49a846530a94a3ee4eb8e56984b7a99a68 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 18:04:03 +0100 Subject: [PATCH 045/106] Update manual_fixtures script --- scripts/manual_fixtures.py | 146 ++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 43bd4af52..e8236cb1f 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -36,8 +36,8 @@ def json_writer(manual_name: str, all_data: dict) -> None: adam_multiple_devices_per_zone = base.copy() # Change schedule to not present for "e7693eb9582644e5b865dba8d4447cf1" -adam_multiple_devices_per_zone["devices"]["e7693eb9582644e5b865dba8d4447cf1"].pop("available_schedules") -adam_multiple_devices_per_zone["devices"]["e7693eb9582644e5b865dba8d4447cf1"].pop("select_schedule") +adam_multiple_devices_per_zone["device_zones"]["e7693eb9582644e5b865dba8d4447cf1"].pop("available_schedules") +adam_multiple_devices_per_zone["device_zones"]["e7693eb9582644e5b865dba8d4447cf1"].pop("select_schedule") json_writer("m_adam_multiple_devices_per_zone", adam_multiple_devices_per_zone) @@ -50,7 +50,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: adam_jip = base.copy() # Change mode to off for "1346fbd8498d4dbcab7e18d51b771f3d" -adam_jip["devices"]["1346fbd8498d4dbcab7e18d51b771f3d"]["climate_mode"] = "off" +adam_jip["device_zones"]["1346fbd8498d4dbcab7e18d51b771f3d"]["climate_mode"] = "off" json_writer("m_adam_jip", adam_jip) @@ -70,86 +70,86 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling["gateway"]["item_count"] = 89 # Remove devices "67d73d0bd469422db25a618a5fb8eeb0" and "10016900610d4c7481df78c89606ef22" from anywhere -m_adam_cooling["devices"].pop("67d73d0bd469422db25a618a5fb8eeb0") -m_adam_cooling["devices"].pop("10016900610d4c7481df78c89606ef22") +m_adam_cooling["device_zones"].pop("67d73d0bd469422db25a618a5fb8eeb0") +m_adam_cooling["device_zones"].pop("10016900610d4c7481df78c89606ef22") # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ +m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ "setpoint" ] = 23.5 # Add new key available -m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["available"] = True +m_adam_cooling["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["available"] = True -m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ "select_schedule" ] = "off" -m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ "control_state" ] = "cooling" -m_adam_cooling["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" +m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" # (following diff, now 2954 is removed) # Remove device "29542b2b6a6a4169acecc15c72a599b8" from anywhere -m_adam_cooling["devices"].pop("29542b2b6a6a4169acecc15c72a599b8") +m_adam_cooling["device_zones"].pop("29542b2b6a6a4169acecc15c72a599b8") # Back at ad48 -m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_cooling["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "temperature" ] = 25.8 -m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_cooling["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "setpoint" ] = 23.5 # (again, following diff) # Remove device "2568cc4b9c1e401495d4741a5f89bee1" from anywhere -m_adam_cooling["devices"].pop("2568cc4b9c1e401495d4741a5f89bee1") +m_adam_cooling["device_zones"].pop("2568cc4b9c1e401495d4741a5f89bee1") # Remove device "854f8a9b0e7e425db97f1f110e1ce4b3" from anywhere -m_adam_cooling["devices"].pop("854f8a9b0e7e425db97f1f110e1ce4b3") +m_adam_cooling["device_zones"].pop("854f8a9b0e7e425db97f1f110e1ce4b3") # Go for 1772 -m_adam_cooling["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"].pop("setpoint") -m_adam_cooling["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ +m_adam_cooling["device_zones"]["1772a4ea304041adb83f357b751341ff"]["sensors"].pop("setpoint") +m_adam_cooling["device_zones"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 21.6 # Go for e2f4 -m_adam_cooling["zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ +m_adam_cooling["device_zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 25.0 -m_adam_cooling["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_cooling["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "temperature" ] = 23.9 -m_adam_cooling["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_cooling["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "setpoint" ] = 23.5 # Go for da22 -m_adam_cooling["devices"]["da224107914542988a88561b4452b0f6"][ +m_adam_cooling["device_zones"]["da224107914542988a88561b4452b0f6"][ "select_regulation_mode" ] = "cooling" -m_adam_cooling["devices"]["da224107914542988a88561b4452b0f6"][ +m_adam_cooling["device_zones"]["da224107914542988a88561b4452b0f6"][ "regulation_modes" ].append("cooling") -m_adam_cooling["devices"]["da224107914542988a88561b4452b0f6"]["sensors"][ +m_adam_cooling["device_zones"]["da224107914542988a88561b4452b0f6"]["sensors"][ "outdoor_temperature" ] = 29.65 # Go for 056e -m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "cooling_state" ] = True -m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = False -m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "flame_state" ] = False -m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "water_temperature" ] = 19.0 -m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 17.5 @@ -163,73 +163,73 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_heating["gateway"]["cooling_present"] = False # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_heating["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ +m_adam_heating["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ "setpoint" ] = 20.0 -m_adam_heating["zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_heating["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ "control_state" ] = "preheating" -m_adam_heating["zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" +m_adam_heating["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" # Back at ad48 -m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_heating["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "setpoint" ] = 20.0 -m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_heating["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "temperature" ] = 19.1 # Go for 1772 -m_adam_heating["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ +m_adam_heating["device_zones"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 18.6 # Go for e2f4 -m_adam_heating["zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ +m_adam_heating["device_zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 15.0 -m_adam_heating["devices"]["e2f4322d57924fa090fbbc48b3a140dc"][ +m_adam_heating["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"][ "control_state" ] = "off" -m_adam_heating["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_heating["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "setpoint" ] = 15.0 -m_adam_heating["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_heating["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "temperature" ] = 17.9 # Go for da22 -m_adam_heating["devices"]["da224107914542988a88561b4452b0f6"][ +m_adam_heating["device_zones"]["da224107914542988a88561b4452b0f6"][ "select_regulation_mode" ] = "heating" -m_adam_heating["devices"]["da224107914542988a88561b4452b0f6"][ +m_adam_heating["device_zones"]["da224107914542988a88561b4452b0f6"][ "regulation_modes" ].remove("cooling") -m_adam_heating["devices"]["da224107914542988a88561b4452b0f6"]["sensors"][ +m_adam_heating["device_zones"]["da224107914542988a88561b4452b0f6"]["sensors"][ "outdoor_temperature" ] = -1.25 # Go for 056e -m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"].pop( +m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"].pop( "cooling_state" ) -m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = True -m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "flame_state" ] = False -m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "water_temperature" ] = 37.0 -m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 38.1 -m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["max_dhw_temperature"] = { +m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["max_dhw_temperature"] = { "setpoint": 60.0, "lower_bound": 40.0, "upper_bound": 60.0, @@ -251,60 +251,60 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_anna_heatpump_cooling["gateway"]["cooling_present"] = True # Go for 1cbf -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "model" ] = "Generic heater/cooler" -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["cooling_enabled"] = True -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["heating_state"] = False -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["cooling_state"] = True -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "water_temperature" ] = 22.7 -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "dhw_temperature" ] = 41.5 -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "intended_boiler_temperature" ] = 0.0 -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "modulation_level" ] = 40 -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "return_temperature" ] = 23.8 -m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "outdoor_air_temperature" ] = 28.0 # Go for 015a -m_anna_heatpump_cooling["devices"]["015ae9ea3f964e668e490fa39da3870b"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["015ae9ea3f964e668e490fa39da3870b"]["sensors"][ "outdoor_temperature" ] = 28.2 # Go for 3cb7 -m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ +m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ "setpoint_low" ] = 20.5 -m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ +m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ "setpoint_high" ] = 30.0 -m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "temperature" ] = 26.3 -m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "setpoint_low" ] = 20.5 -m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "setpoint_high" ] = 30.0 @@ -315,39 +315,39 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_anna_heatpump_idle = m_anna_heatpump_cooling.copy() # Go for 1cbf -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ "compressor_state" ] = False -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ "cooling_state" ] = False -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "water_temperature" ] = 19.1 -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "dhw_temperature" ] = 46.3 -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "intended_boiler_temperature" ] = 18.0 -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "modulation_level" ] = 0 -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "return_temperature" ] = 22.0 -m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "outdoor_air_temperature" ] = 28.2 # Go for 3cb7 -m_anna_heatpump_idle["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "temperature" ] = 23.0 -m_anna_heatpump_idle["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_idle["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "cooling_activation_outdoor_temperature" ] = 25.0 From 9e49d8f5c89d29a86fa82a535c46d2e7a9a09bc9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 18:05:45 +0100 Subject: [PATCH 046/106] Bump to a1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6c9086030..1a94ab6d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.6.0a0" +version = "1.6.0a1" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From fd1389a635cbbff10418efc7cdcf59a3f41f7c66 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 Nov 2024 18:06:44 +0100 Subject: [PATCH 047/106] Disable manual fixture creation --- scripts/tests_and_coverage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index 5195652c3..081d8b6bf 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -50,9 +50,9 @@ fi # As to not generated fixtures, leaving biome to re-do them # so no auto-generation during github run of testing # Creating todo #313 to 'gracefully' do this on merge on github action -if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "fixtures" ] ; then - echo "... crafting manual fixtures ..." - PYTHONPATH=$(pwd) python3 scripts/manual_fixtures.py -fi +# if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "fixtures" ] ; then +# echo "... crafting manual fixtures ..." +# PYTHONPATH=$(pwd) python3 scripts/manual_fixtures.py +# fi echo "... biome-ing (fixtures and testdata) ..." ./tmp/biome lint --staged --files-ignore-unknown=true --no-errors-on-unmatched From 9e01661cad76d3de610f380f5c6d7406aed3d77f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 09:48:23 +0100 Subject: [PATCH 048/106] Count test-asserts per device/zone and output --- tests/test_init.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_init.py b/tests/test_init.py index 63e2105f1..2d8dfcb6f 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -553,6 +553,7 @@ def test_and_assert(test_dict, data, header): asserts = 0 bsw_list = ["binary_sensors", "central", "climate", "sensors", "switches"] for testitem, measurements in test_dict.items(): + item_asserts = 0 tests += 1 assert testitem in data asserts += 1 @@ -586,12 +587,15 @@ def test_and_assert(test_dict, data, header): ) assert val_1 == val_2 asserts += 1 + item_asserts += 1 else: assert details[measure_key] == measure_assert asserts += 1 + item_asserts += 1 + _LOGGER.debug("Item %s test-asserts: %s", testitem, item_asserts) assert tests == asserts - _LOGGER.debug("Number of zone test-assert: %s", asserts) + _LOGGER.debug("Total device_zone test-asserts: %s", asserts) # pragma warning disable S3776 From fbdf823212d1d93615a9c986ea20287ae57e0e95 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 08:48:54 +0000 Subject: [PATCH 049/106] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_init.py b/tests/test_init.py index 2d8dfcb6f..87d933cbc 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -592,7 +592,7 @@ def test_and_assert(test_dict, data, header): assert details[measure_key] == measure_assert asserts += 1 item_asserts += 1 - _LOGGER.debug("Item %s test-asserts: %s", testitem, item_asserts) + _LOGGER.debug("Item %s test-asserts: %s", testitem, item_asserts) assert tests == asserts _LOGGER.debug("Total device_zone test-asserts: %s", asserts) From cc96b86a2853b703b517cdc546c0c03bab213524 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 11:30:12 +0100 Subject: [PATCH 050/106] Reduce complexity --- plugwise/helper.py | 156 ++++++++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 66 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 641bf1d3b..a98432f31 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -534,19 +534,9 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: if appliance.find("type").text in ACTUATOR_CLASSES: self._get_actuator_functionalities(appliance, device, data) - if dev_id == self.gateway_id and self.smile(ADAM): - self._get_regulation_mode(appliance, data) - self._get_gateway_mode(appliance, data) - - # Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS - under Home - # The outdoor_temperature present in APPLIANCES is a local sensor connected to the active device - if self._is_thermostat and dev_id == self.gateway_id: - outdoor_temperature = self._object_value( - self._home_location, "outdoor_temperature" - ) - if outdoor_temperature is not None: - data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) - self._count += 1 + self._get_regulation_mode(appliance, dev_id, data) + self._get_gateway_mode(appliance, dev_id, data) + self._get_gateway_outdoor_temp(dev_id, data) if "c_heating_state" in data: self._process_c_heating_state(data) @@ -554,38 +544,8 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: data.pop("c_heating_state") self._count -= 1 - if self._is_thermostat and self.smile(ANNA) and dev_id == self._heater_id: - # Anna+Elga: base cooling_state on the elga-status-code - if "elga_status_code" in data: - if data["thermostat_supports_cooling"]: - # Techneco Elga has cooling-capability - self._cooling_present = True - data["model"] = "Generic heater/cooler" - self._cooling_enabled = data["elga_status_code"] in (8, 9) - data["binary_sensors"]["cooling_state"] = self._cooling_active = ( - data["elga_status_code"] == 8 - ) - # Elga has no cooling-switch - if "cooling_ena_switch" in data["switches"]: - data["switches"].pop("cooling_ena_switch") - self._count -= 1 - - data.pop("elga_status_code", None) - self._count -= 1 - - # Loria/Thermastage: cooling-related is based on cooling_state - # and modulation_level - elif self._cooling_present and "cooling_state" in data["binary_sensors"]: - self._cooling_enabled = data["binary_sensors"]["cooling_state"] - self._cooling_active = data["sensors"]["modulation_level"] == 100 - # For Loria the above does not work (pw-beta issue #301) - if "cooling_ena_switch" in data["switches"]: - self._cooling_enabled = data["switches"]["cooling_ena_switch"] - self._cooling_active = data["binary_sensors"]["cooling_state"] - - self._cleanup_data(data) - - return data + if self._is_thermostat and self.smile(ANNA): + self._update_anna_cooling(dev_id, data) def _power_data_from_location(self, loc_id: str) -> DeviceZoneData: """Helper-function for smile.py: _get_device_zone_data(). @@ -731,27 +691,50 @@ def _get_actuator_functionalities( act_item = cast(ActuatorType, item) data[act_item] = temp_dict - def _get_regulation_mode(self, appliance: etree, data: DeviceZoneData) -> None: + def _get_regulation_mode( + self, appliance: etree, dev_id: str, data: DeviceZoneData + ) -> None: """Helper-function for _get_measurement_data(). - Collect the gateway regulation_mode. + Adam: collect the gateway regulation_mode. """ + if not (self.smile(ADAM) and dev_id == self.gateway_id): + return + locator = "./actuator_functionalities/regulation_mode_control_functionality" if (search := appliance.find(locator)) is not None: data["select_regulation_mode"] = search.find("mode").text self._count += 1 self._cooling_enabled = data["select_regulation_mode"] == "cooling" - def _get_gateway_mode(self, appliance: etree, data: DeviceZoneData) -> None: + def _get_gateway_mode( + self, appliance: etree, dev_id: str, data: DeviceZoneData + ) -> None: """Helper-function for _get_measurement_data(). - Collect the gateway mode. + Adam: collect the gateway mode. """ + if not (self.smile(ADAM) and dev_id == self.gateway_id): + return + locator = "./actuator_functionalities/gateway_mode_control_functionality" if (search := appliance.find(locator)) is not None: data["select_gateway_mode"] = search.find("mode").text self._count += 1 + def _get_gateway_outdoor_temp(self, dev_id: str, data: DeviceZoneData) -> None: + """Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS. + + Available under the Home location. + """ + if self._is_thermostat and dev_id == self.gateway_id: + outdoor_temperature = self._object_value( + self._home_location, "outdoor_temperature" + ) + if outdoor_temperature is not None: + data.update({"sensors": {"outdoor_temperature": outdoor_temperature}}) + self._count += 1 + def _object_value(self, obj_id: str, measurement: str) -> float | int | None: """Helper-function for smile.py: _get_device_zone_data() and _device_data_anna(). @@ -770,29 +753,70 @@ def _process_c_heating_state(self, data: DeviceZoneData) -> None: Process the central_heating_state value. """ + # Adam or Anna + OnOff device if self._on_off_device: - # Anna + OnOff heater: use central_heating_state to show heating_state - # Solution for Core issue #81839 - if self.smile(ANNA): - data["binary_sensors"]["heating_state"] = data["c_heating_state"] - - # Adam + OnOff cooling: use central_heating_state to show heating/cooling_state - if self.smile(ADAM): - if "heating_state" not in data["binary_sensors"]: - self._count += 1 - data["binary_sensors"]["heating_state"] = False - if "cooling_state" not in data["binary_sensors"]: - self._count += 1 - data["binary_sensors"]["cooling_state"] = False - if self._cooling_enabled: - data["binary_sensors"]["cooling_state"] = data["c_heating_state"] - else: - data["binary_sensors"]["heating_state"] = data["c_heating_state"] + self._process_on_off_device_c_heating_state(data) # Anna + Elga: use central_heating_state to show heating_state if self._elga: data["binary_sensors"]["heating_state"] = data["c_heating_state"] + def _process_on_off_device_c_heating_state(self, data: DeviceZoneData) -> None: + """Adam or Anna + OnOff device - use central_heating_state to show heating/cooling_state. + + Solution for Core issue #81839. + """ + if self.smile(ANNA): + data["binary_sensors"]["heating_state"] = data["c_heating_state"] + + if self.smile(ADAM): + if "heating_state" not in data["binary_sensors"]: + self._count += 1 + data["binary_sensors"]["heating_state"] = False + if "cooling_state" not in data["binary_sensors"]: + self._count += 1 + data["binary_sensors"]["cooling_state"] = False + if self._cooling_enabled: + data["binary_sensors"]["cooling_state"] = data["c_heating_state"] + else: + data["binary_sensors"]["heating_state"] = data["c_heating_state"] + + def _update_anna_cooling(self, dev_id: str, data: DeviceZoneData) -> None: + """Update the Anna heater_central device for cooling. + + Support added for Techneco Elga and Thercon Loria/Thermastage. + """ + if dev_id == self._heater_id: + # Anna+Elga: base cooling_state on the elga-status-code + if "elga_status_code" in data: + if data["thermostat_supports_cooling"]: + # Techneco Elga has cooling-capability + self._cooling_present = True + data["model"] = "Generic heater/cooler" + self._cooling_enabled = data["elga_status_code"] in (8, 9) + data["binary_sensors"]["cooling_state"] = self._cooling_active = ( + data["elga_status_code"] == 8 + ) + # Elga has no cooling-switch + if "cooling_ena_switch" in data["switches"]: + data["switches"].pop("cooling_ena_switch") + self._count -= 1 + + data.pop("elga_status_code", None) + self._count -= 1 + + # Loria/Thermastage: cooling-related is based on cooling_state + # and modulation_level + elif self._cooling_present and "cooling_state" in data["binary_sensors"]: + self._cooling_enabled = data["binary_sensors"]["cooling_state"] + self._cooling_active = data["sensors"]["modulation_level"] == 100 + # For Loria the above does not work (pw-beta issue #301) + if "cooling_ena_switch" in data["switches"]: + self._cooling_enabled = data["switches"]["cooling_ena_switch"] + self._cooling_active = data["binary_sensors"]["cooling_state"] + + self._cleanup_data(data) + def _cleanup_data(self, data: DeviceZoneData) -> None: """Helper-function for _get_measurement_data(). From 4638ed66a2019e8843505c27452a990105315fb1 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 11:33:07 +0100 Subject: [PATCH 051/106] Improve as suggested --- plugwise/helper.py | 72 ++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index a98432f31..39bb9db9f 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -786,36 +786,42 @@ def _update_anna_cooling(self, dev_id: str, data: DeviceZoneData) -> None: Support added for Techneco Elga and Thercon Loria/Thermastage. """ - if dev_id == self._heater_id: - # Anna+Elga: base cooling_state on the elga-status-code - if "elga_status_code" in data: - if data["thermostat_supports_cooling"]: - # Techneco Elga has cooling-capability - self._cooling_present = True - data["model"] = "Generic heater/cooler" - self._cooling_enabled = data["elga_status_code"] in (8, 9) - data["binary_sensors"]["cooling_state"] = self._cooling_active = ( - data["elga_status_code"] == 8 - ) - # Elga has no cooling-switch - if "cooling_ena_switch" in data["switches"]: - data["switches"].pop("cooling_ena_switch") - self._count -= 1 + if dev_id != self._heater_id: + return + + if "elga_status_code" in data: + self._update_elga_cooling(data) + elif self._cooling_present and "cooling_state" in data["binary_sensors"]: + self._update_loria_cooling(data) + + self._cleanup_data(data) - data.pop("elga_status_code", None) + def _update_elga_cooling(self, data: DeviceZoneData) -> None: + """# Anna+Elga: base cooling_state on the elga-status-code.""" + if data["thermostat_supports_cooling"]: + # Techneco Elga has cooling-capability + self._cooling_present = True + data["model"] = "Generic heater/cooler" + self._cooling_enabled = data["elga_status_code"] in (8, 9) + data["binary_sensors"]["cooling_state"] = self._cooling_active = ( + data["elga_status_code"] == 8 + ) + # Elga has no cooling-switch + if "cooling_ena_switch" in data["switches"]: + data["switches"].pop("cooling_ena_switch") self._count -= 1 - # Loria/Thermastage: cooling-related is based on cooling_state - # and modulation_level - elif self._cooling_present and "cooling_state" in data["binary_sensors"]: - self._cooling_enabled = data["binary_sensors"]["cooling_state"] - self._cooling_active = data["sensors"]["modulation_level"] == 100 - # For Loria the above does not work (pw-beta issue #301) - if "cooling_ena_switch" in data["switches"]: - self._cooling_enabled = data["switches"]["cooling_ena_switch"] - self._cooling_active = data["binary_sensors"]["cooling_state"] + data.pop("elga_status_code", None) + self._count -= 1 - self._cleanup_data(data) + def _update_loria_cooling(self, data: DeviceZoneData) -> None: + """Loria/Thermastage: base cooling-related on cooling_state and modulation_level.""" + self._cooling_enabled = data["binary_sensors"]["cooling_state"] + self._cooling_active = data["sensors"]["modulation_level"] == 100 + # For Loria the above does not work (pw-beta issue #301) + if "cooling_ena_switch" in data["switches"]: + self._cooling_enabled = data["switches"]["cooling_ena_switch"] + self._cooling_active = data["binary_sensors"]["cooling_state"] def _cleanup_data(self, data: DeviceZoneData) -> None: """Helper-function for _get_measurement_data(). @@ -860,15 +866,11 @@ def _scan_thermostats(self) -> None: for loc_id, loc_data in list(self._thermo_locs.items()): if loc_data["primary_prio"] != 0: - self.zone_data.update( - { - loc_id: { - "dev_class": "climate", - "name": loc_data["name"], - "thermostats": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} - } - } - ) + self.zone_data[loc_id] = { + "dev_class": "climate", + "name": loc_data["name"], + "thermostats": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} + } self._count += 3 def _match_locations(self) -> dict[str, ThermoLoc]: From 2e0c603218054583f3f02d08536c17ac94bf4abc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:49:37 +0000 Subject: [PATCH 052/106] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugwise/helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 39bb9db9f..e4b0615f0 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -788,12 +788,12 @@ def _update_anna_cooling(self, dev_id: str, data: DeviceZoneData) -> None: """ if dev_id != self._heater_id: return - + if "elga_status_code" in data: self._update_elga_cooling(data) elif self._cooling_present and "cooling_state" in data["binary_sensors"]: self._update_loria_cooling(data) - + self._cleanup_data(data) def _update_elga_cooling(self, data: DeviceZoneData) -> None: From 1e312a445fbafd6d759ab46eb0ae96f94d7572d4 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 15:02:48 +0100 Subject: [PATCH 053/106] Update naming --- plugwise/__init__.py | 12 ++-- plugwise/common.py | 92 ++++++++++++-------------- plugwise/constants.py | 11 +-- plugwise/data.py | 136 +++++++++++++++++++------------------- plugwise/helper.py | 130 ++++++++++++++++++------------------ plugwise/legacy/data.py | 46 ++++++------- plugwise/legacy/helper.py | 90 ++++++++++++------------- plugwise/legacy/smile.py | 24 +++---- plugwise/smile.py | 32 ++++----- plugwise/util.py | 6 +- 10 files changed, 288 insertions(+), 291 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 2571881be..121de3388 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -298,17 +298,17 @@ async def _smile_detect_legacy( self.smile_legacy = True return return_model - async def full_update_device(self) -> None: + async def full_xml_update(self) -> None: """Helper-function used for testing.""" - await self._smile_api.full_update_device() + await self._smile_api.full_xml_update() - def get_all_device_zones(self) -> None: + def get_all_gateway_entities(self) -> None: """Helper-function used for testing.""" - self._smile_api.get_all_device_zones() + self._smile_api.get_all_gateway_entities() async def async_update(self) -> PlugwiseData: - """Perform an incremental update for updating the various device states.""" - data = PlugwiseData(device_zones={}, gateway={}) + """Update the various entities and their states.""" + data = PlugwiseData(entities={}, gateway={}) try: data = await self._smile_api.async_update() self.gateway_id = data.gateway["gateway_id"] diff --git a/plugwise/common.py b/plugwise/common.py index d00d1f888..7ccb6d183 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -11,8 +11,8 @@ SPECIAL_PLUG_TYPES, SWITCH_GROUP_TYPES, ApplianceType, - DeviceZoneData, - ModelData, + GwEntityData, + ModuleData, SensorType, ) from plugwise.util import ( @@ -40,7 +40,7 @@ def __init__(self) -> None: self._heater_id: str self._on_off_device: bool self._opentherm_device: bool - self.gw_device_zones: dict[str, DeviceZoneData] + self.gw_entities: dict[str, GwEntityData] self.smile_name: str self.smile_type: str @@ -108,7 +108,7 @@ def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) return appl - def _collect_power_values(self, data: DeviceZoneData, loc: Munch, tariff: str, legacy: bool = False) -> None: + def _collect_power_values(self, data: GwEntityData, loc: Munch, tariff: str, legacy: bool = False) -> None: """Something.""" for loc.peak_select in ("nl_peak", "nl_offpeak"): loc.locator = ( @@ -160,8 +160,8 @@ def _power_data_energy_diff( measurement: str, net_string: SensorType, f_val: float | int, - direct_data: DeviceZoneData, - ) -> DeviceZoneData: + data: GwEntityData, + ) -> GwEntityData: """Calculate differential energy.""" if ( "electricity" in measurement @@ -174,7 +174,7 @@ def _power_data_energy_diff( if net_string not in direct_data["sensors"]: tmp_val: float | int = 0 else: - tmp_val = direct_data["sensors"][net_string] + tmp_val = data["sensors"][net_string] if isinstance(f_val, int): tmp_val += f_val * diff @@ -182,13 +182,13 @@ def _power_data_energy_diff( tmp_val += float(f_val * diff) tmp_val = float(f"{round(tmp_val, 3):.3f}") - direct_data["sensors"][net_string] = tmp_val + data["sensors"][net_string] = tmp_val - return direct_data + return data - def _create_gw_device_zones(self, appl: Munch) -> None: - """Helper-function for creating/updating gw_device_zones.""" - self.gw_device_zones[appl.dev_id] = {"dev_class": appl.pwclass} + def _create_gw_entities(self, appl: Munch) -> None: + """Helper-function for creating/updating gw_entities.""" + self.gw_entities[appl.dev_id] = {"dev_class": appl.pwclass} self._count += 1 for key, value in { "available": appl.available, @@ -204,30 +204,30 @@ def _create_gw_device_zones(self, appl: Munch) -> None: }.items(): if value is not None or key == "location": appl_key = cast(ApplianceType, key) - self.gw_device_zones[appl.dev_id][appl_key] = value + self.gw_entities[appl.dev_id][appl_key] = value self._count += 1 - def _device_data_switching_group( - self, device: DeviceZoneData, data: DeviceZoneData + def _entity_switching_group( + self, entity: GwEntityData, data: GwEntityData ) -> None: """Helper-function for _get_device_zone_data(). Determine switching group device data. """ - if device["dev_class"] in SWITCH_GROUP_TYPES: + if entity["dev_class"] in SWITCH_GROUP_TYPES: counter = 0 - for member in device["members"]: - if self.gw_device_zones[member]["switches"].get("relay"): + for member in entity["members"]: + if self.gw_entities[member]["switches"].get("relay"): counter += 1 data["switches"]["relay"] = counter != 0 self._count += 1 - def _get_group_switches(self) -> dict[str, DeviceZoneData]: - """Helper-function for smile.py: get_all_device_zones(). + def _get_group_switches(self) -> dict[str, GwEntityData]: + """Helper-function for smile.py: get_all_gateway_entities(). Collect switching- or pump-group info. """ - switch_groups: dict[str, DeviceZoneData] = {} + switch_groups: dict[str, GwEntityData] = {} # P1 and Anna don't have switchgroups if self.smile_type == "power" or self.smile(ANNA): return switch_groups @@ -240,25 +240,21 @@ def _get_group_switches(self) -> dict[str, DeviceZoneData]: group_appliances = group.findall("appliances/appliance") for item in group_appliances: # Check if members are not orphaned - stretch - if item.attrib["id"] in self.gw_device_zones: + if item.attrib["id"] in self.gw_entities: members.append(item.attrib["id"]) if group_type in SWITCH_GROUP_TYPES and members: - switch_groups.update( - { - group_id: { - "dev_class": group_type, - "model": "Switchgroup", - "name": group_name, - "members": members, - }, - }, - ) + switch_groups[group_id] = { + "dev_class": group_type, + "model": "Switchgroup", + "name": group_name, + "members": members, + } self._count += 4 return switch_groups - def _get_lock_state(self, xml: etree, data: DeviceZoneData, stretch_v2: bool = False) -> None: + def _get_lock_state(self, xml: etree, data: GwEntityData, stretch_v2: bool = False) -> None: """Helper-function for _get_measurement_data(). Adam & Stretches: obtain the relay-switch lock state. @@ -280,12 +276,12 @@ def _get_module_data( locator: str, xml_2: etree = None, legacy: bool = False, - ) -> ModelData: + ) -> ModuleData: """Helper-function for _energy_device_info_finder() and _appliance_info_finder(). Collect requested info from MODULES. """ - model_data: ModelData = { + module_data: ModuleData = { "contents": False, "firmware_version": None, "hardware_version": None, @@ -304,25 +300,25 @@ def _get_module_data( search = return_valid(xml_2, self._domain_objects) module = search.find(loc) if module is not None: # pylint: disable=consider-using-assignment-expr - model_data["contents"] = True - get_vendor_name(module, model_data) - model_data["vendor_model"] = module.find("vendor_model").text - model_data["hardware_version"] = module.find("hardware_version").text - model_data["firmware_version"] = module.find("firmware_version").text - self._get_zigbee_data(module, model_data, legacy) + module_data["contents"] = True + get_vendor_name(module, module_data) + module_data["vendor_model"] = module.find("vendor_model").text + module_data["hardware_version"] = module.find("hardware_version").text + module_data["firmware_version"] = module.find("firmware_version").text + self._get_zigbee_data(module, module_data, legacy) - return model_data + return module_data - def _get_zigbee_data(self, module: etree, model_data: ModelData, legacy: bool) -> None: - """Helper-function for _get_model_data().""" + def _get_zigbee_data(self, module: etree, module_data: ModuleData, legacy: bool) -> None: + """Helper-function for _get_module_data().""" if legacy: # Stretches if (router := module.find("./protocols/network_router")) is not None: - model_data["zigbee_mac_address"] = router.find("mac_address").text + module_data["zigbee_mac_address"] = router.find("mac_address").text # Also look for the Circle+/Stealth M+ if (coord := module.find("./protocols/network_coordinator")) is not None: - model_data["zigbee_mac_address"] = coord.find("mac_address").text + module_data["zigbee_mac_address"] = coord.find("mac_address").text # Adam elif (zb_node := module.find("./protocols/zig_bee_node")) is not None: - model_data["zigbee_mac_address"] = zb_node.find("mac_address").text - model_data["reachable"] = zb_node.find("reachable").text == "true" + module_data["zigbee_mac_address"] = zb_node.find("mac_address").text + module_data["reachable"] = zb_node.find("reachable").text == "true" diff --git a/plugwise/constants.py b/plugwise/constants.py index ccc192935..9186ee96f 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -405,8 +405,8 @@ class GatewayData(TypedDict, total=False): smile_name: str -class ModelData(TypedDict): - """The ModelData class.""" +class ModuleData(TypedDict): + """The Module data class.""" contents: bool firmware_version: str | None @@ -516,8 +516,8 @@ class ActuatorData(TypedDict, total=False): upper_bound: float -class DeviceZoneData(TypedDict, total=False): - """The DeviceZone data class. +class GwEntityData(TypedDict, total=False): + """The Gateway Entity data class. Covering the collected output-data per device or location. """ @@ -582,5 +582,6 @@ class DeviceZoneData(TypedDict, total=False): class PlugwiseData: """Plugwise data provided as output.""" + entities: dict[str, GwEntityData] gateway: GatewayData - device_zones: dict[str, DeviceZoneData] + diff --git a/plugwise/data.py b/plugwise/data.py index 83084823e..e423d804b 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -14,7 +14,7 @@ NONE, OFF, ActuatorData, - DeviceZoneData, + GwEntityData, ) from plugwise.helper import SmileHelper from plugwise.util import remove_empty_platform_dicts @@ -28,15 +28,15 @@ def __init__(self) -> None: SmileHelper.__init__(self) - def _all_device_zone_data(self) -> None: - """Helper-function for get_all_device_zones(). + def _all_entity_data(self) -> None: + """Helper-function for get_all_gateway_entities(). - Collect data for each device/zone and add to self.gw_data and self.gw_device_zones. + Collect data for each entity and add to self.gw_data and self.gw_entities. """ - self._update_gw_device_zones() + self._update_gw_entities() if self.smile(ADAM): self._update_zones() - self.gw_device_zones.update(self.zone_data) + self.gw_entities.update(self.zones) self.gw_data.update( { @@ -53,39 +53,39 @@ def _all_device_zone_data(self) -> None: ) def _update_zones(self) -> None: - """Helper-function for _all_device_zone_data() and async_update(). + """Helper-function for _all_entity_data() and async_update(). - Collect data for each zone/location and add to self.zone_data. + Collect data for each zone/location and add to self.zones. """ - for location_id, zone in self.zone_data.items(): + for location_id, zone in self.zones.items(): data = self._get_location_data(location_id) zone.update(data) - def _update_gw_device_zones(self) -> None: - """Helper-function for _all_device_zone_data() and async_update(). + def _update_gw_entities(self) -> None: + """Helper-function for _all_entities_data() and async_update(). - Collect data for each device and add to self.gw_device_zones. + Collect data for each entity and add to self.gw_entities. """ mac_list: list[str] = [] - for devzone_id, devzone in self.gw_device_zones.items(): - data = self._get_device_zone_data(devzone_id) - if devzone_id == self.gateway_id: + for entity_id, entity in self.gw_entities.items(): + data = self._get_entity_data(entity_id) + if entity_id == self.gateway_id: mac_list = self._detect_low_batteries() - self._add_or_update_notifications(devzone_id, devzone, data) + self._add_or_update_notifications(entity_id, entity, data) - devzone.update(data) + entity.update(data) is_battery_low = ( mac_list - and "low_battery" in devzone["binary_sensors"] - and devzone["zigbee_mac_address"] in mac_list - and devzone["dev_class"] in ("thermo_sensor", "thermostatic_radiator_valve", "zone_thermometer", "zone_thermostat") + and "low_battery" in entity["binary_sensors"] + and entity["zigbee_mac_address"] in mac_list + and entity["dev_class"] in ("thermo_sensor", "thermostatic_radiator_valve", "zone_thermometer", "zone_thermostat") ) if is_battery_low: - devzone["binary_sensors"]["low_battery"] = True + entity["binary_sensors"]["low_battery"] = True - self._update_for_cooling(devzone) + self._update_for_cooling(entity) - remove_empty_platform_dicts(devzone) + remove_empty_platform_dicts(entity) def _detect_low_batteries(self) -> list[str]: """Helper-function updating the low-battery binary_sensor status from a Battery-is-low message.""" @@ -109,31 +109,31 @@ def _detect_low_batteries(self) -> list[str]: return mac_address_list def _add_or_update_notifications( - self, devzone_id: str, devzone: DeviceZoneData, data: DeviceZoneData + self, entity_id: str, entity: GwEntityData, data: GwEntityData ) -> None: """Helper-function adding or updating the Plugwise notifications.""" if ( - devzone_id == self.gateway_id + entity_id == self.gateway_id and ( self._is_thermostat or self.smile_type == "power" ) ) or ( - "binary_sensors" in devzone - and "plugwise_notification" in devzone["binary_sensors"] + "binary_sensors" in entity + and "plugwise_notification" in entity["binary_sensors"] ): data["binary_sensors"]["plugwise_notification"] = bool(self._notifications) self._count += 1 - def _update_for_cooling(self, devzone: DeviceZoneData) -> None: + def _update_for_cooling(self, entity: GwEntityData) -> None: """Helper-function for adding/updating various cooling-related values.""" # For Anna and heating + cooling, replace setpoint with setpoint_high/_low if ( self.smile(ANNA) and self._cooling_present - and devzone["dev_class"] == "thermostat" + and entity["dev_class"] == "thermostat" ): - thermostat = devzone["thermostat"] - sensors = devzone["sensors"] + thermostat = entity["thermostat"] + sensors = entity["sensors"] temp_dict: ActuatorData = { "setpoint_low": thermostat["setpoint"], "setpoint_high": MAX_SETPOINT, @@ -145,7 +145,7 @@ def _update_for_cooling(self, devzone: DeviceZoneData) -> None: } thermostat.pop("setpoint") temp_dict.update(thermostat) - devzone["thermostat"] = temp_dict + entity["thermostat"] = temp_dict if "setpoint" in sensors: sensors.pop("setpoint") sensors["setpoint_low"] = temp_dict["setpoint_low"] @@ -153,60 +153,60 @@ def _update_for_cooling(self, devzone: DeviceZoneData) -> None: self._count += 2 # add 4, remove 2 - def _get_location_data(self, loc_id: str) -> DeviceZoneData: - """Helper-function for _all_device_zone_data() and async_update(). + def _get_location_data(self, loc_id: str) -> GwEntityData: + """Helper-function for _all_entity_data() and async_update(). - Provide device-data, based on Location ID (= loc_id). + Provide entity-data, based on Location ID (= loc_id). """ - zone = self.zone_data[loc_id] + zone = self.zones[loc_id] data = self._get_zone_data(loc_id) if ctrl_state := self._control_state(loc_id): data["control_state"] = ctrl_state self._count += 1 # Thermostat data (presets, temperatures etc) - self._devzone_data_climate(loc_id, zone, data) + self._climate_data(loc_id, zone, data) return data - def _get_device_zone_data(self, dev_id: str) -> DeviceZoneData: - """Helper-function for _update_gw_devices() and async_update(). + def _get_entity_data(self, entity_id: str) -> GwEntityData: + """Helper-function for _update_gw_entities() and async_update(). - Provide device-data, based on appliance_id (= dev_id). + Provide entity-data, based on appliance_id (= entity_id). """ - device = self.gw_device_zones[dev_id] - data = self._get_measurement_data(dev_id) + entity = self.gw_entities[entity_id] + data = self._get_measurement_data(entity_id) - # Check availability of wired-connected devices + # Check availability of wired-connected entities # Smartmeter self._check_availability( - device, "smartmeter", data, "P1 does not seem to be connected" + entity, "smartmeter", data, "P1 does not seem to be connected" ) - # OpenTherm device - if device["name"] != "OnOff": + # OpenTherm entity + if entity["name"] != "OnOff": self._check_availability( - device, "heater_central", data, "no OpenTherm communication" + entity, "heater_central", data, "no OpenTherm communication" ) # Switching groups data - self._device_data_switching_group(device, data) + self._entity_switching_group(entity, data) # Adam data - self._device_data_adam(device, data) + self._get_adam_data(entity, data) # Thermostat data for Anna (presets, temperatures etc) - if self.smile(ANNA) and device["dev_class"] == "thermostat": - self._devzone_data_climate(dev_id, device, data) + if self.smile(ANNA) and entity["dev_class"] == "thermostat": + self._climate_data(entity_id, entity, data) return data def _check_availability( - self, device: DeviceZoneData, dev_class: str, data: DeviceZoneData, message: str + self, entity: GwEntityData, dev_class: str, data: GwEntityData, message: str ) -> None: - """Helper-function for _get_device_zone_data(). + """Helper-function for _get_entity_data(). - Provide availability status for the wired-commected devices. + Provide availability status for the wired-connected devices. """ - if device["dev_class"] == dev_class: + if entity["dev_class"] == dev_class: data["available"] = True self._count += 1 for item in self._notifications.values(): @@ -214,8 +214,8 @@ def _check_availability( if message in msg: data["available"] = False - def _device_data_adam(self, device: DeviceZoneData, data: DeviceZoneData) -> None: - """Helper-function for _get_device_zone_data(). + def _get_adam_data(self, entity: GwEntityData, data: GwEntityData) -> None: + """Helper-function for _get_entity_data(). Determine Adam heating-status for on-off heating via valves, available regulations_modes and thermostat control_states. @@ -223,14 +223,14 @@ def _device_data_adam(self, device: DeviceZoneData, data: DeviceZoneData) -> Non if self.smile(ADAM): # Indicate heating_state based on valves being open in case of city-provided heating if ( - device["dev_class"] == "heater_central" + entity["dev_class"] == "heater_central" and self._on_off_device and isinstance(self._heating_valves(), int) ): data["binary_sensors"]["heating_state"] = self._heating_valves() != 0 # Show the allowed regulation_modes and gateway_modes - if device["dev_class"] == "gateway": + if entity["dev_class"] == "gateway": if self._reg_allowed_modes: data["regulation_modes"] = self._reg_allowed_modes self._count += 1 @@ -239,19 +239,19 @@ def _device_data_adam(self, device: DeviceZoneData, data: DeviceZoneData) -> Non self._count += 1 - def _devzone_data_climate( + def _climate_data( self, location_id: str, - devzone: DeviceZoneData, - data: DeviceZoneData + entity: GwEntityData, + data: GwEntityData ) -> None: - """Helper-function for _get_device_zone_data(). + """Helper-function for _get_entity_data(). - Determine climate-control device data. + Determine climate-control entity data. """ loc_id = location_id - if devzone.get("location") is not None: - loc_id = devzone["location"] + if entity.get("location") is not None: + loc_id = entity["location"] # Presets data["preset_modes"] = None @@ -286,13 +286,13 @@ def _devzone_data_climate( def check_reg_mode(self, mode: str) -> bool: """Helper-function for device_data_climate().""" - gateway = self.gw_device_zones[self.gateway_id] + gateway = self.gw_entities[self.gateway_id] return ( "regulation_modes" in gateway and gateway["select_regulation_mode"] == mode ) def _get_schedule_states_with_off( - self, location: str, schedules: list[str], selected: str, data: DeviceZoneData + self, location: str, schedules: list[str], selected: str, data: GwEntityData ) -> None: """Collect schedules with states for each thermostat. diff --git a/plugwise/helper.py b/plugwise/helper.py index e4b0615f0..34ae49493 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -36,8 +36,8 @@ ActuatorData, ActuatorDataType, ActuatorType, - DeviceZoneData, GatewayData, + GwEntityData, SensorType, ThermoLoc, ToggleNameType, @@ -250,7 +250,7 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} - self.gw_device_zones: dict[str, DeviceZoneData] = {} + self.gw_entities: dict[str, GwEntityData] = {} self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None @@ -261,7 +261,7 @@ def __init__(self) -> None: self.smile_type: str self.smile_zigbee_mac_address: str | None self.therms_with_offset_func: list[str] = [] - self.zone_data: dict[str, DeviceZoneData] = {} + self.zone_data: dict[str, GwEntityData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -303,7 +303,7 @@ def _all_appliances(self) -> None: continue appl.available = None - appl.dev_id = appliance.attrib["id"] + appl.entity_id = appliance.attrib["id"] appl.name = appliance.find("name").text appl.model = None appl.model_id = None @@ -317,18 +317,18 @@ def _all_appliances(self) -> None: if not (appl := self._appliance_info_finder(appl, appliance)): continue - # P1: for gateway and smartmeter switch device_id - part 1 + # P1: for gateway and smartmeter switch entity_id - part 1 # This is done to avoid breakage in HA Core if appl.pwclass == "gateway" and self.smile_type == "power": - appl.dev_id = appl.location + appl.entity_id = appl.location - self._create_gw_device_zones(appl) + self._create_gw_entities(appl) # For P1 collect the connected SmartMeter info if self.smile_type == "power": self._p1_smartmeter_info_finder(appl) - # P1: for gateway and smartmeter switch device_id - part 2 - for item in self.gw_device_zones: + # P1: for gateway and smartmeter switch entity_id - part 2 + for item in self.gw_entities: if item != self.gateway_id: self.gateway_id = item # Leave for-loop to avoid a 2nd device_id switch @@ -336,13 +336,13 @@ def _all_appliances(self) -> None: # Place the gateway and optional heater_central devices as 1st and 2nd for dev_class in ("heater_central", "gateway"): - for dev_id, device in dict(self.gw_device_zones).items(): - if device["dev_class"] == dev_class: - tmp_device = device - self.gw_device_zones.pop(dev_id) - cleared_dict = self.gw_device_zones - add_to_front = {dev_id: tmp_device} - self.gw_device_zones = {**add_to_front, **cleared_dict} + for entity_id, entity in dict(self.gw_entities).items(): + if entity["dev_class"] == dev_class: + tmp_entity = entity + self.gw_entities.pop(entity_id) + cleared_dict = self.gw_entities + add_to_front = {entity_id: tmp_entity} + self.gw_entities = {**add_to_front, **cleared_dict} def _all_locations(self) -> None: """Collect all locations.""" @@ -366,7 +366,7 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: LOGGER.error("No module data found for SmartMeter") # pragma: no cover return None # pragma: no cover - appl.dev_id = self.gateway_id + appl.entity_id = self.gateway_id appl.firmware = module_data["firmware_version"] appl.hardware = module_data["hardware_version"] appl.location = loc_id @@ -378,7 +378,7 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: appl.vendor_name = module_data["vendor_name"] appl.zigbee_mac = None - self._create_gw_device_zones(appl) + self._create_gw_entities(appl) def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: """Collect info for all appliances found.""" @@ -394,7 +394,7 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch: self._appl_heater_central_info(appl, appliance, False) # False means non-legacy device self._appl_dhw_mode_info(appl, appliance) # Skip orphaned heater_central (Core Issue #104433) - if appl.dev_id != self._heater_id: + if appl.entity_id != self._heater_id: return Munch() return appl case _ as s if s.endswith("_plug"): @@ -482,12 +482,12 @@ def _get_appliances_with_offset_functionality(self) -> list[str]: return therm_list - def _get_zone_data(self, loc_id: str) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_zone_data(). + def _get_zone_data(self, loc_id: str) -> GwEntityData: + """Helper-function for smile.py: _get_entity_data(). Collect the location-data based on location id. """ - data: DeviceZoneData = {"sensors": {}} + data: GwEntityData = {"sensors": {}} zone = self.zone_data[loc_id] measurements = ZONE_MEASUREMENTS if ( @@ -498,24 +498,24 @@ def _get_zone_data(self, loc_id: str) -> DeviceZoneData: return data - def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_zone_data(). + def _get_measurement_data(self, entity_id: str) -> GwEntityData: + """Helper-function for smile.py: _get_entity_data(). - Collect the appliance-data based on device id. + Collect the appliance-data based on entity_id. """ - data: DeviceZoneData = {"binary_sensors": {}, "sensors": {}, "switches": {}} + data: GwEntityData = {"binary_sensors": {}, "sensors": {}, "switches": {}} # Get P1 smartmeter data from LOCATIONS - device = self.gw_device_zones[dev_id] + entity = self.gw_entities[entity_id] # !! DON'T CHANGE below two if-lines, will break stuff !! if self.smile_type == "power": - if device["dev_class"] == "smartmeter": - data.update(self._power_data_from_location(device["location"])) + if entity["dev_class"] == "smartmeter": + data.update(self._power_data_from_location(entity["location"])) return data # Get non-P1 data from APPLIANCES measurements = DEVICE_MEASUREMENTS - if self._is_thermostat and dev_id == self._heater_id: + if self._is_thermostat and entity_id == self._heater_id: measurements = HEATER_CENTRAL_MEASUREMENTS # Show the allowed dhw_modes (Loria only) if self._dhw_allowed_modes: @@ -523,7 +523,7 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: # Counting of this item is done in _appliance_measurements() if ( - appliance := self._domain_objects.find(f'./appliance[@id="{dev_id}"]') + appliance := self._domain_objects.find(f'./appliance[@id="{entity_id}"]') ) is not None: self._appliance_measurements(appliance, data, measurements) self._get_lock_state(appliance, data) @@ -532,11 +532,11 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: self._get_toggle_state(appliance, toggle, name, data) if appliance.find("type").text in ACTUATOR_CLASSES: - self._get_actuator_functionalities(appliance, device, data) + self._get_actuator_functionalities(appliance, entity, data) - self._get_regulation_mode(appliance, dev_id, data) - self._get_gateway_mode(appliance, dev_id, data) - self._get_gateway_outdoor_temp(dev_id, data) + self._get_regulation_mode(appliance, entity_id, data) + self._get_gateway_mode(appliance, entity_id, data) + self._get_gateway_outdoor_temp(entity_id, data) if "c_heating_state" in data: self._process_c_heating_state(data) @@ -545,14 +545,14 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: self._count -= 1 if self._is_thermostat and self.smile(ANNA): - self._update_anna_cooling(dev_id, data) + self._update_anna_cooling(entity_id, data) - def _power_data_from_location(self, loc_id: str) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_zone_data(). + def _power_data_from_location(self, loc_id: str) -> GwEntityData: + """Helper-function for smile.py: _get_entity_data(). Collect the power-data based on Location ID, from LOCATIONS. """ - direct_data: DeviceZoneData = {"sensors": {}} + direct_data: GwEntityData = {"sensors": {}} loc = Munch() log_list: list[str] = ["point_log", "cumulative_log", "interval_log"] t_string = "tariff" @@ -569,7 +569,7 @@ def _power_data_from_location(self, loc_id: str) -> DeviceZoneData: def _appliance_measurements( self, appliance: etree, - data: DeviceZoneData, + data: GwEntityData, measurements: dict[str, DATA | UOM], ) -> None: """Helper-function for _get_measurement_data() - collect appliance measurement data.""" @@ -607,7 +607,7 @@ def _appliance_measurements( self._count += len(data) - 3 def _get_toggle_state( - self, xml: etree, toggle: str, name: ToggleNameType, data: DeviceZoneData + self, xml: etree, toggle: str, name: ToggleNameType, data: GwEntityData ) -> None: """Helper-function for _get_measurement_data(). @@ -636,7 +636,7 @@ def _get_plugwise_notifications(self) -> None: ) def _get_actuator_functionalities( - self, xml: etree, device: DeviceZoneData, data: DeviceZoneData + self, xml: etree, entity: GwEntityData, data: GwEntityData ) -> None: """Helper-function for _get_measurement_data().""" for item in ACTIVE_ACTUATORS: @@ -644,7 +644,7 @@ def _get_actuator_functionalities( # skip thermostat for all but zones with thermostats if item == "max_dhw_temperature" or ( item == "thermostat" and ( - device["dev_class"] != "climate" if self.smile(ADAM) else device["dev_class"] != "thermostat" + entity["dev_class"] != "climate" if self.smile(ADAM) else entity["dev_class"] != "thermostat" ) ): continue @@ -692,13 +692,13 @@ def _get_actuator_functionalities( data[act_item] = temp_dict def _get_regulation_mode( - self, appliance: etree, dev_id: str, data: DeviceZoneData + self, appliance: etree, entity_id: str, data: GwEntityData ) -> None: """Helper-function for _get_measurement_data(). Adam: collect the gateway regulation_mode. """ - if not (self.smile(ADAM) and dev_id == self.gateway_id): + if not (self.smile(ADAM) and entity_id == self.gateway_id): return locator = "./actuator_functionalities/regulation_mode_control_functionality" @@ -708,13 +708,13 @@ def _get_regulation_mode( self._cooling_enabled = data["select_regulation_mode"] == "cooling" def _get_gateway_mode( - self, appliance: etree, dev_id: str, data: DeviceZoneData + self, appliance: etree, entity_id: str, data: GwEntityData ) -> None: """Helper-function for _get_measurement_data(). Adam: collect the gateway mode. """ - if not (self.smile(ADAM) and dev_id == self.gateway_id): + if not (self.smile(ADAM) and entity_id == self.gateway_id): return locator = "./actuator_functionalities/gateway_mode_control_functionality" @@ -722,12 +722,12 @@ def _get_gateway_mode( data["select_gateway_mode"] = search.find("mode").text self._count += 1 - def _get_gateway_outdoor_temp(self, dev_id: str, data: DeviceZoneData) -> None: + def _get_gateway_outdoor_temp(self, entity_id: str, data: GwEntityData) -> None: """Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS. Available under the Home location. """ - if self._is_thermostat and dev_id == self.gateway_id: + if self._is_thermostat and entity_id == self.gateway_id: outdoor_temperature = self._object_value( self._home_location, "outdoor_temperature" ) @@ -736,7 +736,7 @@ def _get_gateway_outdoor_temp(self, dev_id: str, data: DeviceZoneData) -> None: self._count += 1 def _object_value(self, obj_id: str, measurement: str) -> float | int | None: - """Helper-function for smile.py: _get_device_zone_data() and _device_data_anna(). + """Helper-function for smile.py: _get_entity_data(). Obtain the value/state for the given object from a location in DOMAIN_OBJECTS """ @@ -748,7 +748,7 @@ def _object_value(self, obj_id: str, measurement: str) -> float | int | None: return val - def _process_c_heating_state(self, data: DeviceZoneData) -> None: + def _process_c_heating_state(self, data: GwEntityData) -> None: """Helper-function for _get_measurement_data(). Process the central_heating_state value. @@ -761,7 +761,7 @@ def _process_c_heating_state(self, data: DeviceZoneData) -> None: if self._elga: data["binary_sensors"]["heating_state"] = data["c_heating_state"] - def _process_on_off_device_c_heating_state(self, data: DeviceZoneData) -> None: + def _process_on_off_device_c_heating_state(self, data: GwEntityData) -> None: """Adam or Anna + OnOff device - use central_heating_state to show heating/cooling_state. Solution for Core issue #81839. @@ -781,12 +781,12 @@ def _process_on_off_device_c_heating_state(self, data: DeviceZoneData) -> None: else: data["binary_sensors"]["heating_state"] = data["c_heating_state"] - def _update_anna_cooling(self, dev_id: str, data: DeviceZoneData) -> None: + def _update_anna_cooling(self, entity_id: str, data: GwEntityData) -> None: """Update the Anna heater_central device for cooling. Support added for Techneco Elga and Thercon Loria/Thermastage. """ - if dev_id != self._heater_id: + if entity_id != self._heater_id: return if "elga_status_code" in data: @@ -796,7 +796,7 @@ def _update_anna_cooling(self, dev_id: str, data: DeviceZoneData) -> None: self._cleanup_data(data) - def _update_elga_cooling(self, data: DeviceZoneData) -> None: + def _update_elga_cooling(self, data: GwEntityData) -> None: """# Anna+Elga: base cooling_state on the elga-status-code.""" if data["thermostat_supports_cooling"]: # Techneco Elga has cooling-capability @@ -814,7 +814,7 @@ def _update_elga_cooling(self, data: DeviceZoneData) -> None: data.pop("elga_status_code", None) self._count -= 1 - def _update_loria_cooling(self, data: DeviceZoneData) -> None: + def _update_loria_cooling(self, data: GwEntityData) -> None: """Loria/Thermastage: base cooling-related on cooling_state and modulation_level.""" self._cooling_enabled = data["binary_sensors"]["cooling_state"] self._cooling_active = data["sensors"]["modulation_level"] == 100 @@ -823,7 +823,7 @@ def _update_loria_cooling(self, data: DeviceZoneData) -> None: self._cooling_enabled = data["switches"]["cooling_ena_switch"] self._cooling_active = data["binary_sensors"]["cooling_state"] - def _cleanup_data(self, data: DeviceZoneData) -> None: + def _cleanup_data(self, data: GwEntityData) -> None: """Helper-function for _get_measurement_data(). Clean up the data dict. @@ -846,7 +846,7 @@ def _cleanup_data(self, data: DeviceZoneData) -> None: self._count -= 1 def _scan_thermostats(self) -> None: - """Helper-function for smile.py: get_all_devices(). + """Helper-function for smile.py: get_all_entities(). Update locations with thermostat ranking results and use the result to update the device_class of secondary thermostats. @@ -861,8 +861,8 @@ def _scan_thermostats(self) -> None: } for loc_id in self._thermo_locs: - for dev_id, device in self.gw_device_zones.items(): - self._rank_thermostat(thermo_matching, loc_id, dev_id, device) + for entity_id, entity in self.gw_entities.items(): + self._rank_thermostat(thermo_matching, loc_id, entity_id, entity) for loc_id, loc_data in list(self._thermo_locs.items()): if loc_data["primary_prio"] != 0: @@ -880,7 +880,7 @@ def _match_locations(self) -> dict[str, ThermoLoc]: """ matched_locations: dict[str, ThermoLoc] = {} for location_id, location_details in self.loc_data.items(): - for appliance_details in self.gw_device_zones.values(): + for appliance_details in self.gw_entities.values(): if appliance_details["location"] == location_id: location_details.update( {"primary": [], "primary_prio": 0, "secondary": []} @@ -894,7 +894,7 @@ def _rank_thermostat( thermo_matching: dict[str, int], loc_id: str, appliance_id: str, - appliance_details: DeviceZoneData, + appliance_details: GwEntityData, ) -> None: """Helper-function for _scan_thermostats(). @@ -918,7 +918,7 @@ def _rank_thermostat( self._thermo_locs[loc_id]["secondary"].append(appliance_id) def _control_state(self, loc_id: str) -> str | bool: - """Helper-function for _device_data_adam(). + """Helper-function for _get_adam_data(). Adam: find the thermostat control_state of a location, from DOMAIN_OBJECTS. Represents the heating/cooling demand-state of the local primary thermostat. @@ -933,7 +933,7 @@ def _control_state(self, loc_id: str) -> str | bool: return False def _heating_valves(self) -> int | bool: - """Helper-function for smile.py: _device_data_adam(). + """Helper-function for smile.py: _get_adam_data(). Collect amount of open valves indicating active direct heating. For cases where the heat is provided from an external shared source (city heating). @@ -1018,7 +1018,7 @@ def _rule_ids_by_tag(self, tag: str, loc_id: str) -> dict[str, dict[str, str]]: return schedule_ids def _schedules(self, location: str) -> tuple[list[str], str]: - """Helper-function for smile.py: _device_data_climate(). + """Helper-function for smile.py: _climate_data(). Obtain the available schedules/schedules. Adam: a schedule can be connected to more than one location. NEW: when a location_id is present then the schedule is active. Valid for both Adam and non-legacy Anna. diff --git a/plugwise/legacy/data.py b/plugwise/legacy/data.py index 896ea85ff..66b089ead 100644 --- a/plugwise/legacy/data.py +++ b/plugwise/legacy/data.py @@ -6,7 +6,7 @@ # Dict as class # Version detection -from plugwise.constants import NONE, OFF, DeviceZoneData +from plugwise.constants import NONE, OFF, GwEntityData from plugwise.legacy.helper import SmileLegacyHelper from plugwise.util import remove_empty_platform_dicts @@ -18,12 +18,12 @@ def __init__(self) -> None: """Init.""" SmileLegacyHelper.__init__(self) - def _all_device_data(self) -> None: - """Helper-function for get_all_devices(). + def _all_entity_data(self) -> None: + """Helper-function for get_all_gateway_entities(). - Collect data for each device and add to self.gw_data and self.gw_device_zones. + Collect data for each entity and add to self.gw_data and self.gw_entities. """ - self._update_gw_devices() + self._update_gw_entities() self.gw_data.update( { "gateway_id": self.gateway_id, @@ -36,40 +36,40 @@ def _all_device_data(self) -> None: {"heater_id": self._heater_id, "cooling_present": False} ) - def _update_gw_devices(self) -> None: - """Helper-function for _all_device_data() and async_update(). + def _update_gw_entities(self) -> None: + """Helper-function for _all_entity_data() and async_update(). - Collect data for each device and add to self.gw_device_zones. + Collect data for each entity and add to self.gw_entities. """ - for device_id, device in self.gw_device_zones.items(): - data = self._get_device_data(device_id) - device.update(data) - remove_empty_platform_dicts(device) + for entity_id, entity in self.gw_entities.items(): + data = self._get_entity_data(entity_id) + entity.update(data) + remove_empty_platform_dicts(entity) - def _get_device_data(self, dev_id: str) -> DeviceZoneData: - """Helper-function for _all_device_data() and async_update(). + def _get_entity_data(self, entity_id: str) -> GwEntityData: + """Helper-function for _all_entity_data() and async_update(). - Provide device-data, based on Location ID (= dev_id), from APPLIANCES. + Provide entity-data, based on Location ID (= entity_id), from APPLIANCES. """ - device = self.gw_device_zones[dev_id] - data = self._get_measurement_data(dev_id) + entity = self.gw_entities[entity_id] + data = self._get_measurement_data(entity_id) # Switching groups data - self._device_data_switching_group(device, data) + self._entity_switching_group(entity, data) # Skip obtaining data when not a thermostat - if device["dev_class"] != "thermostat": + if entity["dev_class"] != "thermostat": return data # Thermostat data (presets, temperatures etc) - self._device_data_climate(device, data) + self._climate_data(entity, data) return data - def _device_data_climate(self, device: DeviceZoneData, data: DeviceZoneData) -> None: - """Helper-function for _get_device_data(). + def _climate_data(self, entity: GwEntityData, data: GwEntityData) -> None: + """Helper-function for _get_entity_data(). - Determine climate-control device data. + Determine climate-control entity data. """ # Presets data["preset_modes"] = None diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 42c0e1eb1..088364b7e 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -29,7 +29,7 @@ ActuatorDataType, ActuatorType, ApplianceType, - DeviceZoneData, + GwEntityData, GatewayData, SensorType, ThermoLoc, @@ -80,7 +80,7 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} - self.gw_device_zones: dict[str, DeviceZoneData] = {} + self.gw_entities: dict[str, GwEntityData] = {} self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None @@ -89,7 +89,7 @@ def __init__(self) -> None: self.smile_name: str self.smile_type: str self.smile_zigbee_mac_address: str | None - self.zone_data: dict[str, DeviceZoneData] = {} + self.zone_data: dict[str, GwEntityData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -116,7 +116,7 @@ def _all_appliances(self) -> None: continue # pragma: no cover appl.location = self._home_location - appl.dev_id = appliance.attrib["id"] + appl.entity_id = appliance.attrib["id"] appl.name = appliance.find("name").text # Extend device_class name when a Circle/Stealth is type heater_central -- Pw-Beta Issue #739 if ( @@ -140,20 +140,20 @@ def _all_appliances(self) -> None: continue # Skip orphaned heater_central (Core Issue #104433) - if appl.pwclass == "heater_central" and appl.dev_id != self._heater_id: + if appl.pwclass == "heater_central" and appl.entity_id != self._heater_id: continue # pragma: no cover - self._create_gw_device_zones(appl) + self._create_gw_entities(appl) # Place the gateway and optional heater_central devices as 1st and 2nd for dev_class in ("heater_central", "gateway"): - for dev_id, device in dict(self.gw_device_zones).items(): - if device["dev_class"] == dev_class: - tmp_device = device - self.gw_device_zones.pop(dev_id) - cleared_dict = self.gw_device_zones - add_to_front = {dev_id: tmp_device} - self.gw_device_zones = {**add_to_front, **cleared_dict} + for entity_id, entity in dict(self.gw_entities).items(): + if entity["dev_class"] == dev_class: + tmp_entity = entity + self.gw_entities.pop(entity_id) + cleared_dict = self.gw_entities + add_to_front = {entity_id: tmp_entity} + self.gw_entities = {**add_to_front, **cleared_dict} def _all_locations(self) -> None: """Collect all locations.""" @@ -186,15 +186,15 @@ def _all_locations(self) -> None: self.loc_data[loc.loc_id] = {"name": loc.name} def _create_legacy_gateway(self) -> None: - """Create the (missing) gateway devices for legacy Anna, P1 and Stretch. + """Create the (missing) gateway entities for legacy Anna, P1 and Stretch. - Use the home_location or FAKE_APPL as device id. + Use the home_location or FAKE_APPL as entity id. """ self.gateway_id = self._home_location if self.smile_type == "power": self.gateway_id = FAKE_APPL - self.gw_device_zones[self.gateway_id] = {"dev_class": "gateway"} + self.gw_entities[self.gateway_id] = {"dev_class": "gateway"} self._count += 1 for key, value in { "firmware": str(self.smile_fw_version), @@ -207,28 +207,28 @@ def _create_legacy_gateway(self) -> None: }.items(): if value is not None: gw_key = cast(ApplianceType, key) - self.gw_device_zones[self.gateway_id][gw_key] = value + self.gw_entities[self.gateway_id][gw_key] = value self._count += 1 def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch: - """Collect device info (Smile/Stretch, Thermostats, OpenTherm/On-Off): firmware, model and vendor name.""" + """Collect entity info (Smile/Stretch, Thermostats, OpenTherm/On-Off): firmware, model and vendor name.""" match appl.pwclass: - # Collect thermostat device info + # Collect thermostat entity info case _ as dev_class if dev_class in THERMOSTAT_CLASSES: return self._appl_thermostat_info(appl, appliance, self._modules) - # Collect heater_central device info + # Collect heater_central entity info case "heater_central": return self._appl_heater_central_info( appl, appliance, True, self._appliances, self._modules ) # True means legacy device # Collect info from Stretches case _: - return self._energy_device_info_finder(appliance, appl) + return self._energy_entity_info_finder(appliance, appl) - def _energy_device_info_finder(self, appliance: etree, appl: Munch) -> Munch: + def _energy_entity_info_finder(self, appliance: etree, appl: Munch) -> Munch: """Helper-function for _appliance_info_finder(). - Collect energy device info (Smartmeter, Circle, Stealth, etc.): firmware, model and vendor name. + Collect energy entity info (Smartmeter, Circle, Stealth, etc.): firmware, model and vendor name. """ if self.smile_type in ("power", "stretch"): locator = "./services/electricity_point_meter" @@ -254,7 +254,7 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: """Collect P1 DSMR Smartmeter info.""" loc_id = next(iter(self.loc_data.keys())) appl.available = None - appl.dev_id = loc_id + appl.entity_id = loc_id appl.location = loc_id appl.mac = None appl.model = self.smile_model @@ -263,41 +263,41 @@ def _p1_smartmeter_info_finder(self, appl: Munch) -> None: appl.pwclass = "smartmeter" appl.zigbee_mac = None location = self._locations.find(f'./location[@id="{loc_id}"]') - appl = self._energy_device_info_finder(location, appl) + appl = self._energy_entity_info_finder(location, appl) - self._create_gw_device_zones(appl) + self._create_gw_entities(appl) - def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_data(). + def _get_measurement_data(self, entity_id: str) -> GwEntityData: + """Helper-function for smile.py: _get_entity_data(). - Collect the appliance-data based on device id. + Collect the appliance-data based on entity_id. """ - data: DeviceZoneData = {"binary_sensors": {}, "sensors": {}, "switches": {}} + data: GwEntityData = {"binary_sensors": {}, "sensors": {}, "switches": {}} # Get P1 smartmeter data from LOCATIONS or MODULES - device = self.gw_device_zones[dev_id] + entity = self.gw_entities[entity_id] # !! DON'T CHANGE below two if-lines, will break stuff !! if self.smile_type == "power": - if device["dev_class"] == "smartmeter": + if entity["dev_class"] == "smartmeter": data.update(self._power_data_from_modules()) return data measurements = DEVICE_MEASUREMENTS - if self._is_thermostat and dev_id == self._heater_id: + if self._is_thermostat and entity_id == self._heater_id: measurements = HEATER_CENTRAL_MEASUREMENTS if ( - appliance := self._appliances.find(f'./appliance[@id="{dev_id}"]') + appliance := self._appliances.find(f'./appliance[@id="{entity_id}"]') ) is not None: self._appliance_measurements(appliance, data, measurements) self._get_lock_state(appliance, data, self._stretch_v2) if appliance.find("type").text in ACTUATOR_CLASSES: - self._get_actuator_functionalities(appliance, device, data) + self._get_actuator_functionalities(appliance, entity, data) # Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS - under Home # The outdoor_temperature present in APPLIANCES is a local sensor connected to the active device - if self._is_thermostat and dev_id == self.gateway_id: + if self._is_thermostat and entity_id == self.gateway_id: outdoor_temperature = self._object_value( self._home_location, "outdoor_temperature" ) @@ -311,12 +311,12 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData: return data - def _power_data_from_modules(self) -> DeviceZoneData: - """Helper-function for smile.py: _get_device_data(). + def _power_data_from_modules(self) -> GwEntityData: + """Helper-function for smile.py: _get_entity_data(). Collect the power-data from MODULES (P1 legacy only). """ - direct_data: DeviceZoneData = {"sensors": {}} + direct_data: GwEntityData = {"sensors": {}} loc = Munch() mod_list: list[str] = ["interval_meter", "cumulative_meter", "point_meter"] t_string = "tariff_indicator" @@ -335,7 +335,7 @@ def _power_data_from_modules(self) -> DeviceZoneData: def _appliance_measurements( self, appliance: etree, - data: DeviceZoneData, + data: GwEntityData, measurements: dict[str, DATA | UOM], ) -> None: """Helper-function for _get_measurement_data() - collect appliance measurement data.""" @@ -369,15 +369,15 @@ def _appliance_measurements( def _get_actuator_functionalities( self, xml: etree, - device: DeviceZoneData, - data: DeviceZoneData + entity: GwEntityData, + data: GwEntityData ) -> None: """Helper-function for _get_measurement_data().""" for item in ACTIVE_ACTUATORS: # Skip max_dhw_temperature, not initially valid, # skip thermostat for thermo_sensors if item == "max_dhw_temperature" or ( - item == "thermostat" and device["dev_class"] == "thermo_sensor" + item == "thermostat" and entity["dev_class"] == "thermo_sensor" ): continue @@ -405,7 +405,7 @@ def _get_actuator_functionalities( data[act_item] = temp_dict def _object_value(self, obj_id: str, measurement: str) -> float | int | None: - """Helper-function for smile.py: _get_device_data() and _device_data_anna(). + """Helper-function for smile.py: _get_entity_data(). Obtain the value/state for the given object from a location in DOMAIN_OBJECTS """ @@ -419,7 +419,7 @@ def _object_value(self, obj_id: str, measurement: str) -> float | int | None: return val def _preset(self) -> str | None: - """Helper-function for smile.py: device_data_climate(). + """Helper-function for smile.py: _climate_data(). Collect the active preset based on the active rule. """ diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 3bd701b0e..a08f42446 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -19,8 +19,8 @@ OFF, REQUIRE_APPLIANCES, RULES, - DeviceZoneData, GatewayData, + GwEntityData, PlugwiseData, ThermoLoc, ) @@ -82,7 +82,7 @@ def __init__( self._previous_day_number: str = "0" - async def full_update_device(self) -> None: + async def full_xml_update(self) -> None: """Perform a first fetch of all XML data, needed for initialization.""" self._domain_objects = await self.request(DOMAIN_OBJECTS) self._locations = await self.request(LOCATIONS) @@ -91,8 +91,8 @@ async def full_update_device(self) -> None: if self.smile_type != "power": self._appliances = await self.request(APPLIANCES) - def get_all_device_zones(self) -> None: - """Determine the devices present from the obtained XML-data. + def get_all_gateway_entities(self) -> None: + """Collect the gateway entities from the received raw XML-data. Run this functions once to gather the initial device configuration, then regularly run async_update() to refresh the device data. @@ -102,10 +102,10 @@ def get_all_device_zones(self) -> None: # Collect and add switching- and/or pump-group devices if group_data := self._get_group_switches(): - self.gw_device_zones.update(group_data) + self.gw_entities.update(group_data) - # Collect the remaining data for all devices - self._all_device_data() + # Collect the remaining data for all entities + self._all_entity_data() async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" @@ -119,9 +119,9 @@ async def async_update(self) -> PlugwiseData: "Performing daily full-update, reload the Plugwise integration when a single entity becomes unavailable." ) self.gw_data: GatewayData = {} - self.gw_device_zones: dict[str, DeviceZoneData] = {} - await self.full_update_device() - self.get_all_device_zones() + self.gw_entities: dict[str, GwEntityData] = {} + await self.full_xml_update() + self.get_all_gateway_entities() # Otherwise perform an incremental update else: self._domain_objects = await self.request(DOMAIN_OBJECTS) @@ -131,11 +131,11 @@ async def async_update(self) -> PlugwiseData: case self._target_smile if self._target_smile in REQUIRE_APPLIANCES: self._appliances = await self.request(APPLIANCES) - self._update_gw_devices() + self._update_gw_entities() self._previous_day_number = day_number return PlugwiseData( - device_zones=self.gw_device_zones, + entities=self.gw_entities, gateway=self.gw_data, ) diff --git a/plugwise/smile.py b/plugwise/smile.py index 5b5fc9b9a..6a062d215 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -22,8 +22,8 @@ NOTIFICATIONS, OFF, RULES, - DeviceZoneData, GatewayData, + GwEntityData, PlugwiseData, ThermoLoc, ) @@ -94,18 +94,18 @@ def __init__( self._heater_id: str self._cooling_enabled = False - async def full_update_device(self) -> None: + async def full_xml_update(self) -> None: """Perform a first fetch of all XML data, needed for initialization.""" self._domain_objects = await self.request(DOMAIN_OBJECTS) self._get_plugwise_notifications() - def get_all_device_zones(self) -> None: - """Determine the evices present from the obtained XML-data. + def get_all_gateway_entities(self) -> None: + """Collect the gateway entities from the received raw XML-data. - Run this functions once to gather the initial device configuration, - then regularly run async_update() to refresh the device data. + Run this functions once to gather the initial configuration, + then regularly run async_update() to refresh the entity data. """ - # Gather all the devices and their initial data + # Gather all the entities and their initial data self._all_appliances() if self._is_thermostat: if self.smile(ADAM): @@ -117,21 +117,21 @@ def get_all_device_zones(self) -> None: # Collect and add switching- and/or pump-group devices if group_data := self._get_group_switches(): - self.gw_device_zones.update(group_data) + self.gw_entities.update(group_data) - # Collect the remaining data for all devices - self._all_device_zone_data() + # Collect the remaining data for all entities + self._all_entity_data() async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" self.gw_data: GatewayData = {} - self.gw_device_zones: dict[str, DeviceZoneData] = {} - self.zone_data: dict[str, DeviceZoneData] = {} + self.gw_entities: dict[str, GwEntityData] = {} + self.zones: dict[str, GwEntityData] = {} try: - await self.full_update_device() - self.get_all_device_zones() + await self.full_xml_update() + self.get_all_gateway_entities() if "heater_id" in self.gw_data: - heat_cooler = self.gw_device_zones[self.gw_data["heater_id"]] + heat_cooler = self.gw_entities[self.gw_data["heater_id"]] if ( "binary_sensors" in heat_cooler and "cooling_enabled" in heat_cooler["binary_sensors"] @@ -141,7 +141,7 @@ async def async_update(self) -> PlugwiseData: raise DataMissingError("No Plugwise data received") from err return PlugwiseData( - device_zones=self.gw_device_zones, + entities=self.gw_entities, gateway=self.gw_data, ) diff --git a/plugwise/util.py b/plugwise/util.py index d14983160..bfa804724 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -22,7 +22,7 @@ TEMP_CELSIUS, UOM, BinarySensorType, - DeviceZoneData, + GwEntityData, ModelData, SensorType, SpecialType, @@ -122,7 +122,7 @@ def common_match_cases( measurement: str, attrs: DATA | UOM, location: etree, - data: DeviceZoneData, + data: GwEntityData, ) -> None: """Helper-function for common match-case execution.""" value = location.text in ("on", "true") @@ -202,7 +202,7 @@ def power_data_local_format( return format_measure(val, attrs_uom) -def remove_empty_platform_dicts(data: DeviceZoneData) -> None: +def remove_empty_platform_dicts(data: GwEntityData) -> None: """Helper-function for removing any empty platform dicts.""" if not data["binary_sensors"]: data.pop("binary_sensors") From a7ac3a7ca97e8ff6db3c6e5d67316551f202208f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:35:15 +0000 Subject: [PATCH 054/106] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugwise/legacy/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 088364b7e..709912b38 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -29,8 +29,8 @@ ActuatorDataType, ActuatorType, ApplianceType, - GwEntityData, GatewayData, + GwEntityData, SensorType, ThermoLoc, ) From 60b28800ed9e87fb1fdb32e04b3b96b6f20fb434 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 15:38:55 +0100 Subject: [PATCH 055/106] Clean up --- plugwise/common.py | 2 +- plugwise/helper.py | 14 +++++++------- plugwise/legacy/helper.py | 8 ++++---- plugwise/util.py | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index 7ccb6d183..70c661878 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -171,7 +171,7 @@ def _power_data_energy_diff( diff = 1 if "produced" in measurement: diff = -1 - if net_string not in direct_data["sensors"]: + if net_string not in data["sensors"]: tmp_val: float | int = 0 else: tmp_val = data["sensors"][net_string] diff --git a/plugwise/helper.py b/plugwise/helper.py index 34ae49493..6a190b556 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -261,7 +261,7 @@ def __init__(self) -> None: self.smile_type: str self.smile_zigbee_mac_address: str | None self.therms_with_offset_func: list[str] = [] - self.zone_data: dict[str, GwEntityData] = {} + self.zones: dict[str, GwEntityData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -488,7 +488,7 @@ def _get_zone_data(self, loc_id: str) -> GwEntityData: Collect the location-data based on location id. """ data: GwEntityData = {"sensors": {}} - zone = self.zone_data[loc_id] + zone = self.zones[loc_id] measurements = ZONE_MEASUREMENTS if ( location := self._domain_objects.find(f'./location[@id="{loc_id}"]') @@ -552,7 +552,7 @@ def _power_data_from_location(self, loc_id: str) -> GwEntityData: Collect the power-data based on Location ID, from LOCATIONS. """ - direct_data: GwEntityData = {"sensors": {}} + data: GwEntityData = {"sensors": {}} loc = Munch() log_list: list[str] = ["point_log", "cumulative_log", "interval_log"] t_string = "tariff" @@ -561,10 +561,10 @@ def _power_data_from_location(self, loc_id: str) -> GwEntityData: loc.logs = search.find(f'./location[@id="{loc_id}"]/logs') for loc.measurement, loc.attrs in P1_MEASUREMENTS.items(): for loc.log_type in log_list: - self._collect_power_values(direct_data, loc, t_string) + self._collect_power_values(data, loc, t_string) - self._count += len(direct_data["sensors"]) - return direct_data + self._count += len(data["sensors"]) + return data def _appliance_measurements( self, @@ -866,7 +866,7 @@ def _scan_thermostats(self) -> None: for loc_id, loc_data in list(self._thermo_locs.items()): if loc_data["primary_prio"] != 0: - self.zone_data[loc_id] = { + self.zones[loc_id] = { "dev_class": "climate", "name": loc_data["name"], "thermostats": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 709912b38..c9a2acb75 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -316,7 +316,7 @@ def _power_data_from_modules(self) -> GwEntityData: Collect the power-data from MODULES (P1 legacy only). """ - direct_data: GwEntityData = {"sensors": {}} + data: GwEntityData = {"sensors": {}} loc = Munch() mod_list: list[str] = ["interval_meter", "cumulative_meter", "point_meter"] t_string = "tariff_indicator" @@ -327,10 +327,10 @@ def _power_data_from_modules(self) -> GwEntityData: loc.meas_list = loc.measurement.split("_") for loc.logs in mod_logs: for loc.log_type in mod_list: - self._collect_power_values(direct_data, loc, t_string, legacy=True) + self._collect_power_values(data, loc, t_string, legacy=True) - self._count += len(direct_data["sensors"]) - return direct_data + self._count += len(data["sensors"]) + return data def _appliance_measurements( self, diff --git a/plugwise/util.py b/plugwise/util.py index bfa804724..7beec330e 100644 --- a/plugwise/util.py +++ b/plugwise/util.py @@ -23,7 +23,7 @@ UOM, BinarySensorType, GwEntityData, - ModelData, + ModuleData, SensorType, SpecialType, SwitchType, @@ -179,7 +179,7 @@ def format_measure(measure: str, unit: str) -> float | int: return result -def get_vendor_name(module: etree, model_data: ModelData) -> ModelData: +def get_vendor_name(module: etree, model_data: ModuleData) -> ModuleData: """Helper-function for _get_model_data().""" if (vendor_name := module.find("vendor_name").text) is not None: model_data["vendor_name"] = vendor_name From 0c689a569a416e52f37ad5017a366afb4f556c37 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 16:04:47 +0100 Subject: [PATCH 056/106] Adapt test-code --- tests/test_init.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_init.py b/tests/test_init.py index 87d933cbc..9119021d3 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -605,8 +605,8 @@ def test_and_assert(test_dict, data, header): if initialize: _LOGGER.info("Asserting testdata:") if smile.smile_legacy: - await smile.full_update_device() - smile.get_all_device_zones() + await smile.full_xml_update() + smile.get_all_gateway_entities() data = await smile.async_update() assert smile._timeout == 30 else: @@ -621,19 +621,19 @@ def test_and_assert(test_dict, data, header): self.cooling_present = data.gateway["cooling_present"] if "notifications" in data.gateway: self.notifications = data.gateway["notifications"] - self.device_items = data.gateway["item_count"] + self.entity_items = data.gateway["item_count"] self._cooling_active = False self._cooling_enabled = False if "heater_id" in data.gateway: - heat_cooler = data.device_zones[data.gateway["heater_id"]] + heat_cooler = data.entities[data.gateway["heater_id"]] if "binary_sensors" in heat_cooler: if "cooling_enabled" in heat_cooler["binary_sensors"]: self._cooling_enabled = heat_cooler["binary_sensors"]["cooling_enabled"] if "cooling_state" in heat_cooler["binary_sensors"]: self._cooling_active = heat_cooler["binary_sensors"]["cooling_state"] - self._write_json("all_data", {"device_zones": data.device_zones, "gateway": data.gateway}) + self._write_json("all_data", {"entities": data.entities, "gateway": data.gateway}) if "FIXTURES" in os.environ: _LOGGER.info("Skipping tests: Requested fixtures only") # pragma: no cover @@ -645,7 +645,7 @@ def test_and_assert(test_dict, data, header): _LOGGER.info("Gateway id = %s", data.gateway["gateway_id"]) _LOGGER.info("Hostname = %s", smile.smile_hostname) _LOGGER.info("Gateway data = %s", data.gateway) - _LOGGER.info("Device_zone list = %s", data.device_zones) + _LOGGER.info("Entities list = %s", data.entities) self.show_setup(location_list, data.device_zones) if skip_testing: @@ -653,7 +653,7 @@ def test_and_assert(test_dict, data, header): # Perform tests and asserts in two steps: devices and zones for header, data_dict in testdata.items(): - test_and_assert(data_dict, data.device_zones, header) + test_and_assert(data_dict, data.entities, header) # pragma warning restore S3776 From 556e8c526c24552ae4db61105b114f913903c09d Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 16:13:31 +0100 Subject: [PATCH 057/106] Correct function-name --- plugwise/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 121de3388..bf95ba661 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -173,7 +173,7 @@ async def connect(self) -> Version | None: ) # Update all endpoints on first connect - await self._smile_api.full_update_device() + await self._smile_api.full_xml_update() return self.smile_version From a7385384b1efa3a3a931cfbae15f103ec6429683 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 16:20:07 +0100 Subject: [PATCH 058/106] Fix missed --- plugwise/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index 70c661878..f909eaf7a 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -188,7 +188,7 @@ def _power_data_energy_diff( def _create_gw_entities(self, appl: Munch) -> None: """Helper-function for creating/updating gw_entities.""" - self.gw_entities[appl.dev_id] = {"dev_class": appl.pwclass} + self.gw_entities[appl.entity_id] = {"dev_class": appl.pwclass} self._count += 1 for key, value in { "available": appl.available, @@ -204,7 +204,7 @@ def _create_gw_entities(self, appl: Munch) -> None: }.items(): if value is not None or key == "location": appl_key = cast(ApplianceType, key) - self.gw_entities[appl.dev_id][appl_key] = value + self.gw_entities[appl.entity_id][appl_key] = value self._count += 1 def _entity_switching_group( From d0ecf085576df4c3c8fa755cb62e5e52fe6db32e Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 16:36:28 +0100 Subject: [PATCH 059/106] Fix return --- plugwise/helper.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugwise/helper.py b/plugwise/helper.py index 6a190b556..fdd08f77e 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -547,6 +547,8 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: if self._is_thermostat and self.smile(ANNA): self._update_anna_cooling(entity_id, data) + return data + def _power_data_from_location(self, loc_id: str) -> GwEntityData: """Helper-function for smile.py: _get_entity_data(). From 9ef88545f5f410eba9458a1b9f6b3bf7e840b1ef Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 17:41:51 +0100 Subject: [PATCH 060/106] Fix test-code --- tests/test_adam.py | 4 ++-- tests/test_init.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_adam.py b/tests/test_adam.py index ffe994d34..56a9b5708 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -36,8 +36,8 @@ 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 self.device_items == 173 - assert self.device_list == [ + assert self.entity_items == 173 + assert self.entity_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", "10016900610d4c7481df78c89606ef22", diff --git a/tests/test_init.py b/tests/test_init.py index 9119021d3..cf070b475 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -516,7 +516,7 @@ async def disconnect(cls, server, client): await server.close() @staticmethod - def show_setup(location_list, device_zone_list): + def show_setup(location_list, entity_list): """Show informative outline of the setup.""" _LOGGER.info("This environment looks like:") for loc_id, loc_info in location_list.items(): @@ -524,11 +524,11 @@ def show_setup(location_list, device_zone_list): " --> Location: %s", "{} ({})".format(loc_info["name"], loc_id) ) devzone_count = 0 - for devzone_id, devzone_info in device_zone_list.items(): + for devzone_id, devzone_info in entity_list.items(): if devzone_info.get("location", "not_found") == loc_id: devzone_count += 1 _LOGGER.info( - " + Device_Zone: %s", + " + Entity: %s", "{} ({} - {})".format( devzone_info["name"], devzone_info["dev_class"], devzone_id ), @@ -595,7 +595,7 @@ def test_and_assert(test_dict, data, header): _LOGGER.debug("Item %s test-asserts: %s", testitem, item_asserts) assert tests == asserts - _LOGGER.debug("Total device_zone test-asserts: %s", asserts) + _LOGGER.debug("Total entity test-asserts: %s", asserts) # pragma warning disable S3776 @@ -639,14 +639,14 @@ def test_and_assert(test_dict, data, header): _LOGGER.info("Skipping tests: Requested fixtures only") # pragma: no cover return # pragma: no cover - self.device_list = list(data.device_zones.keys()) + self.entity_list = list(data.entities.keys()) location_list = smile.loc_data _LOGGER.info("Gateway id = %s", data.gateway["gateway_id"]) _LOGGER.info("Hostname = %s", smile.smile_hostname) _LOGGER.info("Gateway data = %s", data.gateway) _LOGGER.info("Entities list = %s", data.entities) - self.show_setup(location_list, data.device_zones) + self.show_setup(location_list, data.entities) if skip_testing: return From 070e808f51302a2288d7ecd46e0fac3fe041f069 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 17:49:12 +0100 Subject: [PATCH 061/106] Save/fix --- fixtures/adam_plus_anna_new/all_data.json | 2 +- fixtures/anna_v4/all_data.json | 2 +- fixtures/legacy_anna/all_data.json | 2 +- fixtures/p1v4_442_single/all_data.json | 2 +- fixtures/smile_p1_v2/all_data.json | 2 +- fixtures/stretch_v31/all_data.json | 2 +- plugwise/helper.py | 4 ++-- tests/test_anna.py | 2 +- tests/test_legacy_anna.py | 2 +- tests/test_legacy_p1.py | 2 +- tests/test_legacy_stretch.py | 2 +- tests/test_p1.py | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 589ba8ae8..80d4413a3 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { diff --git a/fixtures/anna_v4/all_data.json b/fixtures/anna_v4/all_data.json index 0e3d52eba..51c9ec0f1 100644 --- a/fixtures/anna_v4/all_data.json +++ b/fixtures/anna_v4/all_data.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/legacy_anna/all_data.json b/fixtures/legacy_anna/all_data.json index fa20bd587..17e1cd8e6 100644 --- a/fixtures/legacy_anna/all_data.json +++ b/fixtures/legacy_anna/all_data.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "1.8.22", diff --git a/fixtures/p1v4_442_single/all_data.json b/fixtures/p1v4_442_single/all_data.json index febf457fa..27d3dceb7 100644 --- a/fixtures/p1v4_442_single/all_data.json +++ b/fixtures/p1v4_442_single/all_data.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "a455b61e52394b2db5081ce025a430f3": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/smile_p1_v2/all_data.json b/fixtures/smile_p1_v2/all_data.json index 571df9cd3..4c0aa878e 100644 --- a/fixtures/smile_p1_v2/all_data.json +++ b/fixtures/smile_p1_v2/all_data.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "938696c4bcdb4b8a9a595cb38ed43913": { "dev_class": "smartmeter", "location": "938696c4bcdb4b8a9a595cb38ed43913", diff --git a/fixtures/stretch_v31/all_data.json b/fixtures/stretch_v31/all_data.json index 0af1473c7..d5bb7cb09 100644 --- a/fixtures/stretch_v31/all_data.json +++ b/fixtures/stretch_v31/all_data.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "3.1.11", diff --git a/plugwise/helper.py b/plugwise/helper.py index fdd08f77e..9b67610c4 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -547,6 +547,8 @@ def _get_measurement_data(self, entity_id: str) -> GwEntityData: if self._is_thermostat and self.smile(ANNA): self._update_anna_cooling(entity_id, data) + self._cleanup_data(data) + return data def _power_data_from_location(self, loc_id: str) -> GwEntityData: @@ -796,8 +798,6 @@ def _update_anna_cooling(self, entity_id: str, data: GwEntityData) -> None: elif self._cooling_present and "cooling_state" in data["binary_sensors"]: self._update_loria_cooling(data) - self._cleanup_data(data) - def _update_elga_cooling(self, data: GwEntityData) -> None: """# Anna+Elga: base cooling_state on the elga-status-code.""" if data["thermostat_supports_cooling"]: diff --git a/tests/test_anna.py b/tests/test_anna.py index b69965c29..45d429b59 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -30,7 +30,7 @@ async def test_connect_anna_v4(self): await self.device_test(smile, "2020-04-05 00:00:01", testdata) assert smile.gateway_id == "0466eae8520144c78afb29628384edeb" assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard" - assert self.device_items == 58 + assert self.entity_items == 58 assert not self.notifications assert not self.cooling_present diff --git a/tests/test_legacy_anna.py b/tests/test_legacy_anna.py index 6963aee30..d108f55a7 100644 --- a/tests/test_legacy_anna.py +++ b/tests/test_legacy_anna.py @@ -30,7 +30,7 @@ async def test_connect_legacy_anna(self): await self.device_test(smile, "2020-03-22 00:00:01", testdata) assert smile.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00" - assert self.device_items == 41 + assert self.entity_items == 41 result = await self.tinker_legacy_thermostat(smile, schedule_on=False) assert result diff --git a/tests/test_legacy_p1.py b/tests/test_legacy_p1.py index 6432216ad..7379679cc 100644 --- a/tests/test_legacy_p1.py +++ b/tests/test_legacy_p1.py @@ -29,7 +29,7 @@ async def test_connect_smile_p1_v2(self): await self.device_test(smile, "2022-05-16 00:00:01", testdata) assert smile.gateway_id == "aaaa0000aaaa0000aaaa0000aaaa00aa" - assert self.device_items == 26 + assert self.entity_items == 26 await smile.close_connection() await self.disconnect(server, client) diff --git a/tests/test_legacy_stretch.py b/tests/test_legacy_stretch.py index d38415776..d3f0b57e4 100644 --- a/tests/test_legacy_stretch.py +++ b/tests/test_legacy_stretch.py @@ -31,7 +31,7 @@ async def test_connect_stretch_v31(self): await self.device_test(smile, "2022-05-16 00:00:01", testdata) assert smile.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00" - assert self.device_items == 83 + assert self.entity_items == 83 switch_change = await self.tinker_switch( smile, "059e4d03c7a34d278add5c7a4a781d19", diff --git a/tests/test_p1.py b/tests/test_p1.py index 5d3f1840a..cf2f1fb2f 100644 --- a/tests/test_p1.py +++ b/tests/test_p1.py @@ -28,7 +28,7 @@ async def test_connect_p1v4_442_single(self): await self.device_test(smile, "2022-05-16 00:00:01", testdata) assert smile.gateway_id == "a455b61e52394b2db5081ce025a430f3" - assert self.device_items == 32 + assert self.entity_items == 32 assert not self.notifications # Now change some data and change directory reading xml from From af767332af4d483e8d2b9fdedaf9a3e1d0a6254d Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 18:38:49 +0100 Subject: [PATCH 062/106] Improve counting of tested entities, tests/asserts --- tests/test_init.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_init.py b/tests/test_init.py index cf070b475..3666ee372 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -550,13 +550,14 @@ async def device_test( def test_and_assert(test_dict, data, header): """Test-and-assert helper-function.""" tests = 0 + tested_items = 0 asserts = 0 bsw_list = ["binary_sensors", "central", "climate", "sensors", "switches"] for testitem, measurements in test_dict.items(): item_asserts = 0 tests += 1 assert testitem in data - asserts += 1 + tested_items += 1 for data_id, details in data.items(): if testitem == data_id: _LOGGER.info( @@ -594,7 +595,8 @@ def test_and_assert(test_dict, data, header): item_asserts += 1 _LOGGER.debug("Item %s test-asserts: %s", testitem, item_asserts) - assert tests == asserts + assert tests == asserts + tested_items + _LOGGER.debug("Total items tested: %s", tested_items) _LOGGER.debug("Total entity test-asserts: %s", asserts) # pragma warning disable S3776 From 9727382e2509943c0c55e58fcd3a1d75f7727a66 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 20:05:46 +0100 Subject: [PATCH 063/106] Fix counting in _appliance_measurements() --- plugwise/helper.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 9b67610c4..1b6a4d1fd 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -601,14 +601,15 @@ def _appliance_measurements( appl_i_loc.text, ENERGY_WATT_HOUR ) - if data.get("binary_sensors"): - self._count += len(data["binary_sensors"]) - if data.get("sensors"): - self._count += len(data["sensors"]) - if data.get("switches"): - self._count += len(data["switches"]) - # Don't count the above top-level dicts, only the remaining single items - self._count += len(data) - 3 + # Don't count the below top-level dicts when present + if "binary_sensors" in data: + self._count += len(data["binary_sensors"]) -1 + if "sensors" in data: + self._count += len(data["sensors"]) - 1 + if "switches" in data: + self._count += len(data["switches"]) -1 + # Count the remaining single data items, + self._count += len(data) def _get_toggle_state( self, xml: etree, toggle: str, name: ToggleNameType, data: GwEntityData From 3c3aedab61fc3e9c063c7816c11ed76c3a2a709d Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 20:06:31 +0100 Subject: [PATCH 064/106] Save --- fixtures/adam_plus_anna_new/all_data.json | 2 +- tests/test_adam.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 80d4413a3..fa2362a27 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -310,7 +310,7 @@ "cooling_present": false, "gateway_id": "da224107914542988a88561b4452b0f6", "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 173, + "item_count": 177, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/tests/test_adam.py b/tests/test_adam.py index 56a9b5708..5c1ef893f 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -36,7 +36,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 self.entity_items == 173 + assert self.entity_items == 177 assert self.entity_list == [ "da224107914542988a88561b4452b0f6", "056ee145a816487eaa69243c3280f8bf", From 57172899cc20e0b3b1666abc31d0e6b123333b15 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 20:09:09 +0100 Subject: [PATCH 065/106] Improve comment --- plugwise/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index 1b6a4d1fd..e4ac39dd0 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -608,7 +608,7 @@ def _appliance_measurements( self._count += len(data["sensors"]) - 1 if "switches" in data: self._count += len(data["switches"]) -1 - # Count the remaining single data items, + # Count the remaining single data items, with the sub-dicts present already subtracted self._count += len(data) def _get_toggle_state( From eb8aab6413b274f42fb40bee51523a3e7c5821ef Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 20:15:25 +0100 Subject: [PATCH 066/106] Return other Adam testcases --- tests/test_adam.py | 249 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) diff --git a/tests/test_adam.py b/tests/test_adam.py index 5c1ef893f..a58050c6d 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -166,3 +166,252 @@ async def test_connect_adam_plus_anna_new(self): await smile.close_connection() await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_adam_zone_per_device(self): + """Test an extensive setup of Adam with a zone per device.""" + self.smile_setup = "adam_zone_per_device" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="3.0.15", + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert smile.gateway_id == "fe799307f1624099878210aa0b9f1475" + assert smile._last_active["12493538af164a409c6a1c79e38afe1c"] == BADKAMER_SCHEMA + assert smile._last_active["c50f167537524366a5af7aa3942feb1e"] == GF7_WOONKAMER + assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE + assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA + assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA + assert self.entity_items == 340 + + assert "af82e4ccf9c548528166d38e560662a4" in self.notifications + await smile.delete_notification() + + result = await self.tinker_thermostat( + smile, "c50f167537524366a5af7aa3942feb1e", good_schedules=[GF7_WOONKAMER] + ) + assert result + result = await self.tinker_thermostat( + smile, "82fa13f017d240daa0d0ea1775420f24", good_schedules=[CV_JESSIE] + ) + assert result + switch_change = await self.tinker_switch( + smile, "675416a629f343c495449970e2ca37b5" + ) + assert not switch_change + + reboot = await self.tinker_reboot(smile) + assert reboot + + await smile.close_connection() + await self.disconnect(server, client) + + server, smile, client = await self.connect_wrapper(raise_timeout=True) + await self.device_test(smile, "2022-05-16 00:00:01", testdata, skip_testing=True) + result = await self.tinker_thermostat( + smile, + "c50f167537524366a5af7aa3942feb1e", + good_schedules=[GF7_WOONKAMER], + unhappy=True, + ) + assert result + result = await self.tinker_thermostat( + smile, + "82fa13f017d240daa0d0ea1775420f24", + good_schedules=[CV_JESSIE], + unhappy=True, + ) + assert result + + tinkered = await self.tinker_max_boiler_temp(smile, unhappy=True) + assert not tinkered + + try: + await smile.delete_notification() + notification_deletion = False # pragma: no cover + except pw_exceptions.ConnectionFailedError: + notification_deletion = True + assert notification_deletion + + reboot = await self.tinker_reboot(smile, unhappy=True) + assert reboot + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_adam_multiple_devices_per_zone(self): + """Test an extensive setup of Adam with multiple devices per zone.""" + self.smile_setup = "adam_multiple_devices_per_zone" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="3.0.15", + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert smile._last_active["12493538af164a409c6a1c79e38afe1c"] == BADKAMER_SCHEMA + assert smile._last_active["c50f167537524366a5af7aa3942feb1e"] == GF7_WOONKAMER + assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE + assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA + assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA + assert self.entity_items == 340 + + assert "af82e4ccf9c548528166d38e560662a4" in self.notifications + + result = await self.tinker_thermostat( + smile, "c50f167537524366a5af7aa3942feb1e", good_schedules=[GF7_WOONKAMER] + ) + assert result + result = await self.tinker_thermostat( + smile, "82fa13f017d240daa0d0ea1775420f24", good_schedules=[CV_JESSIE] + ) + assert result + switch_change = await self.tinker_switch( + smile, "675416a629f343c495449970e2ca37b5" + ) + assert not switch_change + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_adam_heatpump_cooling(self): + """Test Adam with heatpump in cooling mode and idle.""" + self.smile_setup = "adam_heatpump_cooling" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + + await self.device_test(smile, "2022-01-02 00:00:01", testdata) + assert smile._last_active["b52908550469425b812c87f766fe5303"] == WERKDAG_SCHEMA + assert smile._last_active["20e735858f8146cead98b873177a4f99"] == WERKDAG_SCHEMA + assert smile._last_active["e39529c79ab54fda9bed26cfc0447546"] == WERKDAG_SCHEMA + assert smile._last_active["9a27714b970547ee9a6bdadc2b815ad5"] == WERKDAG_SCHEMA + assert smile._last_active["93ac3f7bf25342f58cbb77c4a99ac0b3"] == WERKDAG_SCHEMA + assert smile._last_active["fa5fa6b34f6b40a0972988b20e888ed4"] == WERKDAG_SCHEMA + assert smile._last_active["04b15f6e884448288f811d29fb7b1b30"] == WERKDAG_SCHEMA + assert smile._last_active["a562019b0b1f47a4bde8ebe3dbe3e8a9"] == WERKDAG_SCHEMA + assert smile._last_active["8cf650a4c10c44819e426bed406aec34"] == WERKDAG_SCHEMA + assert smile._last_active["5cc21042f87f4b4c94ccb5537c47a53f"] == WERKDAG_SCHEMA + assert self.entity_items == 439 + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_adam_onoff_cooling_fake_firmware(self): + """Test an Adam with a fake OnOff cooling device in cooling mode.""" + self.smile_setup = "adam_onoff_cooling_fake_firmware" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version=None, + ) + + await self.device_test(smile, "2022-01-02 00:00:01", testdata) + assert self.entity_items == 58 + assert self.cooling_present + # assert self._cooling_enabled - no cooling_enabled indication present + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_adam_plus_anna(self): + """Test Adam (firmware 3.0) with Anna setup.""" + self.smile_setup = "adam_plus_anna" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="3.0.15", + ) + + await self.device_test(smile, "2020-03-22 00:00:01", testdata) + assert smile.gateway_id == "b128b4bbbd1f47e9bf4d756e8fb5ee94" + assert smile._last_active["009490cc2f674ce6b576863fbb64f867"] == "Weekschema" + assert self.entity_items == 73 + assert "6fb89e35caeb4b1cb275184895202d84" in self.notifications + + result = await self.tinker_thermostat( + smile, "009490cc2f674ce6b576863fbb64f867", good_schedules=["Weekschema"] + ) + assert result + switch_change = await self.tinker_switch( + smile, "aa6b0002df0a46e1b1eb94beb61eddfe" + ) + assert switch_change + await smile.close_connection() + await self.disconnect(server, client) + + server, smile, client = await self.connect_wrapper(raise_timeout=True) + await self.device_test(smile, "2020-03-22 00:00:01", testdata, skip_testing=True) + result = await self.tinker_thermostat( + smile, + "009490cc2f674ce6b576863fbb64f867", + good_schedules=["Weekschema"], + unhappy=True, + ) + assert result + switch_change = await self.tinker_switch( + smile, "aa6b0002df0a46e1b1eb94beb61eddfe", unhappy=True + ) + assert switch_change + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_adam_plus_jip(self): + """Test Adam with Jip setup.""" + self.smile_setup = "adam_jip" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + + await self.device_test(smile, "2021-06-20 00:00:01", testdata) + assert smile.gateway_id == "b5c2386c6f6342669e50fe49dd05b188" + assert smile._last_active["d58fec52899f4f1c92e4f8fad6d8c48c"] is None + assert smile._last_active["06aecb3d00354375924f50c47af36bd2"] is None + assert smile._last_active["d27aede973b54be484f6842d1b2802ad"] is None + assert smile._last_active["13228dab8ce04617af318a2888b3c548"] is None + assert self.entity_items == 228 + + # Negative test + result = await self.tinker_thermostat( + smile, + "13228dab8ce04617af318a2888b3c548", + schedule_on=False, + good_schedules=[None], + ) + assert result + + result = await self.tinker_thermostat_schedule( + smile, + "13228dab8ce04617af318a2888b3c548", + "off", + good_schedules=[None], + ) + assert result + await smile.close_connection() + await self.disconnect(server, client) \ No newline at end of file From 10af3fea3d356777569a819bc53c3f08f464471a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 20 Nov 2024 20:16:20 +0100 Subject: [PATCH 067/106] Save updated fixtures, update test-jsons --- fixtures/adam_heatpump_cooling/all_data.json | 592 ++++--- fixtures/adam_jip/all_data.json | 200 ++- .../all_data.json | 323 ++-- .../all_data.json | 33 +- fixtures/adam_plus_anna/all_data.json | 59 +- fixtures/adam_zone_per_device/all_data.json | 323 ++-- tests/data/adam/adam_heatpump_cooling.json | 1441 ++++++++++------- tests/data/adam/adam_jip.json | 634 +++++--- .../adam/adam_multiple_devices_per_zone.json | 1000 +++++++----- .../adam_onoff_cooling_fake_firmware.json | 124 +- tests/data/adam/adam_plus_anna.json | 223 +-- tests/data/adam/adam_zone_per_device.json | 1000 +++++++----- tests/test_adam.py | 14 +- 13 files changed, 3682 insertions(+), 2284 deletions(-) diff --git a/fixtures/adam_heatpump_cooling/all_data.json b/fixtures/adam_heatpump_cooling/all_data.json index 6905438e8..54fe118ca 100644 --- a/fixtures/adam_heatpump_cooling/all_data.json +++ b/fixtures/adam_heatpump_cooling/all_data.json @@ -1,5 +1,43 @@ { - "devices": { + "entities": { + "04b15f6e884448288f811d29fb7b1b30": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer SJ", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 22.6 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 20.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "d3a276aeb3114a509bab1e4bf8c40348" + ], + "secondary": [] + } + }, "0ca13e8176204ca7bf6f09de59f81c83": { "available": true, "binary_sensors": { @@ -40,19 +78,10 @@ "vendor": "Remeha B.V." }, "1053c8bbf8be43c6921742b146a625f1": { - "active_preset": "away", "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "cool", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -60,14 +89,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat BK", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "off", "sensors": { "battery": 55, "setpoint": 18.0, @@ -79,12 +100,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A17" }, @@ -108,6 +123,44 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A05" }, + "20e735858f8146cead98b873177a4f99": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer DB", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 22.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "47e2c550a33846b680725aa3fb229473" + ], + "secondary": [] + } + }, "2e0fc4db2a6d4cbeb7cf786143543961": { "available": true, "dev_class": "valve_actuator_plug", @@ -169,16 +222,7 @@ "zigbee_mac_address": "ABCD012345670A18" }, "47e2c550a33846b680725aa3fb229473": { - "active_preset": "away", "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "climate_mode": "cool", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -186,14 +230,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat DB", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "off", "sensors": { "setpoint": 18.0, "temperature": 22.0 @@ -204,14 +240,45 @@ "setpoint": 0.0, "upper_bound": 2.0 }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A20" + }, + "5cc21042f87f4b4c94ccb5537c47a53f": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Badkamer 2", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 0.0, + "temperature": 21.9 + }, "thermostat": { "lower_bound": 0.0, "resolution": 0.01, - "setpoint": 18.0, + "setpoint": 20.5, "upper_bound": 99.9 }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A20" + "thermostats": { + "primary": [ + "f04c985c11ad4848b8fcd710343f9dcf" + ], + "secondary": [] + } }, "5ead63c65e5f44e7870ba2bd680ceb9e": { "available": true, @@ -266,16 +333,7 @@ "zigbee_mac_address": "ABCD012345670101" }, "7fda9f84f01342f8afe9ebbbbff30c0f": { - "active_preset": "away", "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "climate_mode": "cool", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -283,14 +341,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat JM", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "off", "sensors": { "setpoint": 18.0, "temperature": 20.0 @@ -301,12 +351,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A01" }, @@ -350,6 +394,81 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A10" }, + "8cf650a4c10c44819e426bed406aec34": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Badkamer 1", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 21.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 20.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "eac5db95d97241f6b17790897847ccf5" + ], + "secondary": [] + } + }, + "93ac3f7bf25342f58cbb77c4a99ac0b3": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer RB", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 3.13, + "temperature": 20.7 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 17.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "c4ed311d54e341f58b4cdd201d1fde7e" + ], + "secondary": [] + } + }, "96714ad90fc948bcbcb5021c4b9f5ae9": { "available": true, "dev_class": "valve_actuator_plug", @@ -370,6 +489,44 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A03" }, + "9a27714b970547ee9a6bdadc2b815ad5": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer SQ", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 21.4 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "beb32da072274e698146db8b022f3c36" + ], + "secondary": [] + } + }, "a03b6e8e76dd4646af1a77c31dd9370c": { "available": true, "dev_class": "valve_actuator_plug", @@ -390,6 +547,82 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A08" }, + "a562019b0b1f47a4bde8ebe3dbe3e8a9": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Keuken", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 2.13, + "electricity_produced": 0.0, + "temperature": 22.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 21.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "ea8372c0e3ad4622ad45a041d02425f5" + ], + "secondary": [] + } + }, + "b52908550469425b812c87f766fe5303": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Bijkeuken", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 18.8 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "1053c8bbf8be43c6921742b146a625f1" + ], + "secondary": [] + } + }, "bbcffa48019f4b09b8368bbaf9559e68": { "available": true, "dev_class": "valve_actuator_plug", @@ -411,16 +644,7 @@ "zigbee_mac_address": "ABCD012345670A16" }, "beb32da072274e698146db8b022f3c36": { - "active_preset": "away", "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "climate_mode": "cool", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -428,14 +652,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat SQ", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "off", "sensors": { "setpoint": 18.5, "temperature": 21.4 @@ -446,26 +662,11 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.5, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A07" }, "c4ed311d54e341f58b4cdd201d1fde7e": { - "active_preset": "away", "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "climate_mode": "cool", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -473,14 +674,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat RB", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "off", "sensors": { "setpoint": 17.0, "temperature": 20.7 @@ -491,61 +684,23 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 17.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A04" }, "ca79d23ae0094120b877558734cff85c": { - "active_preset": "away", - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "climate_mode": "auto", - "control_state": "off", "dev_class": "thermostat", "location": "fa5fa6b34f6b40a0972988b20e888ed4", "model": "ThermoTouch", "model_id": "143.1", "name": "Thermostaat WK", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "Werkdag schema", "sensors": { "setpoint": 21.5, "temperature": 22.5 }, - "thermostat": { - "lower_bound": 1.0, - "resolution": 0.01, - "setpoint": 21.5, - "upper_bound": 35.0 - }, "vendor": "Plugwise" }, "d3a276aeb3114a509bab1e4bf8c40348": { - "active_preset": "away", "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "climate_mode": "cool", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -553,14 +708,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat SJ", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "off", "sensors": { "setpoint": 20.5, "temperature": 22.6 @@ -571,29 +718,52 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 20.5, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A13" }, - "ea8372c0e3ad4622ad45a041d02425f5": { + "e39529c79ab54fda9bed26cfc0447546": { "active_preset": "away", - "available": true, "available_schedules": [ "Opstaan weekdag", "Werkdag schema", "Weekend", "off" ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer JM", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 20.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "7fda9f84f01342f8afe9ebbbbff30c0f" + ], + "secondary": [] + } + }, + "ea8372c0e3ad4622ad45a041d02425f5": { + "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -601,14 +771,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat KK", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "Werkdag schema", "sensors": { "battery": 53, "setpoint": 21.5, @@ -620,26 +782,11 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 21.5, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A02" }, "eac5db95d97241f6b17790897847ccf5": { - "active_preset": "away", "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "climate_mode": "auto", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -647,14 +794,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Thermostaat BK1", - "preset_modes": [ - "no_frost", - "vacation", - "away", - "home", - "asleep" - ], - "select_schedule": "Werkdag schema", "sensors": { "setpoint": 20.5, "temperature": 21.5 @@ -665,18 +804,33 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 20.5, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A09" }, "f04c985c11ad4848b8fcd710343f9dcf": { - "active_preset": "away", "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "5cc21042f87f4b4c94ccb5537c47a53f", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat BK2", + "sensors": { + "setpoint": 20.5, + "temperature": 21.9 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A11" + }, + "fa5fa6b34f6b40a0972988b20e888ed4": { + "active_preset": "away", "available_schedules": [ "Opstaan weekdag", "Werkdag schema", @@ -685,13 +839,8 @@ ], "climate_mode": "auto", "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "5cc21042f87f4b4c94ccb5537c47a53f", - "model": "Lisa", - "model_id": "158-01", - "name": "Thermostaat BK2", + "dev_class": "climate", + "name": "Woonkamer", "preset_modes": [ "no_frost", "vacation", @@ -701,30 +850,29 @@ ], "select_schedule": "Werkdag schema", "sensors": { - "setpoint": 20.5, - "temperature": 21.9 - }, - "temperature_offset": { - "lower_bound": -2.0, - "resolution": 0.1, - "setpoint": 0.0, - "upper_bound": 2.0 + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 22.5 }, "thermostat": { - "lower_bound": 0.0, + "lower_bound": 1.0, "resolution": 0.01, - "setpoint": 20.5, - "upper_bound": 99.9 + "setpoint": 21.5, + "upper_bound": 35.0 }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A11" + "thermostats": { + "primary": [ + "ca79d23ae0094120b877558734cff85c" + ], + "secondary": [] + } } }, "gateway": { "cooling_present": true, "gateway_id": "7d97fc3117784cfdafe347bcedcbbbcb", "heater_id": "0ca13e8176204ca7bf6f09de59f81c83", - "item_count": 439, + "item_count": 497, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/fixtures/adam_jip/all_data.json b/fixtures/adam_jip/all_data.json index bbedf1527..c89c25218 100644 --- a/fixtures/adam_jip/all_data.json +++ b/fixtures/adam_jip/all_data.json @@ -1,13 +1,72 @@ { - "devices": { - "1346fbd8498d4dbcab7e18d51b771f3d": { + "entities": { + "06aecb3d00354375924f50c47af36bd2": { "active_preset": "no_frost", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 24.2 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "1346fbd8498d4dbcab7e18d51b771f3d" + ], + "secondary": [ + "356b65335e274d769c338223e7af9c33" + ] + } + }, + "13228dab8ce04617af318a2888b3c548": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 27.4 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.01, + "setpoint": 9.0, + "upper_bound": 30.0 + }, + "thermostats": { + "primary": [ + "f61f1a2535f54f52ad006a3d18e459ca" + ], + "secondary": [ + "833de10f269c4deab58fb9df69901b4e" + ] + } + }, + "1346fbd8498d4dbcab7e18d51b771f3d": { "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -15,13 +74,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Slaapkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 92, "setpoint": 13.0, @@ -33,18 +85,12 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A03" }, "1da4d325838e4ad8aac12177214505c9": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "d58fec52899f4f1c92e4f8fad6d8c48c", @@ -68,7 +114,7 @@ }, "356b65335e274d769c338223e7af9c33": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "06aecb3d00354375924f50c47af36bd2", @@ -108,13 +154,10 @@ "zigbee_mac_address": "ABCD012345670A06" }, "6f3e9d7084214c21b9dfa46f6eeb8700": { - "active_preset": "home", "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -122,13 +165,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Kinderkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 79, "setpoint": 13.0, @@ -140,18 +176,12 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A02" }, "833de10f269c4deab58fb9df69901b4e": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "13228dab8ce04617af318a2888b3c548", @@ -174,13 +204,10 @@ "zigbee_mac_address": "ABCD012345670A09" }, "a6abc6a129ee499c88a4d420cc413b47": { - "active_preset": "home", "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -188,13 +215,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Logeerkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 80, "setpoint": 13.0, @@ -206,12 +226,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A01" }, @@ -246,9 +260,40 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670101" }, + "d27aede973b54be484f6842d1b2802ad": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Kinderkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 30.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "6f3e9d7084214c21b9dfa46f6eeb8700" + ], + "secondary": [ + "d4496250d0e942cfa7aea3476e9070d5" + ] + } + }, "d4496250d0e942cfa7aea3476e9070d5": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "d27aede973b54be484f6842d1b2802ad", @@ -270,6 +315,37 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A04" }, + "d58fec52899f4f1c92e4f8fad6d8c48c": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Logeerkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 30.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "a6abc6a129ee499c88a4d420cc413b47" + ], + "secondary": [ + "1da4d325838e4ad8aac12177214505c9" + ] + } + }, "e4684553153b44afbef2200885f379dc": { "available": true, "binary_sensors": { @@ -307,13 +383,10 @@ "vendor": "Remeha B.V." }, "f61f1a2535f54f52ad006a3d18e459ca": { - "active_preset": "home", "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", - "control_state": "off", "dev_class": "zone_thermometer", "firmware": "2020-09-01T02:00:00+02:00", "hardware": "1", @@ -321,13 +394,6 @@ "model": "Jip", "model_id": "168-01", "name": "Woonkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 100, "humidity": 56.2, @@ -340,12 +406,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 4.0, - "resolution": 0.01, - "setpoint": 9.0, - "upper_bound": 30.0 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A08" } @@ -354,7 +414,7 @@ "cooling_present": false, "gateway_id": "b5c2386c6f6342669e50fe49dd05b188", "heater_id": "e4684553153b44afbef2200885f379dc", - "item_count": 228, + "item_count": 244, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/fixtures/adam_multiple_devices_per_zone/all_data.json b/fixtures/adam_multiple_devices_per_zone/all_data.json index f725a86c2..1f6ee01f4 100644 --- a/fixtures/adam_multiple_devices_per_zone/all_data.json +++ b/fixtures/adam_multiple_devices_per_zone/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "02cf28bfec924855854c544690a609ef": { "available": true, "dev_class": "vcr_plug", @@ -21,6 +21,86 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A15" }, + "08963fec7c53423ca5680aa4cb502c63": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Badkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "Badkamer Schema", + "sensors": { + "temperature": 18.9 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 14.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "f1fee6043d3642a9b0a65297455f008e" + ], + "secondary": [ + "680423ff840043738f42cc7f1ff97a36" + ] + } + }, + "12493538af164a409c6a1c79e38afe1c": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Bios", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "df4a4a8169904cdb9c03d61a21f42140" + ], + "secondary": [ + "a2c3583e0a6349358998b760cea82d2a" + ] + } + }, "21f2b542c49845e6bb416884c55778d6": { "available": true, "dev_class": "game_console_plug", @@ -42,6 +122,43 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A12" }, + "446ac08dd04d4eff8ac57489757b7314": { + "active_preset": "no_frost", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Garage", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "temperature": 15.6 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 5.5, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "e7693eb9582644e5b865dba8d4447cf1" + ], + "secondary": [] + } + }, "4a810418d5394b3f82727340b91ba740": { "available": true, "dev_class": "router_plug", @@ -89,7 +206,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "08963fec7c53423ca5680aa4cb502c63", @@ -113,20 +230,10 @@ "zigbee_mac_address": "ABCD012345670A17" }, "6a3bf693d05e48e0b460c815a4fdd09d": { - "active_preset": "asleep", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -134,14 +241,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Thermostat Jessie", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "CV Jessie", "sensors": { "battery": 37, "setpoint": 15.0, @@ -153,12 +252,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 15.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A03" }, @@ -182,6 +275,45 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A05" }, + "82fa13f017d240daa0d0ea1775420f24": { + "active_preset": "asleep", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Jessie", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "CV Jessie", + "sensors": { + "temperature": 17.2 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 15.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "6a3bf693d05e48e0b460c815a4fdd09d" + ], + "secondary": [ + "d3da73bde12a47d5a6b8f9dad971f2ec" + ] + } + }, "90986d591dcd426cae3ec3e8111ff730": { "binary_sensors": { "heating_state": true @@ -222,7 +354,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "12493538af164a409c6a1c79e38afe1c", @@ -247,7 +379,7 @@ }, "b310b72a0e354bfab43089919b9a88bf": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "c50f167537524366a5af7aa3942feb1e", @@ -270,20 +402,10 @@ "zigbee_mac_address": "ABCD012345670A02" }, "b59bcebaf94b499ea7d46e4a66fb62d8": { - "active_preset": "home", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-08-02T02:00:00+02:00", "hardware": "255", @@ -291,14 +413,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Lisa WK", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "GF7 Woonkamer", "sensors": { "battery": 34, "setpoint": 21.5, @@ -310,14 +424,49 @@ "setpoint": 0.0, "upper_bound": 2.0 }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" + }, + "c50f167537524366a5af7aa3942feb1e": { + "active_preset": "home", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "GF7 Woonkamer", + "sensors": { + "electricity_consumed": 35.6, + "electricity_produced": 0.0, + "temperature": 20.9 + }, "thermostat": { "lower_bound": 0.0, "resolution": 0.01, "setpoint": 21.5, - "upper_bound": 99.9 + "upper_bound": 100.0 }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A07" + "thermostats": { + "primary": [ + "b59bcebaf94b499ea7d46e4a66fb62d8" + ], + "secondary": [ + "b310b72a0e354bfab43089919b9a88bf" + ] + } }, "cd0ddb54ef694e11ac18ed1cbce5dbbd": { "available": true, @@ -345,7 +494,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "82fa13f017d240daa0d0ea1775420f24", @@ -369,20 +518,10 @@ "zigbee_mac_address": "ABCD012345670A10" }, "df4a4a8169904cdb9c03d61a21f42140": { - "active_preset": "away", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -390,14 +529,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Lisa Bios", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "off", "sensors": { "battery": 67, "setpoint": 13.0, @@ -409,30 +540,14 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A06" }, "e7693eb9582644e5b865dba8d4447cf1": { - "active_preset": "no_frost", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", @@ -440,14 +555,6 @@ "model": "Tom/Floor", "model_id": "106-03", "name": "CV Kraan Garage", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "off", "sensors": { "battery": 68, "setpoint": 5.5, @@ -461,30 +568,14 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 5.5, - "upper_bound": 100.0 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A11" }, "f1fee6043d3642a9b0a65297455f008e": { - "active_preset": "away", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -492,14 +583,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Thermostat Badkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "Badkamer Schema", "sensors": { "battery": 92, "setpoint": 14.0, @@ -511,12 +594,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 14.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A08" }, @@ -544,7 +621,7 @@ "cooling_present": false, "gateway_id": "fe799307f1624099878210aa0b9f1475", "heater_id": "90986d591dcd426cae3ec3e8111ff730", - "item_count": 340, + "item_count": 364, "notifications": { "af82e4ccf9c548528166d38e560662a4": { "warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device." diff --git a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json index d5c121418..60b85cc9a 100644 --- a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json +++ b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "0ca13e8176204ca7bf6f09de59f81c83": { "binary_sensors": { "cooling_state": true, @@ -69,6 +69,18 @@ "zigbee_mac_address": "ABCD012345670101" }, "ca79d23ae0094120b877558734cff85c": { + "dev_class": "thermostat", + "location": "fa5fa6b34f6b40a0972988b20e888ed4", + "model": "ThermoTouch", + "model_id": "143.1", + "name": "Thermostaat WK", + "sensors": { + "setpoint": 21.5, + "temperature": 22.5 + }, + "vendor": "Plugwise" + }, + "fa5fa6b34f6b40a0972988b20e888ed4": { "active_preset": "away", "available_schedules": [ "Opstaan weekdag", @@ -78,11 +90,8 @@ ], "climate_mode": "auto", "control_state": "off", - "dev_class": "thermostat", - "location": "fa5fa6b34f6b40a0972988b20e888ed4", - "model": "ThermoTouch", - "model_id": "143.1", - "name": "Thermostaat WK", + "dev_class": "climate", + "name": "Woonkamer", "preset_modes": [ "no_frost", "vacation", @@ -92,7 +101,8 @@ ], "select_schedule": "Werkdag schema", "sensors": { - "setpoint": 21.5, + "electricity_consumed": 0.0, + "electricity_produced": 0.0, "temperature": 22.5 }, "thermostat": { @@ -101,14 +111,19 @@ "setpoint": 21.5, "upper_bound": 35.0 }, - "vendor": "Plugwise" + "thermostats": { + "primary": [ + "ca79d23ae0094120b877558734cff85c" + ], + "secondary": [] + } } }, "gateway": { "cooling_present": true, "gateway_id": "7d97fc3117784cfdafe347bcedcbbbcb", "heater_id": "0ca13e8176204ca7bf6f09de59f81c83", - "item_count": 58, + "item_count": 64, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/fixtures/adam_plus_anna/all_data.json b/fixtures/adam_plus_anna/all_data.json index ae4f10dbb..12db8e05f 100644 --- a/fixtures/adam_plus_anna/all_data.json +++ b/fixtures/adam_plus_anna/all_data.json @@ -1,5 +1,40 @@ { - "devices": { + "entities": { + "009490cc2f674ce6b576863fbb64f867": { + "active_preset": "home", + "available_schedules": [ + "Weekschema", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Living room", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "Weekschema", + "sensors": { + "electricity_consumed": 74.2, + "electricity_produced": 0.0, + "temperature": 20.5 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 20.5, + "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ee62cad889f94e8ca3d09021f03a660b" + ], + "secondary": [] + } + }, "2743216f626f43948deec1f7ab3b3d70": { "available": false, "binary_sensors": { @@ -66,35 +101,15 @@ "zigbee_mac_address": "ABCD012345670101" }, "ee62cad889f94e8ca3d09021f03a660b": { - "active_preset": "home", - "available_schedules": [ - "Weekschema", - "off" - ], - "climate_mode": "auto", "dev_class": "thermostat", "location": "009490cc2f674ce6b576863fbb64f867", "model": "ThermoTouch", "model_id": "143.1", "name": "Anna", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "Weekschema", "sensors": { "setpoint": 20.5, "temperature": 20.5 }, - "thermostat": { - "lower_bound": 1.0, - "resolution": 0.01, - "setpoint": 20.5, - "upper_bound": 35.0 - }, "vendor": "Plugwise" }, "f2be121e4a9345ac83c6e99ed89a98be": { @@ -121,7 +136,7 @@ "cooling_present": false, "gateway_id": "b128b4bbbd1f47e9bf4d756e8fb5ee94", "heater_id": "2743216f626f43948deec1f7ab3b3d70", - "item_count": 73, + "item_count": 79, "notifications": { "6fb89e35caeb4b1cb275184895202d84": { "error": "There is no OpenTherm communication with the boiler." diff --git a/fixtures/adam_zone_per_device/all_data.json b/fixtures/adam_zone_per_device/all_data.json index c6172f46c..657dcd240 100644 --- a/fixtures/adam_zone_per_device/all_data.json +++ b/fixtures/adam_zone_per_device/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "02cf28bfec924855854c544690a609ef": { "available": true, "dev_class": "vcr_plug", @@ -21,6 +21,86 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A15" }, + "08963fec7c53423ca5680aa4cb502c63": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Badkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "Badkamer Schema", + "sensors": { + "temperature": 18.8 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 14.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "f1fee6043d3642a9b0a65297455f008e" + ], + "secondary": [ + "680423ff840043738f42cc7f1ff97a36" + ] + } + }, + "12493538af164a409c6a1c79e38afe1c": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Bios", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "df4a4a8169904cdb9c03d61a21f42140" + ], + "secondary": [ + "a2c3583e0a6349358998b760cea82d2a" + ] + } + }, "21f2b542c49845e6bb416884c55778d6": { "available": true, "dev_class": "game_console_plug", @@ -42,6 +122,43 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A12" }, + "446ac08dd04d4eff8ac57489757b7314": { + "active_preset": "no_frost", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Garage", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "temperature": 15.6 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 5.5, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "e7693eb9582644e5b865dba8d4447cf1" + ], + "secondary": [] + } + }, "4a810418d5394b3f82727340b91ba740": { "available": true, "dev_class": "router_plug", @@ -89,7 +206,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "08963fec7c53423ca5680aa4cb502c63", @@ -113,20 +230,10 @@ "zigbee_mac_address": "ABCD012345670A17" }, "6a3bf693d05e48e0b460c815a4fdd09d": { - "active_preset": "asleep", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -134,14 +241,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Thermostat Jessie", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "CV Jessie", "sensors": { "battery": 37, "setpoint": 16.0, @@ -153,12 +252,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 16.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A03" }, @@ -182,6 +275,45 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A05" }, + "82fa13f017d240daa0d0ea1775420f24": { + "active_preset": "asleep", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Jessie", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "CV Jessie", + "sensors": { + "temperature": 17.1 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 16.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "6a3bf693d05e48e0b460c815a4fdd09d" + ], + "secondary": [ + "d3da73bde12a47d5a6b8f9dad971f2ec" + ] + } + }, "90986d591dcd426cae3ec3e8111ff730": { "binary_sensors": { "heating_state": true @@ -222,7 +354,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "12493538af164a409c6a1c79e38afe1c", @@ -247,7 +379,7 @@ }, "b310b72a0e354bfab43089919b9a88bf": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "c50f167537524366a5af7aa3942feb1e", @@ -270,20 +402,10 @@ "zigbee_mac_address": "ABCD012345670A02" }, "b59bcebaf94b499ea7d46e4a66fb62d8": { - "active_preset": "home", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-08-02T02:00:00+02:00", "hardware": "255", @@ -291,14 +413,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Lisa WK", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "GF7 Woonkamer", "sensors": { "battery": 34, "setpoint": 21.5, @@ -310,14 +424,49 @@ "setpoint": 0.0, "upper_bound": 2.0 }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" + }, + "c50f167537524366a5af7aa3942feb1e": { + "active_preset": "home", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "GF7 Woonkamer", + "sensors": { + "electricity_consumed": 35.8, + "electricity_produced": 0.0, + "temperature": 21.1 + }, "thermostat": { "lower_bound": 0.0, "resolution": 0.01, "setpoint": 21.5, - "upper_bound": 99.9 + "upper_bound": 100.0 }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A07" + "thermostats": { + "primary": [ + "b59bcebaf94b499ea7d46e4a66fb62d8" + ], + "secondary": [ + "b310b72a0e354bfab43089919b9a88bf" + ] + } }, "cd0ddb54ef694e11ac18ed1cbce5dbbd": { "available": true, @@ -345,7 +494,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "82fa13f017d240daa0d0ea1775420f24", @@ -369,20 +518,10 @@ "zigbee_mac_address": "ABCD012345670A10" }, "df4a4a8169904cdb9c03d61a21f42140": { - "active_preset": "away", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -390,14 +529,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Lisa Bios", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "off", "sensors": { "battery": 67, "setpoint": 13.0, @@ -409,30 +540,14 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A06" }, "e7693eb9582644e5b865dba8d4447cf1": { - "active_preset": "no_frost", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", @@ -440,14 +555,6 @@ "model": "Tom/Floor", "model_id": "106-03", "name": "CV Kraan Garage", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "off", "sensors": { "battery": 68, "setpoint": 5.5, @@ -461,30 +568,14 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 5.5, - "upper_bound": 100.0 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A11" }, "f1fee6043d3642a9b0a65297455f008e": { - "active_preset": "away", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -492,14 +583,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Thermostat Badkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "Badkamer Schema", "sensors": { "battery": 92, "setpoint": 14.0, @@ -511,12 +594,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 14.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A08" }, @@ -544,7 +621,7 @@ "cooling_present": false, "gateway_id": "fe799307f1624099878210aa0b9f1475", "heater_id": "90986d591dcd426cae3ec3e8111ff730", - "item_count": 340, + "item_count": 364, "notifications": { "af82e4ccf9c548528166d38e560662a4": { "warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device." diff --git a/tests/data/adam/adam_heatpump_cooling.json b/tests/data/adam/adam_heatpump_cooling.json index 2790e3ea2..029cbfcd4 100644 --- a/tests/data/adam/adam_heatpump_cooling.json +++ b/tests/data/adam/adam_heatpump_cooling.json @@ -1,576 +1,871 @@ { - "0ca13e8176204ca7bf6f09de59f81c83": { - "available": true, - "binary_sensors": { - "cooling_state": false, - "dhw_state": true, - "flame_state": false, - "heating_state": false - }, - "dev_class": "heater_central", - "location": "eedadcb297564f1483faa509179aebed", - "max_dhw_temperature": { - "lower_bound": 40.0, - "resolution": 0.01, - "setpoint": 60.0, - "upper_bound": 65.0 - }, - "maximum_boiler_temperature": { - "lower_bound": 7.0, - "resolution": 0.01, - "setpoint": 35.0, - "upper_bound": 50.0 - }, - "model": "Generic heater/cooler", - "model_id": "17.1", - "name": "OpenTherm", - "sensors": { - "dhw_temperature": 63.5, - "intended_boiler_temperature": 0.0, - "modulation_level": 0.0, - "outdoor_air_temperature": 13.5, - "return_temperature": 24.9, - "water_pressure": 2.0, - "water_temperature": 24.5 - }, - "switches": { - "dhw_cm_switch": true - }, - "vendor": "Remeha B.V." - }, - "1053c8bbf8be43c6921742b146a625f1": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "b52908550469425b812c87f766fe5303", - "climate_mode": "cool", - "model": "Lisa", - "name": "Thermostaat BK", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "off", - "sensors": { - "battery": 55, - "setpoint": 18.0, - "temperature": 18.8 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.0, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A17" - }, - "1a27dd03b5454c4e8b9e75c8d1afc7af": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "20e735858f8146cead98b873177a4f99", - "model": "Plug", - "name": "Smart Plug DB", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A05" - }, - "2e0fc4db2a6d4cbeb7cf786143543961": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "a562019b0b1f47a4bde8ebe3dbe3e8a9", - "model": "Plug", - "name": "Smart Plug KK", - "sensors": { - "electricity_consumed": 2.13, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": true - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A06" - }, - "3b4d2574e2c9443a832b48d19a1c4f06": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "04b15f6e884448288f811d29fb7b1b30", - "model": "Plug", - "name": "Smart Plug SJ", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A14" - }, - "3f0afa71f16c45ab964050002560e43c": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "fa5fa6b34f6b40a0972988b20e888ed4", - "model": "Plug", - "name": "Smart Plug WK", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A18" - }, - "47e2c550a33846b680725aa3fb229473": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "20e735858f8146cead98b873177a4f99", - "climate_mode": "cool", - "model": "Lisa", - "name": "Thermostaat DB", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "off", - "sensors": { - "setpoint": 18.0, - "temperature": 22.0 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.0, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A20" - }, - "5ead63c65e5f44e7870ba2bd680ceb9e": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "9a27714b970547ee9a6bdadc2b815ad5", - "model": "Plug", - "name": "Smart Plug SQ", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A15" - }, - "7d97fc3117784cfdafe347bcedcbbbcb": { - "binary_sensors": { - "plugwise_notification": false - }, - "dev_class": "gateway", - "firmware": "3.2.8", - "gateway_modes": ["away", "full", "vacation"], - "hardware": "AME Smile 2.0 board", - "location": "eedadcb297564f1483faa509179aebed", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Adam", - "select_gateway_mode": "full", - "select_regulation_mode": "cooling", - "regulation_modes": [ - "heating", - "off", - "bleeding_cold", - "bleeding_hot", - "cooling" - ], - "sensors": { - "outdoor_temperature": 13.4 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670101" - }, - "7fda9f84f01342f8afe9ebbbbff30c0f": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "e39529c79ab54fda9bed26cfc0447546", - "climate_mode": "cool", - "model": "Lisa", - "name": "Thermostaat JM", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "off", - "sensors": { - "setpoint": 18.0, - "temperature": 20.0 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.0, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A01" - }, - "838c2f48195242709b87217cf8d8a71f": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "b52908550469425b812c87f766fe5303", - "model": "Plug", - "name": "Smart Plug BK", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A12" - }, - "8a482fa9dddb43acb765d019d8c9838b": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "5cc21042f87f4b4c94ccb5537c47a53f", - "model": "Plug", - "name": "Smart Plug BK2", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A10" - }, - "96714ad90fc948bcbcb5021c4b9f5ae9": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "e39529c79ab54fda9bed26cfc0447546", - "model": "Plug", - "name": "Smart Plug JM", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A03" - }, - "a03b6e8e76dd4646af1a77c31dd9370c": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "93ac3f7bf25342f58cbb77c4a99ac0b3", - "model": "Plug", - "name": "Smart Plug RB", - "sensors": { - "electricity_consumed": 3.13, - "electricity_consumed_interval": 0.77, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A08" - }, - "bbcffa48019f4b09b8368bbaf9559e68": { - "available": true, - "dev_class": "valve_actuator_plug", - "firmware": "2020-05-13T02:00:00+02:00", - "location": "8cf650a4c10c44819e426bed406aec34", - "model": "Plug", - "name": "Smart Plug BK1", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": false - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A16" - }, - "beb32da072274e698146db8b022f3c36": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "9a27714b970547ee9a6bdadc2b815ad5", - "climate_mode": "cool", - "model": "Lisa", - "name": "Thermostaat SQ", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "off", - "sensors": { - "setpoint": 18.5, - "temperature": 21.4 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 18.5, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A07" - }, - "c4ed311d54e341f58b4cdd201d1fde7e": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "93ac3f7bf25342f58cbb77c4a99ac0b3", - "climate_mode": "cool", - "model": "Lisa", - "name": "Thermostaat RB", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "off", - "sensors": { - "setpoint": 17.0, - "temperature": 20.7 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 17.0, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A04" - }, - "ca79d23ae0094120b877558734cff85c": { - "active_preset": "away", - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "thermostat", - "location": "fa5fa6b34f6b40a0972988b20e888ed4", - "climate_mode": "auto", - "model": "ThermoTouch", - "name": "Thermostaat WK", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "Werkdag schema", - "sensors": { - "setpoint": 21.5, - "temperature": 22.5 - }, - "thermostat": { - "lower_bound": 1.0, - "resolution": 0.01, - "setpoint": 21.5, - "upper_bound": 35.0 - }, - "vendor": "Plugwise" - }, - "d3a276aeb3114a509bab1e4bf8c40348": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "04b15f6e884448288f811d29fb7b1b30", - "climate_mode": "cool", - "model": "Lisa", - "name": "Thermostaat SJ", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "off", - "sensors": { - "setpoint": 20.5, - "temperature": 22.6 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 20.5, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A13" - }, - "ea8372c0e3ad4622ad45a041d02425f5": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "a562019b0b1f47a4bde8ebe3dbe3e8a9", - "climate_mode": "auto", - "model": "Lisa", - "name": "Thermostaat KK", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "Werkdag schema", - "sensors": { - "battery": 53, - "setpoint": 21.5, - "temperature": 22.5 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 21.5, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A02" - }, - "eac5db95d97241f6b17790897847ccf5": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "8cf650a4c10c44819e426bed406aec34", - "climate_mode": "auto", - "model": "Lisa", - "name": "Thermostaat BK1", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "Werkdag schema", - "sensors": { - "setpoint": 20.5, - "temperature": 21.5 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 20.5, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A09" - }, - "f04c985c11ad4848b8fcd710343f9dcf": { - "active_preset": "away", - "available": true, - "available_schedules": [ - "Opstaan weekdag", - "Werkdag schema", - "Weekend", - "off" - ], - "control_state": "off", - "dev_class": "zone_thermostat", - "firmware": "2016-10-10T02:00:00+02:00", - "hardware": "255", - "location": "5cc21042f87f4b4c94ccb5537c47a53f", - "climate_mode": "auto", - "model": "Lisa", - "name": "Thermostaat BK2", - "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"], - "select_schedule": "Werkdag schema", - "sensors": { - "setpoint": 20.5, - "temperature": 21.9 - }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 20.5, - "upper_bound": 99.9 - }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A11" + "entities": { + "04b15f6e884448288f811d29fb7b1b30": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer SJ", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 22.6 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 20.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "d3a276aeb3114a509bab1e4bf8c40348" + ], + "secondary": [] + } + }, + "0ca13e8176204ca7bf6f09de59f81c83": { + "available": true, + "binary_sensors": { + "cooling_state": false, + "dhw_state": true, + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "location": "eedadcb297564f1483faa509179aebed", + "max_dhw_temperature": { + "lower_bound": 40.0, + "resolution": 0.01, + "setpoint": 60.0, + "upper_bound": 65.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 7.0, + "resolution": 0.01, + "setpoint": 35.0, + "upper_bound": 50.0 + }, + "model": "Generic heater/cooler", + "model_id": "17.1", + "name": "OpenTherm", + "sensors": { + "dhw_temperature": 63.5, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "outdoor_air_temperature": 13.5, + "return_temperature": 24.9, + "water_pressure": 2.0, + "water_temperature": 24.5 + }, + "switches": { + "dhw_cm_switch": true + }, + "vendor": "Remeha B.V." + }, + "1053c8bbf8be43c6921742b146a625f1": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "b52908550469425b812c87f766fe5303", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat BK", + "sensors": { + "battery": 55, + "setpoint": 18.0, + "temperature": 18.8 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A17" + }, + "1a27dd03b5454c4e8b9e75c8d1afc7af": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "20e735858f8146cead98b873177a4f99", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug DB", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A05" + }, + "20e735858f8146cead98b873177a4f99": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer DB", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 22.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "47e2c550a33846b680725aa3fb229473" + ], + "secondary": [] + } + }, + "2e0fc4db2a6d4cbeb7cf786143543961": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "a562019b0b1f47a4bde8ebe3dbe3e8a9", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug KK", + "sensors": { + "electricity_consumed": 2.13, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A06" + }, + "3b4d2574e2c9443a832b48d19a1c4f06": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "04b15f6e884448288f811d29fb7b1b30", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug SJ", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A14" + }, + "3f0afa71f16c45ab964050002560e43c": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "fa5fa6b34f6b40a0972988b20e888ed4", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug WK", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A18" + }, + "47e2c550a33846b680725aa3fb229473": { + "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "20e735858f8146cead98b873177a4f99", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat DB", + "sensors": { + "setpoint": 18.0, + "temperature": 22.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A20" + }, + "5cc21042f87f4b4c94ccb5537c47a53f": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Badkamer 2", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 0.0, + "temperature": 21.9 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 20.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "f04c985c11ad4848b8fcd710343f9dcf" + ], + "secondary": [] + } + }, + "5ead63c65e5f44e7870ba2bd680ceb9e": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "9a27714b970547ee9a6bdadc2b815ad5", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug SQ", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A15" + }, + "7d97fc3117784cfdafe347bcedcbbbcb": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "3.2.8", + "gateway_modes": [ + "away", + "full", + "vacation" + ], + "hardware": "AME Smile 2.0 board", + "location": "eedadcb297564f1483faa509179aebed", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_open_therm", + "name": "Adam", + "regulation_modes": [ + "heating", + "off", + "bleeding_cold", + "bleeding_hot", + "cooling" + ], + "select_gateway_mode": "full", + "select_regulation_mode": "cooling", + "sensors": { + "outdoor_temperature": 13.4 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" + }, + "7fda9f84f01342f8afe9ebbbbff30c0f": { + "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "e39529c79ab54fda9bed26cfc0447546", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat JM", + "sensors": { + "setpoint": 18.0, + "temperature": 20.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" + }, + "838c2f48195242709b87217cf8d8a71f": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "b52908550469425b812c87f766fe5303", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug BK", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A12" + }, + "8a482fa9dddb43acb765d019d8c9838b": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "5cc21042f87f4b4c94ccb5537c47a53f", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug BK2", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A10" + }, + "8cf650a4c10c44819e426bed406aec34": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Badkamer 1", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 21.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 20.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "eac5db95d97241f6b17790897847ccf5" + ], + "secondary": [] + } + }, + "93ac3f7bf25342f58cbb77c4a99ac0b3": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer RB", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 3.13, + "temperature": 20.7 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 17.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "c4ed311d54e341f58b4cdd201d1fde7e" + ], + "secondary": [] + } + }, + "96714ad90fc948bcbcb5021c4b9f5ae9": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "e39529c79ab54fda9bed26cfc0447546", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug JM", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A03" + }, + "9a27714b970547ee9a6bdadc2b815ad5": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer SQ", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 21.4 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "beb32da072274e698146db8b022f3c36" + ], + "secondary": [] + } + }, + "a03b6e8e76dd4646af1a77c31dd9370c": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "93ac3f7bf25342f58cbb77c4a99ac0b3", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug RB", + "sensors": { + "electricity_consumed": 3.13, + "electricity_consumed_interval": 0.77, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A08" + }, + "a562019b0b1f47a4bde8ebe3dbe3e8a9": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Keuken", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 2.13, + "electricity_produced": 0.0, + "temperature": 22.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 21.5, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "ea8372c0e3ad4622ad45a041d02425f5" + ], + "secondary": [] + } + }, + "b52908550469425b812c87f766fe5303": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Bijkeuken", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 18.8 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "1053c8bbf8be43c6921742b146a625f1" + ], + "secondary": [] + } + }, + "bbcffa48019f4b09b8368bbaf9559e68": { + "available": true, + "dev_class": "valve_actuator_plug", + "firmware": "2020-05-13T02:00:00+02:00", + "location": "8cf650a4c10c44819e426bed406aec34", + "model": "Plug", + "model_id": "160-01", + "name": "Smart Plug BK1", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A16" + }, + "beb32da072274e698146db8b022f3c36": { + "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "9a27714b970547ee9a6bdadc2b815ad5", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat SQ", + "sensors": { + "setpoint": 18.5, + "temperature": 21.4 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" + }, + "c4ed311d54e341f58b4cdd201d1fde7e": { + "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "93ac3f7bf25342f58cbb77c4a99ac0b3", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat RB", + "sensors": { + "setpoint": 17.0, + "temperature": 20.7 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A04" + }, + "ca79d23ae0094120b877558734cff85c": { + "dev_class": "thermostat", + "location": "fa5fa6b34f6b40a0972988b20e888ed4", + "model": "ThermoTouch", + "model_id": "143.1", + "name": "Thermostaat WK", + "sensors": { + "setpoint": 21.5, + "temperature": 22.5 + }, + "vendor": "Plugwise" + }, + "d3a276aeb3114a509bab1e4bf8c40348": { + "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "04b15f6e884448288f811d29fb7b1b30", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat SJ", + "sensors": { + "setpoint": 20.5, + "temperature": 22.6 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A13" + }, + "e39529c79ab54fda9bed26cfc0447546": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "cool", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer JM", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 20.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 18.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "7fda9f84f01342f8afe9ebbbbff30c0f" + ], + "secondary": [] + } + }, + "ea8372c0e3ad4622ad45a041d02425f5": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "a562019b0b1f47a4bde8ebe3dbe3e8a9", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat KK", + "sensors": { + "battery": 53, + "setpoint": 21.5, + "temperature": 22.5 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" + }, + "eac5db95d97241f6b17790897847ccf5": { + "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "8cf650a4c10c44819e426bed406aec34", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat BK1", + "sensors": { + "setpoint": 20.5, + "temperature": 21.5 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A09" + }, + "f04c985c11ad4848b8fcd710343f9dcf": { + "available": true, + "dev_class": "zone_thermostat", + "firmware": "2016-10-10T02:00:00+02:00", + "hardware": "255", + "location": "5cc21042f87f4b4c94ccb5537c47a53f", + "model": "Lisa", + "model_id": "158-01", + "name": "Thermostaat BK2", + "sensors": { + "setpoint": 20.5, + "temperature": 21.9 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A11" + }, + "fa5fa6b34f6b40a0972988b20e888ed4": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 22.5 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 21.5, + "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ca79d23ae0094120b877558734cff85c" + ], + "secondary": [] + } + } } } diff --git a/tests/data/adam/adam_jip.json b/tests/data/adam/adam_jip.json index e734e1707..097c530a7 100644 --- a/tests/data/adam/adam_jip.json +++ b/tests/data/adam/adam_jip.json @@ -1,249 +1,413 @@ { - "e4684553153b44afbef2200885f379dc": { - "dev_class": "heater_central", - "location": "9e4433a9d69f40b3aefd15e74395eaec", - "model": "Generic heater", - "model_id": "10.20", - "name": "OpenTherm", - "vendor": "Remeha B.V.", - "maximum_boiler_temperature": { - "setpoint": 90.0, - "lower_bound": 20.0, - "upper_bound": 90.0, - "resolution": 0.01 + "entities": { + "06aecb3d00354375924f50c47af36bd2": { + "active_preset": "no_frost", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 24.2 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "1346fbd8498d4dbcab7e18d51b771f3d" + ], + "secondary": [ + "356b65335e274d769c338223e7af9c33" + ] + } }, - "max_dhw_temperature": { - "setpoint": 60.0, - "lower_bound": 40.0, - "upper_bound": 60.0, - "resolution": 0.01 + "13228dab8ce04617af318a2888b3c548": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 27.4 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.01, + "setpoint": 9.0, + "upper_bound": 30.0 + }, + "thermostats": { + "primary": [ + "f61f1a2535f54f52ad006a3d18e459ca" + ], + "secondary": [ + "833de10f269c4deab58fb9df69901b4e" + ] + } }, - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": false, - "flame_state": false + "1346fbd8498d4dbcab7e18d51b771f3d": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "06aecb3d00354375924f50c47af36bd2", + "model": "Lisa", + "model_id": "158-01", + "name": "Slaapkamer", + "sensors": { + "battery": 92, + "setpoint": 13.0, + "temperature": 24.2 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A03" }, - "sensors": { - "water_temperature": 37.3, - "intended_boiler_temperature": 0.0, - "modulation_level": 0, - "return_temperature": 37.1, - "water_pressure": 1.4 + "1da4d325838e4ad8aac12177214505c9": { + "available": true, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2020-11-04T01:00:00+01:00", + "hardware": "1", + "location": "d58fec52899f4f1c92e4f8fad6d8c48c", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Tom Logeerkamer", + "sensors": { + "setpoint": 13.0, + "temperature": 28.8, + "temperature_difference": 2.0, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.1, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" }, - "switches": { - "dhw_cm_switch": false - } - }, - "a6abc6a129ee499c88a4d420cc413b47": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "d58fec52899f4f1c92e4f8fad6d8c48c", - "model": "Lisa", - "name": "Logeerkamer", - "zigbee_mac_address": "ABCD012345670A01", - "vendor": "Plugwise", - "thermostat": { - "lower_bound": 0.0, - "setpoint": 13.0, - "resolution": 0.01, - "upper_bound": 99.9 + "356b65335e274d769c338223e7af9c33": { + "available": true, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2020-11-04T01:00:00+01:00", + "hardware": "1", + "location": "06aecb3d00354375924f50c47af36bd2", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Tom Slaapkamer", + "sensors": { + "setpoint": 13.0, + "temperature": 24.2, + "temperature_difference": 1.7, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.1, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A05" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "home", - "control_state": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 30.0, - "setpoint": 13.0, - "battery": 80 - } - }, - "1346fbd8498d4dbcab7e18d51b771f3d": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "06aecb3d00354375924f50c47af36bd2", - "model": "Lisa", - "name": "Slaapkamer", - "zigbee_mac_address": "ABCD012345670A03", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 13.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "457ce8414de24596a2d5e7dbc9c7682f": { + "available": true, + "dev_class": "zz_misc_plug", + "location": "9e4433a9d69f40b3aefd15e74395eaec", + "model": "Aqara Smart Plug", + "model_id": "lumi.plug.maeu01", + "name": "Plug", + "sensors": { + "electricity_consumed_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": false + }, + "vendor": "LUMI", + "zigbee_mac_address": "ABCD012345670A06" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "no_frost", - "control_state": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 24.2, - "setpoint": 13.0, - "battery": 92 - } - }, - "833de10f269c4deab58fb9df69901b4e": { - "dev_class": "thermo_sensor", - "firmware": "2020-11-04T01:00:00+01:00", - "hardware": "1", - "location": "13228dab8ce04617af318a2888b3c548", - "model": "Tom/Floor", - "name": "Tom Woonkamer", - "zigbee_mac_address": "ABCD012345670A09", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 24.0, - "setpoint": 9.0, - "temperature_difference": 1.8, - "valve_position": 100 - } - }, - "6f3e9d7084214c21b9dfa46f6eeb8700": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "d27aede973b54be484f6842d1b2802ad", - "model": "Lisa", - "name": "Kinderkamer", - "zigbee_mac_address": "ABCD012345670A02", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 13.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "6f3e9d7084214c21b9dfa46f6eeb8700": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "d27aede973b54be484f6842d1b2802ad", + "model": "Lisa", + "model_id": "158-01", + "name": "Kinderkamer", + "sensors": { + "battery": 79, + "setpoint": 13.0, + "temperature": 30.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "home", - "control_state": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 30.0, - "setpoint": 13.0, - "battery": 79 - } - }, - "f61f1a2535f54f52ad006a3d18e459ca": { - "dev_class": "zone_thermometer", - "firmware": "2020-09-01T02:00:00+02:00", - "hardware": "1", - "location": "13228dab8ce04617af318a2888b3c548", - "model": "Jip", - "name": "Woonkamer", - "zigbee_mac_address": "ABCD012345670A08", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 9.0, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.01 + "833de10f269c4deab58fb9df69901b4e": { + "available": true, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2020-11-04T01:00:00+01:00", + "hardware": "1", + "location": "13228dab8ce04617af318a2888b3c548", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Tom Woonkamer", + "sensors": { + "setpoint": 9.0, + "temperature": 24.0, + "temperature_difference": 1.8, + "valve_position": 100 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.1, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A09" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "home", - "control_state": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 27.4, - "setpoint": 9.0, - "battery": 100, - "humidity": 56.2 - } - }, - "d4496250d0e942cfa7aea3476e9070d5": { - "dev_class": "thermo_sensor", - "firmware": "2020-11-04T01:00:00+01:00", - "hardware": "1", - "location": "d27aede973b54be484f6842d1b2802ad", - "model": "Tom/Floor", - "name": "Tom Kinderkamer", - "zigbee_mac_address": "ABCD012345670A04", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 28.7, - "setpoint": 13.0, - "temperature_difference": 1.9, - "valve_position": 0 - } - }, - "356b65335e274d769c338223e7af9c33": { - "dev_class": "thermo_sensor", - "firmware": "2020-11-04T01:00:00+01:00", - "hardware": "1", - "location": "06aecb3d00354375924f50c47af36bd2", - "model": "Tom/Floor", - "name": "Tom Slaapkamer", - "zigbee_mac_address": "ABCD012345670A05", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 24.2, - "setpoint": 13.0, - "temperature_difference": 1.7, - "valve_position": 0 - } - }, - "b5c2386c6f6342669e50fe49dd05b188": { - "dev_class": "gateway", - "firmware": "3.2.8", - "gateway_modes": ["away", "full", "vacation"], - "hardware": "AME Smile 2.0 board", - "location": "9e4433a9d69f40b3aefd15e74395eaec", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Adam", - "zigbee_mac_address": "ABCD012345670101", - "vendor": "Plugwise", - "select_gateway_mode": "full", - "select_regulation_mode": "heating", - "regulation_modes": ["heating", "off", "bleeding_cold", "bleeding_hot"], - "binary_sensors": { - "plugwise_notification": false + "a6abc6a129ee499c88a4d420cc413b47": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "d58fec52899f4f1c92e4f8fad6d8c48c", + "model": "Lisa", + "model_id": "158-01", + "name": "Logeerkamer", + "sensors": { + "battery": 80, + "setpoint": 13.0, + "temperature": 30.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" }, - "sensors": { - "outdoor_temperature": 24.9 - } - }, - "1da4d325838e4ad8aac12177214505c9": { - "dev_class": "thermo_sensor", - "firmware": "2020-11-04T01:00:00+01:00", - "hardware": "1", - "location": "d58fec52899f4f1c92e4f8fad6d8c48c", - "model": "Tom/Floor", - "name": "Tom Logeerkamer", - "zigbee_mac_address": "ABCD012345670A07", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 28.8, - "setpoint": 13.0, - "temperature_difference": 2.0, - "valve_position": 0 - } - }, - "457ce8414de24596a2d5e7dbc9c7682f": { - "dev_class": "zz_misc_plug", - "location": "9e4433a9d69f40b3aefd15e74395eaec", - "model": "Aqara Smart Plug", - "model_id": "lumi.plug.maeu01", - "name": "Plug", - "zigbee_mac_address": "ABCD012345670A06", - "vendor": "LUMI", - "available": true, - "sensors": { - "electricity_consumed_interval": 0.0 + "b5c2386c6f6342669e50fe49dd05b188": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "3.2.8", + "gateway_modes": [ + "away", + "full", + "vacation" + ], + "hardware": "AME Smile 2.0 board", + "location": "9e4433a9d69f40b3aefd15e74395eaec", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_open_therm", + "name": "Adam", + "regulation_modes": [ + "heating", + "off", + "bleeding_cold", + "bleeding_hot" + ], + "select_gateway_mode": "full", + "select_regulation_mode": "heating", + "sensors": { + "outdoor_temperature": 24.9 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" + }, + "d27aede973b54be484f6842d1b2802ad": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Kinderkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 30.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "6f3e9d7084214c21b9dfa46f6eeb8700" + ], + "secondary": [ + "d4496250d0e942cfa7aea3476e9070d5" + ] + } + }, + "d4496250d0e942cfa7aea3476e9070d5": { + "available": true, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2020-11-04T01:00:00+01:00", + "hardware": "1", + "location": "d27aede973b54be484f6842d1b2802ad", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Tom Kinderkamer", + "sensors": { + "setpoint": 13.0, + "temperature": 28.7, + "temperature_difference": 1.9, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.1, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A04" + }, + "d58fec52899f4f1c92e4f8fad6d8c48c": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Logeerkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 30.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "a6abc6a129ee499c88a4d420cc413b47" + ], + "secondary": [ + "1da4d325838e4ad8aac12177214505c9" + ] + } + }, + "e4684553153b44afbef2200885f379dc": { + "available": true, + "binary_sensors": { + "dhw_state": false, + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "location": "9e4433a9d69f40b3aefd15e74395eaec", + "max_dhw_temperature": { + "lower_bound": 40.0, + "resolution": 0.01, + "setpoint": 60.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 20.0, + "resolution": 0.01, + "setpoint": 90.0, + "upper_bound": 90.0 + }, + "model": "Generic heater", + "model_id": "10.20", + "name": "OpenTherm", + "sensors": { + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "return_temperature": 37.1, + "water_pressure": 1.4, + "water_temperature": 37.3 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Remeha B.V." }, - "switches": { - "relay": false, - "lock": true + "f61f1a2535f54f52ad006a3d18e459ca": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermometer", + "firmware": "2020-09-01T02:00:00+02:00", + "hardware": "1", + "location": "13228dab8ce04617af318a2888b3c548", + "model": "Jip", + "model_id": "168-01", + "name": "Woonkamer", + "sensors": { + "battery": 100, + "humidity": 56.2, + "setpoint": 9.0, + "temperature": 27.4 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A08" } } } diff --git a/tests/data/adam/adam_multiple_devices_per_zone.json b/tests/data/adam/adam_multiple_devices_per_zone.json index 51a8f3378..790223e09 100644 --- a/tests/data/adam/adam_multiple_devices_per_zone.json +++ b/tests/data/adam/adam_multiple_devices_per_zone.json @@ -1,416 +1,620 @@ { - "df4a4a8169904cdb9c03d61a21f42140": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "12493538af164a409c6a1c79e38afe1c", - "model": "Lisa", - "name": "Zone Lisa Bios", - "zigbee_mac_address": "ABCD012345670A06", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 13.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "entities": { + "02cf28bfec924855854c544690a609ef": { + "available": true, + "dev_class": "vcr_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "cd143c07248f491493cea0533bc3d669", + "model": "Plug", + "model_id": "160-01", + "name": "NVR", + "sensors": { + "electricity_consumed": 34.0, + "electricity_consumed_interval": 9.15, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A15" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "away", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 16.5, - "setpoint": 13.0, - "battery": 67 - } - }, - "b310b72a0e354bfab43089919b9a88bf": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "c50f167537524366a5af7aa3942feb1e", - "model": "Tom/Floor", - "name": "Floor kraan", - "zigbee_mac_address": "ABCD012345670A02", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 26.0, - "setpoint": 21.5, - "temperature_difference": 3.5, - "valve_position": 100 - } - }, - "a2c3583e0a6349358998b760cea82d2a": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "12493538af164a409c6a1c79e38afe1c", - "model": "Tom/Floor", - "name": "Bios Cv Thermostatic Radiator ", - "zigbee_mac_address": "ABCD012345670A09", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 17.2, - "setpoint": 13.0, - "battery": 62, - "temperature_difference": -0.2, - "valve_position": 0 - } - }, - "b59bcebaf94b499ea7d46e4a66fb62d8": { - "dev_class": "zone_thermostat", - "firmware": "2016-08-02T02:00:00+02:00", - "hardware": "255", - "location": "c50f167537524366a5af7aa3942feb1e", - "model": "Lisa", - "name": "Zone Lisa WK", - "zigbee_mac_address": "ABCD012345670A07", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 21.5, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "08963fec7c53423ca5680aa4cb502c63": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Badkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "Badkamer Schema", + "sensors": { + "temperature": 18.9 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 14.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "f1fee6043d3642a9b0a65297455f008e" + ], + "secondary": [ + "680423ff840043738f42cc7f1ff97a36" + ] + } }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "home", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "GF7 Woonkamer", - "climate_mode": "auto", - "sensors": { - "temperature": 20.9, - "setpoint": 21.5, - "battery": 34 - } - }, - "fe799307f1624099878210aa0b9f1475": { - "dev_class": "gateway", - "firmware": "3.0.15", - "hardware": "AME Smile 2.0 board", - "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Adam", - "zigbee_mac_address": "ABCD012345670101", - "vendor": "Plugwise", - "select_regulation_mode": "heating", - "binary_sensors": { - "plugwise_notification": true + "12493538af164a409c6a1c79e38afe1c": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Bios", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "df4a4a8169904cdb9c03d61a21f42140" + ], + "secondary": [ + "a2c3583e0a6349358998b760cea82d2a" + ] + } }, - "sensors": { - "outdoor_temperature": 7.81 - } - }, - "d3da73bde12a47d5a6b8f9dad971f2ec": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "82fa13f017d240daa0d0ea1775420f24", - "model": "Tom/Floor", - "name": "Thermostatic Radiator Jessie", - "zigbee_mac_address": "ABCD012345670A10", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 17.1, - "setpoint": 15.0, - "battery": 62, - "temperature_difference": 0.1, - "valve_position": 0 - } - }, - "21f2b542c49845e6bb416884c55778d6": { - "dev_class": "game_console_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "cd143c07248f491493cea0533bc3d669", - "model": "Plug", - "name": "Playstation Smart Plug", - "zigbee_mac_address": "ABCD012345670A12", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 84.1, - "electricity_consumed_interval": 8.6, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "21f2b542c49845e6bb416884c55778d6": { + "available": true, + "dev_class": "game_console_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "cd143c07248f491493cea0533bc3d669", + "model": "Plug", + "model_id": "160-01", + "name": "Playstation Smart Plug", + "sensors": { + "electricity_consumed": 84.1, + "electricity_consumed_interval": 8.6, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A12" }, - "switches": { - "relay": true, - "lock": false - } - }, - "78d1126fc4c743db81b61c20e88342a7": { - "dev_class": "central_heating_pump_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "c50f167537524366a5af7aa3942feb1e", - "model": "Plug", - "name": "CV Pomp", - "zigbee_mac_address": "ABCD012345670A05", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 35.6, - "electricity_consumed_interval": 7.37, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "446ac08dd04d4eff8ac57489757b7314": { + "active_preset": "no_frost", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Garage", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "temperature": 15.6 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 5.5, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "e7693eb9582644e5b865dba8d4447cf1" + ], + "secondary": [] + } }, - "switches": { - "relay": true - } - }, - "90986d591dcd426cae3ec3e8111ff730": { - "dev_class": "heater_central", - "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", - "model": "Unknown", - "name": "OnOff", - "binary_sensors": { - "heating_state": true + "4a810418d5394b3f82727340b91ba740": { + "available": true, + "dev_class": "router_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "cd143c07248f491493cea0533bc3d669", + "model": "Plug", + "model_id": "160-01", + "name": "USG Smart Plug", + "sensors": { + "electricity_consumed": 8.5, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A16" }, - "sensors": { - "water_temperature": 70.0, - "intended_boiler_temperature": 70.0, - "modulation_level": 1 - } - }, - "cd0ddb54ef694e11ac18ed1cbce5dbbd": { - "dev_class": "vcr_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "cd143c07248f491493cea0533bc3d669", - "model": "Plug", - "name": "NAS", - "zigbee_mac_address": "ABCD012345670A14", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 16.5, - "electricity_consumed_interval": 0.5, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "675416a629f343c495449970e2ca37b5": { + "available": true, + "dev_class": "router_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "cd143c07248f491493cea0533bc3d669", + "model": "Plug", + "model_id": "160-01", + "name": "Ziggo Modem", + "sensors": { + "electricity_consumed": 12.2, + "electricity_consumed_interval": 2.97, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" }, - "switches": { - "relay": true, - "lock": true - } - }, - "4a810418d5394b3f82727340b91ba740": { - "dev_class": "router_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "cd143c07248f491493cea0533bc3d669", - "model": "Plug", - "name": "USG Smart Plug", - "zigbee_mac_address": "ABCD012345670A16", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 8.5, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "680423ff840043738f42cc7f1ff97a36": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "08963fec7c53423ca5680aa4cb502c63", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Thermostatic Radiator Badkamer", + "sensors": { + "battery": 51, + "setpoint": 14.0, + "temperature": 19.1, + "temperature_difference": -0.4, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A17" }, - "switches": { - "relay": true, - "lock": true - } - }, - "02cf28bfec924855854c544690a609ef": { - "dev_class": "vcr_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "cd143c07248f491493cea0533bc3d669", - "model": "Plug", - "name": "NVR", - "zigbee_mac_address": "ABCD012345670A15", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 34.0, - "electricity_consumed_interval": 9.15, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "6a3bf693d05e48e0b460c815a4fdd09d": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "82fa13f017d240daa0d0ea1775420f24", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Thermostat Jessie", + "sensors": { + "battery": 37, + "setpoint": 15.0, + "temperature": 17.2 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A03" }, - "switches": { - "relay": true, - "lock": true - } - }, - "a28f588dc4a049a483fd03a30361ad3a": { - "dev_class": "settop_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "cd143c07248f491493cea0533bc3d669", - "model": "Plug", - "name": "Fibaro HC2", - "zigbee_mac_address": "ABCD012345670A13", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 12.5, - "electricity_consumed_interval": 3.8, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "78d1126fc4c743db81b61c20e88342a7": { + "available": true, + "dev_class": "central_heating_pump_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "c50f167537524366a5af7aa3942feb1e", + "model": "Plug", + "model_id": "160-01", + "name": "CV Pomp", + "sensors": { + "electricity_consumed": 35.6, + "electricity_consumed_interval": 7.37, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A05" }, - "switches": { - "relay": true, - "lock": true - } - }, - "6a3bf693d05e48e0b460c815a4fdd09d": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "82fa13f017d240daa0d0ea1775420f24", - "model": "Lisa", - "name": "Zone Thermostat Jessie", - "zigbee_mac_address": "ABCD012345670A03", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 15.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "82fa13f017d240daa0d0ea1775420f24": { + "active_preset": "asleep", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Jessie", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "CV Jessie", + "sensors": { + "temperature": 17.2 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 15.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "6a3bf693d05e48e0b460c815a4fdd09d" + ], + "secondary": [ + "d3da73bde12a47d5a6b8f9dad971f2ec" + ] + } }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "asleep", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "CV Jessie", - "climate_mode": "auto", - "sensors": { - "temperature": 17.2, - "setpoint": 15.0, - "battery": 37 - } - }, - "680423ff840043738f42cc7f1ff97a36": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "08963fec7c53423ca5680aa4cb502c63", - "model": "Tom/Floor", - "name": "Thermostatic Radiator Badkamer", - "zigbee_mac_address": "ABCD012345670A17", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 19.1, - "setpoint": 14.0, - "battery": 51, - "temperature_difference": -0.4, - "valve_position": 0 - } - }, - "f1fee6043d3642a9b0a65297455f008e": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "08963fec7c53423ca5680aa4cb502c63", - "model": "Lisa", - "name": "Zone Thermostat Badkamer", - "zigbee_mac_address": "ABCD012345670A08", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 14.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "90986d591dcd426cae3ec3e8111ff730": { + "binary_sensors": { + "heating_state": true + }, + "dev_class": "heater_central", + "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", + "model": "Unknown", + "name": "OnOff", + "sensors": { + "intended_boiler_temperature": 70.0, + "modulation_level": 1, + "water_temperature": 70.0 + } }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "away", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "Badkamer Schema", - "climate_mode": "auto", - "sensors": { - "temperature": 18.9, - "setpoint": 14.0, - "battery": 92 - } - }, - "675416a629f343c495449970e2ca37b5": { - "dev_class": "router_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "cd143c07248f491493cea0533bc3d669", - "model": "Plug", - "name": "Ziggo Modem", - "zigbee_mac_address": "ABCD012345670A01", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 12.2, - "electricity_consumed_interval": 2.97, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "a28f588dc4a049a483fd03a30361ad3a": { + "available": true, + "dev_class": "settop_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "cd143c07248f491493cea0533bc3d669", + "model": "Plug", + "model_id": "160-01", + "name": "Fibaro HC2", + "sensors": { + "electricity_consumed": 12.5, + "electricity_consumed_interval": 3.8, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A13" }, - "switches": { - "relay": true, - "lock": true - } - }, - "e7693eb9582644e5b865dba8d4447cf1": { - "dev_class": "thermostatic_radiator_valve", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "446ac08dd04d4eff8ac57489757b7314", - "model": "Tom/Floor", - "name": "CV Kraan Garage", - "zigbee_mac_address": "ABCD012345670A11", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 5.5, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 0.01 + "a2c3583e0a6349358998b760cea82d2a": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "12493538af164a409c6a1c79e38afe1c", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Bios Cv Thermostatic Radiator ", + "sensors": { + "battery": 62, + "setpoint": 13.0, + "temperature": 17.2, + "temperature_difference": -0.2, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A09" + }, + "b310b72a0e354bfab43089919b9a88bf": { + "available": true, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "c50f167537524366a5af7aa3942feb1e", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Floor kraan", + "sensors": { + "setpoint": 21.5, + "temperature": 26.0, + "temperature_difference": 3.5, + "valve_position": 100 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" + }, + "b59bcebaf94b499ea7d46e4a66fb62d8": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-08-02T02:00:00+02:00", + "hardware": "255", + "location": "c50f167537524366a5af7aa3942feb1e", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Lisa WK", + "sensors": { + "battery": 34, + "setpoint": 21.5, + "temperature": 20.9 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" + }, + "c50f167537524366a5af7aa3942feb1e": { + "active_preset": "home", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "GF7 Woonkamer", + "sensors": { + "electricity_consumed": 35.6, + "electricity_produced": 0.0, + "temperature": 20.9 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 21.5, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "b59bcebaf94b499ea7d46e4a66fb62d8" + ], + "secondary": [ + "b310b72a0e354bfab43089919b9a88bf" + ] + } + }, + "cd0ddb54ef694e11ac18ed1cbce5dbbd": { + "available": true, + "dev_class": "vcr_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "cd143c07248f491493cea0533bc3d669", + "model": "Plug", + "model_id": "160-01", + "name": "NAS", + "sensors": { + "electricity_consumed": 16.5, + "electricity_consumed_interval": 0.5, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A14" + }, + "d3da73bde12a47d5a6b8f9dad971f2ec": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "82fa13f017d240daa0d0ea1775420f24", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Thermostatic Radiator Jessie", + "sensors": { + "battery": 62, + "setpoint": 15.0, + "temperature": 17.1, + "temperature_difference": 0.1, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A10" + }, + "df4a4a8169904cdb9c03d61a21f42140": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "12493538af164a409c6a1c79e38afe1c", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Lisa Bios", + "sensors": { + "battery": 67, + "setpoint": 13.0, + "temperature": 16.5 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A06" + }, + "e7693eb9582644e5b865dba8d4447cf1": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "446ac08dd04d4eff8ac57489757b7314", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "CV Kraan Garage", + "sensors": { + "battery": 68, + "setpoint": 5.5, + "temperature": 15.6, + "temperature_difference": 0.0, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A11" + }, + "f1fee6043d3642a9b0a65297455f008e": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "08963fec7c53423ca5680aa4cb502c63", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Thermostat Badkamer", + "sensors": { + "battery": 92, + "setpoint": 14.0, + "temperature": 18.9 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A08" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "no_frost", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 15.6, - "setpoint": 5.5, - "battery": 68, - "temperature_difference": 0.0, - "valve_position": 0 + "fe799307f1624099878210aa0b9f1475": { + "binary_sensors": { + "plugwise_notification": true + }, + "dev_class": "gateway", + "firmware": "3.0.15", + "hardware": "AME Smile 2.0 board", + "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_open_therm", + "name": "Adam", + "select_regulation_mode": "heating", + "sensors": { + "outdoor_temperature": 7.81 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" } } } diff --git a/tests/data/adam/adam_onoff_cooling_fake_firmware.json b/tests/data/adam/adam_onoff_cooling_fake_firmware.json index 1c3dac0e0..335ef5d01 100644 --- a/tests/data/adam/adam_onoff_cooling_fake_firmware.json +++ b/tests/data/adam/adam_onoff_cooling_fake_firmware.json @@ -1,12 +1,122 @@ { - "0ca13e8176204ca7bf6f09de59f81c83": { - "binary_sensors": { - "cooling_state": true, - "dhw_state": true, - "heating_state": false + "entities": { + "0ca13e8176204ca7bf6f09de59f81c83": { + "binary_sensors": { + "cooling_state": true, + "dhw_state": true, + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "location": "eedadcb297564f1483faa509179aebed", + "max_dhw_temperature": { + "lower_bound": 40.0, + "resolution": 0.01, + "setpoint": 60.0, + "upper_bound": 65.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 7.0, + "resolution": 0.01, + "setpoint": 35.0, + "upper_bound": 50.0 + }, + "model": "Unknown", + "name": "OnOff", + "sensors": { + "dhw_temperature": 63.5, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "outdoor_air_temperature": 13.5, + "return_temperature": 24.9, + "water_pressure": 2.0, + "water_temperature": 24.5 + }, + "switches": { + "dhw_cm_switch": true + } }, - "sensors": { - "modulation_level": 0 + "7d97fc3117784cfdafe347bcedcbbbcb": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "3.2.8", + "gateway_modes": [ + "away", + "full", + "vacation" + ], + "hardware": "AME Smile 2.0 board", + "location": "eedadcb297564f1483faa509179aebed", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_open_therm", + "name": "Adam", + "regulation_modes": [ + "heating", + "off", + "bleeding_cold", + "bleeding_hot", + "cooling" + ], + "select_gateway_mode": "full", + "select_regulation_mode": "cooling", + "sensors": { + "outdoor_temperature": 13.4 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" + }, + "ca79d23ae0094120b877558734cff85c": { + "dev_class": "thermostat", + "location": "fa5fa6b34f6b40a0972988b20e888ed4", + "model": "ThermoTouch", + "model_id": "143.1", + "name": "Thermostaat WK", + "sensors": { + "setpoint": 21.5, + "temperature": 22.5 + }, + "vendor": "Plugwise" + }, + "fa5fa6b34f6b40a0972988b20e888ed4": { + "active_preset": "away", + "available_schedules": [ + "Opstaan weekdag", + "Werkdag schema", + "Weekend", + "off" + ], + "climate_mode": "auto", + "control_state": "off", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "no_frost", + "vacation", + "away", + "home", + "asleep" + ], + "select_schedule": "Werkdag schema", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 22.5 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 21.5, + "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ca79d23ae0094120b877558734cff85c" + ], + "secondary": [] + } } } } diff --git a/tests/data/adam/adam_plus_anna.json b/tests/data/adam/adam_plus_anna.json index be742da7b..e6cd0e985 100644 --- a/tests/data/adam/adam_plus_anna.json +++ b/tests/data/adam/adam_plus_anna.json @@ -1,106 +1,135 @@ { - "2743216f626f43948deec1f7ab3b3d70": { - "dev_class": "heater_central", - "location": "07d618f0bb80412687f065b8698ce3e7", - "model": "Generic heater", - "name": "OpenTherm", - "maximum_boiler_temperature": { - "setpoint": 80.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1.0 + "entities": { + "009490cc2f674ce6b576863fbb64f867": { + "active_preset": "home", + "available_schedules": [ + "Weekschema", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Living room", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "Weekschema", + "sensors": { + "electricity_consumed": 74.2, + "electricity_produced": 0.0, + "temperature": 20.5 + }, + "thermostat": { + "lower_bound": 1.0, + "resolution": 0.01, + "setpoint": 20.5, + "upper_bound": 35.0 + }, + "thermostats": { + "primary": [ + "ee62cad889f94e8ca3d09021f03a660b" + ], + "secondary": [] + } }, - "available": false, - "binary_sensors": { - "dhw_state": false, - "heating_state": false, - "flame_state": false + "2743216f626f43948deec1f7ab3b3d70": { + "available": false, + "binary_sensors": { + "dhw_state": false, + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "location": "07d618f0bb80412687f065b8698ce3e7", + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 80.0, + "upper_bound": 100.0 + }, + "model": "Generic heater", + "name": "OpenTherm", + "sensors": { + "intended_boiler_temperature": 0.0, + "water_temperature": 48.0 + }, + "switches": { + "dhw_cm_switch": false + } }, - "sensors": { - "water_temperature": 48.0, - "intended_boiler_temperature": 0.0 + "aa6b0002df0a46e1b1eb94beb61eddfe": { + "available": true, + "dev_class": "hometheater_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "45d410adf8fd461e85cebf16d5ead542", + "model": "Plug", + "model_id": "160-01", + "name": "MediaCenter", + "sensors": { + "electricity_consumed": 10.3, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" }, - "switches": { - "dhw_cm_switch": false - } - }, - "aa6b0002df0a46e1b1eb94beb61eddfe": { - "dev_class": "hometheater_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "45d410adf8fd461e85cebf16d5ead542", - "model": "Plug", - "name": "MediaCenter", - "zigbee_mac_address": "ABCD012345670A01", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 10.3, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": true, - "lock": false - } - }, - "b128b4bbbd1f47e9bf4d756e8fb5ee94": { - "dev_class": "gateway", - "firmware": "3.0.15", - "hardware": "AME Smile 2.0 board", - "location": "07d618f0bb80412687f065b8698ce3e7", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Adam", - "zigbee_mac_address": "ABCD012345670101", - "vendor": "Plugwise", - "select_regulation_mode": "heating", - "binary_sensors": { - "plugwise_notification": true + "b128b4bbbd1f47e9bf4d756e8fb5ee94": { + "binary_sensors": { + "plugwise_notification": true + }, + "dev_class": "gateway", + "firmware": "3.0.15", + "hardware": "AME Smile 2.0 board", + "location": "07d618f0bb80412687f065b8698ce3e7", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_open_therm", + "name": "Adam", + "select_regulation_mode": "heating", + "sensors": { + "outdoor_temperature": 11.9 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" }, - "sensors": { - "outdoor_temperature": 11.9 - } - }, - "ee62cad889f94e8ca3d09021f03a660b": { - "dev_class": "thermostat", - "location": "009490cc2f674ce6b576863fbb64f867", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 20.5, - "lower_bound": 1.0, - "upper_bound": 35.0, - "resolution": 0.01 - }, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "home", - "available_schedules": ["Weekschema", "off"], - "select_schedule": "Weekschema", - "climate_mode": "auto", - "sensors": { - "temperature": 20.5, - "setpoint": 20.5 - } - }, - "f2be121e4a9345ac83c6e99ed89a98be": { - "dev_class": "computer_desktop_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "5ccb6c41a7d9403988d261ceee04239f", - "name": "Work-PC", - "zigbee_mac_address": "ABCD012345670A02", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 80.5, - "electricity_consumed_interval": 7.03, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "ee62cad889f94e8ca3d09021f03a660b": { + "dev_class": "thermostat", + "location": "009490cc2f674ce6b576863fbb64f867", + "model": "ThermoTouch", + "model_id": "143.1", + "name": "Anna", + "sensors": { + "setpoint": 20.5, + "temperature": 20.5 + }, + "vendor": "Plugwise" }, - "switches": { - "relay": true, - "lock": false + "f2be121e4a9345ac83c6e99ed89a98be": { + "available": true, + "dev_class": "computer_desktop_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "5ccb6c41a7d9403988d261ceee04239f", + "name": "Work-PC", + "sensors": { + "electricity_consumed": 80.5, + "electricity_consumed_interval": 7.03, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" } } } diff --git a/tests/data/adam/adam_zone_per_device.json b/tests/data/adam/adam_zone_per_device.json index d9969d045..bb5220de9 100644 --- a/tests/data/adam/adam_zone_per_device.json +++ b/tests/data/adam/adam_zone_per_device.json @@ -1,416 +1,620 @@ { - "df4a4a8169904cdb9c03d61a21f42140": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "12493538af164a409c6a1c79e38afe1c", - "model": "Lisa", - "name": "Zone Lisa Bios", - "zigbee_mac_address": "ABCD012345670A06", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 13.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "entities": { + "02cf28bfec924855854c544690a609ef": { + "available": true, + "dev_class": "vcr_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "c4d2bda6df8146caa2e5c2b5dc65660e", + "model": "Plug", + "model_id": "160-01", + "name": "NVR", + "sensors": { + "electricity_consumed": 34.0, + "electricity_consumed_interval": 8.65, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A15" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "away", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 16.5, - "setpoint": 13.0, - "battery": 67 - } - }, - "b310b72a0e354bfab43089919b9a88bf": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "c50f167537524366a5af7aa3942feb1e", - "model": "Tom/Floor", - "name": "Floor kraan", - "zigbee_mac_address": "ABCD012345670A02", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 26.2, - "setpoint": 21.5, - "temperature_difference": 3.7, - "valve_position": 100 - } - }, - "a2c3583e0a6349358998b760cea82d2a": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "12493538af164a409c6a1c79e38afe1c", - "model": "Tom/Floor", - "name": "Bios Cv Thermostatic Radiator ", - "zigbee_mac_address": "ABCD012345670A09", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 17.1, - "setpoint": 13.0, - "battery": 62, - "temperature_difference": -0.1, - "valve_position": 0 - } - }, - "b59bcebaf94b499ea7d46e4a66fb62d8": { - "dev_class": "zone_thermostat", - "firmware": "2016-08-02T02:00:00+02:00", - "hardware": "255", - "location": "c50f167537524366a5af7aa3942feb1e", - "model": "Lisa", - "name": "Zone Lisa WK", - "zigbee_mac_address": "ABCD012345670A07", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 21.5, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "08963fec7c53423ca5680aa4cb502c63": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Badkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "Badkamer Schema", + "sensors": { + "temperature": 18.8 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 14.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "f1fee6043d3642a9b0a65297455f008e" + ], + "secondary": [ + "680423ff840043738f42cc7f1ff97a36" + ] + } }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "home", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "GF7 Woonkamer", - "climate_mode": "auto", - "sensors": { - "temperature": 21.1, - "setpoint": 21.5, - "battery": 34 - } - }, - "fe799307f1624099878210aa0b9f1475": { - "dev_class": "gateway", - "firmware": "3.0.15", - "hardware": "AME Smile 2.0 board", - "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Adam", - "zigbee_mac_address": "ABCD012345670101", - "vendor": "Plugwise", - "select_regulation_mode": "heating", - "binary_sensors": { - "plugwise_notification": true + "12493538af164a409c6a1c79e38afe1c": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Bios", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "df4a4a8169904cdb9c03d61a21f42140" + ], + "secondary": [ + "a2c3583e0a6349358998b760cea82d2a" + ] + } }, - "sensors": { - "outdoor_temperature": 7.69 - } - }, - "d3da73bde12a47d5a6b8f9dad971f2ec": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "82fa13f017d240daa0d0ea1775420f24", - "model": "Tom/Floor", - "name": "Thermostatic Radiator Jessie", - "zigbee_mac_address": "ABCD012345670A10", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 16.9, - "setpoint": 16.0, - "battery": 62, - "temperature_difference": 0.1, - "valve_position": 0 - } - }, - "21f2b542c49845e6bb416884c55778d6": { - "dev_class": "game_console_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "4efbab4c8bb84fbab26c8decf670eb96", - "model": "Plug", - "name": "Playstation Smart Plug", - "zigbee_mac_address": "ABCD012345670A12", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 80.1, - "electricity_consumed_interval": 12.7, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "21f2b542c49845e6bb416884c55778d6": { + "available": true, + "dev_class": "game_console_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "4efbab4c8bb84fbab26c8decf670eb96", + "model": "Plug", + "model_id": "160-01", + "name": "Playstation Smart Plug", + "sensors": { + "electricity_consumed": 80.1, + "electricity_consumed_interval": 12.7, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A12" }, - "switches": { - "relay": true, - "lock": false - } - }, - "78d1126fc4c743db81b61c20e88342a7": { - "dev_class": "central_heating_pump_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "c50f167537524366a5af7aa3942feb1e", - "model": "Plug", - "name": "CV Pomp", - "zigbee_mac_address": "ABCD012345670A05", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 35.8, - "electricity_consumed_interval": 5.85, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "446ac08dd04d4eff8ac57489757b7314": { + "active_preset": "no_frost", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Garage", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "temperature": 15.6 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 5.5, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "e7693eb9582644e5b865dba8d4447cf1" + ], + "secondary": [] + } }, - "switches": { - "relay": true - } - }, - "90986d591dcd426cae3ec3e8111ff730": { - "dev_class": "heater_central", - "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", - "model": "Unknown", - "name": "OnOff", - "binary_sensors": { - "heating_state": true + "4a810418d5394b3f82727340b91ba740": { + "available": true, + "dev_class": "router_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "0217e9743c174eef9d6e9f680d403ce2", + "model": "Plug", + "model_id": "160-01", + "name": "USG Smart Plug", + "sensors": { + "electricity_consumed": 8.5, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A16" }, - "sensors": { - "water_temperature": 70.0, - "intended_boiler_temperature": 70.0, - "modulation_level": 1 - } - }, - "cd0ddb54ef694e11ac18ed1cbce5dbbd": { - "dev_class": "vcr_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "e704bae65654496f9cade9c855decdfe", - "model": "Plug", - "name": "NAS", - "zigbee_mac_address": "ABCD012345670A14", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 16.5, - "electricity_consumed_interval": 0.29, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "675416a629f343c495449970e2ca37b5": { + "available": true, + "dev_class": "router_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "2b1591ecf6344d4d93b03dece9747648", + "model": "Plug", + "model_id": "160-01", + "name": "Ziggo Modem", + "sensors": { + "electricity_consumed": 12.2, + "electricity_consumed_interval": 2.8, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" }, - "switches": { - "relay": true, - "lock": true - } - }, - "4a810418d5394b3f82727340b91ba740": { - "dev_class": "router_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "0217e9743c174eef9d6e9f680d403ce2", - "model": "Plug", - "name": "USG Smart Plug", - "zigbee_mac_address": "ABCD012345670A16", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 8.5, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "680423ff840043738f42cc7f1ff97a36": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "08963fec7c53423ca5680aa4cb502c63", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Thermostatic Radiator Badkamer", + "sensors": { + "battery": 51, + "setpoint": 14.0, + "temperature": 19.1, + "temperature_difference": -0.3, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A17" }, - "switches": { - "relay": true, - "lock": true - } - }, - "02cf28bfec924855854c544690a609ef": { - "dev_class": "vcr_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "c4d2bda6df8146caa2e5c2b5dc65660e", - "model": "Plug", - "name": "NVR", - "zigbee_mac_address": "ABCD012345670A15", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 34.0, - "electricity_consumed_interval": 8.65, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "6a3bf693d05e48e0b460c815a4fdd09d": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "82fa13f017d240daa0d0ea1775420f24", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Thermostat Jessie", + "sensors": { + "battery": 37, + "setpoint": 16.0, + "temperature": 17.1 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A03" }, - "switches": { - "relay": true, - "lock": true - } - }, - "a28f588dc4a049a483fd03a30361ad3a": { - "dev_class": "settop_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "cd143c07248f491493cea0533bc3d669", - "model": "Plug", - "name": "Fibaro HC2", - "zigbee_mac_address": "ABCD012345670A13", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 12.5, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "78d1126fc4c743db81b61c20e88342a7": { + "available": true, + "dev_class": "central_heating_pump_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "c50f167537524366a5af7aa3942feb1e", + "model": "Plug", + "model_id": "160-01", + "name": "CV Pomp", + "sensors": { + "electricity_consumed": 35.8, + "electricity_consumed_interval": 5.85, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A05" }, - "switches": { - "relay": true, - "lock": true - } - }, - "6a3bf693d05e48e0b460c815a4fdd09d": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "82fa13f017d240daa0d0ea1775420f24", - "model": "Lisa", - "name": "Zone Thermostat Jessie", - "zigbee_mac_address": "ABCD012345670A03", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 16.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "82fa13f017d240daa0d0ea1775420f24": { + "active_preset": "asleep", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Jessie", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "CV Jessie", + "sensors": { + "temperature": 17.1 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 16.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "6a3bf693d05e48e0b460c815a4fdd09d" + ], + "secondary": [ + "d3da73bde12a47d5a6b8f9dad971f2ec" + ] + } }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "asleep", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "CV Jessie", - "climate_mode": "auto", - "sensors": { - "temperature": 17.1, - "setpoint": 16.0, - "battery": 37 - } - }, - "680423ff840043738f42cc7f1ff97a36": { - "dev_class": "thermo_sensor", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "08963fec7c53423ca5680aa4cb502c63", - "model": "Tom/Floor", - "name": "Thermostatic Radiator Badkamer", - "zigbee_mac_address": "ABCD012345670A17", - "vendor": "Plugwise", - "available": true, - "sensors": { - "temperature": 19.1, - "setpoint": 14.0, - "battery": 51, - "temperature_difference": -0.3, - "valve_position": 0 - } - }, - "f1fee6043d3642a9b0a65297455f008e": { - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", - "location": "08963fec7c53423ca5680aa4cb502c63", - "model": "Lisa", - "name": "Zone Thermostat Badkamer", - "zigbee_mac_address": "ABCD012345670A08", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 14.0, - "lower_bound": 0.0, - "upper_bound": 99.9, - "resolution": 0.01 + "90986d591dcd426cae3ec3e8111ff730": { + "binary_sensors": { + "heating_state": true + }, + "dev_class": "heater_central", + "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", + "model": "Unknown", + "name": "OnOff", + "sensors": { + "intended_boiler_temperature": 70.0, + "modulation_level": 1, + "water_temperature": 70.0 + } }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "away", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "Badkamer Schema", - "climate_mode": "auto", - "sensors": { - "temperature": 18.8, - "setpoint": 14.0, - "battery": 92 - } - }, - "675416a629f343c495449970e2ca37b5": { - "dev_class": "router_plug", - "firmware": "2019-06-21T02:00:00+02:00", - "location": "2b1591ecf6344d4d93b03dece9747648", - "model": "Plug", - "name": "Ziggo Modem", - "zigbee_mac_address": "ABCD012345670A01", - "vendor": "Plugwise", - "available": true, - "sensors": { - "electricity_consumed": 12.2, - "electricity_consumed_interval": 2.8, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "a28f588dc4a049a483fd03a30361ad3a": { + "available": true, + "dev_class": "settop_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "cd143c07248f491493cea0533bc3d669", + "model": "Plug", + "model_id": "160-01", + "name": "Fibaro HC2", + "sensors": { + "electricity_consumed": 12.5, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A13" }, - "switches": { - "relay": true, - "lock": true - } - }, - "e7693eb9582644e5b865dba8d4447cf1": { - "dev_class": "thermostatic_radiator_valve", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", - "location": "446ac08dd04d4eff8ac57489757b7314", - "model": "Tom/Floor", - "name": "CV Kraan Garage", - "zigbee_mac_address": "ABCD012345670A11", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 5.5, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 0.01 + "a2c3583e0a6349358998b760cea82d2a": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "12493538af164a409c6a1c79e38afe1c", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Bios Cv Thermostatic Radiator ", + "sensors": { + "battery": 62, + "setpoint": 13.0, + "temperature": 17.1, + "temperature_difference": -0.1, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A09" + }, + "b310b72a0e354bfab43089919b9a88bf": { + "available": true, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "c50f167537524366a5af7aa3942feb1e", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Floor kraan", + "sensors": { + "setpoint": 21.5, + "temperature": 26.2, + "temperature_difference": 3.7, + "valve_position": 100 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" + }, + "b59bcebaf94b499ea7d46e4a66fb62d8": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-08-02T02:00:00+02:00", + "hardware": "255", + "location": "c50f167537524366a5af7aa3942feb1e", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Lisa WK", + "sensors": { + "battery": 34, + "setpoint": 21.5, + "temperature": 21.1 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" + }, + "c50f167537524366a5af7aa3942feb1e": { + "active_preset": "home", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "GF7 Woonkamer", + "sensors": { + "electricity_consumed": 35.8, + "electricity_produced": 0.0, + "temperature": 21.1 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 21.5, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "b59bcebaf94b499ea7d46e4a66fb62d8" + ], + "secondary": [ + "b310b72a0e354bfab43089919b9a88bf" + ] + } + }, + "cd0ddb54ef694e11ac18ed1cbce5dbbd": { + "available": true, + "dev_class": "vcr_plug", + "firmware": "2019-06-21T02:00:00+02:00", + "location": "e704bae65654496f9cade9c855decdfe", + "model": "Plug", + "model_id": "160-01", + "name": "NAS", + "sensors": { + "electricity_consumed": 16.5, + "electricity_consumed_interval": 0.29, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A14" + }, + "d3da73bde12a47d5a6b8f9dad971f2ec": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "82fa13f017d240daa0d0ea1775420f24", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Thermostatic Radiator Jessie", + "sensors": { + "battery": 62, + "setpoint": 16.0, + "temperature": 16.9, + "temperature_difference": 0.1, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A10" + }, + "df4a4a8169904cdb9c03d61a21f42140": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "12493538af164a409c6a1c79e38afe1c", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Lisa Bios", + "sensors": { + "battery": 67, + "setpoint": 13.0, + "temperature": 16.5 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A06" + }, + "e7693eb9582644e5b865dba8d4447cf1": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", + "location": "446ac08dd04d4eff8ac57489757b7314", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "CV Kraan Garage", + "sensors": { + "battery": 68, + "setpoint": 5.5, + "temperature": 15.6, + "temperature_difference": 0.1, + "valve_position": 0.0 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A11" + }, + "f1fee6043d3642a9b0a65297455f008e": { + "available": true, + "binary_sensors": { + "low_battery": false + }, + "dev_class": "zone_thermostat", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", + "location": "08963fec7c53423ca5680aa4cb502c63", + "model": "Lisa", + "model_id": "158-01", + "name": "Zone Thermostat Badkamer", + "sensors": { + "battery": 92, + "setpoint": 14.0, + "temperature": 18.8 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A08" }, - "available": true, - "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], - "active_preset": "no_frost", - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], - "select_schedule": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 15.6, - "setpoint": 5.5, - "battery": 68, - "temperature_difference": 0.1, - "valve_position": 0 + "fe799307f1624099878210aa0b9f1475": { + "binary_sensors": { + "plugwise_notification": true + }, + "dev_class": "gateway", + "firmware": "3.0.15", + "hardware": "AME Smile 2.0 board", + "location": "1f9dcf83fd4e4b66b72ff787957bfe5d", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_open_therm", + "name": "Adam", + "select_regulation_mode": "heating", + "sensors": { + "outdoor_temperature": 7.69 + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" } } } diff --git a/tests/test_adam.py b/tests/test_adam.py index a58050c6d..2bf559be7 100644 --- a/tests/test_adam.py +++ b/tests/test_adam.py @@ -189,7 +189,7 @@ async def test_connect_adam_zone_per_device(self): assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA - assert self.entity_items == 340 + assert self.entity_items == 364 assert "af82e4ccf9c548528166d38e560662a4" in self.notifications await smile.delete_notification() @@ -267,7 +267,7 @@ async def test_connect_adam_multiple_devices_per_zone(self): assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA - assert self.entity_items == 340 + assert self.entity_items == 364 assert "af82e4ccf9c548528166d38e560662a4" in self.notifications @@ -305,7 +305,7 @@ async def test_adam_heatpump_cooling(self): assert smile._last_active["a562019b0b1f47a4bde8ebe3dbe3e8a9"] == WERKDAG_SCHEMA assert smile._last_active["8cf650a4c10c44819e426bed406aec34"] == WERKDAG_SCHEMA assert smile._last_active["5cc21042f87f4b4c94ccb5537c47a53f"] == WERKDAG_SCHEMA - assert self.entity_items == 439 + assert self.entity_items == 497 await smile.close_connection() await self.disconnect(server, client) @@ -326,7 +326,7 @@ async def test_connect_adam_onoff_cooling_fake_firmware(self): ) await self.device_test(smile, "2022-01-02 00:00:01", testdata) - assert self.entity_items == 58 + assert self.entity_items == 64 assert self.cooling_present # assert self._cooling_enabled - no cooling_enabled indication present @@ -351,7 +351,7 @@ async def test_connect_adam_plus_anna(self): await self.device_test(smile, "2020-03-22 00:00:01", testdata) assert smile.gateway_id == "b128b4bbbd1f47e9bf4d756e8fb5ee94" assert smile._last_active["009490cc2f674ce6b576863fbb64f867"] == "Weekschema" - assert self.entity_items == 73 + assert self.entity_items == 79 assert "6fb89e35caeb4b1cb275184895202d84" in self.notifications result = await self.tinker_thermostat( @@ -395,7 +395,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 self.entity_items == 228 + assert self.entity_items == 244 # Negative test result = await self.tinker_thermostat( @@ -414,4 +414,4 @@ async def test_adam_plus_jip(self): ) assert result await smile.close_connection() - await self.disconnect(server, client) \ No newline at end of file + await self.disconnect(server, client) From 095ce9f20319d9d99aa76c29e1e8276c326c5d22 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 08:37:27 +0100 Subject: [PATCH 068/106] Return other Anna testcases --- tests/test_anna.py | 439 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) diff --git a/tests/test_anna.py b/tests/test_anna.py index 45d429b59..5cfc71d2b 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -87,3 +87,442 @@ async def test_connect_anna_v4(self): await smile.close_connection() await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_v4_dhw(self): + """Test an Anna firmware 4 setup for domestic hot water.""" + self.smile_setup = "anna_v4_dhw" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.0.15", + ) + + await self.device_test(smile, "2020-04-05 00:00:01", testdata) + assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard" + assert self.entitiy_items == 58 + assert not self.notifications + + result = await self.tinker_thermostat( + smile, + "eb5309212bf5407bb143e5bfa3b18aee", + schedule_on=False, + good_schedules=["Standaard", "Thuiswerken"], + ) + assert result + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_v4_no_tag(self): + """Test an Anna firmware 4 setup - missing tag (issue).""" + testdata = { + # Anna + "01b85360fdd243d0aaad4d6ac2a5ba7e": { + "active_preset": "home", + } + } + self.smile_setup = "anna_v4_no_tag" + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.0.15", + ) + + await self.device_test(smile, "2020-04-05 00:00:01", testdata) + assert self.entitiy_items == 58 + + result = await self.tinker_thermostat( + smile, + "eb5309212bf5407bb143e5bfa3b18aee", + schedule_on=False, + good_schedules=["Standaard", "Thuiswerken"], + ) + assert result + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_without_boiler_fw441(self): + """Test an Anna with firmware 4.4, without a boiler.""" + self.smile_setup = "anna_without_boiler_fw441" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.4.1", + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert smile._last_active["c34c6864216446528e95d88985e714cc"] == "Normaal" + assert self.entitiy_items == 39 + assert not self.notifications + + result = await self.tinker_thermostat( + smile, "c34c6864216446528e95d88985e714cc", good_schedules=["Normaal"] + ) + assert result + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_heatpump_heating(self): + """Test an Anna with Elga, cooling-mode off, in heating mode.""" + + self.smile_setup = "anna_heatpump_heating" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.0.15", + ) + + await self.device_test(smile, "2020-04-12 00:00:01", testdata) + assert smile.gateway_id == "015ae9ea3f964e668e490fa39da3870b" + assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" + assert self.entitiy_items == 67 + assert not self.notifications + assert self.cooling_present + assert not self._cooling_enabled + assert not self._cooling_active + + with pytest.raises(pw_exceptions.PlugwiseError) as exc: + await self.tinker_thermostat( + smile, + "c784ee9fdab44e1395b8dee7d7a497d5", + good_schedules=[ + "standaard", + ], + ) + _LOGGER.debug( + "ERROR raised setting good schedule standaard: %s", exc.value + ) # pragma: no cover + + # Now change some data and change directory reading xml from + # emulating reading newer dataset after an update_interval, + # set testday to Monday to force an incremental update + testdata_updated = self.load_testdata( + SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA" + ) + + self.smile_setup = "updated/anna_heatpump_heating" + await self.device_test( + smile, "2020-04-13 00:00:01", testdata_updated, initialize=False + ) + assert self.entitiy_items == 64 + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_heatpump_cooling(self): + """Test an Anna with Elga setup in cooling mode. + + This test also covers the situation that the operation-mode it switched + from heating to cooling due to the outdoor temperature rising above the + cooling_activation_outdoor_temperature threshold. + """ + self.smile_setup = "anna_heatpump_cooling" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.0.15", + ) + + await self.device_test(smile, "2020-04-19 00:00:01", testdata) + assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" + assert self.entitiy_items == 64 + assert self.cooling_present + assert not self.notifications + + assert self._cooling_enabled + assert self._cooling_active + + with pytest.raises(pw_exceptions.PlugwiseError) as exc: + await self.tinker_thermostat( + smile, + "c784ee9fdab44e1395b8dee7d7a497d5", + good_schedules=[ + "standaard", + ], + ) + _LOGGER.debug( + "ERROR raised good schedule to standaard: %s", exc.value + ) # pragma: no cover + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_heatpump_cooling_fake_firmware(self): + """Test an Anna with a fake Loria/Thermastate setup in cooling mode. + + The Anna + Elga firmware has been amended with the point_log cooling_enabled and + gateway/features/cooling keys. + This test also covers the situation that the operation-mode it switched + from heating to cooling due to the outdoor temperature rising above the + cooling_activation_outdoor_temperature threshold. + """ + self.smile_setup = "anna_heatpump_cooling_fake_firmware" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.10.10", + ) + + await self.device_test(smile, "2020-04-19 00:00:01", testdata) + assert self.entitiy_items == 64 + assert self.cooling_present + assert self._cooling_enabled + assert self._cooling_active + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_elga_no_cooling(self): + """Test an Anna with Elga, cooling-mode not used, in heating mode.""" + + self.smile_setup = "anna_elga_no_cooling" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.0.15", + ) + + await self.device_test(smile, "2020-04-12 00:00:01", testdata) + assert smile.gateway_id == "015ae9ea3f964e668e490fa39da3870b" + assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" + assert self.entitiy_items == 63 + assert not self.notifications + assert not self.cooling_present + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_elga_2(self): + """Test a 2nd Anna with Elga setup, cooling off, in idle mode (with missing outdoor temperature - solved).""" + self.smile_setup = "anna_elga_2" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.2.1", + ) + + await self.device_test(smile, "2022-03-13 00:00:01", testdata) + assert ( + smile._last_active["d3ce834534114348be628b61b26d9220"] + == THERMOSTAT_SCHEDULE + ) + assert self.entitiy_items == 63 + assert smile.gateway_id == "fb49af122f6e4b0f91267e1cf7666d6f" + assert self.cooling_present + assert not self._cooling_enabled + assert not self.notifications + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_elga_2_schedule_off(self): + """Test Anna with Elga setup, cooling off, in idle mode, modified to schedule off.""" + self.smile_setup = "anna_elga_2_schedule_off" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + await self.device_test(smile, "2022-03-13 00:00:01", testdata) + assert ( + smile._last_active["d3ce834534114348be628b61b26d9220"] + == THERMOSTAT_SCHEDULE + ) + assert self.cooling_present + assert not self._cooling_enabled + assert self.entitiy_items == 63 + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_elga_2_cooling(self): + """Test a 2nd Anna with Elga setup with cooling active. + + This testcase also covers testing of the generation of a cooling-based + schedule, opposite the generation of a heating-based schedule. + """ + self.smile_setup = "anna_elga_2_cooling" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="4.2.1", + ) + + await self.device_test(smile, "2022-03-10 00:00:01", testdata) + assert ( + smile._last_active["d3ce834534114348be628b61b26d9220"] + == THERMOSTAT_SCHEDULE + ) + assert self.entitiy_items == 63 + assert not self.notifications + + assert self.cooling_present + assert self._cooling_enabled + assert self._cooling_active + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_loria_heating_idle(self): + """Test an Anna with a Loria in heating mode - state idle.""" + self.smile_setup = "anna_loria_heating_idle" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version=None, + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter" + assert self.entitiy_items == 66 + assert self.cooling_present + assert not self._cooling_enabled + + switch_change = await self.tinker_switch( + smile, + "bfb5ee0a88e14e5f97bfa725a760cc49", + model="cooling_ena_switch", + ) + assert switch_change + + with pytest.raises(pw_exceptions.PlugwiseError) as exc: + await self.tinker_thermostat( + smile, + "15da035090b847e7a21f93e08c015ebc", + good_schedules=[ + "Winter", + ], + ) + _LOGGER.debug( + "ERROR raised setting to schedule Winter: %s", exc.value + ) # pragma: no cover + + with pytest.raises(pw_exceptions.PlugwiseError) as exc: + await self.tinker_thermostat_temp( + smile, + "15da035090b847e7a21f93e08c015ebc", + block_cooling=True, + ) + _LOGGER.debug( + "ERROR raised setting block cooling: %s", exc.value + ) # pragma: no cover + + tinkered = await self.tinker_dhw_mode(smile) + assert not tinkered + + await smile.close_connection() + await self.disconnect(server, client) + + server, smile, client = await self.connect_wrapper(raise_timeout=True) + await self.device_test(smile, "2022-05-16 00:00:01", testdata, skip_testing=True) + + tinkered = await self.tinker_dhw_mode(smile, unhappy=True) + assert tinkered + + await smile.close_connection() + await self.disconnect(server, client) + + + @pytest.mark.asyncio + async def test_connect_anna_loria_cooling_active(self): + """Test an Anna with a Loria in heating mode - state idle.""" + self.smile_setup = "anna_loria_cooling_active" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version=None, + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter" + assert self.entitiy_items == 66 + assert self.cooling_present + assert self._cooling_enabled + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_anna_loria_driessens(self): + """Test an Anna with a Loria in heating mode - state idle.""" + self.smile_setup = "anna_loria_driessens" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version=None, + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert self.entitiy_items == 66 + assert self.cooling_present + assert not self._cooling_enabled + + await smile.close_connection() + await self.disconnect(server, client) From 844150d070532ca8ae0f16ba690db8816fbde17a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 08:41:24 +0100 Subject: [PATCH 069/106] Return remaining testcases --- tests/test_legacy_anna.py | 30 +++++++++++++++++ tests/test_legacy_p1.py | 32 ++++++++++++++++++ tests/test_legacy_stretch.py | 64 ++++++++++++++++++++++++++++++++++++ tests/test_p1.py | 58 ++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+) diff --git a/tests/test_legacy_anna.py b/tests/test_legacy_anna.py index d108f55a7..32b1a26da 100644 --- a/tests/test_legacy_anna.py +++ b/tests/test_legacy_anna.py @@ -44,3 +44,33 @@ async def test_connect_legacy_anna(self): assert result await smile.close_connection() await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_legacy_anna_2(self): + """Test another legacy Anna device.""" + self.smile_setup = "legacy_anna_2" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_legacy_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_version="1.8.22", + smile_legacy=True, + ) + + await self.device_test(smile, "2020-05-03 00:00:01", testdata) + + assert smile.gateway_id == "be81e3f8275b4129852c4d8d550ae2eb" + assert self.entity_items == 43 + + result = await self.tinker_legacy_thermostat(smile) + assert result + + result = await self.tinker_legacy_thermostat_schedule(smile, "on") + assert result + + await smile.close_connection() + await self.disconnect(server, client) diff --git a/tests/test_legacy_p1.py b/tests/test_legacy_p1.py index 7379679cc..17e0f5d04 100644 --- a/tests/test_legacy_p1.py +++ b/tests/test_legacy_p1.py @@ -34,3 +34,35 @@ async def test_connect_smile_p1_v2(self): await smile.close_connection() await self.disconnect(server, client) + @pytest.mark.asyncio + async def test_connect_smile_p1_v2_2(self): + """Test another legacy P1 device.""" + self.smile_setup = "smile_p1_v2_2" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_legacy_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_type="power", + smile_version="2.5.9", + smile_legacy=True, + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert self.device_items == 26 + + # Now change some data and change directory reading xml from + # emulating reading newer dataset after an update_interval + testdata_updated = self.load_testdata( + SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA" + ) + self.smile_setup = "updated/smile_p1_v2_2" + await self.device_test( + smile, "2022-05-16 00:00:01", testdata_updated, initialize=False + ) + + await smile.close_connection() + await self.disconnect(server, client) diff --git a/tests/test_legacy_stretch.py b/tests/test_legacy_stretch.py index d3f0b57e4..f50decf74 100644 --- a/tests/test_legacy_stretch.py +++ b/tests/test_legacy_stretch.py @@ -50,3 +50,67 @@ async def test_connect_stretch_v31(self): await smile.close_connection() await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_stretch_v23(self): + """Test a legacy Stretch with firmware 2.3 setup.""" + self.smile_setup = "stretch_v23" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_legacy_wrapper(stretch=True) + assert smile.smile_hostname == "stretch000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_type="stretch", + smile_version="2.3.12", + smile_legacy=True, + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert self.device_items == 243 + + switch_change = await self.tinker_switch( + smile, "2587a7fcdd7e482dab03fda256076b4b" + ) + assert switch_change + switch_change = await self.tinker_switch( + smile, + "f7b145c8492f4dd7a4de760456fdef3e", + ["407aa1c1099d463c9137a3a9eda787fd"], + ) + assert switch_change + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_stretch_v27_no_domain(self): + """Test a legacy Stretch with firmware 2.7 setup, with no domain_objects.""" + # testdata dictionary with key ctrl_id_dev_id => keys:values + self.smile_setup = "stretch_v27_no_domain" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_legacy_wrapper(stretch=True) + assert smile.smile_hostname == "stretch000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_type="stretch", + smile_version="2.7.18", + smile_legacy=True, + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert self.device_items == 190 + _LOGGER.info(" # Assert no master thermostat") + + switch_change = await self.tinker_switch( + smile, "8b8d14b242e24cd789743c828b9a2ea9" + ) + assert switch_change + + await smile.close_connection() + await self.disconnect(server, client) diff --git a/tests/test_p1.py b/tests/test_p1.py index cf2f1fb2f..b2e8deb86 100644 --- a/tests/test_p1.py +++ b/tests/test_p1.py @@ -43,3 +43,61 @@ async def test_connect_p1v4_442_single(self): await smile.close_connection() await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_p1v4_442_single(self): + """Test a P1 firmware 4.4 single-phase setup.""" + self.smile_setup = "p1v4_442_single" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_type="power", + smile_version="4.4.2", + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert smile.gateway_id == "a455b61e52394b2db5081ce025a430f3" + assert self.device_items == 32 + assert not self.notifications + + # Now change some data and change directory reading xml from + # emulating reading newer dataset after an update_interval + testdata_updated = self.load_testdata( + SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA" + ) + self.smile_setup = "updated/p1v4_442_single" + await self.device_test( + smile, "2022-05-16 00:00:01", testdata_updated, initialize=False + ) + + await smile.close_connection() + await self.disconnect(server, client) + + @pytest.mark.asyncio + async def test_connect_p1v4_442_triple(self): + """Test a P1 firmware 4 3-phase setup.""" + self.smile_setup = "p1v4_442_triple" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + server, smile, client = await self.connect_wrapper() + assert smile.smile_hostname == "smile000000" + + self.validate_test_basics( + _LOGGER, + smile, + smile_type="power", + smile_version="4.4.2", + ) + + await self.device_test(smile, "2022-05-16 00:00:01", testdata) + assert smile.gateway_id == "03e65b16e4b247a29ae0d75a78cb492e" + assert self.device_items == 41 + assert self.notifications + + await smile.close_connection() + await self.disconnect(server, client) From 77ccb9166c3bebc332d67290b6d734394cd8b97d Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 13:42:11 +0100 Subject: [PATCH 070/106] Break out _count_data_items() function and implement --- plugwise/common.py | 13 +++++++++++++ plugwise/helper.py | 10 +--------- plugwise/legacy/helper.py | 6 +----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index f909eaf7a..c3bba8939 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -131,6 +131,19 @@ def _collect_power_values(self, data: GwEntityData, loc: Munch, tariff: str, leg key = cast(SensorType, loc.key_string) data["sensors"][key] = loc.f_val + def _count_data_items(self, data: GwEntityData) -> None: + """When present, count the binary_sensors, sensors and switches dict-items, don't count the dicts. + + Also, count the remaining single data items, the amount of dicts present have already been pre-subtracted in the previous step. + """ + if "binary_sensors" in data: + self._count += len(data["binary_sensors"]) -1 + if "sensors" in data: + self._count += len(data["sensors"]) - 1 + if "switches" in data: + self._count += len(data["switches"]) -1 + self._count += len(data) + def _power_data_peak_value(self, loc: Munch, legacy: bool) -> Munch: """Helper-function for _power_data_from_location() and _power_data_from_modules().""" loc.found = True diff --git a/plugwise/helper.py b/plugwise/helper.py index e4ac39dd0..ad53b5fdd 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -601,15 +601,7 @@ def _appliance_measurements( appl_i_loc.text, ENERGY_WATT_HOUR ) - # Don't count the below top-level dicts when present - if "binary_sensors" in data: - self._count += len(data["binary_sensors"]) -1 - if "sensors" in data: - self._count += len(data["sensors"]) - 1 - if "switches" in data: - self._count += len(data["switches"]) -1 - # Count the remaining single data items, with the sub-dicts present already subtracted - self._count += len(data) + self._count_data_items(data) def _get_toggle_state( self, xml: etree, toggle: str, name: ToggleNameType, data: GwEntityData diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index c9a2acb75..6ea9be3e9 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -360,11 +360,7 @@ def _appliance_measurements( appl_i_loc.text, ENERGY_WATT_HOUR ) - self._count += len(data["binary_sensors"]) - self._count += len(data["sensors"]) - self._count += len(data["switches"]) - # Don't count the above top-level dicts, only the remaining single items - self._count += len(data) - 3 + self._count_data_items(data) def _get_actuator_functionalities( self, From 7868a9fa897c3018dc9b5fc0b996049adc8f9a63 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 14:00:32 +0100 Subject: [PATCH 071/106] Improve --- plugwise/helper.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugwise/helper.py b/plugwise/helper.py index ad53b5fdd..09850a4a8 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -898,19 +898,22 @@ def _rank_thermostat( """ appl_class = appliance_details["dev_class"] appl_d_loc = appliance_details["location"] + thermo_loc = self._thermo_locs[loc_id] if loc_id == appl_d_loc and appl_class in thermo_matching: + if thermo_matching[appl_class] == thermo_loc["primary_prio"]: + thermo_loc["primary"].append(appliance_id) # Pre-elect new primary - if thermo_matching[appl_class] > self._thermo_locs[loc_id]["primary_prio"]: + elif (thermo_rank := thermo_matching[appl_class]) > thermo_loc["primary_prio"]: + thermo_loc["primary_prio"] = thermo_rank # Demote former primary - if (tl_primary := self._thermo_locs[loc_id]["primary"]): - self._thermo_locs[loc_id]["secondary"] = tl_primary - self._thermo_locs[loc_id]["primary"] = [] + if (tl_primary := thermo_loc["primary"]): + thermo_loc["secondary"] += tl_primary + thermo_loc["primary"] = [] # Crown primary - self._thermo_locs[loc_id]["primary_prio"] = thermo_matching[appl_class] - self._thermo_locs[loc_id]["primary"].append(appliance_id) + thermo_loc["primary"].append(appliance_id) else: - self._thermo_locs[loc_id]["secondary"].append(appliance_id) + thermo_loc["secondary"].append(appliance_id) def _control_state(self, loc_id: str) -> str | bool: """Helper-function for _get_adam_data(). From 387ac92f619c2641b9dd46fd5ff423d1c7a9e275 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 19:03:28 +0100 Subject: [PATCH 072/106] Save --- fixtures/anna_v4_dhw/all_data.json | 2 +- fixtures/anna_v4_no_tag/all_data.json | 2 +- .../adam/adam_plus_anna_new_UPDATED_DATA.json | 2 +- tests/data/anna/anna_v4_UPDATED_DATA.json | 2 +- tests/data/anna/anna_v4_dhw.json | 165 ++++++++++-------- tests/test_anna.py | 28 +-- 6 files changed, 110 insertions(+), 91 deletions(-) diff --git a/fixtures/anna_v4_dhw/all_data.json b/fixtures/anna_v4_dhw/all_data.json index d50a8144b..590e56c95 100644 --- a/fixtures/anna_v4_dhw/all_data.json +++ b/fixtures/anna_v4_dhw/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/anna_v4_no_tag/all_data.json b/fixtures/anna_v4_no_tag/all_data.json index 602e59ea4..86ab1962b 100644 --- a/fixtures/anna_v4_no_tag/all_data.json +++ b/fixtures/anna_v4_no_tag/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ diff --git a/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json index 3748bb59c..b924ec501 100644 --- a/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json +++ b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "67d73d0bd469422db25a618a5fb8eeb0": { "switches": { "lock": true diff --git a/tests/data/anna/anna_v4_UPDATED_DATA.json b/tests/data/anna/anna_v4_UPDATED_DATA.json index 17c2899bf..fbd34b429 100644 --- a/tests/data/anna/anna_v4_UPDATED_DATA.json +++ b/tests/data/anna/anna_v4_UPDATED_DATA.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "cd0e6156b1f04d5f952349ffbe397481": { "maximum_boiler_temperature": { "setpoint": 69.0, diff --git a/tests/data/anna/anna_v4_dhw.json b/tests/data/anna/anna_v4_dhw.json index 2b3252a82..3cbf7e717 100644 --- a/tests/data/anna/anna_v4_dhw.json +++ b/tests/data/anna/anna_v4_dhw.json @@ -1,79 +1,98 @@ { - "cd0e6156b1f04d5f952349ffbe397481": { - "dev_class": "heater_central", - "location": "94c107dc6ac84ed98e9f68c0dd06bf71", - "model": "Generic heater", - "model_id": "2.32", - "name": "OpenTherm", - "vendor": "Bosch Thermotechniek B.V.", - "maximum_boiler_temperature": { - "setpoint": 70.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1 + "entities": { + "01b85360fdd243d0aaad4d6ac2a5ba7e": { + "active_preset": "home", + "available_schedules": [ + "Standaard", + "Thuiswerken", + "off" + ], + "climate_mode": "heat", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "eb5309212bf5407bb143e5bfa3b18aee", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "vacation", + "no_frost", + "away", + "asleep", + "home" + ], + "select_schedule": "off", + "sensors": { + "illuminance": 60.0, + "setpoint": 20.5, + "temperature": 20.6 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 20.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "max_dhw_temperature": { - "setpoint": 60.0, - "lower_bound": 30.0, - "upper_bound": 60.0, - "resolution": 0.01 + "0466eae8520144c78afb29628384edeb": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.0.15", + "hardware": "AME Smile 2.0 board", + "location": "94c107dc6ac84ed98e9f68c0dd06bf71", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 7.44 + }, + "vendor": "Plugwise" }, - "available": true, - "binary_sensors": { - "dhw_state": true, - "heating_state": false, - "flame_state": true - }, - "sensors": { - "water_temperature": 45.0, - "intended_boiler_temperature": 39.9, - "modulation_level": 0, - "return_temperature": 32.0, - "water_pressure": 2.2 - }, - "switches": { - "dhw_cm_switch": false - } - }, - "01b85360fdd243d0aaad4d6ac2a5ba7e": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "eb5309212bf5407bb143e5bfa3b18aee", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 20.5, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 - }, - "preset_modes": ["vacation", "no_frost", "away", "asleep", "home"], - "active_preset": "home", - "available_schedules": ["Standaard", "Thuiswerken", "off"], - "select_schedule": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 20.6, - "setpoint": 20.5, - "illuminance": 60.0 - } - }, - "0466eae8520144c78afb29628384edeb": { - "dev_class": "gateway", - "firmware": "4.0.15", - "hardware": "AME Smile 2.0 board", - "location": "94c107dc6ac84ed98e9f68c0dd06bf71", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false - }, - "sensors": { - "outdoor_temperature": 7.44 + "cd0e6156b1f04d5f952349ffbe397481": { + "available": true, + "binary_sensors": { + "dhw_state": true, + "flame_state": true, + "heating_state": false + }, + "dev_class": "heater_central", + "location": "94c107dc6ac84ed98e9f68c0dd06bf71", + "max_dhw_temperature": { + "lower_bound": 30.0, + "resolution": 0.01, + "setpoint": 60.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 70.0, + "upper_bound": 100.0 + }, + "model": "Generic heater", + "model_id": "2.32", + "name": "OpenTherm", + "sensors": { + "intended_boiler_temperature": 39.9, + "modulation_level": 0.0, + "return_temperature": 32.0, + "water_pressure": 2.2, + "water_temperature": 45.0 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Bosch Thermotechniek B.V." } } } diff --git a/tests/test_anna.py b/tests/test_anna.py index 5cfc71d2b..f129e088e 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -105,7 +105,7 @@ async def test_connect_anna_v4_dhw(self): await self.device_test(smile, "2020-04-05 00:00:01", testdata) assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard" - assert self.entitiy_items == 58 + assert self.entity_items == 58 assert not self.notifications result = await self.tinker_thermostat( @@ -138,7 +138,7 @@ async def test_connect_anna_v4_no_tag(self): ) await self.device_test(smile, "2020-04-05 00:00:01", testdata) - assert self.entitiy_items == 58 + assert self.entity_items == 58 result = await self.tinker_thermostat( smile, @@ -167,7 +167,7 @@ async def test_connect_anna_without_boiler_fw441(self): await self.device_test(smile, "2022-05-16 00:00:01", testdata) assert smile._last_active["c34c6864216446528e95d88985e714cc"] == "Normaal" - assert self.entitiy_items == 39 + assert self.entity_items == 39 assert not self.notifications result = await self.tinker_thermostat( @@ -196,7 +196,7 @@ async def test_connect_anna_heatpump_heating(self): await self.device_test(smile, "2020-04-12 00:00:01", testdata) assert smile.gateway_id == "015ae9ea3f964e668e490fa39da3870b" assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" - assert self.entitiy_items == 67 + assert self.entity_items == 67 assert not self.notifications assert self.cooling_present assert not self._cooling_enabled @@ -225,7 +225,7 @@ async def test_connect_anna_heatpump_heating(self): await self.device_test( smile, "2020-04-13 00:00:01", testdata_updated, initialize=False ) - assert self.entitiy_items == 64 + assert self.entity_items == 64 await smile.close_connection() await self.disconnect(server, client) @@ -251,7 +251,7 @@ async def test_connect_anna_heatpump_cooling(self): await self.device_test(smile, "2020-04-19 00:00:01", testdata) assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" - assert self.entitiy_items == 64 + assert self.entity_items == 64 assert self.cooling_present assert not self.notifications @@ -296,7 +296,7 @@ async def test_connect_anna_heatpump_cooling_fake_firmware(self): ) await self.device_test(smile, "2020-04-19 00:00:01", testdata) - assert self.entitiy_items == 64 + assert self.entity_items == 64 assert self.cooling_present assert self._cooling_enabled assert self._cooling_active @@ -323,7 +323,7 @@ async def test_connect_anna_elga_no_cooling(self): await self.device_test(smile, "2020-04-12 00:00:01", testdata) assert smile.gateway_id == "015ae9ea3f964e668e490fa39da3870b" assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard" - assert self.entitiy_items == 63 + assert self.entity_items == 63 assert not self.notifications assert not self.cooling_present @@ -350,7 +350,7 @@ async def test_connect_anna_elga_2(self): smile._last_active["d3ce834534114348be628b61b26d9220"] == THERMOSTAT_SCHEDULE ) - assert self.entitiy_items == 63 + assert self.entity_items == 63 assert smile.gateway_id == "fb49af122f6e4b0f91267e1cf7666d6f" assert self.cooling_present assert not self._cooling_enabled @@ -375,7 +375,7 @@ async def test_connect_anna_elga_2_schedule_off(self): ) assert self.cooling_present assert not self._cooling_enabled - assert self.entitiy_items == 63 + assert self.entity_items == 63 await smile.close_connection() await self.disconnect(server, client) @@ -404,7 +404,7 @@ async def test_connect_anna_elga_2_cooling(self): smile._last_active["d3ce834534114348be628b61b26d9220"] == THERMOSTAT_SCHEDULE ) - assert self.entitiy_items == 63 + assert self.entity_items == 63 assert not self.notifications assert self.cooling_present @@ -431,7 +431,7 @@ async def test_connect_anna_loria_heating_idle(self): await self.device_test(smile, "2022-05-16 00:00:01", testdata) assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter" - assert self.entitiy_items == 66 + assert self.entity_items == 66 assert self.cooling_present assert not self._cooling_enabled @@ -497,7 +497,7 @@ async def test_connect_anna_loria_cooling_active(self): await self.device_test(smile, "2022-05-16 00:00:01", testdata) assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter" - assert self.entitiy_items == 66 + assert self.entity_items == 66 assert self.cooling_present assert self._cooling_enabled @@ -520,7 +520,7 @@ async def test_connect_anna_loria_driessens(self): ) await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.entitiy_items == 66 + assert self.entity_items == 66 assert self.cooling_present assert not self._cooling_enabled From 4fbd9e65077535ec905e65987111f57adf5f5fcb Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 19:17:44 +0100 Subject: [PATCH 073/106] Save --- fixtures/anna_elga_2/all_data.json | 2 +- fixtures/anna_elga_2_cooling/all_data.json | 2 +- .../anna_elga_2_schedule_off/all_data.json | 2 +- fixtures/anna_elga_no_cooling/all_data.json | 2 +- fixtures/anna_heatpump_cooling/all_data.json | 2 +- .../all_data.json | 2 +- fixtures/anna_heatpump_heating/all_data.json | 2 +- .../anna_loria_cooling_active/all_data.json | 2 +- fixtures/anna_loria_driessens/all_data.json | 2 +- .../anna_loria_heating_idle/all_data.json | 2 +- fixtures/legacy_anna_2/all_data.json | 2 +- fixtures/p1v4_442_triple/all_data.json | 2 +- fixtures/smile_p1_v2_2/all_data.json | 2 +- fixtures/stretch_v23/all_data.json | 2 +- fixtures/stretch_v27_no_domain/all_data.json | 2 +- tests/data/anna/anna_elga_2.json | 170 +++-- tests/data/anna/anna_elga_2_cooling.json | 172 +++-- tests/data/anna/anna_elga_2_schedule_off.json | 121 +++- tests/data/anna/anna_elga_no_cooling.json | 180 ++--- tests/data/anna/anna_heatpump_cooling.json | 171 +++-- .../anna_heatpump_cooling_fake_firmware.json | 107 ++- tests/data/anna/anna_heatpump_heating.json | 191 ++--- .../anna_heatpump_heating_UPDATED_DATA.json | 70 +- .../data/anna/anna_loria_cooling_active.json | 187 ++--- tests/data/anna/anna_loria_driessens.json | 203 +++--- tests/data/anna/anna_loria_heating_idle.json | 187 ++--- .../data/anna/anna_without_boiler_fw441.json | 111 +-- tests/data/anna/legacy_anna_2.json | 125 ++-- tests/data/p1/p1v4_442_single.json | 2 +- .../data/p1/p1v4_442_single_UPDATED_DATA.json | 2 +- tests/data/p1/p1v4_442_triple.json | 96 +-- tests/data/p1/smile_p1_v2_2.json | 62 +- tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json | 26 +- tests/data/stretch/stretch_v23.json | 670 +++++++++--------- tests/data/stretch/stretch_v27_no_domain.json | 302 +++++++- tests/test_anna.py | 2 +- tests/test_legacy_p1.py | 2 +- tests/test_legacy_stretch.py | 4 +- tests/test_p1.py | 36 +- 39 files changed, 1886 insertions(+), 1343 deletions(-) diff --git a/fixtures/anna_elga_2/all_data.json b/fixtures/anna_elga_2/all_data.json index 4b8c73c7a..107169b78 100644 --- a/fixtures/anna_elga_2/all_data.json +++ b/fixtures/anna_elga_2/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "573c152e7d4f4720878222bd75638f5b": { "available": true, "binary_sensors": { diff --git a/fixtures/anna_elga_2_cooling/all_data.json b/fixtures/anna_elga_2_cooling/all_data.json index 2bad3f05d..41c76174a 100644 --- a/fixtures/anna_elga_2_cooling/all_data.json +++ b/fixtures/anna_elga_2_cooling/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "573c152e7d4f4720878222bd75638f5b": { "available": true, "binary_sensors": { diff --git a/fixtures/anna_elga_2_schedule_off/all_data.json b/fixtures/anna_elga_2_schedule_off/all_data.json index 3ea0ab5b5..d92bf09f6 100644 --- a/fixtures/anna_elga_2_schedule_off/all_data.json +++ b/fixtures/anna_elga_2_schedule_off/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "573c152e7d4f4720878222bd75638f5b": { "available": true, "binary_sensors": { diff --git a/fixtures/anna_elga_no_cooling/all_data.json b/fixtures/anna_elga_no_cooling/all_data.json index ee3a73ab7..360a372a7 100644 --- a/fixtures/anna_elga_no_cooling/all_data.json +++ b/fixtures/anna_elga_no_cooling/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_heatpump_cooling/all_data.json b/fixtures/anna_heatpump_cooling/all_data.json index 5e7096d2e..ef96db377 100644 --- a/fixtures/anna_heatpump_cooling/all_data.json +++ b/fixtures/anna_heatpump_cooling/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json b/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json index 5749bea7e..0a14757c8 100644 --- a/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json +++ b/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_heatpump_heating/all_data.json b/fixtures/anna_heatpump_heating/all_data.json index 66b02931f..0d3bc93a6 100644 --- a/fixtures/anna_heatpump_heating/all_data.json +++ b/fixtures/anna_heatpump_heating/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_loria_cooling_active/all_data.json b/fixtures/anna_loria_cooling_active/all_data.json index c4cd3cebc..efb18770c 100644 --- a/fixtures/anna_loria_cooling_active/all_data.json +++ b/fixtures/anna_loria_cooling_active/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "582dfbdace4d4aeb832923ce7d1ddda0": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/anna_loria_driessens/all_data.json b/fixtures/anna_loria_driessens/all_data.json index d6225e4a5..fac986eea 100644 --- a/fixtures/anna_loria_driessens/all_data.json +++ b/fixtures/anna_loria_driessens/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "5c118b1842e943c0a5b6ef88a60bb17a": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_loria_heating_idle/all_data.json b/fixtures/anna_loria_heating_idle/all_data.json index 1006547da..2c318d838 100644 --- a/fixtures/anna_loria_heating_idle/all_data.json +++ b/fixtures/anna_loria_heating_idle/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "582dfbdace4d4aeb832923ce7d1ddda0": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/legacy_anna_2/all_data.json b/fixtures/legacy_anna_2/all_data.json index 537a12b86..5664dc7cf 100644 --- a/fixtures/legacy_anna_2/all_data.json +++ b/fixtures/legacy_anna_2/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "9e7377867dc24e51b8098a5ba02bd89d": { "active_preset": null, "available_schedules": [ diff --git a/fixtures/p1v4_442_triple/all_data.json b/fixtures/p1v4_442_triple/all_data.json index b7476b24a..75b3e4dfb 100644 --- a/fixtures/p1v4_442_triple/all_data.json +++ b/fixtures/p1v4_442_triple/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "03e65b16e4b247a29ae0d75a78cb492e": { "binary_sensors": { "plugwise_notification": true diff --git a/fixtures/smile_p1_v2_2/all_data.json b/fixtures/smile_p1_v2_2/all_data.json index 3cc59aa60..e425207b6 100644 --- a/fixtures/smile_p1_v2_2/all_data.json +++ b/fixtures/smile_p1_v2_2/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "199aa40f126840f392983d171374ab0b": { "dev_class": "smartmeter", "location": "199aa40f126840f392983d171374ab0b", diff --git a/fixtures/stretch_v23/all_data.json b/fixtures/stretch_v23/all_data.json index 07e89a8f2..a372a313f 100644 --- a/fixtures/stretch_v23/all_data.json +++ b/fixtures/stretch_v23/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "2.3.12", diff --git a/fixtures/stretch_v27_no_domain/all_data.json b/fixtures/stretch_v27_no_domain/all_data.json index 042cfe538..ab00efeac 100644 --- a/fixtures/stretch_v27_no_domain/all_data.json +++ b/fixtures/stretch_v27_no_domain/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "2.7.18", diff --git a/tests/data/anna/anna_elga_2.json b/tests/data/anna/anna_elga_2.json index 1530cb866..6e7c93904 100644 --- a/tests/data/anna/anna_elga_2.json +++ b/tests/data/anna/anna_elga_2.json @@ -1,82 +1,100 @@ { - "fb49af122f6e4b0f91267e1cf7666d6f": { - "dev_class": "gateway", - "firmware": "4.2.1", - "hardware": "AME Smile 2.0 board", - "location": "d34dfe6ab90b410c98068e75de3eb631", - "mac_address": "C4930002FE76", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false + "entities": { + "573c152e7d4f4720878222bd75638f5b": { + "available": true, + "binary_sensors": { + "compressor_state": false, + "cooling_enabled": false, + "cooling_state": false, + "dhw_state": false, + "flame_state": false, + "heating_state": false, + "secondary_boiler_state": false + }, + "dev_class": "heater_central", + "location": "d34dfe6ab90b410c98068e75de3eb631", + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 60.0, + "upper_bound": 100.0 + }, + "model": "Generic heater/cooler", + "name": "OpenTherm", + "sensors": { + "domestic_hot_water_setpoint": 60.0, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "outdoor_air_temperature": 14.0, + "return_temperature": 23.4, + "water_pressure": 0.5, + "water_temperature": 22.8 + }, + "switches": { + "dhw_cm_switch": true + }, + "vendor": "Techneco" }, - "sensors": { - "outdoor_temperature": 13.0 - } - }, - "573c152e7d4f4720878222bd75638f5b": { - "dev_class": "heater_central", - "location": "d34dfe6ab90b410c98068e75de3eb631", - "model": "Generic heater/cooler", - "name": "OpenTherm", - "vendor": "Techneco", - "maximum_boiler_temperature": { - "setpoint": 60.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1.0 - }, - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": false, - "compressor_state": false, - "cooling_state": false, - "cooling_enabled": false, - "secondary_boiler_state": false, - "flame_state": false - }, - "sensors": { - "water_temperature": 22.8, - "domestic_hot_water_setpoint": 60.0, - "intended_boiler_temperature": 0.0, - "modulation_level": 0, - "return_temperature": 23.4, - "water_pressure": 0.5, - "outdoor_air_temperature": 14.0 - }, - "switches": { - "dhw_cm_switch": true - } - }, - "ebd90df1ab334565b5895f37590ccff4": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "d3ce834534114348be628b61b26d9220", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint_low": 19.5, - "setpoint_high": 30.0, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "ebd90df1ab334565b5895f37590ccff4": { + "active_preset": "home", + "available_schedules": [ + "Thermostat schedule", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "d3ce834534114348be628b61b26d9220", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "away", + "no_frost", + "vacation", + "home", + "asleep" + ], + "select_schedule": "Thermostat schedule", + "sensors": { + "cooling_activation_outdoor_temperature": 26.0, + "cooling_deactivation_threshold": 3.0, + "illuminance": 0.5, + "setpoint_high": 30.0, + "setpoint_low": 19.5, + "temperature": 20.9 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 30.0, + "setpoint_low": 19.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"], - "active_preset": "home", - "available_schedules": ["Thermostat schedule", "off"], - "select_schedule": "Thermostat schedule", - "climate_mode": "auto", - "sensors": { - "temperature": 20.9, - "illuminance": 0.5, - "cooling_activation_outdoor_temperature": 26.0, - "cooling_deactivation_threshold": 3.0, - "setpoint_low": 19.5, - "setpoint_high": 30.0 + "fb49af122f6e4b0f91267e1cf7666d6f": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.2.1", + "hardware": "AME Smile 2.0 board", + "location": "d34dfe6ab90b410c98068e75de3eb631", + "mac_address": "C4930002FE76", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 13.0 + }, + "vendor": "Plugwise" } } } diff --git a/tests/data/anna/anna_elga_2_cooling.json b/tests/data/anna/anna_elga_2_cooling.json index d74c77fbf..55afba51a 100644 --- a/tests/data/anna/anna_elga_2_cooling.json +++ b/tests/data/anna/anna_elga_2_cooling.json @@ -1,82 +1,100 @@ { - "573c152e7d4f4720878222bd75638f5b": { - "available": true, - "binary_sensors": { - "compressor_state": true, - "cooling_enabled": true, - "cooling_state": true, - "dhw_state": false, - "flame_state": false, - "heating_state": false, - "secondary_boiler_state": false + "entities": { + "573c152e7d4f4720878222bd75638f5b": { + "available": true, + "binary_sensors": { + "compressor_state": true, + "cooling_enabled": true, + "cooling_state": true, + "dhw_state": false, + "flame_state": false, + "heating_state": false, + "secondary_boiler_state": false + }, + "dev_class": "heater_central", + "location": "d34dfe6ab90b410c98068e75de3eb631", + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 60.0, + "upper_bound": 100.0 + }, + "model": "Generic heater/cooler", + "name": "OpenTherm", + "sensors": { + "domestic_hot_water_setpoint": 60.0, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "outdoor_air_temperature": 30.0, + "return_temperature": 23.4, + "water_pressure": 0.5, + "water_temperature": 22.8 + }, + "switches": { + "dhw_cm_switch": true + }, + "vendor": "Techneco" }, - "dev_class": "heater_central", - "location": "d34dfe6ab90b410c98068e75de3eb631", - "maximum_boiler_temperature": { - "lower_bound": 0.0, - "resolution": 1.0, - "setpoint": 60.0, - "upper_bound": 100.0 + "ebd90df1ab334565b5895f37590ccff4": { + "active_preset": "home", + "available_schedules": [ + "Thermostat schedule", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "d3ce834534114348be628b61b26d9220", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "away", + "no_frost", + "vacation", + "home", + "asleep" + ], + "select_schedule": "Thermostat schedule", + "sensors": { + "cooling_activation_outdoor_temperature": 26.0, + "cooling_deactivation_threshold": 3.0, + "illuminance": 0.5, + "setpoint_high": 23.0, + "setpoint_low": 4.0, + "temperature": 24.9 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 23.0, + "setpoint_low": 4.0, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "model": "Generic heater/cooler", - "name": "OpenTherm", - "sensors": { - "domestic_hot_water_setpoint": 60.0, - "intended_boiler_temperature": 0.0, - "modulation_level": 0, - "outdoor_air_temperature": 30.0, - "return_temperature": 23.4, - "water_pressure": 0.5, - "water_temperature": 22.8 - }, - "switches": { - "dhw_cm_switch": true - }, - "vendor": "Techneco" - }, - "ebd90df1ab334565b5895f37590ccff4": { - "active_preset": "home", - "available_schedules": ["Thermostat schedule", "off"], - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "d3ce834534114348be628b61b26d9220", - "climate_mode": "auto", - "model": "ThermoTouch", - "name": "Anna", - "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"], - "select_schedule": "Thermostat schedule", - "sensors": { - "cooling_activation_outdoor_temperature": 26.0, - "cooling_deactivation_threshold": 3.0, - "illuminance": 0.5, - "setpoint_high": 23.0, - "setpoint_low": 4.0, - "temperature": 24.9 - }, - "thermostat": { - "lower_bound": 4.0, - "resolution": 0.1, - "setpoint_high": 23.0, - "setpoint_low": 4.0, - "upper_bound": 30.0 - }, - "vendor": "Plugwise" - }, - "fb49af122f6e4b0f91267e1cf7666d6f": { - "binary_sensors": { - "plugwise_notification": false - }, - "dev_class": "gateway", - "firmware": "4.2.1", - "hardware": "AME Smile 2.0 board", - "location": "d34dfe6ab90b410c98068e75de3eb631", - "mac_address": "C4930002FE76", - "model": "Gateway", - "name": "Smile Anna", - "sensors": { - "outdoor_temperature": 31.0 - }, - "vendor": "Plugwise" + "fb49af122f6e4b0f91267e1cf7666d6f": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.2.1", + "hardware": "AME Smile 2.0 board", + "location": "d34dfe6ab90b410c98068e75de3eb631", + "mac_address": "C4930002FE76", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 31.0 + }, + "vendor": "Plugwise" + } } } diff --git a/tests/data/anna/anna_elga_2_schedule_off.json b/tests/data/anna/anna_elga_2_schedule_off.json index 714c68de8..7e911ca2c 100644 --- a/tests/data/anna/anna_elga_2_schedule_off.json +++ b/tests/data/anna/anna_elga_2_schedule_off.json @@ -1,31 +1,100 @@ { - "ebd90df1ab334565b5895f37590ccff4": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "d3ce834534114348be628b61b26d9220", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint_low": 19.5, - "setpoint_high": 30.0, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "entities": { + "573c152e7d4f4720878222bd75638f5b": { + "available": true, + "binary_sensors": { + "compressor_state": false, + "cooling_enabled": false, + "cooling_state": false, + "dhw_state": false, + "flame_state": false, + "heating_state": false, + "secondary_boiler_state": false + }, + "dev_class": "heater_central", + "location": "d34dfe6ab90b410c98068e75de3eb631", + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 60.0, + "upper_bound": 100.0 + }, + "model": "Generic heater/cooler", + "name": "OpenTherm", + "sensors": { + "domestic_hot_water_setpoint": 60.0, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "outdoor_air_temperature": 13.0, + "return_temperature": 23.4, + "water_pressure": 0.5, + "water_temperature": 22.8 + }, + "switches": { + "dhw_cm_switch": true + }, + "vendor": "Techneco" }, - "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"], - "active_preset": "home", - "available_schedules": ["Thermostat schedule", "off"], - "select_schedule": "off", - "climate_mode": "heat_cool", - "sensors": { - "temperature": 20.9, - "illuminance": 0.5, - "cooling_activation_outdoor_temperature": 26.0, - "cooling_deactivation_threshold": 3.0, - "setpoint_low": 19.5, - "setpoint_high": 30.0 + "ebd90df1ab334565b5895f37590ccff4": { + "active_preset": "home", + "available_schedules": [ + "Thermostat schedule", + "off" + ], + "climate_mode": "heat_cool", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "d3ce834534114348be628b61b26d9220", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "away", + "no_frost", + "vacation", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "cooling_activation_outdoor_temperature": 26.0, + "cooling_deactivation_threshold": 3.0, + "illuminance": 0.5, + "setpoint_high": 30.0, + "setpoint_low": 19.5, + "temperature": 20.9 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 30.0, + "setpoint_low": 19.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" + }, + "fb49af122f6e4b0f91267e1cf7666d6f": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.2.1", + "hardware": "AME Smile 2.0 board", + "location": "d34dfe6ab90b410c98068e75de3eb631", + "mac_address": "C4930002FE76", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 13.0 + }, + "vendor": "Plugwise" } } } diff --git a/tests/data/anna/anna_elga_no_cooling.json b/tests/data/anna/anna_elga_no_cooling.json index 320e43349..056ef3310 100644 --- a/tests/data/anna/anna_elga_no_cooling.json +++ b/tests/data/anna/anna_elga_no_cooling.json @@ -1,90 +1,102 @@ { - "015ae9ea3f964e668e490fa39da3870b": { - "dev_class": "gateway", - "firmware": "4.0.15", - "hardware": "AME Smile 2.0 board", - "location": "a57efe5f145f498c9be62a9b63626fbf", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false + "entities": { + "015ae9ea3f964e668e490fa39da3870b": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.0.15", + "hardware": "AME Smile 2.0 board", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 20.2 + }, + "vendor": "Plugwise" }, - "sensors": { - "outdoor_temperature": 20.2 - } - }, - "1cbf783bb11e4a7c8a6843dee3a86927": { - "dev_class": "heater_central", - "location": "a57efe5f145f498c9be62a9b63626fbf", - "model": "Generic heater", - "name": "OpenTherm", - "vendor": "Techneco", - "maximum_boiler_temperature": { - "setpoint": 60.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1.0 - }, - "max_dhw_temperature": { - "setpoint": 53.0, - "lower_bound": 35.0, - "upper_bound": 60.0, - "resolution": 0.01 - }, - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": true, - "compressor_state": true, - "secondary_boiler_state": false, - "flame_state": false - }, - "sensors": { - "water_temperature": 29.1, - "dhw_temperature": 46.3, - "intended_boiler_temperature": 35.0, - "modulation_level": 52, - "return_temperature": 25.1, - "water_pressure": 1.57, - "outdoor_air_temperature": 3.0 - }, - "switches": { - "dhw_cm_switch": false - } - }, - "3cb70739631c4d17a86b8b12e8a5161b": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "c784ee9fdab44e1395b8dee7d7a497d5", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "temperature_offset": { - "lower_bound": -2.0, - "resolution": 0.1, - "upper_bound": 2.0, - "setpoint": -0.5 - }, - "thermostat": { - "setpoint": 20.5, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "1cbf783bb11e4a7c8a6843dee3a86927": { + "available": true, + "binary_sensors": { + "compressor_state": true, + "dhw_state": false, + "flame_state": false, + "heating_state": true, + "secondary_boiler_state": false + }, + "dev_class": "heater_central", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "max_dhw_temperature": { + "lower_bound": 35.0, + "resolution": 0.01, + "setpoint": 53.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 60.0, + "upper_bound": 100.0 + }, + "model": "Generic heater", + "name": "OpenTherm", + "sensors": { + "dhw_temperature": 46.3, + "intended_boiler_temperature": 35.0, + "modulation_level": 52, + "outdoor_air_temperature": 3.0, + "return_temperature": 25.1, + "water_pressure": 1.57, + "water_temperature": 29.1 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Techneco" }, - "preset_modes": ["no_frost", "home", "away", "asleep", "vacation"], - "active_preset": "home", - "available_schedules": ["standaard", "off"], - "select_schedule": "standaard", - "climate_mode": "auto", - "sensors": { - "setpoint": 20.5, - "temperature": 19.3, - "illuminance": 86.0, - "cooling_activation_outdoor_temperature": 21.0, - "cooling_deactivation_threshold": 4.0 + "3cb70739631c4d17a86b8b12e8a5161b": { + "active_preset": "home", + "available_schedules": [ + "standaard", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "c784ee9fdab44e1395b8dee7d7a497d5", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "no_frost", + "home", + "away", + "asleep", + "vacation" + ], + "select_schedule": "standaard", + "sensors": { + "cooling_activation_outdoor_temperature": 21.0, + "cooling_deactivation_threshold": 4.0, + "illuminance": 86.0, + "setpoint": 20.5, + "temperature": 19.3 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": -0.5, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 20.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" } } } diff --git a/tests/data/anna/anna_heatpump_cooling.json b/tests/data/anna/anna_heatpump_cooling.json index b69c6fff0..854a2ed01 100644 --- a/tests/data/anna/anna_heatpump_cooling.json +++ b/tests/data/anna/anna_heatpump_cooling.json @@ -1,82 +1,101 @@ { - "015ae9ea3f964e668e490fa39da3870b": { - "dev_class": "gateway", - "firmware": "4.0.15", - "hardware": "AME Smile 2.0 board", - "location": "a57efe5f145f498c9be62a9b63626fbf", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false + "entities": { + "015ae9ea3f964e668e490fa39da3870b": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.0.15", + "hardware": "AME Smile 2.0 board", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 22.0 + }, + "vendor": "Plugwise" }, - "sensors": { - "outdoor_temperature": 22.0 - } - }, - "1cbf783bb11e4a7c8a6843dee3a86927": { - "dev_class": "heater_central", - "location": "a57efe5f145f498c9be62a9b63626fbf", - "model": "Generic heater/cooler", - "name": "OpenTherm", - "vendor": "Techneco", - "maximum_boiler_temperature": { - "setpoint": 60.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1.0 - }, - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": false, - "compressor_state": true, - "cooling_enabled": true, - "cooling_state": true, - "secondary_boiler_state": false, - "flame_state": false - }, - "sensors": { - "water_temperature": 24.7, - "domestic_hot_water_setpoint": 60.0, - "intended_boiler_temperature": 0.0, - "modulation_level": 40, - "return_temperature": 23.8, - "water_pressure": 1.61, - "outdoor_air_temperature": 22.0 - }, - "switches": { - "dhw_cm_switch": false - } - }, - "3cb70739631c4d17a86b8b12e8a5161b": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "c784ee9fdab44e1395b8dee7d7a497d5", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint_low": 4.0, - "setpoint_high": 22.0, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "1cbf783bb11e4a7c8a6843dee3a86927": { + "available": true, + "binary_sensors": { + "compressor_state": true, + "cooling_enabled": true, + "cooling_state": true, + "dhw_state": false, + "flame_state": false, + "heating_state": false, + "secondary_boiler_state": false + }, + "dev_class": "heater_central", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 60.0, + "upper_bound": 100.0 + }, + "model": "Generic heater/cooler", + "name": "OpenTherm", + "sensors": { + "dhw_temperature": 41.5, + "domestic_hot_water_setpoint": 60.0, + "intended_boiler_temperature": 0.0, + "modulation_level": 40, + "outdoor_air_temperature": 22.0, + "return_temperature": 23.8, + "water_pressure": 1.61, + "water_temperature": 24.7 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Techneco" }, - "preset_modes": ["no_frost", "home", "away", "asleep", "vacation"], - "active_preset": "home", - "available_schedules": ["standaard", "off"], - "select_schedule": "off", - "climate_mode": "heat_cool", - "sensors": { - "temperature": 22.3, - "illuminance": 24.5, - "cooling_activation_outdoor_temperature": 21.0, - "cooling_deactivation_threshold": 6.0, - "setpoint_low": 4.0, - "setpoint_high": 22.0 + "3cb70739631c4d17a86b8b12e8a5161b": { + "active_preset": "home", + "available_schedules": [ + "standaard", + "off" + ], + "climate_mode": "heat_cool", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "c784ee9fdab44e1395b8dee7d7a497d5", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "no_frost", + "home", + "away", + "asleep", + "vacation" + ], + "select_schedule": "off", + "sensors": { + "cooling_activation_outdoor_temperature": 21.0, + "cooling_deactivation_threshold": 6.0, + "illuminance": 24.5, + "setpoint_high": 22.0, + "setpoint_low": 4.0, + "temperature": 22.3 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": -0.5, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 22.0, + "setpoint_low": 4.0, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" } } } diff --git a/tests/data/anna/anna_heatpump_cooling_fake_firmware.json b/tests/data/anna/anna_heatpump_cooling_fake_firmware.json index 2a7f146a0..dd9291df2 100644 --- a/tests/data/anna/anna_heatpump_cooling_fake_firmware.json +++ b/tests/data/anna/anna_heatpump_cooling_fake_firmware.json @@ -1,16 +1,101 @@ { - "1cbf783bb11e4a7c8a6843dee3a86927": { - "binary_sensors": { - "cooling_enabled": true, - "cooling_state": true, - "dhw_state": false, - "heating_state": false + "entities": { + "015ae9ea3f964e668e490fa39da3870b": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.10.10", + "hardware": "AME Smile 2.0 board", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 22.0 + }, + "vendor": "Plugwise" }, - "sensors": { - "modulation_level": 100 + "1cbf783bb11e4a7c8a6843dee3a86927": { + "available": true, + "binary_sensors": { + "compressor_state": true, + "cooling_enabled": true, + "cooling_state": true, + "dhw_state": false, + "flame_state": false, + "heating_state": false, + "secondary_boiler_state": false + }, + "dev_class": "heater_central", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 60.0, + "upper_bound": 100.0 + }, + "model": "Generic heater/cooler", + "name": "OpenTherm", + "sensors": { + "dhw_temperature": 41.5, + "domestic_hot_water_setpoint": 60.0, + "intended_boiler_temperature": 0.0, + "modulation_level": 100, + "outdoor_air_temperature": 22.0, + "return_temperature": 23.8, + "water_pressure": 1.61, + "water_temperature": 24.7 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Techneco" + }, + "3cb70739631c4d17a86b8b12e8a5161b": { + "active_preset": "home", + "available_schedules": [ + "standaard", + "off" + ], + "climate_mode": "heat_cool", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "c784ee9fdab44e1395b8dee7d7a497d5", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "no_frost", + "home", + "away", + "asleep", + "vacation" + ], + "select_schedule": "off", + "sensors": { + "cooling_activation_outdoor_temperature": 21.0, + "cooling_deactivation_threshold": 6.0, + "illuminance": 24.5, + "setpoint_high": 22.0, + "setpoint_low": 4.0, + "temperature": 22.3 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": -0.5, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 22.0, + "setpoint_low": 4.0, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" } - }, - "015ae9ea3f964e668e490fa39da3870b": { - "firmware": "4.10.10" } } diff --git a/tests/data/anna/anna_heatpump_heating.json b/tests/data/anna/anna_heatpump_heating.json index a78ccefe2..db65c31cb 100644 --- a/tests/data/anna/anna_heatpump_heating.json +++ b/tests/data/anna/anna_heatpump_heating.json @@ -1,95 +1,106 @@ { - "015ae9ea3f964e668e490fa39da3870b": { - "binary_sensors": { - "plugwise_notification": false + "entities": { + "015ae9ea3f964e668e490fa39da3870b": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.0.15", + "hardware": "AME Smile 2.0 board", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 20.2 + }, + "vendor": "Plugwise" }, - "dev_class": "gateway", - "firmware": "4.0.15", - "hardware": "AME Smile 2.0 board", - "location": "a57efe5f145f498c9be62a9b63626fbf", - "mac_address": "012345670001", - "model": "Gateway", - "model_id": "smile_thermo", - "name": "Smile Anna", - "sensors": { - "outdoor_temperature": 20.2 + "1cbf783bb11e4a7c8a6843dee3a86927": { + "available": true, + "binary_sensors": { + "compressor_state": true, + "cooling_enabled": false, + "cooling_state": false, + "dhw_state": false, + "flame_state": false, + "heating_state": true, + "secondary_boiler_state": false + }, + "dev_class": "heater_central", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "max_dhw_temperature": { + "lower_bound": 35.0, + "resolution": 0.01, + "setpoint": 53.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 60.0, + "upper_bound": 100.0 + }, + "model": "Generic heater/cooler", + "name": "OpenTherm", + "sensors": { + "dhw_temperature": 46.3, + "intended_boiler_temperature": 35.0, + "modulation_level": 52, + "outdoor_air_temperature": 3.0, + "return_temperature": 25.1, + "water_pressure": 1.57, + "water_temperature": 29.1 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Techneco" }, - "vendor": "Plugwise" - }, - "1cbf783bb11e4a7c8a6843dee3a86927": { - "available": true, - "binary_sensors": { - "compressor_state": true, - "cooling_enabled": false, - "cooling_state": false, - "dhw_state": false, - "flame_state": false, - "heating_state": true, - "secondary_boiler_state": false - }, - "dev_class": "heater_central", - "location": "a57efe5f145f498c9be62a9b63626fbf", - "max_dhw_temperature": { - "lower_bound": 35.0, - "resolution": 0.01, - "setpoint": 53.0, - "upper_bound": 60.0 - }, - "maximum_boiler_temperature": { - "lower_bound": 0.0, - "resolution": 1.0, - "setpoint": 60.0, - "upper_bound": 100.0 - }, - "model": "Generic heater/cooler", - "name": "OpenTherm", - "sensors": { - "dhw_temperature": 46.3, - "intended_boiler_temperature": 35.0, - "modulation_level": 52, - "outdoor_air_temperature": 3.0, - "return_temperature": 25.1, - "water_pressure": 1.57, - "water_temperature": 29.1 - }, - "switches": { - "dhw_cm_switch": false - }, - "vendor": "Techneco" - }, - "3cb70739631c4d17a86b8b12e8a5161b": { - "active_preset": "home", - "available_schedules": ["standaard", "off"], - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "c784ee9fdab44e1395b8dee7d7a497d5", - "climate_mode": "auto", - "model": "ThermoTouch", - "name": "Anna", - "preset_modes": ["no_frost", "home", "away", "asleep", "vacation"], - "select_schedule": "standaard", - "sensors": { - "cooling_activation_outdoor_temperature": 21.0, - "cooling_deactivation_threshold": 4.0, - "illuminance": 86.0, - "setpoint_high": 30.0, - "setpoint_low": 20.5, - "temperature": 19.3 - }, - "temperature_offset": { - "lower_bound": -2.0, - "resolution": 0.1, - "setpoint": -0.5, - "upper_bound": 2.0 - }, - "thermostat": { - "lower_bound": 4.0, - "resolution": 0.1, - "setpoint_high": 30.0, - "setpoint_low": 20.5, - "upper_bound": 30.0 - }, - "vendor": "Plugwise" + "3cb70739631c4d17a86b8b12e8a5161b": { + "active_preset": "home", + "available_schedules": [ + "standaard", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "c784ee9fdab44e1395b8dee7d7a497d5", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "no_frost", + "home", + "away", + "asleep", + "vacation" + ], + "select_schedule": "standaard", + "sensors": { + "cooling_activation_outdoor_temperature": 21.0, + "cooling_deactivation_threshold": 4.0, + "illuminance": 86.0, + "setpoint_high": 30.0, + "setpoint_low": 20.5, + "temperature": 19.3 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": -0.5, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 30.0, + "setpoint_low": 20.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" + } } } diff --git a/tests/data/anna/anna_heatpump_heating_UPDATED_DATA.json b/tests/data/anna/anna_heatpump_heating_UPDATED_DATA.json index a36012587..aa1e3dc4d 100644 --- a/tests/data/anna/anna_heatpump_heating_UPDATED_DATA.json +++ b/tests/data/anna/anna_heatpump_heating_UPDATED_DATA.json @@ -1,38 +1,40 @@ { - "1cbf783bb11e4a7c8a6843dee3a86927": { - "dev_class": "heater_central", - "location": "a57efe5f145f498c9be62a9b63626fbf", - "model": "Generic heater/cooler", - "name": "OpenTherm", - "vendor": "Techneco", - "maximum_boiler_temperature": { - "setpoint": 60.0, - "lower_bound": 0.0, - "upper_bound": 100.0, - "resolution": 1.0 - }, - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": true, - "compressor_state": true, - "cooling_state": false, - "cooling_enabled": false, - "secondary_boiler_state": false, - "flame_state": false - }, - "sensors": { - "water_temperature": 29.1, - "domestic_hot_water_setpoint": 60.0, - "dhw_temperature": 46.3, - "intended_boiler_temperature": 35.0, - "modulation_level": 52, - "return_temperature": 25.1, - "water_pressure": 1.57, - "outdoor_air_temperature": 3.0 - }, - "switches": { - "dhw_cm_switch": false + "entities": { + "1cbf783bb11e4a7c8a6843dee3a86927": { + "dev_class": "heater_central", + "location": "a57efe5f145f498c9be62a9b63626fbf", + "model": "Generic heater/cooler", + "name": "OpenTherm", + "vendor": "Techneco", + "maximum_boiler_temperature": { + "setpoint": 60.0, + "lower_bound": 0.0, + "upper_bound": 100.0, + "resolution": 1.0 + }, + "available": true, + "binary_sensors": { + "dhw_state": false, + "heating_state": true, + "compressor_state": true, + "cooling_state": false, + "cooling_enabled": false, + "secondary_boiler_state": false, + "flame_state": false + }, + "sensors": { + "water_temperature": 29.1, + "domestic_hot_water_setpoint": 60.0, + "dhw_temperature": 46.3, + "intended_boiler_temperature": 35.0, + "modulation_level": 52, + "return_temperature": 25.1, + "water_pressure": 1.57, + "outdoor_air_temperature": 3.0 + }, + "switches": { + "dhw_cm_switch": false + } } } } diff --git a/tests/data/anna/anna_loria_cooling_active.json b/tests/data/anna/anna_loria_cooling_active.json index 5902980e8..eca1cfe6c 100644 --- a/tests/data/anna/anna_loria_cooling_active.json +++ b/tests/data/anna/anna_loria_cooling_active.json @@ -1,87 +1,112 @@ { - "582dfbdace4d4aeb832923ce7d1ddda0": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "15da035090b847e7a21f93e08c015ebc", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint_low": 4.0, - "setpoint_high": 23.5, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "entities": { + "582dfbdace4d4aeb832923ce7d1ddda0": { + "active_preset": "home", + "available_schedules": [ + "Winter", + "Test ", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "15da035090b847e7a21f93e08c015ebc", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "away", + "vacation", + "no_frost", + "home", + "asleep" + ], + "select_schedule": "Winter", + "sensors": { + "illuminance": 45.0, + "setpoint_high": 23.5, + "setpoint_low": 4.0, + "temperature": 24.1 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 23.5, + "setpoint_low": 4.0, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "preset_modes": ["away", "vacation", "no_frost", "home", "asleep"], - "active_preset": "home", - "available_schedules": ["Winter", "Test ", "off"], - "select_schedule": "Winter", - "climate_mode": "auto", - "sensors": { - "temperature": 24.1, - "illuminance": 45.0, - "setpoint_low": 4.0, - "setpoint_high": 23.5 - } - }, - "bfb5ee0a88e14e5f97bfa725a760cc49": { - "dev_class": "heater_central", - "location": "674b657c138a41a291d315d7471deb06", - "model": "Generic heater/cooler", - "model_id": "173", - "name": "OpenTherm", - "vendor": "Atlantic", - "select_dhw_mode": "auto", - "maximum_boiler_temperature": { - "setpoint": 40.0, - "lower_bound": 25.0, - "upper_bound": 45.0, - "resolution": 0.01 - }, - "max_dhw_temperature": { - "setpoint": 53.0, - "lower_bound": 35.0, - "upper_bound": 60.0, - "resolution": 0.01 - }, - "dhw_modes": ["off", "auto", "boost", "eco", "comfort"], - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": false, - "cooling_state": true, - "cooling_enabled": true, - "flame_state": false - }, - "sensors": { - "water_temperature": 25.3, - "dhw_temperature": 52.9, - "intended_boiler_temperature": 0.0, - "modulation_level": 100, - "return_temperature": 26.3, - "outdoor_air_temperature": 17.2 - }, - "switches": { - "dhw_cm_switch": true, - "cooling_ena_switch": true - } - }, - "9ff0569b4984459fb243af64c0901894": { - "dev_class": "gateway", - "firmware": "4.3.8", - "hardware": "AME Smile 2.0 board", - "location": "674b657c138a41a291d315d7471deb06", - "mac_address": "C493000278E2", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false + "9ff0569b4984459fb243af64c0901894": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.3.8", + "hardware": "AME Smile 2.0 board", + "location": "674b657c138a41a291d315d7471deb06", + "mac_address": "C493000278E2", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 15.5 + }, + "vendor": "Plugwise" }, - "sensors": { - "outdoor_temperature": 15.5 + "bfb5ee0a88e14e5f97bfa725a760cc49": { + "available": true, + "binary_sensors": { + "cooling_enabled": true, + "cooling_state": true, + "dhw_state": false, + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "dhw_modes": [ + "off", + "auto", + "boost", + "eco", + "comfort" + ], + "location": "674b657c138a41a291d315d7471deb06", + "max_dhw_temperature": { + "lower_bound": 35.0, + "resolution": 0.01, + "setpoint": 53.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 25.0, + "resolution": 0.01, + "setpoint": 40.0, + "upper_bound": 45.0 + }, + "model": "Generic heater/cooler", + "model_id": "173", + "name": "OpenTherm", + "select_dhw_mode": "auto", + "sensors": { + "dhw_temperature": 52.9, + "intended_boiler_temperature": 0.0, + "modulation_level": 100, + "outdoor_air_temperature": 17.2, + "return_temperature": 26.3, + "water_temperature": 25.3 + }, + "switches": { + "cooling_ena_switch": true, + "dhw_cm_switch": true + }, + "vendor": "Atlantic" } } } diff --git a/tests/data/anna/anna_loria_driessens.json b/tests/data/anna/anna_loria_driessens.json index 0c1b5689e..8b6061c9e 100644 --- a/tests/data/anna/anna_loria_driessens.json +++ b/tests/data/anna/anna_loria_driessens.json @@ -1,99 +1,114 @@ { - "5c118b1842e943c0a5b6ef88a60bb17a": { - "binary_sensors": { - "plugwise_notification": false + "entities": { + "5c118b1842e943c0a5b6ef88a60bb17a": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.4.1", + "hardware": "AME Smile 2.0 board", + "location": "82c15f65c9bf44c592d69e16139355e3", + "mac_address": "D40FB2011556", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 6.81 + }, + "vendor": "Plugwise" }, - "dev_class": "gateway", - "firmware": "4.4.1", - "hardware": "AME Smile 2.0 board", - "location": "82c15f65c9bf44c592d69e16139355e3", - "mac_address": "D40FB2011556", - "model": "Gateway", - "name": "Smile Anna", - "sensors": { - "outdoor_temperature": 6.81 + "9fb768d699e44c7fb5cc50309dc4e7d4": { + "active_preset": "home", + "available_schedules": [ + "Verwarmen@9-23u", + "VAKANTIE (winter)", + "VERWARMEN", + "KOELEN", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "fa70e08550c94de3a34feb27ecf31421", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "no_frost", + "asleep", + "vacation", + "away", + "home" + ], + "select_schedule": "Verwarmen@9-23u", + "sensors": { + "illuminance": 5.5, + "setpoint_high": 30.0, + "setpoint_low": 20.0, + "temperature": 21.2 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 30.0, + "setpoint_low": 20.0, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "vendor": "Plugwise" - }, - "9fb768d699e44c7fb5cc50309dc4e7d4": { - "active_preset": "home", - "available_schedules": [ - "Verwarmen@9-23u", - "VAKANTIE (winter)", - "VERWARMEN", - "KOELEN", - "off" - ], - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "fa70e08550c94de3a34feb27ecf31421", - "climate_mode": "auto", - "model": "ThermoTouch", - "name": "Anna", - "preset_modes": ["no_frost", "asleep", "vacation", "away", "home"], - "select_schedule": "Verwarmen@9-23u", - "sensors": { - "illuminance": 5.5, - "setpoint_high": 30.0, - "setpoint_low": 20.0, - "temperature": 21.2 - }, - "temperature_offset": { - "lower_bound": -2.0, - "resolution": 0.1, - "setpoint": 0.0, - "upper_bound": 2.0 - }, - "thermostat": { - "lower_bound": 4.0, - "resolution": 0.1, - "setpoint_high": 30.0, - "setpoint_low": 20.0, - "upper_bound": 30.0 - }, - "vendor": "Plugwise" - }, - "a449cbc334ae4a5bb7f89064984b2906": { - "available": true, - "binary_sensors": { - "cooling_enabled": false, - "cooling_state": false, - "dhw_state": false, - "flame_state": false, - "heating_state": false - }, - "dev_class": "heater_central", - "dhw_modes": ["comfort", "eco", "off", "boost", "auto"], - "location": "82c15f65c9bf44c592d69e16139355e3", - "max_dhw_temperature": { - "lower_bound": 35.0, - "resolution": 0.01, - "setpoint": 53.0, - "upper_bound": 60.0 - }, - "maximum_boiler_temperature": { - "lower_bound": 25.0, - "resolution": 0.01, - "setpoint": 45.0, - "upper_bound": 45.0 - }, - "model": "Generic heater/cooler", - "model_id": "173", - "name": "OpenTherm", - "select_dhw_mode": "auto", - "sensors": { - "dhw_temperature": 49.5, - "intended_boiler_temperature": 0.0, - "modulation_level": 0, - "outdoor_air_temperature": 7.5, - "return_temperature": 23.0, - "water_temperature": 23.3 - }, - "switches": { - "cooling_ena_switch": false, - "dhw_cm_switch": true - }, - "vendor": "Atlantic" + "a449cbc334ae4a5bb7f89064984b2906": { + "available": true, + "binary_sensors": { + "cooling_enabled": false, + "cooling_state": false, + "dhw_state": false, + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "dhw_modes": [ + "comfort", + "eco", + "off", + "boost", + "auto" + ], + "location": "82c15f65c9bf44c592d69e16139355e3", + "max_dhw_temperature": { + "lower_bound": 35.0, + "resolution": 0.01, + "setpoint": 53.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 25.0, + "resolution": 0.01, + "setpoint": 45.0, + "upper_bound": 45.0 + }, + "model": "Generic heater/cooler", + "model_id": "173", + "name": "OpenTherm", + "select_dhw_mode": "auto", + "sensors": { + "dhw_temperature": 49.5, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "outdoor_air_temperature": 7.5, + "return_temperature": 23.0, + "water_temperature": 23.3 + }, + "switches": { + "cooling_ena_switch": false, + "dhw_cm_switch": true + }, + "vendor": "Atlantic" + } } } diff --git a/tests/data/anna/anna_loria_heating_idle.json b/tests/data/anna/anna_loria_heating_idle.json index 2ac87d7fd..c4baacc9f 100644 --- a/tests/data/anna/anna_loria_heating_idle.json +++ b/tests/data/anna/anna_loria_heating_idle.json @@ -1,87 +1,112 @@ { - "582dfbdace4d4aeb832923ce7d1ddda0": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "15da035090b847e7a21f93e08c015ebc", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint_low": 20.5, - "setpoint_high": 30.0, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "entities": { + "582dfbdace4d4aeb832923ce7d1ddda0": { + "active_preset": "home", + "available_schedules": [ + "Winter", + "Test ", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "15da035090b847e7a21f93e08c015ebc", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "away", + "vacation", + "no_frost", + "home", + "asleep" + ], + "select_schedule": "Winter", + "sensors": { + "illuminance": 45.0, + "setpoint_high": 30.0, + "setpoint_low": 20.5, + "temperature": 22.1 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint_high": 30.0, + "setpoint_low": 20.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "preset_modes": ["away", "vacation", "no_frost", "home", "asleep"], - "active_preset": "home", - "available_schedules": ["Winter", "Test ", "off"], - "select_schedule": "Winter", - "climate_mode": "auto", - "sensors": { - "temperature": 22.1, - "illuminance": 45.0, - "setpoint_low": 20.5, - "setpoint_high": 30.0 - } - }, - "bfb5ee0a88e14e5f97bfa725a760cc49": { - "dev_class": "heater_central", - "location": "674b657c138a41a291d315d7471deb06", - "model": "Generic heater/cooler", - "model_id": "173", - "name": "OpenTherm", - "vendor": "Atlantic", - "select_dhw_mode": "auto", - "maximum_boiler_temperature": { - "setpoint": 40.0, - "lower_bound": 25.0, - "upper_bound": 45.0, - "resolution": 0.01 - }, - "max_dhw_temperature": { - "setpoint": 53.0, - "lower_bound": 35.0, - "upper_bound": 60.0, - "resolution": 0.01 - }, - "dhw_modes": ["off", "auto", "boost", "eco", "comfort"], - "available": true, - "binary_sensors": { - "dhw_state": false, - "heating_state": false, - "cooling_state": false, - "cooling_enabled": false, - "flame_state": false - }, - "sensors": { - "water_temperature": 25.3, - "dhw_temperature": 52.9, - "intended_boiler_temperature": 0.0, - "modulation_level": 0, - "return_temperature": 26.3, - "outdoor_air_temperature": 17.2 - }, - "switches": { - "dhw_cm_switch": true, - "cooling_ena_switch": false - } - }, - "9ff0569b4984459fb243af64c0901894": { - "dev_class": "gateway", - "firmware": "4.3.8", - "hardware": "AME Smile 2.0 board", - "location": "674b657c138a41a291d315d7471deb06", - "mac_address": "C493000278E2", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false + "9ff0569b4984459fb243af64c0901894": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.3.8", + "hardware": "AME Smile 2.0 board", + "location": "674b657c138a41a291d315d7471deb06", + "mac_address": "C493000278E2", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 15.5 + }, + "vendor": "Plugwise" }, - "sensors": { - "outdoor_temperature": 15.5 + "bfb5ee0a88e14e5f97bfa725a760cc49": { + "available": true, + "binary_sensors": { + "cooling_enabled": false, + "cooling_state": false, + "dhw_state": false, + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "dhw_modes": [ + "off", + "auto", + "boost", + "eco", + "comfort" + ], + "location": "674b657c138a41a291d315d7471deb06", + "max_dhw_temperature": { + "lower_bound": 35.0, + "resolution": 0.01, + "setpoint": 53.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 25.0, + "resolution": 0.01, + "setpoint": 40.0, + "upper_bound": 45.0 + }, + "model": "Generic heater/cooler", + "model_id": "173", + "name": "OpenTherm", + "select_dhw_mode": "auto", + "sensors": { + "dhw_temperature": 52.9, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "outdoor_air_temperature": 17.2, + "return_temperature": 26.3, + "water_temperature": 25.3 + }, + "switches": { + "cooling_ena_switch": false, + "dhw_cm_switch": true + }, + "vendor": "Atlantic" } } } diff --git a/tests/data/anna/anna_without_boiler_fw441.json b/tests/data/anna/anna_without_boiler_fw441.json index c175ef90e..f5b6b0c77 100644 --- a/tests/data/anna/anna_without_boiler_fw441.json +++ b/tests/data/anna/anna_without_boiler_fw441.json @@ -1,52 +1,71 @@ { - "a270735e4ccd45239424badc0578a2b1": { - "dev_class": "gateway", - "firmware": "4.4.1", - "hardware": "AME Smile 2.0 board", - "location": "0f4f2ada20734a339fe353348fe87b96", - "mac_address": "D40FB200FA1C", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": false + "entities": { + "7ffbb3ab4b6c4ab2915d7510f7bf8fe9": { + "active_preset": "home", + "available_schedules": [ + "Test", + "Normaal", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "c34c6864216446528e95d88985e714cc", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "no_frost", + "asleep", + "away", + "vacation", + "home" + ], + "select_schedule": "Normaal", + "sensors": { + "illuminance": 0.25, + "setpoint": 19.0, + "temperature": 19.1 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 19.0, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "sensors": { - "outdoor_temperature": 8.31 - } - }, - "7ffbb3ab4b6c4ab2915d7510f7bf8fe9": { - "dev_class": "thermostat", - "firmware": "2018-02-08T11:15:53+01:00", - "hardware": "6539-1301-5002", - "location": "c34c6864216446528e95d88985e714cc", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 19.0, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 + "a270735e4ccd45239424badc0578a2b1": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.4.1", + "hardware": "AME Smile 2.0 board", + "location": "0f4f2ada20734a339fe353348fe87b96", + "mac_address": "D40FB200FA1C", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 8.31 + }, + "vendor": "Plugwise" }, - "preset_modes": ["no_frost", "asleep", "away", "vacation", "home"], - "active_preset": "home", - "available_schedules": ["Test", "Normaal", "off"], - "select_schedule": "Normaal", - "climate_mode": "auto", - "sensors": { - "temperature": 19.1, - "setpoint": 19.0, - "illuminance": 0.25 - } - }, - "c46b4794d28149699eacf053deedd003": { - "dev_class": "heater_central", - "location": "0f4f2ada20734a339fe353348fe87b96", - "model": "Unknown", - "name": "OnOff", - "binary_sensors": { - "heating_state": false + "c46b4794d28149699eacf053deedd003": { + "binary_sensors": { + "heating_state": false + }, + "dev_class": "heater_central", + "location": "0f4f2ada20734a339fe353348fe87b96", + "model": "Unknown", + "name": "OnOff" } } } diff --git a/tests/data/anna/legacy_anna_2.json b/tests/data/anna/legacy_anna_2.json index 4721af5b6..d41d7ca94 100644 --- a/tests/data/anna/legacy_anna_2.json +++ b/tests/data/anna/legacy_anna_2.json @@ -1,63 +1,74 @@ { - "be81e3f8275b4129852c4d8d550ae2eb": { - "dev_class": "gateway", - "firmware": "1.8.22", - "location": "be81e3f8275b4129852c4d8d550ae2eb", - "mac_address": "01:23:45:67:89:AB", - "model": "Gateway", - "name": "Smile Anna", - "vendor": "Plugwise", - "sensors": { - "outdoor_temperature": 21.0 - } - }, - "9e7377867dc24e51b8098a5ba02bd89d": { - "dev_class": "thermostat", - "firmware": "2017-03-13T11:54:58+01:00", - "hardware": "6539-1301-5002", - "location": "be81e3f8275b4129852c4d8d550ae2eb", - "model": "ThermoTouch", - "name": "Anna", - "vendor": "Plugwise", - "thermostat": { - "setpoint": 15.0, - "lower_bound": 4.0, - "upper_bound": 30.0, - "resolution": 0.1 - }, - "preset_modes": ["vacation", "away", "no_frost", "home", "asleep"], - "active_preset": null, - "available_schedules": ["Thermostat schedule", "off"], - "select_schedule": "off", - "climate_mode": "heat", - "sensors": { - "temperature": 21.4, - "illuminance": 19.5, - "setpoint": 15.0 - } - }, - "ea5d8a7177e541b0a4b52da815166de4": { - "dev_class": "heater_central", - "location": "be81e3f8275b4129852c4d8d550ae2eb", - "model": "Generic heater", - "name": "OpenTherm", - "maximum_boiler_temperature": { - "setpoint": 70.0, - "lower_bound": 50.0, - "upper_bound": 90.0, - "resolution": 1.0 + "entities": { + "9e7377867dc24e51b8098a5ba02bd89d": { + "active_preset": null, + "available_schedules": [ + "Thermostat schedule", + "off" + ], + "climate_mode": "heat", + "dev_class": "thermostat", + "firmware": "2017-03-13T11:54:58+01:00", + "hardware": "6539-1301-5002", + "location": "be81e3f8275b4129852c4d8d550ae2eb", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "vacation", + "away", + "no_frost", + "home", + "asleep" + ], + "select_schedule": "off", + "sensors": { + "illuminance": 19.5, + "setpoint": 15.0, + "temperature": 21.4 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 15.0, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" }, - "binary_sensors": { - "flame_state": false, - "heating_state": false + "be81e3f8275b4129852c4d8d550ae2eb": { + "dev_class": "gateway", + "firmware": "1.8.22", + "location": "be81e3f8275b4129852c4d8d550ae2eb", + "mac_address": "01:23:45:67:89:AB", + "model": "Gateway", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 21.0 + }, + "vendor": "Plugwise" }, - "sensors": { - "water_temperature": 54.0, - "dhw_temperature": 0.0, - "intended_boiler_temperature": 0.0, - "modulation_level": 0, - "return_temperature": 0.0, - "water_pressure": 1.7 + "ea5d8a7177e541b0a4b52da815166de4": { + "binary_sensors": { + "flame_state": false, + "heating_state": false + }, + "dev_class": "heater_central", + "location": "be81e3f8275b4129852c4d8d550ae2eb", + "maximum_boiler_temperature": { + "lower_bound": 50.0, + "resolution": 1.0, + "setpoint": 70.0, + "upper_bound": 90.0 + }, + "model": "Generic heater", + "name": "OpenTherm", + "sensors": { + "dhw_temperature": 0.0, + "intended_boiler_temperature": 0.0, + "modulation_level": 0.0, + "return_temperature": 0.0, + "water_pressure": 1.7, + "water_temperature": 54.0 + } } } } diff --git a/tests/data/p1/p1v4_442_single.json b/tests/data/p1/p1v4_442_single.json index 8f41b3f13..387ee92f5 100644 --- a/tests/data/p1/p1v4_442_single.json +++ b/tests/data/p1/p1v4_442_single.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "a455b61e52394b2db5081ce025a430f3": { "binary_sensors": { "plugwise_notification": false diff --git a/tests/data/p1/p1v4_442_single_UPDATED_DATA.json b/tests/data/p1/p1v4_442_single_UPDATED_DATA.json index 8db198157..f7c54c9f6 100644 --- a/tests/data/p1/p1v4_442_single_UPDATED_DATA.json +++ b/tests/data/p1/p1v4_442_single_UPDATED_DATA.json @@ -1,5 +1,5 @@ { - "device_zones": { + "entities": { "ba4de7613517478da82dd9b6abea36af": { "sensors": { "net_electricity_point": -2248.0, diff --git a/tests/data/p1/p1v4_442_triple.json b/tests/data/p1/p1v4_442_triple.json index 84780b497..5e8c38bc6 100644 --- a/tests/data/p1/p1v4_442_triple.json +++ b/tests/data/p1/p1v4_442_triple.json @@ -1,51 +1,53 @@ { - "03e65b16e4b247a29ae0d75a78cb492e": { - "dev_class": "gateway", - "firmware": "4.4.2", - "hardware": "AME Smile 2.0 board", - "location": "03e65b16e4b247a29ae0d75a78cb492e", - "mac_address": "012345670001", - "model": "Gateway", - "model_id": "smile", - "name": "Smile P1", - "vendor": "Plugwise", - "binary_sensors": { - "plugwise_notification": true - } - }, - "b82b6b3322484f2ea4e25e0bd5f3d61f": { - "dev_class": "smartmeter", - "location": "03e65b16e4b247a29ae0d75a78cb492e", - "model": "XMX5LGF0010453051839", - "name": "P1", - "vendor": "XEMEX NV", - "available": true, - "sensors": { - "net_electricity_point": 5553.0, - "electricity_consumed_peak_point": 0.0, - "electricity_consumed_off_peak_point": 5553.0, - "net_electricity_cumulative": 231866.539, - "electricity_consumed_peak_cumulative": 161328.641, - "electricity_consumed_off_peak_cumulative": 70537.898, - "electricity_consumed_peak_interval": 0.0, - "electricity_consumed_off_peak_interval": 314.0, - "electricity_produced_peak_point": 0.0, - "electricity_produced_off_peak_point": 0.0, - "electricity_produced_peak_cumulative": 0.0, - "electricity_produced_off_peak_cumulative": 0.0, - "electricity_produced_peak_interval": 0.0, - "electricity_produced_off_peak_interval": 0.0, - "electricity_phase_one_consumed": 1763.0, - "electricity_phase_two_consumed": 1703.0, - "electricity_phase_three_consumed": 2080.0, - "electricity_phase_one_produced": 0.0, - "electricity_phase_two_produced": 0.0, - "electricity_phase_three_produced": 0.0, - "gas_consumed_cumulative": 16811.37, - "gas_consumed_interval": 0.06, - "voltage_phase_one": 233.2, - "voltage_phase_two": 234.4, - "voltage_phase_three": 234.7 + "entities": { + "03e65b16e4b247a29ae0d75a78cb492e": { + "binary_sensors": { + "plugwise_notification": true + }, + "dev_class": "gateway", + "firmware": "4.4.2", + "hardware": "AME Smile 2.0 board", + "location": "03e65b16e4b247a29ae0d75a78cb492e", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile", + "name": "Smile P1", + "vendor": "Plugwise" + }, + "b82b6b3322484f2ea4e25e0bd5f3d61f": { + "available": true, + "dev_class": "smartmeter", + "location": "03e65b16e4b247a29ae0d75a78cb492e", + "model": "XMX5LGF0010453051839", + "name": "P1", + "sensors": { + "electricity_consumed_off_peak_cumulative": 70537.898, + "electricity_consumed_off_peak_interval": 314, + "electricity_consumed_off_peak_point": 5553, + "electricity_consumed_peak_cumulative": 161328.641, + "electricity_consumed_peak_interval": 0, + "electricity_consumed_peak_point": 0, + "electricity_phase_one_consumed": 1763, + "electricity_phase_one_produced": 0, + "electricity_phase_three_consumed": 2080, + "electricity_phase_three_produced": 0, + "electricity_phase_two_consumed": 1703, + "electricity_phase_two_produced": 0, + "electricity_produced_off_peak_cumulative": 0.0, + "electricity_produced_off_peak_interval": 0, + "electricity_produced_off_peak_point": 0, + "electricity_produced_peak_cumulative": 0.0, + "electricity_produced_peak_interval": 0, + "electricity_produced_peak_point": 0, + "gas_consumed_cumulative": 16811.37, + "gas_consumed_interval": 0.06, + "net_electricity_cumulative": 231866.539, + "net_electricity_point": 5553, + "voltage_phase_one": 233.2, + "voltage_phase_three": 234.7, + "voltage_phase_two": 234.4 + }, + "vendor": "XEMEX NV" } } } diff --git a/tests/data/p1/smile_p1_v2_2.json b/tests/data/p1/smile_p1_v2_2.json index bb59a0476..30734158e 100644 --- a/tests/data/p1/smile_p1_v2_2.json +++ b/tests/data/p1/smile_p1_v2_2.json @@ -1,34 +1,36 @@ { - "aaaa0000aaaa0000aaaa0000aaaa00aa": { - "dev_class": "gateway", - "firmware": "2.5.9", - "location": "199aa40f126840f392983d171374ab0b", - "mac_address": "012345670001", - "model": "Gateway", - "name": "Smile P1", - "vendor": "Plugwise" - }, - "199aa40f126840f392983d171374ab0b": { - "dev_class": "smartmeter", - "location": "199aa40f126840f392983d171374ab0b", - "model": "Ene5\\T210-DESMR5.0", - "name": "P1", - "vendor": "Ene5\\T210-DESMR5.0", - "sensors": { - "net_electricity_point": 458.0, - "electricity_consumed_point": 458.0, - "net_electricity_cumulative": 1019.201, - "electricity_consumed_peak_cumulative": 1155.195, - "electricity_consumed_off_peak_cumulative": 1642.74, - "electricity_consumed_peak_interval": 250.0, - "electricity_consumed_off_peak_interval": 0.0, - "electricity_produced_point": 0.0, - "electricity_produced_peak_cumulative": 1296.136, - "electricity_produced_off_peak_cumulative": 482.598, - "electricity_produced_peak_interval": 0.0, - "electricity_produced_off_peak_interval": 0.0, - "gas_consumed_cumulative": 584.433, - "gas_consumed_interval": 0.016 + "entities": { + "199aa40f126840f392983d171374ab0b": { + "dev_class": "smartmeter", + "location": "199aa40f126840f392983d171374ab0b", + "model": "Ene5\\T210-DESMR5.0", + "name": "P1", + "sensors": { + "electricity_consumed_off_peak_cumulative": 1642.74, + "electricity_consumed_off_peak_interval": 0, + "electricity_consumed_peak_cumulative": 1155.195, + "electricity_consumed_peak_interval": 250, + "electricity_consumed_point": 458, + "electricity_produced_off_peak_cumulative": 482.598, + "electricity_produced_off_peak_interval": 0, + "electricity_produced_peak_cumulative": 1296.136, + "electricity_produced_peak_interval": 0, + "electricity_produced_point": 0, + "gas_consumed_cumulative": 584.433, + "gas_consumed_interval": 0.016, + "net_electricity_cumulative": 1019.201, + "net_electricity_point": 458 + }, + "vendor": "Ene5\\T210-DESMR5.0" + }, + "aaaa0000aaaa0000aaaa0000aaaa00aa": { + "dev_class": "gateway", + "firmware": "2.5.9", + "location": "199aa40f126840f392983d171374ab0b", + "mac_address": "012345670001", + "model": "Gateway", + "name": "Smile P1", + "vendor": "Plugwise" } } } diff --git a/tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json b/tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json index 088a6a609..237826b33 100644 --- a/tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json +++ b/tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json @@ -1,16 +1,18 @@ { - "199aa40f126840f392983d171374ab0b": { - "sensors": { - "net_electricity_point": -2248.0, - "electricity_consumed_point": 0.0, - "net_electricity_cumulative": 1019.101, - "electricity_consumed_peak_cumulative": 1155.295, - "electricity_consumed_off_peak_cumulative": 1642.84, - "electricity_produced_point": 2248.0, - "electricity_produced_peak_cumulative": 1296.336, - "electricity_produced_off_peak_cumulative": 482.698, - "gas_consumed_cumulative": 585.433, - "gas_consumed_interval": 0.0 + "entities": { + "199aa40f126840f392983d171374ab0b": { + "sensors": { + "net_electricity_point": -2248.0, + "electricity_consumed_point": 0.0, + "net_electricity_cumulative": 1019.101, + "electricity_consumed_peak_cumulative": 1155.295, + "electricity_consumed_off_peak_cumulative": 1642.84, + "electricity_produced_point": 2248.0, + "electricity_produced_peak_cumulative": 1296.336, + "electricity_produced_off_peak_cumulative": 482.698, + "gas_consumed_cumulative": 585.433, + "gas_consumed_interval": 0.0 + } } } } diff --git a/tests/data/stretch/stretch_v23.json b/tests/data/stretch/stretch_v23.json index 1c3c8cbb2..79038dbb0 100644 --- a/tests/data/stretch/stretch_v23.json +++ b/tests/data/stretch/stretch_v23.json @@ -1,353 +1,357 @@ { - "0000aaaa0000aaaa0000aaaa0000aa00": { - "dev_class": "gateway", - "firmware": "2.3.12", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "mac_address": "01:23:45:67:89:AB", - "model": "Gateway", - "name": "Stretch", - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670101" - }, - "09c8ce93d7064fa6a233c0e4c2449bfe": { - "dev_class": "lamp", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "kerstboom buiten 043B016", - "zigbee_mac_address": "ABCD012345670A01", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "entities": { + "0000aaaa0000aaaa0000aaaa0000aa00": { + "dev_class": "gateway", + "firmware": "2.3.12", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "mac_address": "01:23:45:67:89:AB", + "model": "Gateway", + "name": "Stretch", + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" }, - "switches": { - "relay": false, - "lock": false - } - }, - "33a1c784a9ff4c2d8766a0212714be09": { - "dev_class": "lighting", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Barverlichting", - "zigbee_mac_address": "ABCD012345670A13", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "09c8ce93d7064fa6a233c0e4c2449bfe": { + "dev_class": "lamp", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "kerstboom buiten 043B016", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" }, - "switches": { - "relay": false, - "lock": false - } - }, - "199fd4b2caa44197aaf5b3128f6464ed": { - "dev_class": "airconditioner", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Airco 25F69E3", - "zigbee_mac_address": "ABCD012345670A10", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 2.06, - "electricity_consumed_interval": 1.62, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "199fd4b2caa44197aaf5b3128f6464ed": { + "dev_class": "airconditioner", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Airco 25F69E3", + "sensors": { + "electricity_consumed": 2.06, + "electricity_consumed_interval": 1.62, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A10" }, - "switches": { - "relay": true, - "lock": false - } - }, - "713427748874454ca1eb4488d7919cf2": { - "dev_class": "freezer", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Leeg 043220D", - "zigbee_mac_address": "ABCD012345670A12", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "24b2ed37c8964c73897db6340a39c129": { + "dev_class": "router", + "firmware": "2011-06-27T10:47:37+02:00", + "hardware": "6539-0700-7325", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle+ type F", + "name": "MK Netwerk 1A4455E", + "sensors": { + "electricity_consumed": 4.63, + "electricity_consumed_interval": 0.65, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "0123456789AB" }, - "switches": { - "relay": false, - "lock": false - } - }, - "fd1b74f59e234a9dae4e23b2b5cf07ed": { - "dev_class": "dryer", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Wasdroger 043AECA", - "zigbee_mac_address": "ABCD012345670A04", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 1.31, - "electricity_consumed_interval": 0.21, - "electricity_produced": 0.0 + "2587a7fcdd7e482dab03fda256076b4b": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "00469CA1", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A16" }, - "switches": { - "relay": true, - "lock": true - } - }, - "c71f1cb2100b42ca942f056dcb7eb01f": { - "dev_class": "tv", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Tv hoek 25F6790", - "zigbee_mac_address": "ABCD012345670A11", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 33.3, - "electricity_consumed_interval": 4.93, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "2cc9a0fe70ef4441a9e4f55dfd64b776": { + "dev_class": "lamp", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Lamp TV 025F698F", + "sensors": { + "electricity_consumed": 4.0, + "electricity_consumed_interval": 0.58, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A15" }, - "switches": { - "relay": true, - "lock": false - } - }, - "2cc9a0fe70ef4441a9e4f55dfd64b776": { - "dev_class": "lamp", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Lamp TV 025F698F", - "zigbee_mac_address": "ABCD012345670A15", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 4.0, - "electricity_consumed_interval": 0.58, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "305452ce97c243c0a7b4ab2a4ebfe6e3": { + "dev_class": "lamp", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Lamp piano 025F6819", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A05" }, - "switches": { - "relay": true, - "lock": false - } - }, - "6518f3f72a82486c97b91e26f2e9bd1d": { - "dev_class": "charger", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Bed 025F6768", - "zigbee_mac_address": "ABCD012345670A14", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "33a1c784a9ff4c2d8766a0212714be09": { + "dev_class": "lighting", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Barverlichting", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A13" }, - "switches": { - "relay": true, - "lock": false - } - }, - "828f6ce1e36744689baacdd6ddb1d12c": { - "dev_class": "washingmachine", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Wasmachine 043AEC7", - "zigbee_mac_address": "ABCD012345670A02", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 3.5, - "electricity_consumed_interval": 0.5, - "electricity_produced": 0.0 + "407aa1c1099d463c9137a3a9eda787fd": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "0043B013", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A09" }, - "switches": { - "relay": true, - "lock": true - } - }, - "71e3e65ffc5a41518b19460c6e8ee34f": { - "dev_class": "tv", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Leeg 043AEC6", - "zigbee_mac_address": "ABCD012345670A08", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "6518f3f72a82486c97b91e26f2e9bd1d": { + "dev_class": "charger", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Bed 025F6768", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A14" }, - "switches": { - "relay": false, - "lock": false - } - }, - "305452ce97c243c0a7b4ab2a4ebfe6e3": { - "dev_class": "lamp", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Lamp piano 025F6819", - "zigbee_mac_address": "ABCD012345670A05", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "713427748874454ca1eb4488d7919cf2": { + "dev_class": "freezer", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Leeg 043220D", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A12" }, - "switches": { - "relay": false, - "lock": false - } - }, - "bc0adbebc50d428d9444a5d805c89da9": { - "dev_class": "watercooker", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Waterkoker 043AF7F", - "zigbee_mac_address": "ABCD012345670A07", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "71e3e65ffc5a41518b19460c6e8ee34f": { + "dev_class": "tv", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Leeg 043AEC6", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": false + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A08" }, - "switches": { - "relay": true, - "lock": false - } - }, - "407aa1c1099d463c9137a3a9eda787fd": { - "dev_class": "zz_misc", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "0043B013", - "zigbee_mac_address": "ABCD012345670A09", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "828f6ce1e36744689baacdd6ddb1d12c": { + "dev_class": "washingmachine", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Wasmachine 043AEC7", + "sensors": { + "electricity_consumed": 3.5, + "electricity_consumed_interval": 0.5, + "electricity_produced": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" }, - "switches": { - "relay": false, - "lock": false - } - }, - "2587a7fcdd7e482dab03fda256076b4b": { - "dev_class": "zz_misc", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "0000-0440-0107", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "00469CA1", - "zigbee_mac_address": "ABCD012345670A16", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 0.0, - "electricity_consumed_interval": 0.0, - "electricity_produced": 0.0 + "a28e6f5afc0e4fc68498c1f03e82a052": { + "dev_class": "lamp", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Lamp bank 25F67F8", + "sensors": { + "electricity_consumed": 4.19, + "electricity_consumed_interval": 0.62, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A03" }, - "switches": { - "relay": true, - "lock": false - } - }, - "a28e6f5afc0e4fc68498c1f03e82a052": { - "dev_class": "lamp", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "Lamp bank 25F67F8", - "zigbee_mac_address": "ABCD012345670A03", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 4.19, - "electricity_consumed_interval": 0.62, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "bc0adbebc50d428d9444a5d805c89da9": { + "dev_class": "watercooker", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Waterkoker 043AF7F", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" }, - "switches": { - "relay": true, - "lock": false - } - }, - "24b2ed37c8964c73897db6340a39c129": { - "dev_class": "router", - "firmware": "2011-06-27T10:47:37+02:00", - "hardware": "6539-0700-7325", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle+ type F", - "name": "MK Netwerk 1A4455E", - "zigbee_mac_address": "0123456789AB", - "vendor": "Plugwise", - "sensors": { - "electricity_consumed": 4.63, - "electricity_consumed_interval": 0.65, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 + "c71f1cb2100b42ca942f056dcb7eb01f": { + "dev_class": "tv", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Tv hoek 25F6790", + "sensors": { + "electricity_consumed": 33.3, + "electricity_consumed_interval": 4.93, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A11" }, - "switches": { - "relay": true, - "lock": true - } - }, - "f7b145c8492f4dd7a4de760456fdef3e": { - "dev_class": "switching", - "model": "Switchgroup", - "name": "Test", - "members": ["407aa1c1099d463c9137a3a9eda787fd"], - "switches": { - "relay": false - } - }, - "fead900a56d3430bb2d53d891f7c0656": { - "dev_class": "heater_central_plug", - "firmware": "2011-06-27T10:52:18+02:00", - "hardware": "6539-0701-4026", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle type F", - "name": "CV-ketel 25F6789", - "sensors": { - "electricity_consumed": 1.56, - "electricity_consumed_interval": 0.04, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "lock": true, - "relay": true + "f7b145c8492f4dd7a4de760456fdef3e": { + "dev_class": "switching", + "members": [ + "407aa1c1099d463c9137a3a9eda787fd" + ], + "model": "Switchgroup", + "name": "Test", + "switches": { + "relay": false + } }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A06" + "fd1b74f59e234a9dae4e23b2b5cf07ed": { + "dev_class": "dryer", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "0000-0440-0107", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "Wasdroger 043AECA", + "sensors": { + "electricity_consumed": 1.31, + "electricity_consumed_interval": 0.21, + "electricity_produced": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A04" + }, + "fead900a56d3430bb2d53d891f7c0656": { + "dev_class": "heater_central_plug", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "CV-ketel 25F6789", + "sensors": { + "electricity_consumed": 1.56, + "electricity_consumed_interval": 0.04, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A06" + } } } diff --git a/tests/data/stretch/stretch_v27_no_domain.json b/tests/data/stretch/stretch_v27_no_domain.json index 55a64d2c8..b11b88814 100644 --- a/tests/data/stretch/stretch_v27_no_domain.json +++ b/tests/data/stretch/stretch_v27_no_domain.json @@ -1,36 +1,274 @@ { - "9b9bfdb3c7ad4ca5817ccaa235f1e094": { - "dev_class": "zz_misc", - "firmware": "2011-06-27T10:47:37+02:00", - "hardware": "6539-0700-7326", - "location": "0000aaaa0000aaaa0000aaaa0000aa00", - "model": "Circle+ type F", - "name": "25881A2", - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A04", - "sensors": { - "electricity_consumed": 13.3, - "electricity_consumed_interval": 7.77, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "relay": true, - "lock": true - } - }, - "8b8d14b242e24cd789743c828b9a2ea9": { - "sensors": { - "electricity_consumed": 1.69 - }, - "switches": { - "lock": false, - "relay": true - } - }, - "d0122ac66eba47b99d8e5fbd1e2f5932": { - "sensors": { - "electricity_consumed_interval": 2.21 + "entities": { + "0000aaaa0000aaaa0000aaaa0000aa00": { + "dev_class": "gateway", + "firmware": "2.7.18", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "mac_address": "01:23:45:67:89:AB", + "model": "Gateway", + "name": "Stretch", + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670101" + }, + "0b078d5862614880bc670cabf9f54b4e": { + "dev_class": "zz_misc", + "firmware": "2011-05-13T09:19:23+02:00", + "hardware": "6539-0701-4023", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "769C03", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A01" + }, + "3b729c63ca41421b9e21264adfa0a4e7": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "261B34C", + "sensors": { + "electricity_consumed": 8.5, + "electricity_consumed_interval": 5.19, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A06" + }, + "4661019bbe7b4a3bbe39f345ca5b5d98": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "25F68CC", + "sensors": { + "electricity_consumed": 0.0, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A02" + }, + "553dfa416df94802851de32913f1ebd3": { + "dev_class": "zz_misc", + "firmware": "2011-05-13T09:19:23+02:00", + "hardware": "6539-0701-4023", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "B7DEED", + "sensors": { + "electricity_consumed": 2.5, + "electricity_consumed_interval": 1.66, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A09" + }, + "5ee135e752034ad2a3e38a407332757f": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "261B329", + "sensors": { + "electricity_consumed": 6.75, + "electricity_consumed_interval": 3.98, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A03" + }, + "7c7f0d3da801402291b057f9ec69b5b6": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "261B34D", + "sensors": { + "electricity_consumed": 7.81, + "electricity_consumed_interval": 4.54, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A08" + }, + "8b8d14b242e24cd789743c828b9a2ea9": { + "dev_class": "zz_misc", + "firmware": "2011-05-13T09:19:23+02:00", + "hardware": "6539-0701-4022", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "76BF93", + "sensors": { + "electricity_consumed": 1.69, + "electricity_consumed_interval": 1.14, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A05" + }, + "8e4ecdcc9094481387e0273437bb51f9": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "25F68C3", + "sensors": { + "electricity_consumed": 4.69, + "electricity_consumed_interval": 2.83, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" + }, + "9b9bfdb3c7ad4ca5817ccaa235f1e094": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:47:37+02:00", + "hardware": "6539-0700-7326", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle+ type F", + "name": "25881A2", + "sensors": { + "electricity_consumed": 13.3, + "electricity_consumed_interval": 7.77, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": true, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A04" + }, + "9db23f92fd114e83acce036b6cb82295": { + "dev_class": "zz_misc", + "firmware": "2011-05-13T09:19:23+02:00", + "hardware": "6539-0701-4023", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "76B2F2", + "sensors": { + "electricity_consumed": 0.63, + "electricity_consumed_interval": 0.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A13" + }, + "ad858f416f3e42e6a25bbd6b18178b0e": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "261B2AE", + "sensors": { + "electricity_consumed": 6.06, + "electricity_consumed_interval": 3.41, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A12" + }, + "d0122ac66eba47b99d8e5fbd1e2f5932": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "25F66AD", + "sensors": { + "electricity_consumed": 3.88, + "electricity_consumed_interval": 2.21, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A10" + }, + "e4172142264f488a99b63c73817c9d21": { + "dev_class": "zz_misc", + "firmware": "2011-06-27T10:52:18+02:00", + "hardware": "6539-0701-4026", + "location": "0000aaaa0000aaaa0000aaaa0000aa00", + "model": "Circle type F", + "name": "261B32A", + "sensors": { + "electricity_consumed": 9.63, + "electricity_consumed_interval": 5.84, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A11" } } } diff --git a/tests/test_anna.py b/tests/test_anna.py index f129e088e..879ede27c 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -2,7 +2,7 @@ import pytest -from .test_init import _LOGGER, TestPlugwise +from .test_init import _LOGGER, TestPlugwise, pw_exceptions SMILE_TYPE = "anna" # Reoccuring constants diff --git a/tests/test_legacy_p1.py b/tests/test_legacy_p1.py index 17e0f5d04..d569ca52b 100644 --- a/tests/test_legacy_p1.py +++ b/tests/test_legacy_p1.py @@ -52,7 +52,7 @@ async def test_connect_smile_p1_v2_2(self): ) await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.device_items == 26 + assert self.entity_items == 26 # Now change some data and change directory reading xml from # emulating reading newer dataset after an update_interval diff --git a/tests/test_legacy_stretch.py b/tests/test_legacy_stretch.py index f50decf74..961bb6378 100644 --- a/tests/test_legacy_stretch.py +++ b/tests/test_legacy_stretch.py @@ -69,7 +69,7 @@ async def test_connect_stretch_v23(self): ) await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.device_items == 243 + assert self.entity_items == 243 switch_change = await self.tinker_switch( smile, "2587a7fcdd7e482dab03fda256076b4b" @@ -104,7 +104,7 @@ async def test_connect_stretch_v27_no_domain(self): ) await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert self.device_items == 190 + assert self.entity_items == 190 _LOGGER.info(" # Assert no master thermostat") switch_change = await self.tinker_switch( diff --git a/tests/test_p1.py b/tests/test_p1.py index b2e8deb86..3cd72257e 100644 --- a/tests/test_p1.py +++ b/tests/test_p1.py @@ -44,40 +44,6 @@ async def test_connect_p1v4_442_single(self): await smile.close_connection() await self.disconnect(server, client) - @pytest.mark.asyncio - async def test_connect_p1v4_442_single(self): - """Test a P1 firmware 4.4 single-phase setup.""" - self.smile_setup = "p1v4_442_single" - - testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - server, smile, client = await self.connect_wrapper() - assert smile.smile_hostname == "smile000000" - - self.validate_test_basics( - _LOGGER, - smile, - smile_type="power", - smile_version="4.4.2", - ) - - await self.device_test(smile, "2022-05-16 00:00:01", testdata) - assert smile.gateway_id == "a455b61e52394b2db5081ce025a430f3" - assert self.device_items == 32 - assert not self.notifications - - # Now change some data and change directory reading xml from - # emulating reading newer dataset after an update_interval - testdata_updated = self.load_testdata( - SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA" - ) - self.smile_setup = "updated/p1v4_442_single" - await self.device_test( - smile, "2022-05-16 00:00:01", testdata_updated, initialize=False - ) - - await smile.close_connection() - await self.disconnect(server, client) - @pytest.mark.asyncio async def test_connect_p1v4_442_triple(self): """Test a P1 firmware 4 3-phase setup.""" @@ -96,7 +62,7 @@ async def test_connect_p1v4_442_triple(self): await self.device_test(smile, "2022-05-16 00:00:01", testdata) assert smile.gateway_id == "03e65b16e4b247a29ae0d75a78cb492e" - assert self.device_items == 41 + assert self.entity_items == 41 assert self.notifications await smile.close_connection() From feebc6a739b6772e513530f2a77ff6fc1f1f2df3 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 19:51:11 +0100 Subject: [PATCH 074/106] Revert full test-output --- scripts/tests_and_coverage.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index 081d8b6bf..cfdc15bf5 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -31,8 +31,7 @@ set +u if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "test_and_coverage" ] ; then # Python tests (rerun with debug if failures) - # PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || - PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ + PYTHONPATH=$(pwd) pytest -qx tests/ --cov='.' --no-cov-on-fail --cov-report term-missing || PYTHONPATH=$(pwd) pytest -xrpP --log-level debug tests/ fi if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "linting" ] ; then From ba7678af01fb3f346e1ed8c1a79e901cf813ff3d Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 19:54:22 +0100 Subject: [PATCH 075/106] Save --- .../anna_without_boiler_fw441/all_data.json | 2 +- tests/data/anna/anna_v4_no_tag.json | 98 +++++++++++++++++++ tests/test_anna.py | 14 +-- 3 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 tests/data/anna/anna_v4_no_tag.json diff --git a/fixtures/anna_without_boiler_fw441/all_data.json b/fixtures/anna_without_boiler_fw441/all_data.json index 12b5b0336..05b9c08d5 100644 --- a/fixtures/anna_without_boiler_fw441/all_data.json +++ b/fixtures/anna_without_boiler_fw441/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "7ffbb3ab4b6c4ab2915d7510f7bf8fe9": { "active_preset": "home", "available_schedules": [ diff --git a/tests/data/anna/anna_v4_no_tag.json b/tests/data/anna/anna_v4_no_tag.json new file mode 100644 index 000000000..7ce51a609 --- /dev/null +++ b/tests/data/anna/anna_v4_no_tag.json @@ -0,0 +1,98 @@ +{ + "entities": { + "01b85360fdd243d0aaad4d6ac2a5ba7e": { + "active_preset": "home", + "available_schedules": [ + "Standaard", + "Thuiswerken", + "off" + ], + "climate_mode": "auto", + "dev_class": "thermostat", + "firmware": "2018-02-08T11:15:53+01:00", + "hardware": "6539-1301-5002", + "location": "eb5309212bf5407bb143e5bfa3b18aee", + "model": "ThermoTouch", + "name": "Anna", + "preset_modes": [ + "vacation", + "no_frost", + "away", + "asleep", + "home" + ], + "select_schedule": "Thuiswerken", + "sensors": { + "illuminance": 60.0, + "setpoint": 20.5, + "temperature": 20.6 + }, + "temperature_offset": { + "lower_bound": -2.0, + "resolution": 0.1, + "setpoint": 0.0, + "upper_bound": 2.0 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.1, + "setpoint": 20.5, + "upper_bound": 30.0 + }, + "vendor": "Plugwise" + }, + "0466eae8520144c78afb29628384edeb": { + "binary_sensors": { + "plugwise_notification": false + }, + "dev_class": "gateway", + "firmware": "4.0.15", + "hardware": "AME Smile 2.0 board", + "location": "94c107dc6ac84ed98e9f68c0dd06bf71", + "mac_address": "012345670001", + "model": "Gateway", + "model_id": "smile_thermo", + "name": "Smile Anna", + "sensors": { + "outdoor_temperature": 7.44 + }, + "vendor": "Plugwise" + }, + "cd0e6156b1f04d5f952349ffbe397481": { + "available": true, + "binary_sensors": { + "dhw_state": false, + "flame_state": false, + "heating_state": true + }, + "dev_class": "heater_central", + "location": "94c107dc6ac84ed98e9f68c0dd06bf71", + "max_dhw_temperature": { + "lower_bound": 30.0, + "resolution": 0.01, + "setpoint": 60.0, + "upper_bound": 60.0 + }, + "maximum_boiler_temperature": { + "lower_bound": 0.0, + "resolution": 1.0, + "setpoint": 70.0, + "upper_bound": 100.0 + }, + "model": "Generic heater", + "model_id": "2.32", + "name": "OpenTherm", + "sensors": { + "intended_boiler_temperature": 39.9, + "modulation_level": 0.0, + "return_temperature": 32.0, + "water_pressure": 2.2, + "water_temperature": 45.0 + }, + "switches": { + "dhw_cm_switch": false + }, + "vendor": "Bosch Thermotechniek B.V." + } + } +} diff --git a/tests/test_anna.py b/tests/test_anna.py index 879ede27c..1bc6e1cbf 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -121,13 +121,15 @@ async def test_connect_anna_v4_dhw(self): @pytest.mark.asyncio async def test_connect_anna_v4_no_tag(self): """Test an Anna firmware 4 setup - missing tag (issue).""" - testdata = { - # Anna - "01b85360fdd243d0aaad4d6ac2a5ba7e": { - "active_preset": "home", - } - } self.smile_setup = "anna_v4_no_tag" + + testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) + #testdata = { + # # Anna + # "01b85360fdd243d0aaad4d6ac2a5ba7e": { + # "active_preset": "home", + # } + #} server, smile, client = await self.connect_wrapper() assert smile.smile_hostname == "smile000000" From d0ee25dce688f95b13e0a3cd6d4c0cc39934a317 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 20:02:26 +0100 Subject: [PATCH 076/106] Modify adam_multiple_devs-per_zone Put two Toms in one zone --- .../data/adam/adam_multiple_devices_per_zone.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/data/adam/adam_multiple_devices_per_zone.json b/tests/data/adam/adam_multiple_devices_per_zone.json index 790223e09..ede5d1052 100644 --- a/tests/data/adam/adam_multiple_devices_per_zone.json +++ b/tests/data/adam/adam_multiple_devices_per_zone.json @@ -212,7 +212,7 @@ "location": "08963fec7c53423ca5680aa4cb502c63", "model": "Tom/Floor", "model_id": "106-03", - "name": "Thermostatic Radiator Badkamer", + "name": "Thermostatic Radiator Badkamer 1", "sensors": { "battery": 51, "setpoint": 14.0, @@ -576,13 +576,13 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "zone_thermostat", - "firmware": "2016-10-27T02:00:00+02:00", - "hardware": "255", + "dev_class": "thermostatic_radiator_valve", + "firmware": "2019-03-27T01:00:00+01:00", + "hardware": "1", "location": "08963fec7c53423ca5680aa4cb502c63", - "model": "Lisa", - "model_id": "158-01", - "name": "Zone Thermostat Badkamer", + "model": "Tom/Floor", + "model_id": "106-03", + "name": "Thermostatic Radiator Badkamer 2", "sensors": { "battery": 92, "setpoint": 14.0, From df7d91004e98a72b909324043f0fbec2a3111a40 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 20:06:07 +0100 Subject: [PATCH 077/106] Modify related userdata --- .../core.domain_objects.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/userdata/adam_multiple_devices_per_zone/core.domain_objects.xml b/userdata/adam_multiple_devices_per_zone/core.domain_objects.xml index 802c29970..e38e3a9b1 100644 --- a/userdata/adam_multiple_devices_per_zone/core.domain_objects.xml +++ b/userdata/adam_multiple_devices_per_zone/core.domain_objects.xml @@ -1937,9 +1937,9 @@ - Zone Thermostat Badkamer - A zone thermostat regulates the temperature in a heating zone (generally a room). - zone_thermostat + Thermostatic Radiator Badkamer 2 + A thermostatic radiator valve allows hot water to be pumped into its radiator based on ambient temperature and the local temperature setpoint. + thermostatic_radiator_valve 2019-01-25T08:21:56.648+01:00 2020-03-20T17:46:28.412+01:00 @@ -2094,7 +2094,7 @@ - Thermostatic Radiator Badkamer + Thermostatic Radiator Badkamer 1 A thermostatic radiator valve allows hot water to be pumped into its radiator based on ambient temperature and the local temperature setpoint. thermostatic_radiator_valve 2018-12-10T10:52:45.271+01:00 From c708f28a5aa30a23a07522132eb848f4daaa8154 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 20:07:39 +0100 Subject: [PATCH 078/106] Save updated fixture and test-json --- .../adam_multiple_devices_per_zone/all_data.json | 13 ++++++------- .../data/adam/adam_multiple_devices_per_zone.json | 15 +++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/fixtures/adam_multiple_devices_per_zone/all_data.json b/fixtures/adam_multiple_devices_per_zone/all_data.json index 1f6ee01f4..7a99dd028 100644 --- a/fixtures/adam_multiple_devices_per_zone/all_data.json +++ b/fixtures/adam_multiple_devices_per_zone/all_data.json @@ -53,11 +53,10 @@ }, "thermostats": { "primary": [ - "f1fee6043d3642a9b0a65297455f008e" - ], - "secondary": [ + "f1fee6043d3642a9b0a65297455f008e", "680423ff840043738f42cc7f1ff97a36" - ] + ], + "secondary": [] } }, "12493538af164a409c6a1c79e38afe1c": { @@ -212,7 +211,7 @@ "location": "08963fec7c53423ca5680aa4cb502c63", "model": "Tom/Floor", "model_id": "106-03", - "name": "Thermostatic Radiator Badkamer", + "name": "Thermostatic Radiator Badkamer 1", "sensors": { "battery": 51, "setpoint": 14.0, @@ -576,13 +575,13 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "zone_thermostat", + "dev_class": "thermostatic_radiator_valve", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", "location": "08963fec7c53423ca5680aa4cb502c63", "model": "Lisa", "model_id": "158-01", - "name": "Zone Thermostat Badkamer", + "name": "Thermostatic Radiator Badkamer 2", "sensors": { "battery": 92, "setpoint": 14.0, diff --git a/tests/data/adam/adam_multiple_devices_per_zone.json b/tests/data/adam/adam_multiple_devices_per_zone.json index ede5d1052..8003bdab3 100644 --- a/tests/data/adam/adam_multiple_devices_per_zone.json +++ b/tests/data/adam/adam_multiple_devices_per_zone.json @@ -53,11 +53,10 @@ }, "thermostats": { "primary": [ - "f1fee6043d3642a9b0a65297455f008e" - ], - "secondary": [ + "f1fee6043d3642a9b0a65297455f008e", "680423ff840043738f42cc7f1ff97a36" - ] + ], + "secondary": [] } }, "12493538af164a409c6a1c79e38afe1c": { @@ -577,11 +576,11 @@ "low_battery": false }, "dev_class": "thermostatic_radiator_valve", - "firmware": "2019-03-27T01:00:00+01:00", - "hardware": "1", + "firmware": "2016-10-27T02:00:00+02:00", + "hardware": "255", "location": "08963fec7c53423ca5680aa4cb502c63", - "model": "Tom/Floor", - "model_id": "106-03", + "model": "Lisa", + "model_id": "158-01", "name": "Thermostatic Radiator Badkamer 2", "sensors": { "battery": 92, From 535f3a7705b0f4c475a36277a64a3a194b95969e Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 20:16:36 +0100 Subject: [PATCH 079/106] Update CHANGELOG --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42438d887..6316f6cdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # Changelog -## Ongoing +## v1.6.0 -- Implement collection of zone data: Plugwise thermostat representations are zone/location-based. +- New Feature: implement collection of location/zone data: Plugwise Adam thermostat representations are zone-based + in case there are more than one equal type of thermostats in one zone (e.g. 2 Tom's and no Lisa). +- In PlugwiseData the `devices`-dict is replaced by an `entities`-dict. ## v1.5.2 From 65f2c77c817b014e05b411ea76387ab5cd67916b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 20:17:14 +0100 Subject: [PATCH 080/106] Bump to a2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1a94ab6d9..4e7c6b7b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.6.0a1" +version = "1.6.0a2" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From e35f4f59ac575d5b4ffc4a44503b9b0c36300403 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 21 Nov 2024 20:19:20 +0100 Subject: [PATCH 081/106] Fixes --- plugwise/common.py | 4 ++-- plugwise/legacy/helper.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugwise/common.py b/plugwise/common.py index c3bba8939..2abaef5bd 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -137,11 +137,11 @@ def _count_data_items(self, data: GwEntityData) -> None: Also, count the remaining single data items, the amount of dicts present have already been pre-subtracted in the previous step. """ if "binary_sensors" in data: - self._count += len(data["binary_sensors"]) -1 + self._count += len(data["binary_sensors"]) - 1 if "sensors" in data: self._count += len(data["sensors"]) - 1 if "switches" in data: - self._count += len(data["switches"]) -1 + self._count += len(data["switches"]) - 1 self._count += len(data) def _power_data_peak_value(self, loc: Munch, legacy: bool) -> Munch: diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 6ea9be3e9..ab0a10f89 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -89,7 +89,7 @@ def __init__(self) -> None: self.smile_name: str self.smile_type: str self.smile_zigbee_mac_address: str | None - self.zone_data: dict[str, GwEntityData] = {} + self.zones: dict[str, GwEntityData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: From 9b677e2dc53248b18a52d0ca0d978b1839132967 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 10:10:13 +0100 Subject: [PATCH 082/106] Update manual_fixtures script --- scripts/manual_fixtures.py | 203 +++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 100 deletions(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index e8236cb1f..dcdc1b800 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -35,9 +35,9 @@ def json_writer(manual_name: str, all_data: dict) -> None: adam_multiple_devices_per_zone = base.copy() -# Change schedule to not present for "e7693eb9582644e5b865dba8d4447cf1" -adam_multiple_devices_per_zone["device_zones"]["e7693eb9582644e5b865dba8d4447cf1"].pop("available_schedules") -adam_multiple_devices_per_zone["device_zones"]["e7693eb9582644e5b865dba8d4447cf1"].pop("select_schedule") +# Change schedule to not present for "446ac08dd04d4eff8ac57489757b7314" +adam_multiple_devices_per_zone["entities"]["446ac08dd04d4eff8ac57489757b7314"].pop("available_schedules") +adam_multiple_devices_per_zone["entities"]["446ac08dd04d4eff8ac57489757b7314"].pop("select_schedule") json_writer("m_adam_multiple_devices_per_zone", adam_multiple_devices_per_zone) @@ -49,8 +49,8 @@ def json_writer(manual_name: str, all_data: dict) -> None: adam_jip = base.copy() -# Change mode to off for "1346fbd8498d4dbcab7e18d51b771f3d" -adam_jip["device_zones"]["1346fbd8498d4dbcab7e18d51b771f3d"]["climate_mode"] = "off" +# Change mode to off for "06aecb3d00354375924f50c47af36bd2" +adam_jip["entities"]["06aecb3d00354375924f50c47af36bd2"]["climate_mode"] = "off" json_writer("m_adam_jip", adam_jip) @@ -70,86 +70,86 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling["gateway"]["item_count"] = 89 # Remove devices "67d73d0bd469422db25a618a5fb8eeb0" and "10016900610d4c7481df78c89606ef22" from anywhere -m_adam_cooling["device_zones"].pop("67d73d0bd469422db25a618a5fb8eeb0") -m_adam_cooling["device_zones"].pop("10016900610d4c7481df78c89606ef22") +m_adam_cooling["entities"].pop("67d73d0bd469422db25a618a5fb8eeb0") +m_adam_cooling["entities"].pop("10016900610d4c7481df78c89606ef22") -# Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ +# Correct setpoint for device "ad4838d7d35c4d6ea796ee12ae5aedf8" and zone "f2bf9048bef64cc5b6d5110154e33c81" +m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "setpoint" ] = 23.5 - -# Add new key available -m_adam_cooling["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["available"] = True - -m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ + "setpoint" +] = 23.5 +m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ + "temperature" +] = 25.8 +m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ + "temperature" +] = 25.8 +m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"][ "select_schedule" ] = "off" -m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"][ "control_state" ] = "cooling" -m_adam_cooling["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" +m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" -# (following diff, now 2954 is removed) -# Remove device "29542b2b6a6a4169acecc15c72a599b8" from anywhere -m_adam_cooling["device_zones"].pop("29542b2b6a6a4169acecc15c72a599b8") +# Add new key available +m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["available"] = True -# Back at ad48 -m_adam_cooling["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ - "temperature" -] = 25.8 -m_adam_cooling["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ - "setpoint" -] = 23.5 # (again, following diff) # Remove device "2568cc4b9c1e401495d4741a5f89bee1" from anywhere -m_adam_cooling["device_zones"].pop("2568cc4b9c1e401495d4741a5f89bee1") +m_adam_cooling["entities"].pop("2568cc4b9c1e401495d4741a5f89bee1") # Remove device "854f8a9b0e7e425db97f1f110e1ce4b3" from anywhere -m_adam_cooling["device_zones"].pop("854f8a9b0e7e425db97f1f110e1ce4b3") +m_adam_cooling["entities"].pop("854f8a9b0e7e425db97f1f110e1ce4b3") # Go for 1772 -m_adam_cooling["device_zones"]["1772a4ea304041adb83f357b751341ff"]["sensors"].pop("setpoint") -m_adam_cooling["device_zones"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ +m_adam_cooling["entities"]["1772a4ea304041adb83f357b751341ff"]["sensors"].pop("setpoint") +m_adam_cooling["entities"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 21.6 # Go for e2f4 -m_adam_cooling["device_zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ +m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ + "setpoint" +] = 25.0 +m_adam_cooling["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "setpoint" ] = 25.0 -m_adam_cooling["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ + "temperature" +] = 23.9 +m_adam_cooling["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "temperature" ] = 23.9 -m_adam_cooling["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ - "setpoint" -] = 23.5 # Go for da22 -m_adam_cooling["device_zones"]["da224107914542988a88561b4452b0f6"][ +m_adam_cooling["entities"]["da224107914542988a88561b4452b0f6"][ "select_regulation_mode" ] = "cooling" -m_adam_cooling["device_zones"]["da224107914542988a88561b4452b0f6"][ +m_adam_cooling["entities"]["da224107914542988a88561b4452b0f6"][ "regulation_modes" ].append("cooling") -m_adam_cooling["device_zones"]["da224107914542988a88561b4452b0f6"]["sensors"][ +m_adam_cooling["entities"]["da224107914542988a88561b4452b0f6"]["sensors"][ "outdoor_temperature" ] = 29.65 # Go for 056e -m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "cooling_state" ] = True -m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = False -m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "flame_state" ] = False -m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "water_temperature" ] = 19.0 -m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 17.5 @@ -163,73 +163,78 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_heating["gateway"]["cooling_present"] = False # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_heating["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ +m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ "setpoint" ] = 20.0 - -m_adam_heating["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"][ - "control_state" -] = "preheating" - -m_adam_heating["device_zones"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" - -# Back at ad48 -m_adam_heating["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_heating["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "setpoint" ] = 20.0 -m_adam_heating["device_zones"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ + "temperature" +] = 19.1 +m_adam_heating["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "temperature" ] = 19.1 +m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"][ + "control_state" +] = "preheating" +m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" + # Go for 1772 -m_adam_heating["device_zones"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ +m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ + "temperature" +] = 18.6 +m_adam_heating["entities"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 18.6 # Go for e2f4 -m_adam_heating["device_zones"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ +m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 15.0 - -m_adam_heating["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"][ - "control_state" -] = "off" - -m_adam_heating["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_heating["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "setpoint" ] = 15.0 -m_adam_heating["device_zones"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ + "temperature" +] = 17.9 +m_adam_heating["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "temperature" ] = 17.9 +m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"][ + "control_state" +] = "off" + # Go for da22 -m_adam_heating["device_zones"]["da224107914542988a88561b4452b0f6"][ +m_adam_heating["entities"]["da224107914542988a88561b4452b0f6"][ "select_regulation_mode" ] = "heating" -m_adam_heating["device_zones"]["da224107914542988a88561b4452b0f6"][ +m_adam_heating["entities"]["da224107914542988a88561b4452b0f6"][ "regulation_modes" ].remove("cooling") -m_adam_heating["device_zones"]["da224107914542988a88561b4452b0f6"]["sensors"][ +m_adam_heating["entities"]["da224107914542988a88561b4452b0f6"]["sensors"][ "outdoor_temperature" ] = -1.25 # Go for 056e -m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"].pop( +m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"].pop( "cooling_state" ) -m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = True -m_adam_cooling["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "flame_state" ] = False -m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "water_temperature" ] = 37.0 -m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 38.1 -m_adam_heating["device_zones"]["056ee145a816487eaa69243c3280f8bf"]["max_dhw_temperature"] = { +m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["max_dhw_temperature"] = { "setpoint": 60.0, "lower_bound": 40.0, "upper_bound": 60.0, @@ -251,60 +256,58 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_anna_heatpump_cooling["gateway"]["cooling_present"] = True # Go for 1cbf -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "model" ] = "Generic heater/cooler" - -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["cooling_enabled"] = True -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["heating_state"] = False -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["cooling_state"] = True -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "water_temperature" ] = 22.7 -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "dhw_temperature" ] = 41.5 -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "intended_boiler_temperature" ] = 0.0 -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "modulation_level" ] = 40 -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "return_temperature" ] = 23.8 -m_anna_heatpump_cooling["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "outdoor_air_temperature" ] = 28.0 - # Go for 015a -m_anna_heatpump_cooling["device_zones"]["015ae9ea3f964e668e490fa39da3870b"]["sensors"][ +m_anna_heatpump_cooling["entities"]["015ae9ea3f964e668e490fa39da3870b"]["sensors"][ "outdoor_temperature" ] = 28.2 # Go for 3cb7 -m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ +m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ "setpoint_low" ] = 20.5 -m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ +m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ "setpoint_high" ] = 30.0 -m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "temperature" ] = 26.3 -m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "setpoint_low" ] = 20.5 -m_anna_heatpump_cooling["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "setpoint_high" ] = 30.0 @@ -315,39 +318,39 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_anna_heatpump_idle = m_anna_heatpump_cooling.copy() # Go for 1cbf -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ "compressor_state" ] = False -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ "cooling_state" ] = False -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "water_temperature" ] = 19.1 -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "dhw_temperature" ] = 46.3 -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "intended_boiler_temperature" ] = 18.0 -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "modulation_level" ] = 0 -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "return_temperature" ] = 22.0 -m_anna_heatpump_idle["device_zones"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "outdoor_air_temperature" ] = 28.2 # Go for 3cb7 -m_anna_heatpump_idle["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_idle["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "temperature" ] = 23.0 -m_anna_heatpump_idle["device_zones"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_idle["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "cooling_activation_outdoor_temperature" ] = 25.0 From 3ea59801fde9921723e4774af14d4a7a8b5a7ed0 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 10:17:42 +0100 Subject: [PATCH 083/106] Fix double --- scripts/manual_fixtures.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index dcdc1b800..5599201a8 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -182,12 +182,10 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" # Go for 1772 -m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ - "temperature" -] = 18.6 m_adam_heating["entities"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 18.6 +# Related zone temperature is set below # Go for e2f4 m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ From 9125fe6045343899b14e2fb721221d1ac8d61105 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 10:21:01 +0100 Subject: [PATCH 084/106] Another fix --- scripts/manual_fixtures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 5599201a8..e7bcf59bf 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -223,7 +223,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = True -m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "flame_state" ] = False m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ From 65feb5aa51aecb5c8825e1904e0388100177d6b8 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 10:22:44 +0100 Subject: [PATCH 085/106] Cleanup --- plugwise/legacy/helper.py | 1 - tests/test_anna.py | 6 ------ 2 files changed, 7 deletions(-) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index ab0a10f89..43aa224b8 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -89,7 +89,6 @@ def __init__(self) -> None: self.smile_name: str self.smile_type: str self.smile_zigbee_mac_address: str | None - self.zones: dict[str, GwEntityData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: diff --git a/tests/test_anna.py b/tests/test_anna.py index 1bc6e1cbf..4f5c6e46b 100644 --- a/tests/test_anna.py +++ b/tests/test_anna.py @@ -124,12 +124,6 @@ async def test_connect_anna_v4_no_tag(self): self.smile_setup = "anna_v4_no_tag" testdata = self.load_testdata(SMILE_TYPE, self.smile_setup) - #testdata = { - # # Anna - # "01b85360fdd243d0aaad4d6ac2a5ba7e": { - # "active_preset": "home", - # } - #} server, smile, client = await self.connect_wrapper() assert smile.smile_hostname == "smile000000" From 82e35633b49212d217e8db934c8f150becb9db18 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 13:46:14 +0100 Subject: [PATCH 086/106] Extend internal-use selfs --- plugwise/__init__.py | 6 +++--- plugwise/data.py | 8 ++++---- plugwise/helper.py | 14 +++++++------- plugwise/legacy/helper.py | 8 ++++---- plugwise/legacy/smile.py | 4 ++-- plugwise/smile.py | 6 +++--- tests/test_init.py | 2 +- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index bf95ba661..8177f065d 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -69,6 +69,7 @@ def __init__( self._elga = False self._is_thermostat = False self._last_active: dict[str, str | None] = {} + self._loc_data: dict[str, ThermoLoc] = {} self._on_off_device = False self._opentherm_device = False self._schedule_old_states: dict[str, dict[str, str]] = {} @@ -76,7 +77,6 @@ def __init__( self._stretch_v2 = False self._target_smile: str = NONE self.gateway_id: str = NONE - self.loc_data: dict[str, ThermoLoc] = {} self.smile_fw_version: Version | None = None self.smile_hostname: str = NONE self.smile_hw_version: str | None = None @@ -134,11 +134,11 @@ async def connect(self) -> Version | None: self._elga, self._is_thermostat, self._last_active, + self._loc_data, self._on_off_device, self._opentherm_device, self._schedule_old_states, self.gateway_id, - self.loc_data, self.smile_fw_version, self.smile_hostname, self.smile_hw_version, @@ -155,11 +155,11 @@ async def connect(self) -> Version | None: self._request, self._websession, self._is_thermostat, + self._loc_data, self._on_off_device, self._opentherm_device, self._stretch_v2, self._target_smile, - self.loc_data, self.smile_fw_version, self.smile_hostname, self.smile_hw_version, diff --git a/plugwise/data.py b/plugwise/data.py index e423d804b..22a86e901 100644 --- a/plugwise/data.py +++ b/plugwise/data.py @@ -36,7 +36,7 @@ def _all_entity_data(self) -> None: self._update_gw_entities() if self.smile(ADAM): self._update_zones() - self.gw_entities.update(self.zones) + self.gw_entities.update(self._zones) self.gw_data.update( { @@ -55,9 +55,9 @@ def _all_entity_data(self) -> None: def _update_zones(self) -> None: """Helper-function for _all_entity_data() and async_update(). - Collect data for each zone/location and add to self.zones. + Collect data for each zone/location and add to self._zones. """ - for location_id, zone in self.zones.items(): + for location_id, zone in self._zones.items(): data = self._get_location_data(location_id) zone.update(data) @@ -158,7 +158,7 @@ def _get_location_data(self, loc_id: str) -> GwEntityData: Provide entity-data, based on Location ID (= loc_id). """ - zone = self.zones[loc_id] + zone = self._zones[loc_id] data = self._get_zone_data(loc_id) if ctrl_state := self._control_state(loc_id): data["control_state"] = ctrl_state diff --git a/plugwise/helper.py b/plugwise/helper.py index 09850a4a8..547ab6e24 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -224,6 +224,7 @@ def __init__(self) -> None: self._is_thermostat: bool self._last_active: dict[str, str | None] self._last_modified: dict[str, str] = {} + self._loc_data: dict[str, ThermoLoc] self._notifications: dict[str, dict[str, str]] = {} self._on_off_device: bool self._opentherm_device: bool @@ -251,7 +252,6 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} self.gw_entities: dict[str, GwEntityData] = {} - self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None self.smile_mac_address: str | None @@ -261,7 +261,7 @@ def __init__(self) -> None: self.smile_type: str self.smile_zigbee_mac_address: str | None self.therms_with_offset_func: list[str] = [] - self.zones: dict[str, GwEntityData] = {} + self._zones: dict[str, GwEntityData] = {} SmileCommon.__init__(self) def _all_appliances(self) -> None: @@ -354,11 +354,11 @@ def _all_locations(self) -> None: if loc.name == "Home": self._home_location = loc.loc_id - self.loc_data[loc.loc_id] = {"name": loc.name} + self._loc_data[loc.loc_id] = {"name": loc.name} def _p1_smartmeter_info_finder(self, appl: Munch) -> None: """Collect P1 DSMR SmartMeter info.""" - loc_id = next(iter(self.loc_data.keys())) + loc_id = next(iter(self._loc_data.keys())) location = self._domain_objects.find(f'./location[@id="{loc_id}"]') locator = MODULE_LOCATOR module_data = self._get_module_data(location, locator) @@ -488,7 +488,7 @@ def _get_zone_data(self, loc_id: str) -> GwEntityData: Collect the location-data based on location id. """ data: GwEntityData = {"sensors": {}} - zone = self.zones[loc_id] + zone = self._zones[loc_id] measurements = ZONE_MEASUREMENTS if ( location := self._domain_objects.find(f'./location[@id="{loc_id}"]') @@ -861,7 +861,7 @@ def _scan_thermostats(self) -> None: for loc_id, loc_data in list(self._thermo_locs.items()): if loc_data["primary_prio"] != 0: - self.zones[loc_id] = { + self._zones[loc_id] = { "dev_class": "climate", "name": loc_data["name"], "thermostats": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} @@ -874,7 +874,7 @@ def _match_locations(self) -> dict[str, ThermoLoc]: Match appliances with locations. """ matched_locations: dict[str, ThermoLoc] = {} - for location_id, location_details in self.loc_data.items(): + for location_id, location_details in self._loc_data.items(): for appliance_details in self.gw_entities.values(): if appliance_details["location"] == location_id: location_details.update( diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index 43aa224b8..861b943dd 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -68,6 +68,7 @@ def __init__(self) -> None: self._home_location: str self._is_thermostat: bool self._last_modified: dict[str, str] = {} + self._loc_data: dict[str, ThermoLoc] self._locations: etree self._modules: etree self._notifications: dict[str, dict[str, str]] = {} @@ -81,7 +82,6 @@ def __init__(self) -> None: self.gateway_id: str self.gw_data: GatewayData = {} self.gw_entities: dict[str, GwEntityData] = {} - self.loc_data: dict[str, ThermoLoc] self.smile_fw_version: Version | None self.smile_hw_version: str | None self.smile_mac_address: str | None @@ -161,7 +161,7 @@ def _all_locations(self) -> None: # Legacy Anna without outdoor_temp and Stretches have no locations, create fake location-data if not (locations := self._locations.findall("./location")): self._home_location = FAKE_LOC - self.loc_data[FAKE_LOC] = {"name": "Home"} + self._loc_data[FAKE_LOC] = {"name": "Home"} return for location in locations: @@ -182,7 +182,7 @@ def _all_locations(self) -> None: loc.name = "Home" self._home_location = loc.loc_id - self.loc_data[loc.loc_id] = {"name": loc.name} + self._loc_data[loc.loc_id] = {"name": loc.name} def _create_legacy_gateway(self) -> None: """Create the (missing) gateway entities for legacy Anna, P1 and Stretch. @@ -251,7 +251,7 @@ def _energy_entity_info_finder(self, appliance: etree, appl: Munch) -> Munch: def _p1_smartmeter_info_finder(self, appl: Munch) -> None: """Collect P1 DSMR Smartmeter info.""" - loc_id = next(iter(self.loc_data.keys())) + loc_id = next(iter(self._loc_data.keys())) appl.available = None appl.entity_id = loc_id appl.location = loc_id diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index a08f42446..3c033f705 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -44,11 +44,11 @@ def __init__( request: Callable[..., Awaitable[Any]], websession: aiohttp.ClientSession, _is_thermostat: bool, + _loc_data: dict[str, ThermoLoc], _on_off_device: bool, _opentherm_device: bool, _stretch_v2: bool, _target_smile: str, - loc_data: dict[str, ThermoLoc], smile_fw_version: Version | None, smile_hostname: str, smile_hw_version: str | None, @@ -65,11 +65,11 @@ def __init__( self._cooling_present = False self._is_thermostat = _is_thermostat + self._loc_data = _loc_data self._on_off_device = _on_off_device self._opentherm_device = _opentherm_device self._stretch_v2 = _stretch_v2 self._target_smile = _target_smile - self.loc_data = loc_data self.request = request self.smile_fw_version = smile_fw_version self.smile_hostname = smile_hostname diff --git a/plugwise/smile.py b/plugwise/smile.py index 6a062d215..9cc08f053 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -53,11 +53,11 @@ def __init__( _elga: bool, _is_thermostat: bool, _last_active: dict[str, str | None], + _loc_data: dict[str, ThermoLoc], _on_off_device: bool, _opentherm_device: bool, _schedule_old_states: dict[str, dict[str, str]], gateway_id: str, - loc_data: dict[str, ThermoLoc], smile_fw_version: Version | None, smile_hostname: str | None, smile_hw_version: str | None, @@ -76,11 +76,11 @@ def __init__( self._elga = _elga self._is_thermostat = _is_thermostat self._last_active = _last_active + self._loc_data = _loc_data self._on_off_device = _on_off_device self._opentherm_device = _opentherm_device self._schedule_old_states = _schedule_old_states self.gateway_id = gateway_id - self.loc_data = loc_data self.request = request self.smile_fw_version = smile_fw_version self.smile_hostname = smile_hostname @@ -126,7 +126,7 @@ async def async_update(self) -> PlugwiseData: """Perform an incremental update for updating the various device states.""" self.gw_data: GatewayData = {} self.gw_entities: dict[str, GwEntityData] = {} - self.zones: dict[str, GwEntityData] = {} + self._zones: dict[str, GwEntityData] = {} try: await self.full_xml_update() self.get_all_gateway_entities() diff --git a/tests/test_init.py b/tests/test_init.py index 3666ee372..eabee19c7 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -642,7 +642,7 @@ def test_and_assert(test_dict, data, header): return # pragma: no cover self.entity_list = list(data.entities.keys()) - location_list = smile.loc_data + location_list = smile._loc_data _LOGGER.info("Gateway id = %s", data.gateway["gateway_id"]) _LOGGER.info("Hostname = %s", smile.smile_hostname) From f79fa76f24e3045af304c59857686b81b8420165 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 17:16:03 +0100 Subject: [PATCH 087/106] Enable manual fixture generation --- scripts/tests_and_coverage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/tests_and_coverage.sh b/scripts/tests_and_coverage.sh index cfdc15bf5..c0d0d4f48 100755 --- a/scripts/tests_and_coverage.sh +++ b/scripts/tests_and_coverage.sh @@ -49,9 +49,9 @@ fi # As to not generated fixtures, leaving biome to re-do them # so no auto-generation during github run of testing # Creating todo #313 to 'gracefully' do this on merge on github action -# if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "fixtures" ] ; then -# echo "... crafting manual fixtures ..." -# PYTHONPATH=$(pwd) python3 scripts/manual_fixtures.py -# fi +if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "fixtures" ] ; then + echo "... crafting manual fixtures ..." + PYTHONPATH=$(pwd) python3 scripts/manual_fixtures.py +fi echo "... biome-ing (fixtures and testdata) ..." ./tmp/biome lint --staged --files-ignore-unknown=true --no-errors-on-unmatched From 9d644df4920fe802235370830cfd399101a1f2f5 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 17:17:22 +0100 Subject: [PATCH 088/106] Save updated fixtures --- fixtures/m_adam_cooling/all_data.json | 60 ++-- fixtures/m_adam_heating/all_data.json | 61 ++-- fixtures/m_adam_jip/all_data.json | 200 +++++++---- .../all_data.json | 310 +++++++++++------- .../m_anna_heatpump_cooling/all_data.json | 2 +- fixtures/m_anna_heatpump_idle/all_data.json | 2 +- 6 files changed, 401 insertions(+), 234 deletions(-) diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index 66b32ed94..21430399a 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { @@ -53,16 +53,34 @@ "vendor": "Plugwise", "zigbee_mac_address": "000D6F000C8FF5EE" }, + "29542b2b6a6a4169acecc15c72a599b8": { + "available": true, + "dev_class": "computer_desktop_plug", + "firmware": "2020-11-10T01:00:00+01:00", + "location": "f2bf9048bef64cc5b6d5110154e33c81", + "model": "Plug", + "model_id": "160-01", + "name": "Plug Werkplek", + "sensors": { + "electricity_consumed": 91.3, + "electricity_consumed_interval": 23.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000D13CA9A" + }, "ad4838d7d35c4d6ea796ee12ae5aedf8": { "available": true, - "climate_mode": "cool", - "control_state": "cooling", "dev_class": "thermostat", "location": "f2bf9048bef64cc5b6d5110154e33c81", "model": "ThermoTouch", "model_id": "143.1", "name": "Anna", - "select_schedule": "off", "sensors": { "setpoint": 23.5, "temperature": 25.8 @@ -115,7 +133,7 @@ "name": "Lisa Badkamer", "sensors": { "battery": 14, - "setpoint": 23.5, + "setpoint": 25.0, "temperature": 23.9 }, "temperature_offset": { @@ -138,18 +156,7 @@ "switches": { "relay": true } - } - }, - "gateway": { - "cooling_present": true, - "gateway_id": "da224107914542988a88561b4452b0f6", - "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 89, - "notifications": {}, - "reboot": true, - "smile_name": "Adam" - }, - "zones": { + }, "f2bf9048bef64cc5b6d5110154e33c81": { "active_preset": "home", "available_schedules": [ @@ -159,8 +166,8 @@ "Weekschema", "off" ], - "climate_mode": "auto", - "control_state": "heating", + "climate_mode": "cool", + "control_state": "cooling", "dev_class": "climate", "name": "Living room", "preset_modes": [ @@ -170,11 +177,11 @@ "home", "away" ], - "select_schedule": "Weekschema", + "select_schedule": "off", "sensors": { "electricity_consumed": 149.9, "electricity_produced": 0.0, - "temperature": 18.4 + "temperature": 25.8 }, "thermostat": { "lower_bound": 1.0, @@ -213,7 +220,7 @@ "sensors": { "electricity_consumed": 0.0, "electricity_produced": 0.0, - "temperature": 16.5 + "temperature": 23.9 }, "thermostat": { "lower_bound": 0.0, @@ -230,5 +237,14 @@ ] } } + }, + "gateway": { + "cooling_present": true, + "gateway_id": "da224107914542988a88561b4452b0f6", + "heater_id": "056ee145a816487eaa69243c3280f8bf", + "item_count": 89, + "notifications": {}, + "reboot": true, + "smile_name": "Adam" } } diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index 687076161..f129bfb65 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { @@ -58,16 +58,34 @@ "vendor": "Plugwise", "zigbee_mac_address": "000D6F000C8FF5EE" }, + "29542b2b6a6a4169acecc15c72a599b8": { + "available": true, + "dev_class": "computer_desktop_plug", + "firmware": "2020-11-10T01:00:00+01:00", + "location": "f2bf9048bef64cc5b6d5110154e33c81", + "model": "Plug", + "model_id": "160-01", + "name": "Plug Werkplek", + "sensors": { + "electricity_consumed": 91.3, + "electricity_consumed_interval": 23.0, + "electricity_produced": 0.0, + "electricity_produced_interval": 0.0 + }, + "switches": { + "lock": false, + "relay": true + }, + "vendor": "Plugwise", + "zigbee_mac_address": "000D6F000D13CA9A" + }, "ad4838d7d35c4d6ea796ee12ae5aedf8": { "available": true, - "climate_mode": "heat", - "control_state": "preheating", "dev_class": "thermostat", "location": "f2bf9048bef64cc5b6d5110154e33c81", "model": "ThermoTouch", "model_id": "143.1", "name": "Anna", - "select_schedule": "off", "sensors": { "setpoint": 20.0, "temperature": 19.1 @@ -110,7 +128,6 @@ "binary_sensors": { "low_battery": true }, - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-10T02:00:00+02:00", "hardware": "255", @@ -143,18 +160,7 @@ "switches": { "relay": true } - } - }, - "gateway": { - "cooling_present": false, - "gateway_id": "da224107914542988a88561b4452b0f6", - "heater_id": "056ee145a816487eaa69243c3280f8bf", - "item_count": 89, - "notifications": {}, - "reboot": true, - "smile_name": "Adam" - }, - "zones": { + }, "f2bf9048bef64cc5b6d5110154e33c81": { "active_preset": "home", "available_schedules": [ @@ -164,8 +170,8 @@ "Weekschema", "off" ], - "climate_mode": "auto", - "control_state": "heating", + "climate_mode": "heat", + "control_state": "preheating", "dev_class": "climate", "name": "Living room", "preset_modes": [ @@ -175,11 +181,11 @@ "home", "away" ], - "select_schedule": "Weekschema", + "select_schedule": "off", "sensors": { "electricity_consumed": 149.9, "electricity_produced": 0.0, - "temperature": 18.4 + "temperature": 19.1 }, "thermostat": { "lower_bound": 1.0, @@ -204,7 +210,7 @@ "off" ], "climate_mode": "auto", - "control_state": "preheating", + "control_state": "off", "dev_class": "climate", "name": "Bathroom", "preset_modes": [ @@ -218,7 +224,7 @@ "sensors": { "electricity_consumed": 0.0, "electricity_produced": 0.0, - "temperature": 16.5 + "temperature": 17.9 }, "thermostat": { "lower_bound": 0.0, @@ -235,5 +241,14 @@ ] } } + }, + "gateway": { + "cooling_present": false, + "gateway_id": "da224107914542988a88561b4452b0f6", + "heater_id": "056ee145a816487eaa69243c3280f8bf", + "item_count": 89, + "notifications": {}, + "reboot": true, + "smile_name": "Adam" } } diff --git a/fixtures/m_adam_jip/all_data.json b/fixtures/m_adam_jip/all_data.json index 569525975..f9f8da300 100644 --- a/fixtures/m_adam_jip/all_data.json +++ b/fixtures/m_adam_jip/all_data.json @@ -1,13 +1,72 @@ { - "devices": { - "1346fbd8498d4dbcab7e18d51b771f3d": { + "entities": { + "06aecb3d00354375924f50c47af36bd2": { "active_preset": "no_frost", + "climate_mode": "off", + "control_state": "off", + "dev_class": "climate", + "name": "Slaapkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 24.2 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "1346fbd8498d4dbcab7e18d51b771f3d" + ], + "secondary": [ + "356b65335e274d769c338223e7af9c33" + ] + } + }, + "13228dab8ce04617af318a2888b3c548": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 27.4 + }, + "thermostat": { + "lower_bound": 4.0, + "resolution": 0.01, + "setpoint": 9.0, + "upper_bound": 30.0 + }, + "thermostats": { + "primary": [ + "f61f1a2535f54f52ad006a3d18e459ca" + ], + "secondary": [ + "833de10f269c4deab58fb9df69901b4e" + ] + } + }, + "1346fbd8498d4dbcab7e18d51b771f3d": { "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "off", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -15,13 +74,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Slaapkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 92, "setpoint": 13.0, @@ -33,18 +85,12 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A03" }, "1da4d325838e4ad8aac12177214505c9": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "d58fec52899f4f1c92e4f8fad6d8c48c", @@ -68,7 +114,7 @@ }, "356b65335e274d769c338223e7af9c33": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "06aecb3d00354375924f50c47af36bd2", @@ -108,13 +154,10 @@ "zigbee_mac_address": "ABCD012345670A06" }, "6f3e9d7084214c21b9dfa46f6eeb8700": { - "active_preset": "home", "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -122,13 +165,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Kinderkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 79, "setpoint": 13.0, @@ -140,18 +176,12 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A02" }, "833de10f269c4deab58fb9df69901b4e": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "13228dab8ce04617af318a2888b3c548", @@ -174,13 +204,10 @@ "zigbee_mac_address": "ABCD012345670A09" }, "a6abc6a129ee499c88a4d420cc413b47": { - "active_preset": "home", "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", - "control_state": "off", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -188,13 +215,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Logeerkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 80, "setpoint": 13.0, @@ -206,12 +226,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A01" }, @@ -246,9 +260,40 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670101" }, + "d27aede973b54be484f6842d1b2802ad": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Kinderkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 30.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "6f3e9d7084214c21b9dfa46f6eeb8700" + ], + "secondary": [ + "d4496250d0e942cfa7aea3476e9070d5" + ] + } + }, "d4496250d0e942cfa7aea3476e9070d5": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2020-11-04T01:00:00+01:00", "hardware": "1", "location": "d27aede973b54be484f6842d1b2802ad", @@ -270,6 +315,37 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A04" }, + "d58fec52899f4f1c92e4f8fad6d8c48c": { + "active_preset": "home", + "climate_mode": "heat", + "control_state": "off", + "dev_class": "climate", + "name": "Logeerkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 30.0 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 99.9 + }, + "thermostats": { + "primary": [ + "a6abc6a129ee499c88a4d420cc413b47" + ], + "secondary": [ + "1da4d325838e4ad8aac12177214505c9" + ] + } + }, "e4684553153b44afbef2200885f379dc": { "available": true, "binary_sensors": { @@ -307,13 +383,10 @@ "vendor": "Remeha B.V." }, "f61f1a2535f54f52ad006a3d18e459ca": { - "active_preset": "home", "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", - "control_state": "off", "dev_class": "zone_thermometer", "firmware": "2020-09-01T02:00:00+02:00", "hardware": "1", @@ -321,13 +394,6 @@ "model": "Jip", "model_id": "168-01", "name": "Woonkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 100, "humidity": 56.2, @@ -340,12 +406,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 4.0, - "resolution": 0.01, - "setpoint": 9.0, - "upper_bound": 30.0 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A08" } @@ -354,7 +414,7 @@ "cooling_present": false, "gateway_id": "b5c2386c6f6342669e50fe49dd05b188", "heater_id": "e4684553153b44afbef2200885f379dc", - "item_count": 228, + "item_count": 244, "notifications": {}, "reboot": true, "smile_name": "Adam" diff --git a/fixtures/m_adam_multiple_devices_per_zone/all_data.json b/fixtures/m_adam_multiple_devices_per_zone/all_data.json index 290935ac4..7d3cd9e9c 100644 --- a/fixtures/m_adam_multiple_devices_per_zone/all_data.json +++ b/fixtures/m_adam_multiple_devices_per_zone/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "02cf28bfec924855854c544690a609ef": { "available": true, "dev_class": "vcr_plug", @@ -21,6 +21,85 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A15" }, + "08963fec7c53423ca5680aa4cb502c63": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Badkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "Badkamer Schema", + "sensors": { + "temperature": 18.9 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 14.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "f1fee6043d3642a9b0a65297455f008e", + "680423ff840043738f42cc7f1ff97a36" + ], + "secondary": [] + } + }, + "12493538af164a409c6a1c79e38afe1c": { + "active_preset": "away", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "heat", + "dev_class": "climate", + "name": "Bios", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "off", + "sensors": { + "electricity_consumed": 0.0, + "electricity_produced": 0.0, + "temperature": 16.5 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 13.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "df4a4a8169904cdb9c03d61a21f42140" + ], + "secondary": [ + "a2c3583e0a6349358998b760cea82d2a" + ] + } + }, "21f2b542c49845e6bb416884c55778d6": { "available": true, "dev_class": "game_console_plug", @@ -42,6 +121,34 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A12" }, + "446ac08dd04d4eff8ac57489757b7314": { + "active_preset": "no_frost", + "climate_mode": "heat", + "dev_class": "climate", + "name": "Garage", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "sensors": { + "temperature": 15.6 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 5.5, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "e7693eb9582644e5b865dba8d4447cf1" + ], + "secondary": [] + } + }, "4a810418d5394b3f82727340b91ba740": { "available": true, "dev_class": "router_plug", @@ -89,13 +196,13 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "08963fec7c53423ca5680aa4cb502c63", "model": "Tom/Floor", "model_id": "106-03", - "name": "Thermostatic Radiator Badkamer", + "name": "Thermostatic Radiator Badkamer 1", "sensors": { "battery": 51, "setpoint": 14.0, @@ -113,20 +220,10 @@ "zigbee_mac_address": "ABCD012345670A17" }, "6a3bf693d05e48e0b460c815a4fdd09d": { - "active_preset": "asleep", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -134,14 +231,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Thermostat Jessie", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "CV Jessie", "sensors": { "battery": 37, "setpoint": 15.0, @@ -153,12 +242,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 15.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A03" }, @@ -182,6 +265,45 @@ "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A05" }, + "82fa13f017d240daa0d0ea1775420f24": { + "active_preset": "asleep", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Jessie", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "CV Jessie", + "sensors": { + "temperature": 17.2 + }, + "thermostat": { + "lower_bound": 0.0, + "resolution": 0.01, + "setpoint": 15.0, + "upper_bound": 100.0 + }, + "thermostats": { + "primary": [ + "6a3bf693d05e48e0b460c815a4fdd09d" + ], + "secondary": [ + "d3da73bde12a47d5a6b8f9dad971f2ec" + ] + } + }, "90986d591dcd426cae3ec3e8111ff730": { "binary_sensors": { "heating_state": true @@ -222,7 +344,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "12493538af164a409c6a1c79e38afe1c", @@ -247,7 +369,7 @@ }, "b310b72a0e354bfab43089919b9a88bf": { "available": true, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "c50f167537524366a5af7aa3942feb1e", @@ -270,20 +392,10 @@ "zigbee_mac_address": "ABCD012345670A02" }, "b59bcebaf94b499ea7d46e4a66fb62d8": { - "active_preset": "home", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", "dev_class": "zone_thermostat", "firmware": "2016-08-02T02:00:00+02:00", "hardware": "255", @@ -291,14 +403,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Lisa WK", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "GF7 Woonkamer", "sensors": { "battery": 34, "setpoint": 21.5, @@ -310,14 +414,49 @@ "setpoint": 0.0, "upper_bound": 2.0 }, + "vendor": "Plugwise", + "zigbee_mac_address": "ABCD012345670A07" + }, + "c50f167537524366a5af7aa3942feb1e": { + "active_preset": "home", + "available_schedules": [ + "CV Roan", + "Bios Schema met Film Avond", + "GF7 Woonkamer", + "Badkamer Schema", + "CV Jessie", + "off" + ], + "climate_mode": "auto", + "dev_class": "climate", + "name": "Woonkamer", + "preset_modes": [ + "home", + "asleep", + "away", + "vacation", + "no_frost" + ], + "select_schedule": "GF7 Woonkamer", + "sensors": { + "electricity_consumed": 35.6, + "electricity_produced": 0.0, + "temperature": 20.9 + }, "thermostat": { "lower_bound": 0.0, "resolution": 0.01, "setpoint": 21.5, - "upper_bound": 99.9 + "upper_bound": 100.0 }, - "vendor": "Plugwise", - "zigbee_mac_address": "ABCD012345670A07" + "thermostats": { + "primary": [ + "b59bcebaf94b499ea7d46e4a66fb62d8" + ], + "secondary": [ + "b310b72a0e354bfab43089919b9a88bf" + ] + } }, "cd0ddb54ef694e11ac18ed1cbce5dbbd": { "available": true, @@ -345,7 +484,7 @@ "binary_sensors": { "low_battery": false }, - "dev_class": "thermo_sensor", + "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", "location": "82fa13f017d240daa0d0ea1775420f24", @@ -369,20 +508,10 @@ "zigbee_mac_address": "ABCD012345670A10" }, "df4a4a8169904cdb9c03d61a21f42140": { - "active_preset": "away", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", "dev_class": "zone_thermostat", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", @@ -390,14 +519,6 @@ "model": "Lisa", "model_id": "158-01", "name": "Zone Lisa Bios", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "off", "sensors": { "battery": 67, "setpoint": 13.0, @@ -409,22 +530,14 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 13.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A06" }, "e7693eb9582644e5b865dba8d4447cf1": { - "active_preset": "no_frost", "available": true, "binary_sensors": { "low_battery": false }, - "climate_mode": "heat", "dev_class": "thermostatic_radiator_valve", "firmware": "2019-03-27T01:00:00+01:00", "hardware": "1", @@ -432,13 +545,6 @@ "model": "Tom/Floor", "model_id": "106-03", "name": "CV Kraan Garage", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], "sensors": { "battery": 68, "setpoint": 5.5, @@ -452,45 +558,21 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 5.5, - "upper_bound": 100.0 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A11" }, "f1fee6043d3642a9b0a65297455f008e": { - "active_preset": "away", "available": true, - "available_schedules": [ - "CV Roan", - "Bios Schema met Film Avond", - "GF7 Woonkamer", - "Badkamer Schema", - "CV Jessie", - "off" - ], "binary_sensors": { "low_battery": false }, - "climate_mode": "auto", - "dev_class": "zone_thermostat", + "dev_class": "thermostatic_radiator_valve", "firmware": "2016-10-27T02:00:00+02:00", "hardware": "255", "location": "08963fec7c53423ca5680aa4cb502c63", "model": "Lisa", "model_id": "158-01", - "name": "Zone Thermostat Badkamer", - "preset_modes": [ - "home", - "asleep", - "away", - "vacation", - "no_frost" - ], - "select_schedule": "Badkamer Schema", + "name": "Thermostatic Radiator Badkamer 2", "sensors": { "battery": 92, "setpoint": 14.0, @@ -502,12 +584,6 @@ "setpoint": 0.0, "upper_bound": 2.0 }, - "thermostat": { - "lower_bound": 0.0, - "resolution": 0.01, - "setpoint": 14.0, - "upper_bound": 99.9 - }, "vendor": "Plugwise", "zigbee_mac_address": "ABCD012345670A08" }, @@ -535,7 +611,7 @@ "cooling_present": false, "gateway_id": "fe799307f1624099878210aa0b9f1475", "heater_id": "90986d591dcd426cae3ec3e8111ff730", - "item_count": 340, + "item_count": 364, "notifications": { "af82e4ccf9c548528166d38e560662a4": { "warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device." diff --git a/fixtures/m_anna_heatpump_cooling/all_data.json b/fixtures/m_anna_heatpump_cooling/all_data.json index 044de1244..15f427672 100644 --- a/fixtures/m_anna_heatpump_cooling/all_data.json +++ b/fixtures/m_anna_heatpump_cooling/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/m_anna_heatpump_idle/all_data.json b/fixtures/m_anna_heatpump_idle/all_data.json index bc33ac339..993625000 100644 --- a/fixtures/m_anna_heatpump_idle/all_data.json +++ b/fixtures/m_anna_heatpump_idle/all_data.json @@ -1,5 +1,5 @@ { - "devices": { + "entities": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false From 7e41e8a414f3bc834b92f69fdf4c603170605d65 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 17:20:59 +0100 Subject: [PATCH 089/106] Reorder --- plugwise/legacy/smile.py | 3 +-- plugwise/smile.py | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 3c033f705..fdbaa813d 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -61,8 +61,6 @@ def __init__( username: str = DEFAULT_USERNAME, ) -> None: """Set the constructor for this class.""" - SmileLegacyData.__init__(self) - self._cooling_present = False self._is_thermostat = _is_thermostat self._loc_data = _loc_data @@ -79,6 +77,7 @@ def __init__( self.smile_name = smile_name self.smile_type = smile_type self.smile_zigbee_mac_address = smile_zigbee_mac_address + SmileLegacyData.__init__(self) self._previous_day_number: str = "0" diff --git a/plugwise/smile.py b/plugwise/smile.py index 9cc08f053..216cee271 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -70,10 +70,10 @@ def __init__( username: str = DEFAULT_USERNAME, ) -> None: """Set the constructor for this class.""" - SmileData.__init__(self) - + self._cooling_enabled = False self._cooling_present = _cooling_present self._elga = _elga + self._heater_id: str self._is_thermostat = _is_thermostat self._last_active = _last_active self._loc_data = _loc_data @@ -90,9 +90,8 @@ def __init__( self.smile_model_id = smile_model_id self.smile_name = smile_name self.smile_type = smile_type + SmileData.__init__(self) - self._heater_id: str - self._cooling_enabled = False async def full_xml_update(self) -> None: """Perform a first fetch of all XML data, needed for initialization.""" From 2e69675011471a677ec7f3491f14c87296cae688 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 22 Nov 2024 20:03:23 +0100 Subject: [PATCH 090/106] Updates for cooling --- fixtures/m_adam_cooling/all_data.json | 6 +++--- fixtures/m_adam_heating/all_data.json | 2 +- scripts/manual_fixtures.py | 21 +++++++++++++-------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index 21430399a..583a2d7c6 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -133,7 +133,7 @@ "name": "Lisa Badkamer", "sensors": { "battery": 14, - "setpoint": 25.0, + "setpoint": 23.5, "temperature": 23.9 }, "temperature_offset": { @@ -205,8 +205,8 @@ "Weekschema", "off" ], - "climate_mode": "auto", - "control_state": "preheating", + "climate_mode": "cool", + "control_state": "auto", "dev_class": "climate", "name": "Bathroom", "preset_modes": [ diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index f129bfb65..aa7ece44d 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -209,7 +209,7 @@ "Weekschema", "off" ], - "climate_mode": "auto", + "climate_mode": "cool", "control_state": "off", "dev_class": "climate", "name": "Bathroom", diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index e7bcf59bf..72d3b23f2 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -77,12 +77,12 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "setpoint" ] = 23.5 -m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ - "setpoint" -] = 23.5 m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "temperature" ] = 25.8 +m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ + "setpoint" +] = 23.5 m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ "temperature" ] = 25.8 @@ -112,18 +112,23 @@ def json_writer(manual_name: str, all_data: dict) -> None: ] = 21.6 # Go for e2f4 -m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ +m_adam_cooling["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "setpoint" -] = 25.0 +] = 23.5 m_adam_cooling["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ + "temperature" +] = 23.9 +m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 25.0 m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ "temperature" ] = 23.9 -m_adam_cooling["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ - "temperature" -] = 23.9 +m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"][ + "control_state" +] = "auto" +m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "cool" + # Go for da22 m_adam_cooling["entities"]["da224107914542988a88561b4452b0f6"][ From b1faee4809f4822c315162b424e31b36f89ace8f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 23 Nov 2024 07:36:09 +0100 Subject: [PATCH 091/106] Remove new device --- scripts/manual_fixtures.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 72d3b23f2..2f9becdb9 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -69,7 +69,8 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling["gateway"]["cooling_present"] = True m_adam_cooling["gateway"]["item_count"] = 89 -# Remove devices "67d73d0bd469422db25a618a5fb8eeb0" and "10016900610d4c7481df78c89606ef22" from anywhere +# Remove devices 67d73d0bd469422db25a618a5fb8eeb0, 29542b2b6a6a4169acecc15c72a599b8 and 10016900610d4c7481df78c89606ef22 from anywhere +m_adam_cooling["entities"].pop("29542b2b6a6a4169acecc15c72a599b8") m_adam_cooling["entities"].pop("67d73d0bd469422db25a618a5fb8eeb0") m_adam_cooling["entities"].pop("10016900610d4c7481df78c89606ef22") From 2293435527b9c883dd8e2a4288946bb9913d8e3c Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 23 Nov 2024 07:45:18 +0100 Subject: [PATCH 092/106] Save updated fixtures --- fixtures/m_adam_cooling/all_data.json | 21 --------------------- fixtures/m_adam_heating/all_data.json | 21 --------------------- 2 files changed, 42 deletions(-) diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index 583a2d7c6..f98d48fd2 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -53,27 +53,6 @@ "vendor": "Plugwise", "zigbee_mac_address": "000D6F000C8FF5EE" }, - "29542b2b6a6a4169acecc15c72a599b8": { - "available": true, - "dev_class": "computer_desktop_plug", - "firmware": "2020-11-10T01:00:00+01:00", - "location": "f2bf9048bef64cc5b6d5110154e33c81", - "model": "Plug", - "model_id": "160-01", - "name": "Plug Werkplek", - "sensors": { - "electricity_consumed": 91.3, - "electricity_consumed_interval": 23.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "lock": false, - "relay": true - }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000D13CA9A" - }, "ad4838d7d35c4d6ea796ee12ae5aedf8": { "available": true, "dev_class": "thermostat", diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index aa7ece44d..fb1cc8428 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -58,27 +58,6 @@ "vendor": "Plugwise", "zigbee_mac_address": "000D6F000C8FF5EE" }, - "29542b2b6a6a4169acecc15c72a599b8": { - "available": true, - "dev_class": "computer_desktop_plug", - "firmware": "2020-11-10T01:00:00+01:00", - "location": "f2bf9048bef64cc5b6d5110154e33c81", - "model": "Plug", - "model_id": "160-01", - "name": "Plug Werkplek", - "sensors": { - "electricity_consumed": 91.3, - "electricity_consumed_interval": 23.0, - "electricity_produced": 0.0, - "electricity_produced_interval": 0.0 - }, - "switches": { - "lock": false, - "relay": true - }, - "vendor": "Plugwise", - "zigbee_mac_address": "000D6F000D13CA9A" - }, "ad4838d7d35c4d6ea796ee12ae5aedf8": { "available": true, "dev_class": "thermostat", From e5a72183501e2ac6219fb525517d99f3d781bdd8 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 23 Nov 2024 08:40:57 +0100 Subject: [PATCH 093/106] Manual_fixtures script fix --- scripts/manual_fixtures.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index 2f9becdb9..b8a6c12f2 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -207,6 +207,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: "temperature" ] = 17.9 +m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "auto" m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"][ "control_state" ] = "off" From 45a7e788d751364479f9a2392998da01a06d2979 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 23 Nov 2024 08:41:58 +0100 Subject: [PATCH 094/106] Save updated fixture --- fixtures/m_adam_heating/all_data.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index fb1cc8428..475070110 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -188,7 +188,7 @@ "Weekschema", "off" ], - "climate_mode": "cool", + "climate_mode": "auto", "control_state": "off", "dev_class": "climate", "name": "Bathroom", From de583bfca3ee81f6fbabe89a0279e4f02db6a730 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 24 Nov 2024 16:29:41 +0100 Subject: [PATCH 095/106] Add manufacturer and model for zone and switchgroup --- plugwise/common.py | 1 + plugwise/helper.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugwise/common.py b/plugwise/common.py index 2abaef5bd..8266f9a4a 100644 --- a/plugwise/common.py +++ b/plugwise/common.py @@ -262,6 +262,7 @@ def _get_group_switches(self) -> dict[str, GwEntityData]: "model": "Switchgroup", "name": group_name, "members": members, + "vendor": "Plugwise", } self._count += 4 diff --git a/plugwise/helper.py b/plugwise/helper.py index 547ab6e24..e9a5f5849 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -863,8 +863,10 @@ def _scan_thermostats(self) -> None: if loc_data["primary_prio"] != 0: self._zones[loc_id] = { "dev_class": "climate", + "model": "ThermoZone", "name": loc_data["name"], - "thermostats": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]} + "thermostats": {"primary": loc_data["primary"], "secondary": loc_data["secondary"]}, + "vendor": "Plugwise", } self._count += 3 From bfffb41c2d634e3487279ba26b39d68ab1e5bf9a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sun, 24 Nov 2024 16:32:15 +0100 Subject: [PATCH 096/106] Save updated fixtures --- fixtures/adam_heatpump_cooling/all_data.json | 40 ++++++++++++++----- fixtures/adam_jip/all_data.json | 16 ++++++-- .../all_data.json | 20 +++++++--- .../all_data.json | 4 +- fixtures/adam_plus_anna/all_data.json | 4 +- fixtures/adam_plus_anna_new/all_data.json | 11 +++-- fixtures/adam_zone_per_device/all_data.json | 20 +++++++--- fixtures/m_adam_cooling/all_data.json | 11 +++-- fixtures/m_adam_heating/all_data.json | 11 +++-- fixtures/m_adam_jip/all_data.json | 16 ++++++-- .../all_data.json | 20 +++++++--- fixtures/stretch_v23/all_data.json | 3 +- fixtures/stretch_v31/all_data.json | 6 ++- 13 files changed, 135 insertions(+), 47 deletions(-) diff --git a/fixtures/adam_heatpump_cooling/all_data.json b/fixtures/adam_heatpump_cooling/all_data.json index 54fe118ca..08e991e96 100644 --- a/fixtures/adam_heatpump_cooling/all_data.json +++ b/fixtures/adam_heatpump_cooling/all_data.json @@ -11,6 +11,7 @@ "climate_mode": "cool", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Slaapkamer SJ", "preset_modes": [ "no_frost", @@ -36,7 +37,8 @@ "d3a276aeb3114a509bab1e4bf8c40348" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "0ca13e8176204ca7bf6f09de59f81c83": { "available": true, @@ -134,6 +136,7 @@ "climate_mode": "cool", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Slaapkamer DB", "preset_modes": [ "no_frost", @@ -159,7 +162,8 @@ "47e2c550a33846b680725aa3fb229473" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "2e0fc4db2a6d4cbeb7cf786143543961": { "available": true, @@ -254,6 +258,7 @@ "climate_mode": "auto", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Badkamer 2", "preset_modes": [ "no_frost", @@ -278,7 +283,8 @@ "f04c985c11ad4848b8fcd710343f9dcf" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "5ead63c65e5f44e7870ba2bd680ceb9e": { "available": true, @@ -405,6 +411,7 @@ "climate_mode": "auto", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Badkamer 1", "preset_modes": [ "no_frost", @@ -430,7 +437,8 @@ "eac5db95d97241f6b17790897847ccf5" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "93ac3f7bf25342f58cbb77c4a99ac0b3": { "active_preset": "away", @@ -443,6 +451,7 @@ "climate_mode": "cool", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Slaapkamer RB", "preset_modes": [ "no_frost", @@ -467,7 +476,8 @@ "c4ed311d54e341f58b4cdd201d1fde7e" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "96714ad90fc948bcbcb5021c4b9f5ae9": { "available": true, @@ -500,6 +510,7 @@ "climate_mode": "cool", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Slaapkamer SQ", "preset_modes": [ "no_frost", @@ -525,7 +536,8 @@ "beb32da072274e698146db8b022f3c36" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "a03b6e8e76dd4646af1a77c31dd9370c": { "available": true, @@ -558,6 +570,7 @@ "climate_mode": "auto", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Keuken", "preset_modes": [ "no_frost", @@ -583,7 +596,8 @@ "ea8372c0e3ad4622ad45a041d02425f5" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "b52908550469425b812c87f766fe5303": { "active_preset": "away", @@ -596,6 +610,7 @@ "climate_mode": "cool", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Bijkeuken", "preset_modes": [ "no_frost", @@ -621,7 +636,8 @@ "1053c8bbf8be43c6921742b146a625f1" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "bbcffa48019f4b09b8368bbaf9559e68": { "available": true, @@ -732,6 +748,7 @@ "climate_mode": "cool", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Slaapkamer JM", "preset_modes": [ "no_frost", @@ -757,7 +774,8 @@ "7fda9f84f01342f8afe9ebbbbff30c0f" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "ea8372c0e3ad4622ad45a041d02425f5": { "available": true, @@ -840,6 +858,7 @@ "climate_mode": "auto", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Woonkamer", "preset_modes": [ "no_frost", @@ -865,7 +884,8 @@ "ca79d23ae0094120b877558734cff85c" ], "secondary": [] - } + }, + "vendor": "Plugwise" } }, "gateway": { diff --git a/fixtures/adam_jip/all_data.json b/fixtures/adam_jip/all_data.json index c89c25218..0a6c58a8a 100644 --- a/fixtures/adam_jip/all_data.json +++ b/fixtures/adam_jip/all_data.json @@ -5,6 +5,7 @@ "climate_mode": "heat", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Slaapkamer", "preset_modes": [ "home", @@ -29,13 +30,15 @@ "secondary": [ "356b65335e274d769c338223e7af9c33" ] - } + }, + "vendor": "Plugwise" }, "13228dab8ce04617af318a2888b3c548": { "active_preset": "home", "climate_mode": "heat", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Woonkamer", "preset_modes": [ "home", @@ -60,7 +63,8 @@ "secondary": [ "833de10f269c4deab58fb9df69901b4e" ] - } + }, + "vendor": "Plugwise" }, "1346fbd8498d4dbcab7e18d51b771f3d": { "available": true, @@ -265,6 +269,7 @@ "climate_mode": "heat", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Kinderkamer", "preset_modes": [ "home", @@ -289,7 +294,8 @@ "secondary": [ "d4496250d0e942cfa7aea3476e9070d5" ] - } + }, + "vendor": "Plugwise" }, "d4496250d0e942cfa7aea3476e9070d5": { "available": true, @@ -320,6 +326,7 @@ "climate_mode": "heat", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Logeerkamer", "preset_modes": [ "home", @@ -344,7 +351,8 @@ "secondary": [ "1da4d325838e4ad8aac12177214505c9" ] - } + }, + "vendor": "Plugwise" }, "e4684553153b44afbef2200885f379dc": { "available": true, diff --git a/fixtures/adam_multiple_devices_per_zone/all_data.json b/fixtures/adam_multiple_devices_per_zone/all_data.json index 7a99dd028..658f73773 100644 --- a/fixtures/adam_multiple_devices_per_zone/all_data.json +++ b/fixtures/adam_multiple_devices_per_zone/all_data.json @@ -33,6 +33,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Badkamer", "preset_modes": [ "home", @@ -57,7 +58,8 @@ "680423ff840043738f42cc7f1ff97a36" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "12493538af164a409c6a1c79e38afe1c": { "active_preset": "away", @@ -71,6 +73,7 @@ ], "climate_mode": "heat", "dev_class": "climate", + "model": "ThermoZone", "name": "Bios", "preset_modes": [ "home", @@ -98,7 +101,8 @@ "secondary": [ "a2c3583e0a6349358998b760cea82d2a" ] - } + }, + "vendor": "Plugwise" }, "21f2b542c49845e6bb416884c55778d6": { "available": true, @@ -133,6 +137,7 @@ ], "climate_mode": "heat", "dev_class": "climate", + "model": "ThermoZone", "name": "Garage", "preset_modes": [ "home", @@ -156,7 +161,8 @@ "e7693eb9582644e5b865dba8d4447cf1" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "4a810418d5394b3f82727340b91ba740": { "available": true, @@ -286,6 +292,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Jessie", "preset_modes": [ "home", @@ -311,7 +318,8 @@ "secondary": [ "d3da73bde12a47d5a6b8f9dad971f2ec" ] - } + }, + "vendor": "Plugwise" }, "90986d591dcd426cae3ec3e8111ff730": { "binary_sensors": { @@ -438,6 +446,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Woonkamer", "preset_modes": [ "home", @@ -465,7 +474,8 @@ "secondary": [ "b310b72a0e354bfab43089919b9a88bf" ] - } + }, + "vendor": "Plugwise" }, "cd0ddb54ef694e11ac18ed1cbce5dbbd": { "available": true, diff --git a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json index 60b85cc9a..33f87d4a8 100644 --- a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json +++ b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json @@ -91,6 +91,7 @@ "climate_mode": "auto", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Woonkamer", "preset_modes": [ "no_frost", @@ -116,7 +117,8 @@ "ca79d23ae0094120b877558734cff85c" ], "secondary": [] - } + }, + "vendor": "Plugwise" } }, "gateway": { diff --git a/fixtures/adam_plus_anna/all_data.json b/fixtures/adam_plus_anna/all_data.json index 12db8e05f..ae927a9aa 100644 --- a/fixtures/adam_plus_anna/all_data.json +++ b/fixtures/adam_plus_anna/all_data.json @@ -8,6 +8,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Living room", "preset_modes": [ "home", @@ -33,7 +34,8 @@ "ee62cad889f94e8ca3d09021f03a660b" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "2743216f626f43948deec1f7ab3b3d70": { "available": false, diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index fa2362a27..21ee0f472 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -223,7 +223,8 @@ "name": "Test", "switches": { "relay": true - } + }, + "vendor": "Plugwise" }, "f2bf9048bef64cc5b6d5110154e33c81": { "active_preset": "home", @@ -237,6 +238,7 @@ "climate_mode": "auto", "control_state": "heating", "dev_class": "climate", + "model": "ThermoZone", "name": "Living room", "preset_modes": [ "no_frost", @@ -262,7 +264,8 @@ "ad4838d7d35c4d6ea796ee12ae5aedf8" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "f871b8c4d63549319221e294e4f88074": { "active_preset": "home", @@ -276,6 +279,7 @@ "climate_mode": "auto", "control_state": "preheating", "dev_class": "climate", + "model": "ThermoZone", "name": "Bathroom", "preset_modes": [ "no_frost", @@ -303,7 +307,8 @@ "secondary": [ "1772a4ea304041adb83f357b751341ff" ] - } + }, + "vendor": "Plugwise" } }, "gateway": { diff --git a/fixtures/adam_zone_per_device/all_data.json b/fixtures/adam_zone_per_device/all_data.json index 657dcd240..5d8fda953 100644 --- a/fixtures/adam_zone_per_device/all_data.json +++ b/fixtures/adam_zone_per_device/all_data.json @@ -33,6 +33,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Badkamer", "preset_modes": [ "home", @@ -58,7 +59,8 @@ "secondary": [ "680423ff840043738f42cc7f1ff97a36" ] - } + }, + "vendor": "Plugwise" }, "12493538af164a409c6a1c79e38afe1c": { "active_preset": "away", @@ -72,6 +74,7 @@ ], "climate_mode": "heat", "dev_class": "climate", + "model": "ThermoZone", "name": "Bios", "preset_modes": [ "home", @@ -99,7 +102,8 @@ "secondary": [ "a2c3583e0a6349358998b760cea82d2a" ] - } + }, + "vendor": "Plugwise" }, "21f2b542c49845e6bb416884c55778d6": { "available": true, @@ -134,6 +138,7 @@ ], "climate_mode": "heat", "dev_class": "climate", + "model": "ThermoZone", "name": "Garage", "preset_modes": [ "home", @@ -157,7 +162,8 @@ "e7693eb9582644e5b865dba8d4447cf1" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "4a810418d5394b3f82727340b91ba740": { "available": true, @@ -287,6 +293,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Jessie", "preset_modes": [ "home", @@ -312,7 +319,8 @@ "secondary": [ "d3da73bde12a47d5a6b8f9dad971f2ec" ] - } + }, + "vendor": "Plugwise" }, "90986d591dcd426cae3ec3e8111ff730": { "binary_sensors": { @@ -439,6 +447,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Woonkamer", "preset_modes": [ "home", @@ -466,7 +475,8 @@ "secondary": [ "b310b72a0e354bfab43089919b9a88bf" ] - } + }, + "vendor": "Plugwise" }, "cd0ddb54ef694e11ac18ed1cbce5dbbd": { "available": true, diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index f98d48fd2..94166804f 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -134,7 +134,8 @@ "name": "Test", "switches": { "relay": true - } + }, + "vendor": "Plugwise" }, "f2bf9048bef64cc5b6d5110154e33c81": { "active_preset": "home", @@ -148,6 +149,7 @@ "climate_mode": "cool", "control_state": "cooling", "dev_class": "climate", + "model": "ThermoZone", "name": "Living room", "preset_modes": [ "no_frost", @@ -173,7 +175,8 @@ "ad4838d7d35c4d6ea796ee12ae5aedf8" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "f871b8c4d63549319221e294e4f88074": { "active_preset": "home", @@ -187,6 +190,7 @@ "climate_mode": "cool", "control_state": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Bathroom", "preset_modes": [ "no_frost", @@ -214,7 +218,8 @@ "secondary": [ "1772a4ea304041adb83f357b751341ff" ] - } + }, + "vendor": "Plugwise" } }, "gateway": { diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index 475070110..5d7db1e43 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -138,7 +138,8 @@ "name": "Test", "switches": { "relay": true - } + }, + "vendor": "Plugwise" }, "f2bf9048bef64cc5b6d5110154e33c81": { "active_preset": "home", @@ -152,6 +153,7 @@ "climate_mode": "heat", "control_state": "preheating", "dev_class": "climate", + "model": "ThermoZone", "name": "Living room", "preset_modes": [ "no_frost", @@ -177,7 +179,8 @@ "ad4838d7d35c4d6ea796ee12ae5aedf8" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "f871b8c4d63549319221e294e4f88074": { "active_preset": "home", @@ -191,6 +194,7 @@ "climate_mode": "auto", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Bathroom", "preset_modes": [ "no_frost", @@ -218,7 +222,8 @@ "secondary": [ "1772a4ea304041adb83f357b751341ff" ] - } + }, + "vendor": "Plugwise" } }, "gateway": { diff --git a/fixtures/m_adam_jip/all_data.json b/fixtures/m_adam_jip/all_data.json index f9f8da300..9eac78e79 100644 --- a/fixtures/m_adam_jip/all_data.json +++ b/fixtures/m_adam_jip/all_data.json @@ -5,6 +5,7 @@ "climate_mode": "off", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Slaapkamer", "preset_modes": [ "home", @@ -29,13 +30,15 @@ "secondary": [ "356b65335e274d769c338223e7af9c33" ] - } + }, + "vendor": "Plugwise" }, "13228dab8ce04617af318a2888b3c548": { "active_preset": "home", "climate_mode": "heat", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Woonkamer", "preset_modes": [ "home", @@ -60,7 +63,8 @@ "secondary": [ "833de10f269c4deab58fb9df69901b4e" ] - } + }, + "vendor": "Plugwise" }, "1346fbd8498d4dbcab7e18d51b771f3d": { "available": true, @@ -265,6 +269,7 @@ "climate_mode": "heat", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Kinderkamer", "preset_modes": [ "home", @@ -289,7 +294,8 @@ "secondary": [ "d4496250d0e942cfa7aea3476e9070d5" ] - } + }, + "vendor": "Plugwise" }, "d4496250d0e942cfa7aea3476e9070d5": { "available": true, @@ -320,6 +326,7 @@ "climate_mode": "heat", "control_state": "off", "dev_class": "climate", + "model": "ThermoZone", "name": "Logeerkamer", "preset_modes": [ "home", @@ -344,7 +351,8 @@ "secondary": [ "1da4d325838e4ad8aac12177214505c9" ] - } + }, + "vendor": "Plugwise" }, "e4684553153b44afbef2200885f379dc": { "available": true, diff --git a/fixtures/m_adam_multiple_devices_per_zone/all_data.json b/fixtures/m_adam_multiple_devices_per_zone/all_data.json index 7d3cd9e9c..03ab9dea1 100644 --- a/fixtures/m_adam_multiple_devices_per_zone/all_data.json +++ b/fixtures/m_adam_multiple_devices_per_zone/all_data.json @@ -33,6 +33,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Badkamer", "preset_modes": [ "home", @@ -57,7 +58,8 @@ "680423ff840043738f42cc7f1ff97a36" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "12493538af164a409c6a1c79e38afe1c": { "active_preset": "away", @@ -71,6 +73,7 @@ ], "climate_mode": "heat", "dev_class": "climate", + "model": "ThermoZone", "name": "Bios", "preset_modes": [ "home", @@ -98,7 +101,8 @@ "secondary": [ "a2c3583e0a6349358998b760cea82d2a" ] - } + }, + "vendor": "Plugwise" }, "21f2b542c49845e6bb416884c55778d6": { "available": true, @@ -125,6 +129,7 @@ "active_preset": "no_frost", "climate_mode": "heat", "dev_class": "climate", + "model": "ThermoZone", "name": "Garage", "preset_modes": [ "home", @@ -147,7 +152,8 @@ "e7693eb9582644e5b865dba8d4447cf1" ], "secondary": [] - } + }, + "vendor": "Plugwise" }, "4a810418d5394b3f82727340b91ba740": { "available": true, @@ -277,6 +283,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Jessie", "preset_modes": [ "home", @@ -302,7 +309,8 @@ "secondary": [ "d3da73bde12a47d5a6b8f9dad971f2ec" ] - } + }, + "vendor": "Plugwise" }, "90986d591dcd426cae3ec3e8111ff730": { "binary_sensors": { @@ -429,6 +437,7 @@ ], "climate_mode": "auto", "dev_class": "climate", + "model": "ThermoZone", "name": "Woonkamer", "preset_modes": [ "home", @@ -456,7 +465,8 @@ "secondary": [ "b310b72a0e354bfab43089919b9a88bf" ] - } + }, + "vendor": "Plugwise" }, "cd0ddb54ef694e11ac18ed1cbce5dbbd": { "available": true, diff --git a/fixtures/stretch_v23/all_data.json b/fixtures/stretch_v23/all_data.json index a372a313f..f14cdccc3 100644 --- a/fixtures/stretch_v23/all_data.json +++ b/fixtures/stretch_v23/all_data.json @@ -312,7 +312,8 @@ "name": "Test", "switches": { "relay": false - } + }, + "vendor": "Plugwise" }, "fd1b74f59e234a9dae4e23b2b5cf07ed": { "dev_class": "dryer", diff --git a/fixtures/stretch_v31/all_data.json b/fixtures/stretch_v31/all_data.json index d5bb7cb09..692151f34 100644 --- a/fixtures/stretch_v31/all_data.json +++ b/fixtures/stretch_v31/all_data.json @@ -96,7 +96,8 @@ "name": "Schakel", "switches": { "relay": true - } + }, + "vendor": "Plugwise" }, "d950b314e9d8499f968e6db8d82ef78c": { "dev_class": "report", @@ -111,7 +112,8 @@ "name": "Stroomvreters", "switches": { "relay": true - } + }, + "vendor": "Plugwise" }, "e1c884e7dede431dadee09506ec4f859": { "dev_class": "refrigerator", From 58f27fba20bf3a4d88bfa131ff3dde159818b536 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 25 Nov 2024 13:28:30 +0100 Subject: [PATCH 097/106] Return to devices in the output data --- plugwise/__init__.py | 2 +- plugwise/constants.py | 2 +- plugwise/legacy/smile.py | 2 +- plugwise/smile.py | 2 +- tests/test_init.py | 12 ++++++------ 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 8177f065d..2769177cd 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -308,7 +308,7 @@ def get_all_gateway_entities(self) -> None: async def async_update(self) -> PlugwiseData: """Update the various entities and their states.""" - data = PlugwiseData(entities={}, gateway={}) + data = PlugwiseData(devices={}, gateway={}) try: data = await self._smile_api.async_update() self.gateway_id = data.gateway["gateway_id"] diff --git a/plugwise/constants.py b/plugwise/constants.py index 9186ee96f..16d3e9b29 100644 --- a/plugwise/constants.py +++ b/plugwise/constants.py @@ -582,6 +582,6 @@ class GwEntityData(TypedDict, total=False): class PlugwiseData: """Plugwise data provided as output.""" - entities: dict[str, GwEntityData] + devices: dict[str, GwEntityData] gateway: GatewayData diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index fdbaa813d..c1df96fdc 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -134,7 +134,7 @@ async def async_update(self) -> PlugwiseData: self._previous_day_number = day_number return PlugwiseData( - entities=self.gw_entities, + devices=self.gw_entities, gateway=self.gw_data, ) diff --git a/plugwise/smile.py b/plugwise/smile.py index 216cee271..eac7824ee 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -140,7 +140,7 @@ async def async_update(self) -> PlugwiseData: raise DataMissingError("No Plugwise data received") from err return PlugwiseData( - entities=self.gw_entities, + devices=self.gw_entities, gateway=self.gw_data, ) diff --git a/tests/test_init.py b/tests/test_init.py index eabee19c7..9d3698beb 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -628,34 +628,34 @@ def test_and_assert(test_dict, data, header): self._cooling_active = False self._cooling_enabled = False if "heater_id" in data.gateway: - heat_cooler = data.entities[data.gateway["heater_id"]] + heat_cooler = data.devices[data.gateway["heater_id"]] if "binary_sensors" in heat_cooler: if "cooling_enabled" in heat_cooler["binary_sensors"]: self._cooling_enabled = heat_cooler["binary_sensors"]["cooling_enabled"] if "cooling_state" in heat_cooler["binary_sensors"]: self._cooling_active = heat_cooler["binary_sensors"]["cooling_state"] - self._write_json("all_data", {"entities": data.entities, "gateway": data.gateway}) + self._write_json("all_data", {"devices": data.devices, "gateway": data.gateway}) if "FIXTURES" in os.environ: _LOGGER.info("Skipping tests: Requested fixtures only") # pragma: no cover return # pragma: no cover - self.entity_list = list(data.entities.keys()) + self.entity_list = list(data.devices.keys()) location_list = smile._loc_data _LOGGER.info("Gateway id = %s", data.gateway["gateway_id"]) _LOGGER.info("Hostname = %s", smile.smile_hostname) _LOGGER.info("Gateway data = %s", data.gateway) - _LOGGER.info("Entities list = %s", data.entities) - self.show_setup(location_list, data.entities) + _LOGGER.info("Entities list = %s", data.devices) + self.show_setup(location_list, data.devices) if skip_testing: return # Perform tests and asserts in two steps: devices and zones for header, data_dict in testdata.items(): - test_and_assert(data_dict, data.entities, header) + test_and_assert(data_dict, data.devices, header) # pragma warning restore S3776 From 6978c2b4d53364cc9ef0605c7231827f9921228b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 25 Nov 2024 13:59:39 +0100 Subject: [PATCH 098/106] Update CHANGELOG --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6316f6cdb..47c133553 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,6 @@ - New Feature: implement collection of location/zone data: Plugwise Adam thermostat representations are zone-based in case there are more than one equal type of thermostats in one zone (e.g. 2 Tom's and no Lisa). -- In PlugwiseData the `devices`-dict is replaced by an `entities`-dict. ## v1.5.2 From 23a7007c0c40c217d7d2698b915db2575d1144d8 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 25 Nov 2024 17:52:10 +0100 Subject: [PATCH 099/106] Save updated fixtures --- fixtures/adam_heatpump_cooling/all_data.json | 2 +- fixtures/adam_jip/all_data.json | 2 +- fixtures/adam_multiple_devices_per_zone/all_data.json | 2 +- fixtures/adam_onoff_cooling_fake_firmware/all_data.json | 2 +- fixtures/adam_plus_anna/all_data.json | 2 +- fixtures/adam_plus_anna_new/all_data.json | 2 +- fixtures/adam_zone_per_device/all_data.json | 2 +- fixtures/anna_elga_2/all_data.json | 2 +- fixtures/anna_elga_2_cooling/all_data.json | 2 +- fixtures/anna_elga_2_schedule_off/all_data.json | 2 +- fixtures/anna_elga_no_cooling/all_data.json | 2 +- fixtures/anna_heatpump_cooling/all_data.json | 2 +- fixtures/anna_heatpump_cooling_fake_firmware/all_data.json | 2 +- fixtures/anna_heatpump_heating/all_data.json | 2 +- fixtures/anna_loria_cooling_active/all_data.json | 2 +- fixtures/anna_loria_driessens/all_data.json | 2 +- fixtures/anna_loria_heating_idle/all_data.json | 2 +- fixtures/anna_v4/all_data.json | 2 +- fixtures/anna_v4_dhw/all_data.json | 2 +- fixtures/anna_v4_no_tag/all_data.json | 2 +- fixtures/anna_without_boiler_fw441/all_data.json | 2 +- fixtures/legacy_anna/all_data.json | 2 +- fixtures/legacy_anna_2/all_data.json | 2 +- fixtures/p1v4_442_single/all_data.json | 2 +- fixtures/p1v4_442_triple/all_data.json | 2 +- fixtures/smile_p1_v2/all_data.json | 2 +- fixtures/smile_p1_v2_2/all_data.json | 2 +- fixtures/stretch_v23/all_data.json | 2 +- fixtures/stretch_v27_no_domain/all_data.json | 2 +- fixtures/stretch_v31/all_data.json | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/fixtures/adam_heatpump_cooling/all_data.json b/fixtures/adam_heatpump_cooling/all_data.json index 08e991e96..608bbd6bb 100644 --- a/fixtures/adam_heatpump_cooling/all_data.json +++ b/fixtures/adam_heatpump_cooling/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "04b15f6e884448288f811d29fb7b1b30": { "active_preset": "away", "available_schedules": [ diff --git a/fixtures/adam_jip/all_data.json b/fixtures/adam_jip/all_data.json index 0a6c58a8a..2d58bb730 100644 --- a/fixtures/adam_jip/all_data.json +++ b/fixtures/adam_jip/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "06aecb3d00354375924f50c47af36bd2": { "active_preset": "no_frost", "climate_mode": "heat", diff --git a/fixtures/adam_multiple_devices_per_zone/all_data.json b/fixtures/adam_multiple_devices_per_zone/all_data.json index 658f73773..fa3b9ef6c 100644 --- a/fixtures/adam_multiple_devices_per_zone/all_data.json +++ b/fixtures/adam_multiple_devices_per_zone/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "02cf28bfec924855854c544690a609ef": { "available": true, "dev_class": "vcr_plug", diff --git a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json index 33f87d4a8..79e1109f8 100644 --- a/fixtures/adam_onoff_cooling_fake_firmware/all_data.json +++ b/fixtures/adam_onoff_cooling_fake_firmware/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "0ca13e8176204ca7bf6f09de59f81c83": { "binary_sensors": { "cooling_state": true, diff --git a/fixtures/adam_plus_anna/all_data.json b/fixtures/adam_plus_anna/all_data.json index ae927a9aa..54288e2c6 100644 --- a/fixtures/adam_plus_anna/all_data.json +++ b/fixtures/adam_plus_anna/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "009490cc2f674ce6b576863fbb64f867": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/adam_plus_anna_new/all_data.json b/fixtures/adam_plus_anna_new/all_data.json index 21ee0f472..5aafe2fb7 100644 --- a/fixtures/adam_plus_anna_new/all_data.json +++ b/fixtures/adam_plus_anna_new/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { diff --git a/fixtures/adam_zone_per_device/all_data.json b/fixtures/adam_zone_per_device/all_data.json index 5d8fda953..7acb1b05b 100644 --- a/fixtures/adam_zone_per_device/all_data.json +++ b/fixtures/adam_zone_per_device/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "02cf28bfec924855854c544690a609ef": { "available": true, "dev_class": "vcr_plug", diff --git a/fixtures/anna_elga_2/all_data.json b/fixtures/anna_elga_2/all_data.json index 107169b78..4b8c73c7a 100644 --- a/fixtures/anna_elga_2/all_data.json +++ b/fixtures/anna_elga_2/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "573c152e7d4f4720878222bd75638f5b": { "available": true, "binary_sensors": { diff --git a/fixtures/anna_elga_2_cooling/all_data.json b/fixtures/anna_elga_2_cooling/all_data.json index 41c76174a..2bad3f05d 100644 --- a/fixtures/anna_elga_2_cooling/all_data.json +++ b/fixtures/anna_elga_2_cooling/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "573c152e7d4f4720878222bd75638f5b": { "available": true, "binary_sensors": { diff --git a/fixtures/anna_elga_2_schedule_off/all_data.json b/fixtures/anna_elga_2_schedule_off/all_data.json index d92bf09f6..3ea0ab5b5 100644 --- a/fixtures/anna_elga_2_schedule_off/all_data.json +++ b/fixtures/anna_elga_2_schedule_off/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "573c152e7d4f4720878222bd75638f5b": { "available": true, "binary_sensors": { diff --git a/fixtures/anna_elga_no_cooling/all_data.json b/fixtures/anna_elga_no_cooling/all_data.json index 360a372a7..ee3a73ab7 100644 --- a/fixtures/anna_elga_no_cooling/all_data.json +++ b/fixtures/anna_elga_no_cooling/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_heatpump_cooling/all_data.json b/fixtures/anna_heatpump_cooling/all_data.json index ef96db377..5e7096d2e 100644 --- a/fixtures/anna_heatpump_cooling/all_data.json +++ b/fixtures/anna_heatpump_cooling/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json b/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json index 0a14757c8..5749bea7e 100644 --- a/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json +++ b/fixtures/anna_heatpump_cooling_fake_firmware/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_heatpump_heating/all_data.json b/fixtures/anna_heatpump_heating/all_data.json index 0d3bc93a6..66b02931f 100644 --- a/fixtures/anna_heatpump_heating/all_data.json +++ b/fixtures/anna_heatpump_heating/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_loria_cooling_active/all_data.json b/fixtures/anna_loria_cooling_active/all_data.json index efb18770c..c4cd3cebc 100644 --- a/fixtures/anna_loria_cooling_active/all_data.json +++ b/fixtures/anna_loria_cooling_active/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "582dfbdace4d4aeb832923ce7d1ddda0": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/anna_loria_driessens/all_data.json b/fixtures/anna_loria_driessens/all_data.json index fac986eea..d6225e4a5 100644 --- a/fixtures/anna_loria_driessens/all_data.json +++ b/fixtures/anna_loria_driessens/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "5c118b1842e943c0a5b6ef88a60bb17a": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/anna_loria_heating_idle/all_data.json b/fixtures/anna_loria_heating_idle/all_data.json index 2c318d838..1006547da 100644 --- a/fixtures/anna_loria_heating_idle/all_data.json +++ b/fixtures/anna_loria_heating_idle/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "582dfbdace4d4aeb832923ce7d1ddda0": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/anna_v4/all_data.json b/fixtures/anna_v4/all_data.json index 51c9ec0f1..a9c312534 100644 --- a/fixtures/anna_v4/all_data.json +++ b/fixtures/anna_v4/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/anna_v4_dhw/all_data.json b/fixtures/anna_v4_dhw/all_data.json index 590e56c95..d50a8144b 100644 --- a/fixtures/anna_v4_dhw/all_data.json +++ b/fixtures/anna_v4_dhw/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/anna_v4_no_tag/all_data.json b/fixtures/anna_v4_no_tag/all_data.json index 86ab1962b..602e59ea4 100644 --- a/fixtures/anna_v4_no_tag/all_data.json +++ b/fixtures/anna_v4_no_tag/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "01b85360fdd243d0aaad4d6ac2a5ba7e": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/anna_without_boiler_fw441/all_data.json b/fixtures/anna_without_boiler_fw441/all_data.json index 05b9c08d5..12b5b0336 100644 --- a/fixtures/anna_without_boiler_fw441/all_data.json +++ b/fixtures/anna_without_boiler_fw441/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "7ffbb3ab4b6c4ab2915d7510f7bf8fe9": { "active_preset": "home", "available_schedules": [ diff --git a/fixtures/legacy_anna/all_data.json b/fixtures/legacy_anna/all_data.json index 17e1cd8e6..2b0a27182 100644 --- a/fixtures/legacy_anna/all_data.json +++ b/fixtures/legacy_anna/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "1.8.22", diff --git a/fixtures/legacy_anna_2/all_data.json b/fixtures/legacy_anna_2/all_data.json index 5664dc7cf..537a12b86 100644 --- a/fixtures/legacy_anna_2/all_data.json +++ b/fixtures/legacy_anna_2/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "9e7377867dc24e51b8098a5ba02bd89d": { "active_preset": null, "available_schedules": [ diff --git a/fixtures/p1v4_442_single/all_data.json b/fixtures/p1v4_442_single/all_data.json index 27d3dceb7..3ea4bb01b 100644 --- a/fixtures/p1v4_442_single/all_data.json +++ b/fixtures/p1v4_442_single/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "a455b61e52394b2db5081ce025a430f3": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/p1v4_442_triple/all_data.json b/fixtures/p1v4_442_triple/all_data.json index 75b3e4dfb..b7476b24a 100644 --- a/fixtures/p1v4_442_triple/all_data.json +++ b/fixtures/p1v4_442_triple/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "03e65b16e4b247a29ae0d75a78cb492e": { "binary_sensors": { "plugwise_notification": true diff --git a/fixtures/smile_p1_v2/all_data.json b/fixtures/smile_p1_v2/all_data.json index 4c0aa878e..5d970d401 100644 --- a/fixtures/smile_p1_v2/all_data.json +++ b/fixtures/smile_p1_v2/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "938696c4bcdb4b8a9a595cb38ed43913": { "dev_class": "smartmeter", "location": "938696c4bcdb4b8a9a595cb38ed43913", diff --git a/fixtures/smile_p1_v2_2/all_data.json b/fixtures/smile_p1_v2_2/all_data.json index e425207b6..3cc59aa60 100644 --- a/fixtures/smile_p1_v2_2/all_data.json +++ b/fixtures/smile_p1_v2_2/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "199aa40f126840f392983d171374ab0b": { "dev_class": "smartmeter", "location": "199aa40f126840f392983d171374ab0b", diff --git a/fixtures/stretch_v23/all_data.json b/fixtures/stretch_v23/all_data.json index f14cdccc3..77bc12c40 100644 --- a/fixtures/stretch_v23/all_data.json +++ b/fixtures/stretch_v23/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "2.3.12", diff --git a/fixtures/stretch_v27_no_domain/all_data.json b/fixtures/stretch_v27_no_domain/all_data.json index ab00efeac..042cfe538 100644 --- a/fixtures/stretch_v27_no_domain/all_data.json +++ b/fixtures/stretch_v27_no_domain/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "2.7.18", diff --git a/fixtures/stretch_v31/all_data.json b/fixtures/stretch_v31/all_data.json index 692151f34..b1675116b 100644 --- a/fixtures/stretch_v31/all_data.json +++ b/fixtures/stretch_v31/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "0000aaaa0000aaaa0000aaaa0000aa00": { "dev_class": "gateway", "firmware": "3.1.11", From 0a40885ee5875173fe5ea420b4ca6321795a73a7 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 25 Nov 2024 17:53:36 +0100 Subject: [PATCH 100/106] Update manual-fixtures script --- scripts/manual_fixtures.py | 160 ++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index b8a6c12f2..c766741af 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -36,8 +36,8 @@ def json_writer(manual_name: str, all_data: dict) -> None: adam_multiple_devices_per_zone = base.copy() # Change schedule to not present for "446ac08dd04d4eff8ac57489757b7314" -adam_multiple_devices_per_zone["entities"]["446ac08dd04d4eff8ac57489757b7314"].pop("available_schedules") -adam_multiple_devices_per_zone["entities"]["446ac08dd04d4eff8ac57489757b7314"].pop("select_schedule") +adam_multiple_devices_per_zone["devices"]["446ac08dd04d4eff8ac57489757b7314"].pop("available_schedules") +adam_multiple_devices_per_zone["devices"]["446ac08dd04d4eff8ac57489757b7314"].pop("select_schedule") json_writer("m_adam_multiple_devices_per_zone", adam_multiple_devices_per_zone) @@ -50,7 +50,7 @@ def json_writer(manual_name: str, all_data: dict) -> None: adam_jip = base.copy() # Change mode to off for "06aecb3d00354375924f50c47af36bd2" -adam_jip["entities"]["06aecb3d00354375924f50c47af36bd2"]["climate_mode"] = "off" +adam_jip["devices"]["06aecb3d00354375924f50c47af36bd2"]["climate_mode"] = "off" json_writer("m_adam_jip", adam_jip) @@ -70,92 +70,92 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling["gateway"]["item_count"] = 89 # Remove devices 67d73d0bd469422db25a618a5fb8eeb0, 29542b2b6a6a4169acecc15c72a599b8 and 10016900610d4c7481df78c89606ef22 from anywhere -m_adam_cooling["entities"].pop("29542b2b6a6a4169acecc15c72a599b8") -m_adam_cooling["entities"].pop("67d73d0bd469422db25a618a5fb8eeb0") -m_adam_cooling["entities"].pop("10016900610d4c7481df78c89606ef22") +m_adam_cooling["devices"].pop("29542b2b6a6a4169acecc15c72a599b8") +m_adam_cooling["devices"].pop("67d73d0bd469422db25a618a5fb8eeb0") +m_adam_cooling["devices"].pop("10016900610d4c7481df78c89606ef22") # Correct setpoint for device "ad4838d7d35c4d6ea796ee12ae5aedf8" and zone "f2bf9048bef64cc5b6d5110154e33c81" -m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "setpoint" ] = 23.5 -m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "temperature" ] = 25.8 -m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ +m_adam_cooling["devices"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ "setpoint" ] = 23.5 -m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ +m_adam_cooling["devices"]["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ "temperature" ] = 25.8 -m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_cooling["devices"]["f2bf9048bef64cc5b6d5110154e33c81"][ "select_schedule" ] = "off" -m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_cooling["devices"]["f2bf9048bef64cc5b6d5110154e33c81"][ "control_state" ] = "cooling" -m_adam_cooling["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" +m_adam_cooling["devices"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "cool" # Add new key available -m_adam_cooling["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["available"] = True +m_adam_cooling["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["available"] = True # (again, following diff) # Remove device "2568cc4b9c1e401495d4741a5f89bee1" from anywhere -m_adam_cooling["entities"].pop("2568cc4b9c1e401495d4741a5f89bee1") +m_adam_cooling["devices"].pop("2568cc4b9c1e401495d4741a5f89bee1") # Remove device "854f8a9b0e7e425db97f1f110e1ce4b3" from anywhere -m_adam_cooling["entities"].pop("854f8a9b0e7e425db97f1f110e1ce4b3") +m_adam_cooling["devices"].pop("854f8a9b0e7e425db97f1f110e1ce4b3") # Go for 1772 -m_adam_cooling["entities"]["1772a4ea304041adb83f357b751341ff"]["sensors"].pop("setpoint") -m_adam_cooling["entities"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ +m_adam_cooling["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"].pop("setpoint") +m_adam_cooling["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 21.6 # Go for e2f4 -m_adam_cooling["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_cooling["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "setpoint" ] = 23.5 -m_adam_cooling["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_cooling["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "temperature" ] = 23.9 -m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ +m_adam_cooling["devices"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 25.0 -m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ +m_adam_cooling["devices"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ "temperature" ] = 23.9 -m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"][ +m_adam_cooling["devices"]["f871b8c4d63549319221e294e4f88074"][ "control_state" ] = "auto" -m_adam_cooling["entities"]["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "cool" +m_adam_cooling["devices"]["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "cool" # Go for da22 -m_adam_cooling["entities"]["da224107914542988a88561b4452b0f6"][ +m_adam_cooling["devices"]["da224107914542988a88561b4452b0f6"][ "select_regulation_mode" ] = "cooling" -m_adam_cooling["entities"]["da224107914542988a88561b4452b0f6"][ +m_adam_cooling["devices"]["da224107914542988a88561b4452b0f6"][ "regulation_modes" ].append("cooling") -m_adam_cooling["entities"]["da224107914542988a88561b4452b0f6"]["sensors"][ +m_adam_cooling["devices"]["da224107914542988a88561b4452b0f6"]["sensors"][ "outdoor_temperature" ] = 29.65 # Go for 056e -m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "cooling_state" ] = True -m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = False -m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "flame_state" ] = False -m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "water_temperature" ] = 19.0 -m_adam_cooling["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_cooling["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 17.5 @@ -169,77 +169,77 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_heating["gateway"]["cooling_present"] = False # Correct setpoint for "ad4838d7d35c4d6ea796ee12ae5aedf8" -m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ +m_adam_heating["devices"]["f2bf9048bef64cc5b6d5110154e33c81"]["thermostat"][ "setpoint" ] = 20.0 -m_adam_heating["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "setpoint" ] = 20.0 -m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ +m_adam_heating["devices"]["f2bf9048bef64cc5b6d5110154e33c81"]["sensors"][ "temperature" ] = 19.1 -m_adam_heating["entities"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ +m_adam_heating["devices"]["ad4838d7d35c4d6ea796ee12ae5aedf8"]["sensors"][ "temperature" ] = 19.1 -m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"][ +m_adam_heating["devices"]["f2bf9048bef64cc5b6d5110154e33c81"][ "control_state" ] = "preheating" -m_adam_heating["entities"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" +m_adam_heating["devices"]["f2bf9048bef64cc5b6d5110154e33c81"]["climate_mode"] = "heat" # Go for 1772 -m_adam_heating["entities"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ +m_adam_heating["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 18.6 # Related zone temperature is set below # Go for e2f4 -m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ +m_adam_heating["devices"]["f871b8c4d63549319221e294e4f88074"]["thermostat"][ "setpoint" ] = 15.0 -m_adam_heating["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_heating["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "setpoint" ] = 15.0 -m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ +m_adam_heating["devices"]["f871b8c4d63549319221e294e4f88074"]["sensors"][ "temperature" ] = 17.9 -m_adam_heating["entities"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ +m_adam_heating["devices"]["e2f4322d57924fa090fbbc48b3a140dc"]["sensors"][ "temperature" ] = 17.9 -m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "auto" -m_adam_heating["entities"]["f871b8c4d63549319221e294e4f88074"][ +m_adam_heating["devices"]["f871b8c4d63549319221e294e4f88074"]["climate_mode"] = "auto" +m_adam_heating["devices"]["f871b8c4d63549319221e294e4f88074"][ "control_state" ] = "off" # Go for da22 -m_adam_heating["entities"]["da224107914542988a88561b4452b0f6"][ +m_adam_heating["devices"]["da224107914542988a88561b4452b0f6"][ "select_regulation_mode" ] = "heating" -m_adam_heating["entities"]["da224107914542988a88561b4452b0f6"][ +m_adam_heating["devices"]["da224107914542988a88561b4452b0f6"][ "regulation_modes" ].remove("cooling") -m_adam_heating["entities"]["da224107914542988a88561b4452b0f6"]["sensors"][ +m_adam_heating["devices"]["da224107914542988a88561b4452b0f6"]["sensors"][ "outdoor_temperature" ] = -1.25 # Go for 056e -m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"].pop( +m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"].pop( "cooling_state" ) -m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "heating_state" ] = True -m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ +m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["binary_sensors"][ "flame_state" ] = False -m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "water_temperature" ] = 37.0 -m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ +m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["sensors"][ "intended_boiler_temperature" ] = 38.1 -m_adam_heating["entities"]["056ee145a816487eaa69243c3280f8bf"]["max_dhw_temperature"] = { +m_adam_heating["devices"]["056ee145a816487eaa69243c3280f8bf"]["max_dhw_temperature"] = { "setpoint": 60.0, "lower_bound": 40.0, "upper_bound": 60.0, @@ -261,58 +261,58 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_anna_heatpump_cooling["gateway"]["cooling_present"] = True # Go for 1cbf -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "model" ] = "Generic heater/cooler" -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["cooling_enabled"] = True -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["heating_state"] = False -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"][ "binary_sensors" ]["cooling_state"] = True -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "water_temperature" ] = 22.7 -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "dhw_temperature" ] = 41.5 -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "intended_boiler_temperature" ] = 0.0 -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "modulation_level" ] = 40 -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "return_temperature" ] = 23.8 -m_anna_heatpump_cooling["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_cooling["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "outdoor_air_temperature" ] = 28.0 # Go for 015a -m_anna_heatpump_cooling["entities"]["015ae9ea3f964e668e490fa39da3870b"]["sensors"][ +m_anna_heatpump_cooling["devices"]["015ae9ea3f964e668e490fa39da3870b"]["sensors"][ "outdoor_temperature" ] = 28.2 # Go for 3cb7 -m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ +m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ "setpoint_low" ] = 20.5 -m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ +m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["thermostat"][ "setpoint_high" ] = 30.0 -m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "temperature" ] = 26.3 -m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "setpoint_low" ] = 20.5 -m_anna_heatpump_cooling["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_cooling["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "setpoint_high" ] = 30.0 @@ -323,39 +323,39 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_anna_heatpump_idle = m_anna_heatpump_cooling.copy() # Go for 1cbf -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ "compressor_state" ] = False -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["binary_sensors"][ "cooling_state" ] = False -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "water_temperature" ] = 19.1 -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "dhw_temperature" ] = 46.3 -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "intended_boiler_temperature" ] = 18.0 -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "modulation_level" ] = 0 -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "return_temperature" ] = 22.0 -m_anna_heatpump_idle["entities"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ +m_anna_heatpump_idle["devices"]["1cbf783bb11e4a7c8a6843dee3a86927"]["sensors"][ "outdoor_air_temperature" ] = 28.2 # Go for 3cb7 -m_anna_heatpump_idle["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_idle["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "temperature" ] = 23.0 -m_anna_heatpump_idle["entities"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ +m_anna_heatpump_idle["devices"]["3cb70739631c4d17a86b8b12e8a5161b"]["sensors"][ "cooling_activation_outdoor_temperature" ] = 25.0 From 9aa8c64d5872f2044c7ba435b706590246a8ed04 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 25 Nov 2024 17:54:33 +0100 Subject: [PATCH 101/106] Save updated manual fixtures --- fixtures/m_adam_cooling/all_data.json | 2 +- fixtures/m_adam_heating/all_data.json | 2 +- fixtures/m_adam_jip/all_data.json | 2 +- fixtures/m_adam_multiple_devices_per_zone/all_data.json | 2 +- fixtures/m_anna_heatpump_cooling/all_data.json | 2 +- fixtures/m_anna_heatpump_idle/all_data.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index 94166804f..61b8b3c52 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index 5d7db1e43..6cf97fa6d 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "056ee145a816487eaa69243c3280f8bf": { "available": true, "binary_sensors": { diff --git a/fixtures/m_adam_jip/all_data.json b/fixtures/m_adam_jip/all_data.json index 9eac78e79..fcc817271 100644 --- a/fixtures/m_adam_jip/all_data.json +++ b/fixtures/m_adam_jip/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "06aecb3d00354375924f50c47af36bd2": { "active_preset": "no_frost", "climate_mode": "off", diff --git a/fixtures/m_adam_multiple_devices_per_zone/all_data.json b/fixtures/m_adam_multiple_devices_per_zone/all_data.json index 03ab9dea1..522c3620e 100644 --- a/fixtures/m_adam_multiple_devices_per_zone/all_data.json +++ b/fixtures/m_adam_multiple_devices_per_zone/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "02cf28bfec924855854c544690a609ef": { "available": true, "dev_class": "vcr_plug", diff --git a/fixtures/m_anna_heatpump_cooling/all_data.json b/fixtures/m_anna_heatpump_cooling/all_data.json index 15f427672..044de1244 100644 --- a/fixtures/m_anna_heatpump_cooling/all_data.json +++ b/fixtures/m_anna_heatpump_cooling/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false diff --git a/fixtures/m_anna_heatpump_idle/all_data.json b/fixtures/m_anna_heatpump_idle/all_data.json index 993625000..bc33ac339 100644 --- a/fixtures/m_anna_heatpump_idle/all_data.json +++ b/fixtures/m_anna_heatpump_idle/all_data.json @@ -1,5 +1,5 @@ { - "entities": { + "devices": { "015ae9ea3f964e668e490fa39da3870b": { "binary_sensors": { "plugwise_notification": false From afcff2911438c8e605125ba8091a7d17736efb0f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 25 Nov 2024 17:55:15 +0100 Subject: [PATCH 102/106] Bump to a3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4e7c6b7b0..f5bce3101 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.6.0a2" +version = "1.6.0a3" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" From bbddaf8036eb462a9eec2de2225ac6ff606ae831 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 26 Nov 2024 08:06:08 +0100 Subject: [PATCH 103/106] Manual-fixtures: keep setpoint for Tom --- scripts/manual_fixtures.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/manual_fixtures.py b/scripts/manual_fixtures.py index c766741af..d806cc36d 100755 --- a/scripts/manual_fixtures.py +++ b/scripts/manual_fixtures.py @@ -107,7 +107,6 @@ def json_writer(manual_name: str, all_data: dict) -> None: m_adam_cooling["devices"].pop("854f8a9b0e7e425db97f1f110e1ce4b3") # Go for 1772 -m_adam_cooling["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"].pop("setpoint") m_adam_cooling["devices"]["1772a4ea304041adb83f357b751341ff"]["sensors"][ "temperature" ] = 21.6 From 9e445b74a35aa248aa2f832820e31509d0376b56 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 26 Nov 2024 08:07:16 +0100 Subject: [PATCH 104/106] Save updated fixtures --- fixtures/m_adam_cooling/all_data.json | 1 + fixtures/m_adam_heating/all_data.json | 1 + 2 files changed, 2 insertions(+) diff --git a/fixtures/m_adam_cooling/all_data.json b/fixtures/m_adam_cooling/all_data.json index 61b8b3c52..f594f07bb 100644 --- a/fixtures/m_adam_cooling/all_data.json +++ b/fixtures/m_adam_cooling/all_data.json @@ -40,6 +40,7 @@ "name": "Tom Badkamer", "sensors": { "battery": 99, + "setpoint": 18.0, "temperature": 21.6, "temperature_difference": -0.2, "valve_position": 100 diff --git a/fixtures/m_adam_heating/all_data.json b/fixtures/m_adam_heating/all_data.json index 6cf97fa6d..7b350dddb 100644 --- a/fixtures/m_adam_heating/all_data.json +++ b/fixtures/m_adam_heating/all_data.json @@ -45,6 +45,7 @@ "name": "Tom Badkamer", "sensors": { "battery": 99, + "setpoint": 18.0, "temperature": 18.6, "temperature_difference": -0.2, "valve_position": 100 From 59d5525d2c25a5ef54be608b4ceee94328080868 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 26 Nov 2024 11:50:34 +0100 Subject: [PATCH 105/106] Update CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47c133553..f8b9c73f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ ## v1.6.0 -- New Feature: implement collection of location/zone data: Plugwise Adam thermostat representations are zone-based - in case there are more than one equal type of thermostats in one zone (e.g. 2 Tom's and no Lisa). +- New Feature: implement collection of location/zone data: Plugwise Adam thermostat representations are zone-based instead of device-based. + Solution for HA Core issue [#130597](https://github.com/home-assistant/core/issues/130597) ## v1.5.2 From e328a745ac6055d13543804d47ead1e10eaceee7 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 26 Nov 2024 11:54:57 +0100 Subject: [PATCH 106/106] Bump to v1.6.0 release-version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f5bce3101..67d8fb350 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.6.0a3" +version = "1.6.0" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md"