Repository: plugwise/python-plugwise (language: python)

Issue:
Refresh adam_plus_anna_new userdata



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72b67ef65..c184cbe7b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
 - Refresh adam_plus_anna_new userdata and adapt.
 - Bump actions and requirements to Python 3.12
 - Ruff as per #470 (defaulting black and isort to ruff)
+- Modularize/split testing, including separation of code and data
 
 ## v0.35.4
 


Test patch:
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 000000000..29abf108e
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,1 @@
+"""Tests for the Plugwise module."""
diff --git a/tests/data/adam/adam_heatpump_cooling.json b/tests/data/adam/adam_heatpump_cooling.json
new file mode 100644
index 000000000..dc1f743c2
--- /dev/null
+++ b/tests/data/adam/adam_heatpump_cooling.json
@@ -0,0 +1,573 @@
+{
+  "0ca13e8176204ca7bf6f09de59f81c83": {
+    "available": true,
+    "binary_sensors": {
+      "cooling_state": false,
+      "dhw_state": false,
+      "flame_state": false,
+      "heating_state": false
+    },
+    "dev_class": "heater_central",
+    "location": "eedadcb297564f1483faa509179aebed",
+    "max_dhw_temperature": {
+      "lower_bound": 40,
+      "resolution": 0.01,
+      "setpoint": 60,
+      "upper_bound": 65
+    },
+    "maximum_boiler_temperature": {
+      "lower_bound": 7,
+      "resolution": 0.01,
+      "setpoint": 35,
+      "upper_bound": 50
+    },
+    "model": "17.1",
+    "name": "OpenTherm",
+    "sensors": {
+      "dhw_temperature": 63.5,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "outdoor_air_temperature": 13.5,
+      "return_temperature": 24.9,
+      "water_pressure": 2,
+      "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",
+    "mode": "cool",
+    "model": "Lisa",
+    "name": "Thermostaat BK",
+    "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"],
+    "select_schedule": "off",
+    "sensors": {
+      "battery": 55,
+      "setpoint": 18,
+      "temperature": 18.8
+    },
+    "thermostat": {
+      "lower_bound": 0,
+      "resolution": 0.01,
+      "setpoint": 18,
+      "upper_bound": 99.9
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A17"
+  },
+  "1a27dd03b5454c4e8b9e75c8d1afc7af": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "20e735858f8146cead98b873177a4f99",
+    "model": "Plug",
+    "name": "Smart Plug DB",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": false
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A05"
+  },
+  "2e0fc4db2a6d4cbeb7cf786143543961": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "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,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A06"
+  },
+  "3b4d2574e2c9443a832b48d19a1c4f06": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "04b15f6e884448288f811d29fb7b1b30",
+    "model": "Plug",
+    "name": "Smart Plug SJ",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": false
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A14"
+  },
+  "3f0afa71f16c45ab964050002560e43c": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "fa5fa6b34f6b40a0972988b20e888ed4",
+    "model": "Plug",
+    "name": "Smart Plug WK",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 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",
+    "mode": "cool",
+    "model": "Lisa",
+    "name": "Thermostaat DB",
+    "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"],
+    "select_schedule": "off",
+    "sensors": {
+      "setpoint": 18,
+      "temperature": 22
+    },
+    "thermostat": {
+      "lower_bound": 0,
+      "resolution": 0.01,
+      "setpoint": 18,
+      "upper_bound": 99.9
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A20"
+  },
+  "5ead63c65e5f44e7870ba2bd680ceb9e": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "9a27714b970547ee9a6bdadc2b815ad5",
+    "model": "Plug",
+    "name": "Smart Plug SQ",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": false
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A15"
+  },
+  "7d97fc3117784cfdafe347bcedcbbbcb": {
+    "binary_sensors": {
+      "plugwise_notification": false
+    },
+    "dev_class": "gateway",
+    "firmware": "3.2.8",
+    "hardware": "AME Smile 2.0 board",
+    "location": "eedadcb297564f1483faa509179aebed",
+    "mac_address": "012345670001",
+    "model": "Gateway",
+    "name": "Adam",
+    "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",
+    "mode": "cool",
+    "model": "Lisa",
+    "name": "Thermostaat JM",
+    "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"],
+    "select_schedule": "off",
+    "sensors": {
+      "setpoint": 18,
+      "temperature": 20
+    },
+    "thermostat": {
+      "lower_bound": 0,
+      "resolution": 0.01,
+      "setpoint": 18,
+      "upper_bound": 99.9
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A01"
+  },
+  "838c2f48195242709b87217cf8d8a71f": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "b52908550469425b812c87f766fe5303",
+    "model": "Plug",
+    "name": "Smart Plug BK",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": false
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A12"
+  },
+  "8a482fa9dddb43acb765d019d8c9838b": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "5cc21042f87f4b4c94ccb5537c47a53f",
+    "model": "Plug",
+    "name": "Smart Plug BK2",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": false
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A10"
+  },
+  "96714ad90fc948bcbcb5021c4b9f5ae9": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "e39529c79ab54fda9bed26cfc0447546",
+    "model": "Plug",
+    "name": "Smart Plug JM",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": false
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A03"
+  },
+  "a03b6e8e76dd4646af1a77c31dd9370c": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": false
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A08"
+  },
+  "bbcffa48019f4b09b8368bbaf9559e68": {
+    "available": true,
+    "dev_class": "valve_actuator",
+    "firmware": "2020-05-13T02:00:00+02:00",
+    "location": "8cf650a4c10c44819e426bed406aec34",
+    "model": "Plug",
+    "name": "Smart Plug BK1",
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 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",
+    "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,
+      "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",
+    "mode": "cool",
+    "model": "Lisa",
+    "name": "Thermostaat RB",
+    "preset_modes": ["no_frost", "vacation", "away", "home", "asleep"],
+    "select_schedule": "off",
+    "sensors": {
+      "setpoint": 17,
+      "temperature": 20.7
+    },
+    "thermostat": {
+      "lower_bound": 0,
+      "resolution": 0.01,
+      "setpoint": 17,
+      "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",
+    "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,
+      "resolution": 0.01,
+      "setpoint": 21.5,
+      "upper_bound": 35
+    },
+    "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",
+    "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,
+      "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",
+    "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,
+      "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",
+    "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,
+      "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",
+    "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,
+      "resolution": 0.01,
+      "setpoint": 20.5,
+      "upper_bound": 99.9
+    },
+    "vendor": "Plugwise",
+    "zigbee_mac_address": "ABCD012345670A11"
+  }
+}
diff --git a/tests/data/adam/adam_jip.json b/tests/data/adam/adam_jip.json
new file mode 100644
index 000000000..db5106940
--- /dev/null
+++ b/tests/data/adam/adam_jip.json
@@ -0,0 +1,253 @@
+{
+  "e4684553153b44afbef2200885f379dc": {
+    "dev_class": "heater_central",
+    "location": "9e4433a9d69f40b3aefd15e74395eaec",
+    "model": "10.20",
+    "name": "OpenTherm",
+    "vendor": "Remeha B.V.",
+    "maximum_boiler_temperature": {
+      "setpoint": 90,
+      "lower_bound": 20,
+      "upper_bound": 90,
+      "resolution": 0.01
+    },
+    "max_dhw_temperature": {
+      "setpoint": 60,
+      "lower_bound": 40,
+      "upper_bound": 60,
+      "resolution": 0.01
+    },
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 37.3,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "return_temperature": 37.1,
+      "water_pressure": 1.4
+    },
+    "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": {
+      "setpoint": 13,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "available": true,
+    "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
+    "active_preset": "home",
+    "available_schedules": ["None"],
+    "select_schedule": "None",
+    "control_state": "off",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 30,
+      "setpoint": 13,
+      "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "available": true,
+    "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
+    "active_preset": "no_frost",
+    "available_schedules": ["None"],
+    "select_schedule": "None",
+    "control_state": "off",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 24.2,
+      "setpoint": 13,
+      "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,
+      "setpoint": 9,
+      "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "available": true,
+    "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
+    "active_preset": "home",
+    "available_schedules": ["None"],
+    "select_schedule": "None",
+    "control_state": "off",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 30,
+      "setpoint": 13,
+      "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,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.01
+    },
+    "available": true,
+    "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
+    "active_preset": "home",
+    "available_schedules": ["None"],
+    "select_schedule": "None",
+    "control_state": "off",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 27.4,
+      "setpoint": 9,
+      "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,
+      "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.3,
+      "setpoint": 13,
+      "temperature_difference": 1.7,
+      "valve_position": 0
+    }
+  },
+  "b5c2386c6f6342669e50fe49dd05b188": {
+    "dev_class": "gateway",
+    "firmware": "3.2.8",
+    "hardware": "AME Smile 2.0 board",
+    "location": "9e4433a9d69f40b3aefd15e74395eaec",
+    "mac_address": "012345670001",
+    "model": "Gateway",
+    "name": "Adam",
+    "zigbee_mac_address": "ABCD012345670101",
+    "vendor": "Plugwise",
+    "select_regulation_mode": "heating",
+    "regulation_modes": ["heating", "off", "bleeding_cold", "bleeding_hot"],
+    "binary_sensors": {
+      "plugwise_notification": false
+    },
+    "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,
+      "temperature_difference": 2,
+      "valve_position": 0
+    }
+  },
+  "457ce8414de24596a2d5e7dbc9c7682f": {
+    "dev_class": "zz_misc",
+    "location": "9e4433a9d69f40b3aefd15e74395eaec",
+    "model": "lumi.plug.maeu01",
+    "name": "Plug",
+    "zigbee_mac_address": "ABCD012345670A06",
+    "vendor": "LUMI",
+    "available": true,
+    "sensors": {
+      "electricity_consumed_interval": 0
+    },
+    "switches": {
+      "relay": false,
+      "lock": true
+    }
+  }
+}
diff --git a/tests/data/adam/adam_multiple_devices_per_zone.json b/tests/data/adam/adam_multiple_devices_per_zone.json
new file mode 100644
index 000000000..c719bb33e
--- /dev/null
+++ b/tests/data/adam/adam_multiple_devices_per_zone.json
@@ -0,0 +1,416 @@
+{
+  "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 16.5,
+      "setpoint": 13,
+      "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,
+      "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,
+      "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,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "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
+    },
+    "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,
+      "battery": 62,
+      "temperature_difference": 0.1,
+      "valve_position": 0
+    }
+  },
+  "21f2b542c49845e6bb416884c55778d6": {
+    "dev_class": "game_console",
+    "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": 82.6,
+      "electricity_consumed_interval": 8.6,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": false
+    }
+  },
+  "78d1126fc4c743db81b61c20e88342a7": {
+    "dev_class": "central_heating_pump",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true
+    }
+  },
+  "90986d591dcd426cae3ec3e8111ff730": {
+    "dev_class": "heater_central",
+    "location": "1f9dcf83fd4e4b66b72ff787957bfe5d",
+    "model": "Unknown",
+    "name": "OnOff",
+    "binary_sensors": {
+      "heating_state": true
+    },
+    "sensors": {
+      "water_temperature": 70,
+      "intended_boiler_temperature": 70,
+      "modulation_level": 1
+    }
+  },
+  "cd0ddb54ef694e11ac18ed1cbce5dbbd": {
+    "dev_class": "vcr",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "4a810418d5394b3f82727340b91ba740": {
+    "dev_class": "router",
+    "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,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "02cf28bfec924855854c544690a609ef": {
+    "dev_class": "vcr",
+    "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,
+      "electricity_consumed_interval": 9.15,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "a28f588dc4a049a483fd03a30361ad3a": {
+    "dev_class": "settop",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 17.2,
+      "setpoint": 15,
+      "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,
+      "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 18.9,
+      "setpoint": 14,
+      "battery": 92
+    }
+  },
+  "675416a629f343c495449970e2ca37b5": {
+    "dev_class": "router",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "upper_bound": 100,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 15.6,
+      "setpoint": 5.5,
+      "battery": 68,
+      "temperature_difference": 0,
+      "valve_position": 0
+    }
+  }
+}
diff --git a/tests/data/adam/adam_onoff_cooling_fake_firmware.json b/tests/data/adam/adam_onoff_cooling_fake_firmware.json
new file mode 100644
index 000000000..323ea9bb7
--- /dev/null
+++ b/tests/data/adam/adam_onoff_cooling_fake_firmware.json
@@ -0,0 +1,12 @@
+{
+  "0ca13e8176204ca7bf6f09de59f81c83": {
+    "binary_sensors": {
+      "cooling_state": true,
+      "dhw_state": false,
+      "heating_state": false
+    },
+    "sensors": {
+      "modulation_level": 0
+    }
+  }
+}
diff --git a/tests/data/adam/adam_plus_anna.json b/tests/data/adam/adam_plus_anna.json
new file mode 100644
index 000000000..087484ef4
--- /dev/null
+++ b/tests/data/adam/adam_plus_anna.json
@@ -0,0 +1,106 @@
+{
+  "2743216f626f43948deec1f7ab3b3d70": {
+    "dev_class": "heater_central",
+    "location": "07d618f0bb80412687f065b8698ce3e7",
+    "model": "Generic heater",
+    "name": "OpenTherm",
+    "maximum_boiler_temperature": {
+      "setpoint": 80,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "available": false,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 47,
+      "intended_boiler_temperature": 0
+    },
+    "switches": {
+      "dhw_cm_switch": false
+    }
+  },
+  "aa6b0002df0a46e1b1eb94beb61eddfe": {
+    "dev_class": "hometheater",
+    "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,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 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
+    },
+    "sensors": {
+      "outdoor_temperature": 11.9
+    }
+  },
+  "ee62cad889f94e8ca3d09021f03a660b": {
+    "dev_class": "thermostat",
+    "location": "009490cc2f674ce6b576863fbb64f867",
+    "model": "ThermoTouch",
+    "name": "Anna",
+    "vendor": "Plugwise",
+    "thermostat": {
+      "setpoint": 20.5,
+      "lower_bound": 1,
+      "upper_bound": 35,
+      "resolution": 0.01
+    },
+    "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
+    "active_preset": "home",
+    "available_schedules": ["Weekschema", "off"],
+    "select_schedule": "Weekschema",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 20.5,
+      "setpoint": 20.5
+    }
+  },
+  "f2be121e4a9345ac83c6e99ed89a98be": {
+    "dev_class": "computer_desktop",
+    "firmware": "2019-06-21T02:00:00+02:00",
+    "location": "5ccb6c41a7d9403988d261ceee04239f",
+    "name": "Work-PC",
+    "zigbee_mac_address": "ABCD012345670A02",
+    "vendor": "Plugwise",
+    "available": true,
+    "sensors": {
+      "electricity_consumed": 79.8,
+      "electricity_consumed_interval": 7.03,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": false
+    }
+  }
+}
diff --git a/tests/data/adam/adam_plus_anna_new.json b/tests/data/adam/adam_plus_anna_new.json
new file mode 100644
index 000000000..58218ed0d
--- /dev/null
+++ b/tests/data/adam/adam_plus_anna_new.json
@@ -0,0 +1,226 @@
+{
+  "da224107914542988a88561b4452b0f6": {
+    "dev_class": "gateway",
+    "firmware": "3.7.8",
+    "hardware": "AME Smile 2.0 board",
+    "location": "bc93488efab249e5bc54fd7e175a6f91",
+    "mac_address": "012345679891",
+    "model": "Gateway",
+    "name": "Adam",
+    "zigbee_mac_address": "000D6F000D5A168D",
+    "vendor": "Plugwise",
+    "binary_sensors": {
+      "plugwise_notification": false
+    },
+    "sensors": {
+      "outdoor_temperature": 9.19
+    },
+    "select_regulation_mode": "heating",
+    "regulation_modes": ["bleeding_hot", "bleeding_cold", "off", "heating"]
+  },
+  "056ee145a816487eaa69243c3280f8bf": {
+    "dev_class": "heater_central",
+    "location": "bc93488efab249e5bc54fd7e175a6f91",
+    "model": "Generic heater",
+    "name": "OpenTherm",
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": true,
+      "flame_state": true
+    },
+    "sensors": {
+      "water_temperature": 29,
+      "intended_boiler_temperature": 20
+    },
+    "switches": {
+      "dhw_cm_switch": false
+    },
+    "maximum_boiler_temperature": {
+      "setpoint": 50,
+      "resolution": 0.01,
+      "lower_bound": 25,
+      "upper_bound": 95
+    },
+    "available": true
+  },
+  "67d73d0bd469422db25a618a5fb8eeb0": {
+    "dev_class": "zz_misc",
+    "location": "b4f211175e124df59603412bafa77a34",
+    "model": "lumi.plug.maeu01",
+    "name": "SmartPlug Floor 0",
+    "zigbee_mac_address": "54EF4410002C97F2",
+    "vendor": "LUMI",
+    "sensors": {
+      "electricity_consumed_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": false
+    },
+    "available": true
+  },
+  "e2f4322d57924fa090fbbc48b3a140dc": {
+    "dev_class": "zone_thermostat",
+    "firmware": "2016-10-10T02:00:00+02:00",
+    "hardware": "255",
+    "location": "f871b8c4d63549319221e294e4f88074",
+    "model": "Lisa",
+    "name": "Lisa Badkamer",
+    "zigbee_mac_address": "000D6F000C869B61",
+    "vendor": "Plugwise",
+    "sensors": {
+      "temperature": 16.5,
+      "setpoint": 18,
+      "battery": 38
+    },
+    "temperature_offset": {
+      "lower_bound": -2,
+      "resolution": 0.1,
+      "upper_bound": 2,
+      "setpoint": 0
+    },
+    "thermostat": {
+      "setpoint": 18,
+      "resolution": 0.01,
+      "lower_bound": 0,
+      "upper_bound": 99.9
+    },
+    "available": true,
+    "control_state": "preheating",
+    "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"],
+    "active_preset": "home",
+    "available_schedules": [
+      "Badkamer",
+      "Test",
+      "Vakantie",
+      "Weekschema",
+      "off"
+    ],
+    "select_schedule": "Badkamer",
+    "mode": "auto"
+  },
+  "854f8a9b0e7e425db97f1f110e1ce4b3": {
+    "dev_class": "central_heating_pump",
+    "firmware": "2020-11-10T01:00:00+01:00",
+    "location": "f2bf9048bef64cc5b6d5110154e33c81",
+    "model": "Plug",
+    "name": "Plug Vloerverwarming",
+    "zigbee_mac_address": "000D6F000D13CB6F",
+    "vendor": "Plugwise",
+    "sensors": {
+      "electricity_consumed": 43.8,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true
+    },
+    "available": true
+  },
+  "ad4838d7d35c4d6ea796ee12ae5aedf8": {
+    "dev_class": "thermostat",
+    "location": "f2bf9048bef64cc5b6d5110154e33c81",
+    "model": "ThermoTouch",
+    "name": "Anna",
+    "vendor": "Plugwise",
+    "sensors": {
+      "temperature": 18.4,
+      "setpoint": 18.5
+    },
+    "thermostat": {
+      "setpoint": 18.5,
+      "resolution": 0.01,
+      "lower_bound": 1,
+      "upper_bound": 35
+    },
+    "control_state": "heating",
+    "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"],
+    "active_preset": "home",
+    "available_schedules": [
+      "Badkamer",
+      "Test",
+      "Vakantie",
+      "Weekschema",
+      "off"
+    ],
+    "select_schedule": "Weekschema",
+    "mode": "auto"
+  },
+  "29542b2b6a6a4169acecc15c72a599b8": {
+    "dev_class": "computer_desktop",
+    "firmware": "2020-11-10T01:00:00+01:00",
+    "location": "f2bf9048bef64cc5b6d5110154e33c81",
+    "model": "Plug",
+    "name": "Plug Werkplek",
+    "zigbee_mac_address": "000D6F000D13CA9A",
+    "vendor": "Plugwise",
+    "sensors": {
+      "electricity_consumed": 87.6,
+      "electricity_consumed_interval": 23,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": false
+    },
+    "available": true
+  },
+  "1772a4ea304041adb83f357b751341ff": {
+    "dev_class": "thermo_sensor",
+    "firmware": "2020-11-04T01:00:00+01:00",
+    "hardware": "1",
+    "location": "f871b8c4d63549319221e294e4f88074",
+    "model": "Tom/Floor",
+    "name": "Tom Badkamer",
+    "zigbee_mac_address": "000D6F000C8FF5EE",
+    "vendor": "Plugwise",
+    "sensors": {
+      "temperature": 17.6,
+      "setpoint": 18,
+      "battery": 99,
+      "temperature_difference": -0.2,
+      "valve_position": 100
+    },
+    "temperature_offset": {
+      "lower_bound": -2,
+      "resolution": 0.1,
+      "upper_bound": 2,
+      "setpoint": 0.1
+    },
+    "available": true
+  },
+  "2568cc4b9c1e401495d4741a5f89bee1": {
+    "dev_class": "hometheater",
+    "firmware": "2020-11-10T01:00:00+01:00",
+    "location": "f2bf9048bef64cc5b6d5110154e33c81",
+    "model": "Plug",
+    "name": "Plug MediaTV",
+    "zigbee_mac_address": "000D6F000D13CCFD",
+    "vendor": "Plugwise",
+    "sensors": {
+      "electricity_consumed": 14.8,
+      "electricity_consumed_interval": 3,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    },
+    "available": true
+  },
+  "e8ef2a01ed3b4139a53bf749204fe6b4": {
+    "dev_class": "switching",
+    "model": "Switchgroup",
+    "name": "Test",
+    "members": [
+      "2568cc4b9c1e401495d4741a5f89bee1",
+      "29542b2b6a6a4169acecc15c72a599b8"
+    ],
+    "switches": {
+      "relay": true
+    }
+  }
+}
diff --git a/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json
new file mode 100644
index 000000000..e357757de
--- /dev/null
+++ b/tests/data/adam/adam_plus_anna_new_UPDATED_DATA.json
@@ -0,0 +1,46 @@
+{
+  "67d73d0bd469422db25a618a5fb8eeb0": {
+    "switches": {
+      "lock": true
+    }
+  },
+  "ad4838d7d35c4d6ea796ee12ae5aedf8": {
+    "mode": "off"
+  },
+  "29542b2b6a6a4169acecc15c72a599b8": {
+    "switches": {
+      "relay": false,
+      "lock": false
+    }
+  },
+  "2568cc4b9c1e401495d4741a5f89bee1": {
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0
+    },
+    "switches": {
+      "relay": false,
+      "lock": false
+    }
+  },
+  "1772a4ea304041adb83f357b751341ff": {
+    "available": false
+  },
+  "e2f4322d57924fa090fbbc48b3a140dc": {
+    "mode": "off"
+  },
+  "da224107914542988a88561b4452b0f6": {
+    "binary_sensors": {
+      "plugwise_notification": true
+    }
+  },
+  "e8ef2a01ed3b4139a53bf749204fe6b4": {
+    "members": [
+      "2568cc4b9c1e401495d4741a5f89bee1",
+      "29542b2b6a6a4169acecc15c72a599b8"
+    ],
+    "switches": {
+      "relay": false
+    }
+  }
+}
diff --git a/tests/data/adam/adam_zone_per_device.json b/tests/data/adam/adam_zone_per_device.json
new file mode 100644
index 000000000..e3f3cfaad
--- /dev/null
+++ b/tests/data/adam/adam_zone_per_device.json
@@ -0,0 +1,416 @@
+{
+  "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 16.5,
+      "setpoint": 13,
+      "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": 0
+    }
+  },
+  "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,
+      "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,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "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
+    },
+    "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,
+      "battery": 62,
+      "temperature_difference": 0.1,
+      "valve_position": 0
+    }
+  },
+  "21f2b542c49845e6bb416884c55778d6": {
+    "dev_class": "game_console",
+    "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": 81.2,
+      "electricity_consumed_interval": 12.7,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": false
+    }
+  },
+  "78d1126fc4c743db81b61c20e88342a7": {
+    "dev_class": "central_heating_pump",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true
+    }
+  },
+  "90986d591dcd426cae3ec3e8111ff730": {
+    "dev_class": "heater_central",
+    "location": "1f9dcf83fd4e4b66b72ff787957bfe5d",
+    "model": "Unknown",
+    "name": "OnOff",
+    "binary_sensors": {
+      "heating_state": false
+    },
+    "sensors": {
+      "water_temperature": 70,
+      "intended_boiler_temperature": 70,
+      "modulation_level": 1
+    }
+  },
+  "cd0ddb54ef694e11ac18ed1cbce5dbbd": {
+    "dev_class": "vcr",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "4a810418d5394b3f82727340b91ba740": {
+    "dev_class": "router",
+    "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,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "02cf28bfec924855854c544690a609ef": {
+    "dev_class": "vcr",
+    "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,
+      "electricity_consumed_interval": 8.65,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "a28f588dc4a049a483fd03a30361ad3a": {
+    "dev_class": "settop",
+    "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,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 17.1,
+      "setpoint": 16,
+      "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,
+      "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,
+      "lower_bound": 0,
+      "upper_bound": 99.9,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 18.8,
+      "setpoint": 14,
+      "battery": 92
+    }
+  },
+  "675416a629f343c495449970e2ca37b5": {
+    "dev_class": "router",
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "upper_bound": 100,
+      "resolution": 0.01
+    },
+    "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",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 15.6,
+      "setpoint": 5.5,
+      "battery": 68,
+      "temperature_difference": 0.1,
+      "valve_position": 0
+    }
+  }
+}
diff --git a/tests/data/anna/anna_elga_2.json b/tests/data/anna/anna_elga_2.json
new file mode 100644
index 000000000..5bcfe4a0c
--- /dev/null
+++ b/tests/data/anna/anna_elga_2.json
@@ -0,0 +1,82 @@
+{
+  "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
+    },
+    "sensors": {
+      "outdoor_temperature": 13
+    }
+  },
+  "573c152e7d4f4720878222bd75638f5b": {
+    "dev_class": "heater_central",
+    "location": "d34dfe6ab90b410c98068e75de3eb631",
+    "model": "Generic heater/cooler",
+    "name": "OpenTherm",
+    "vendor": "Techneco",
+    "maximum_boiler_temperature": {
+      "setpoint": 60,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": false,
+      "compressor_state": false,
+      "cooling_state": false,
+      "cooling_enabled": false,
+      "slave_boiler_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 22.8,
+      "domestic_hot_water_setpoint": 60,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "return_temperature": 23.4,
+      "water_pressure": 0.5,
+      "outdoor_air_temperature": 14
+    },
+    "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,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"],
+    "active_preset": "home",
+    "available_schedules": ["Thermostat schedule", "off"],
+    "select_schedule": "Thermostat schedule",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 20.9,
+      "illuminance": 0.5,
+      "cooling_activation_outdoor_temperature": 26,
+      "cooling_deactivation_threshold": 3,
+      "setpoint_low": 19.5,
+      "setpoint_high": 30
+    }
+  }
+}
diff --git a/tests/data/anna/anna_elga_2_cooling.json b/tests/data/anna/anna_elga_2_cooling.json
new file mode 100644
index 000000000..0883ef00c
--- /dev/null
+++ b/tests/data/anna/anna_elga_2_cooling.json
@@ -0,0 +1,82 @@
+{
+  "573c152e7d4f4720878222bd75638f5b": {
+    "available": true,
+    "binary_sensors": {
+      "compressor_state": true,
+      "cooling_enabled": true,
+      "cooling_state": true,
+      "dhw_state": false,
+      "flame_state": false,
+      "heating_state": false,
+      "slave_boiler_state": false
+    },
+    "dev_class": "heater_central",
+    "location": "d34dfe6ab90b410c98068e75de3eb631",
+    "maximum_boiler_temperature": {
+      "lower_bound": 0,
+      "resolution": 1,
+      "setpoint": 60,
+      "upper_bound": 100
+    },
+    "model": "Generic heater/cooler",
+    "name": "OpenTherm",
+    "sensors": {
+      "domestic_hot_water_setpoint": 60,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "outdoor_air_temperature": 30,
+      "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",
+    "mode": "auto",
+    "model": "ThermoTouch",
+    "name": "Anna",
+    "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"],
+    "select_schedule": "Thermostat schedule",
+    "sensors": {
+      "cooling_activation_outdoor_temperature": 26,
+      "cooling_deactivation_threshold": 3,
+      "illuminance": 0.5,
+      "setpoint_high": 23,
+      "setpoint_low": 4,
+      "temperature": 24.9
+    },
+    "thermostat": {
+      "lower_bound": 4,
+      "resolution": 0.1,
+      "setpoint_high": 23,
+      "setpoint_low": 4,
+      "upper_bound": 30
+    },
+    "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
+    },
+    "vendor": "Plugwise"
+  }
+}
diff --git a/tests/data/anna/anna_elga_2_schedule_off.json b/tests/data/anna/anna_elga_2_schedule_off.json
new file mode 100644
index 000000000..d7f9ca6d2
--- /dev/null
+++ b/tests/data/anna/anna_elga_2_schedule_off.json
@@ -0,0 +1,31 @@
+{
+  "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,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"],
+    "active_preset": "home",
+    "available_schedules": ["Thermostat schedule", "off"],
+    "select_schedule": "off",
+    "mode": "heat_cool",
+    "sensors": {
+      "temperature": 20.9,
+      "illuminance": 0.5,
+      "cooling_activation_outdoor_temperature": 26,
+      "cooling_deactivation_threshold": 3,
+      "setpoint_low": 19.5,
+      "setpoint_high": 30
+    }
+  }
+}
diff --git a/tests/data/anna/anna_heatpump_cooling.json b/tests/data/anna/anna_heatpump_cooling.json
new file mode 100644
index 000000000..6141d8029
--- /dev/null
+++ b/tests/data/anna/anna_heatpump_cooling.json
@@ -0,0 +1,82 @@
+{
+  "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
+    },
+    "sensors": {
+      "outdoor_temperature": 22
+    }
+  },
+  "1cbf783bb11e4a7c8a6843dee3a86927": {
+    "dev_class": "heater_central",
+    "location": "a57efe5f145f498c9be62a9b63626fbf",
+    "model": "Generic heater/cooler",
+    "name": "OpenTherm",
+    "vendor": "Techneco",
+    "maximum_boiler_temperature": {
+      "setpoint": 60,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": false,
+      "compressor_state": true,
+      "cooling_enabled": true,
+      "cooling_state": true,
+      "slave_boiler_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 24.7,
+      "domestic_hot_water_setpoint": 60,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 40,
+      "return_temperature": 23.8,
+      "water_pressure": 1.61,
+      "outdoor_air_temperature": 22
+    },
+    "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,
+      "setpoint_high": 22,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["no_frost", "home", "away", "asleep", "vacation"],
+    "active_preset": "home",
+    "available_schedules": ["standaard", "off"],
+    "select_schedule": "off",
+    "mode": "heat_cool",
+    "sensors": {
+      "temperature": 22.3,
+      "illuminance": 25.5,
+      "cooling_activation_outdoor_temperature": 21,
+      "cooling_deactivation_threshold": 6,
+      "setpoint_low": 4,
+      "setpoint_high": 22
+    }
+  }
+}
diff --git a/tests/data/anna/anna_heatpump_cooling_fake_firmware.json b/tests/data/anna/anna_heatpump_cooling_fake_firmware.json
new file mode 100644
index 000000000..2a7f146a0
--- /dev/null
+++ b/tests/data/anna/anna_heatpump_cooling_fake_firmware.json
@@ -0,0 +1,16 @@
+{
+  "1cbf783bb11e4a7c8a6843dee3a86927": {
+    "binary_sensors": {
+      "cooling_enabled": true,
+      "cooling_state": true,
+      "dhw_state": false,
+      "heating_state": false
+    },
+    "sensors": {
+      "modulation_level": 100
+    }
+  },
+  "015ae9ea3f964e668e490fa39da3870b": {
+    "firmware": "4.10.10"
+  }
+}
diff --git a/tests/data/anna/anna_heatpump_heating.json b/tests/data/anna/anna_heatpump_heating.json
new file mode 100644
index 000000000..66083ca89
--- /dev/null
+++ b/tests/data/anna/anna_heatpump_heating.json
@@ -0,0 +1,94 @@
+{
+  "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
+    },
+    "sensors": {
+      "outdoor_temperature": 20.2
+    }
+  },
+  "1cbf783bb11e4a7c8a6843dee3a86927": {
+    "dev_class": "heater_central",
+    "location": "a57efe5f145f498c9be62a9b63626fbf",
+    "model": "Generic heater/cooler",
+    "name": "OpenTherm",
+    "vendor": "Techneco",
+    "maximum_boiler_temperature": {
+      "setpoint": 60,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "max_dhw_temperature": {
+      "setpoint": 53,
+      "lower_bound": 35,
+      "upper_bound": 60,
+      "resolution": 0.01
+    },
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": true,
+      "compressor_state": true,
+      "cooling_state": false,
+      "cooling_enabled": false,
+      "slave_boiler_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 29.1,
+      "dhw_temperature": 46.3,
+      "intended_boiler_temperature": 35,
+      "modulation_level": 52,
+      "return_temperature": 25.1,
+      "water_pressure": 1.57,
+      "outdoor_air_temperature": 3
+    },
+    "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,
+      "resolution": 0.1,
+      "upper_bound": 2,
+      "setpoint": -0.5
+    },
+    "thermostat": {
+      "setpoint_low": 20.5,
+      "setpoint_high": 30,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["no_frost", "home", "away", "asleep", "vacation"],
+    "active_preset": "home",
+    "available_schedules": ["standaard", "off"],
+    "select_schedule": "standaard",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 19.3,
+      "illuminance": 86,
+      "cooling_activation_outdoor_temperature": 21,
+      "cooling_deactivation_threshold": 4,
+      "setpoint_low": 20.5,
+      "setpoint_high": 30
+    }
+  }
+}
diff --git a/tests/data/anna/anna_heatpump_heating_UPDATED_DATA.json b/tests/data/anna/anna_heatpump_heating_UPDATED_DATA.json
new file mode 100644
index 000000000..136af014c
--- /dev/null
+++ b/tests/data/anna/anna_heatpump_heating_UPDATED_DATA.json
@@ -0,0 +1,38 @@
+{
+  "1cbf783bb11e4a7c8a6843dee3a86927": {
+    "dev_class": "heater_central",
+    "location": "a57efe5f145f498c9be62a9b63626fbf",
+    "model": "Generic heater/cooler",
+    "name": "OpenTherm",
+    "vendor": "Techneco",
+    "maximum_boiler_temperature": {
+      "setpoint": 60,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": true,
+      "compressor_state": true,
+      "cooling_state": false,
+      "cooling_enabled": false,
+      "slave_boiler_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 29.1,
+      "domestic_hot_water_setpoint": 60,
+      "dhw_temperature": 46.3,
+      "intended_boiler_temperature": 35,
+      "modulation_level": 52,
+      "return_temperature": 25.1,
+      "water_pressure": 1.57,
+      "outdoor_air_temperature": 3
+    },
+    "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
new file mode 100644
index 000000000..73281903d
--- /dev/null
+++ b/tests/data/anna/anna_loria_cooling_active.json
@@ -0,0 +1,85 @@
+{
+  "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,
+      "setpoint_high": 23.5,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["away", "vacation", "no_frost", "home", "asleep"],
+    "active_preset": "home",
+    "available_schedules": ["Winter", "Test ", "off"],
+    "select_schedule": "Winter",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 24.1,
+      "illuminance": 45,
+      "setpoint_low": 4,
+      "setpoint_high": 23.5
+    }
+  },
+  "bfb5ee0a88e14e5f97bfa725a760cc49": {
+    "dev_class": "heater_central",
+    "location": "674b657c138a41a291d315d7471deb06",
+    "model": "173",
+    "name": "OpenTherm",
+    "vendor": "Atlantic",
+    "select_dhw_mode": "auto",
+    "maximum_boiler_temperature": {
+      "setpoint": 40,
+      "lower_bound": 25,
+      "upper_bound": 45,
+      "resolution": 0.01
+    },
+    "max_dhw_temperature": {
+      "setpoint": 53,
+      "lower_bound": 35,
+      "upper_bound": 60,
+      "resolution": 0.01
+    },
+    "dhw_modes": ["off", "auto", "boost", "eco", "comfort"],
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": false,
+      "cooling_state": true,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 25.3,
+      "dhw_temperature": 52.9,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 100,
+      "return_temperature": 26.3,
+      "outdoor_air_temperature": 17.3
+    },
+    "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
+    },
+    "sensors": {
+      "outdoor_temperature": 15.5
+    }
+  }
+}
diff --git a/tests/data/anna/anna_loria_driessens.json b/tests/data/anna/anna_loria_driessens.json
new file mode 100644
index 000000000..71cae23f6
--- /dev/null
+++ b/tests/data/anna/anna_loria_driessens.json
@@ -0,0 +1,97 @@
+{
+  "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",
+    "name": "Smile Anna",
+    "sensors": {
+      "outdoor_temperature": 6.81
+    },
+    "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",
+    "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,
+      "setpoint_low": 20,
+      "temperature": 21.2
+    },
+    "temperature_offset": {
+      "lower_bound": -2,
+      "resolution": 0.1,
+      "setpoint": 0,
+      "upper_bound": 2
+    },
+    "thermostat": {
+      "lower_bound": 4,
+      "resolution": 0.1,
+      "setpoint_high": 30,
+      "setpoint_low": 20,
+      "upper_bound": 30
+    },
+    "vendor": "Plugwise"
+  },
+  "a449cbc334ae4a5bb7f89064984b2906": {
+    "available": true,
+    "binary_sensors": {
+      "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,
+      "resolution": 0.01,
+      "setpoint": 53,
+      "upper_bound": 60
+    },
+    "maximum_boiler_temperature": {
+      "lower_bound": 25,
+      "resolution": 0.01,
+      "setpoint": 45,
+      "upper_bound": 45
+    },
+    "model": "173",
+    "name": "OpenTherm",
+    "select_dhw_mode": "auto",
+    "sensors": {
+      "dhw_temperature": 49.5,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "outdoor_air_temperature": 7.63,
+      "return_temperature": 23,
+      "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
new file mode 100644
index 000000000..05893ff0f
--- /dev/null
+++ b/tests/data/anna/anna_loria_heating_idle.json
@@ -0,0 +1,85 @@
+{
+  "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,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["away", "vacation", "no_frost", "home", "asleep"],
+    "active_preset": "home",
+    "available_schedules": ["Winter", "Test ", "off"],
+    "select_schedule": "Winter",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 22.1,
+      "illuminance": 45,
+      "setpoint_low": 20.5,
+      "setpoint_high": 30
+    }
+  },
+  "bfb5ee0a88e14e5f97bfa725a760cc49": {
+    "dev_class": "heater_central",
+    "location": "674b657c138a41a291d315d7471deb06",
+    "model": "173",
+    "name": "OpenTherm",
+    "vendor": "Atlantic",
+    "select_dhw_mode": "auto",
+    "maximum_boiler_temperature": {
+      "setpoint": 40,
+      "lower_bound": 25,
+      "upper_bound": 45,
+      "resolution": 0.01
+    },
+    "max_dhw_temperature": {
+      "setpoint": 53,
+      "lower_bound": 35,
+      "upper_bound": 60,
+      "resolution": 0.01
+    },
+    "dhw_modes": ["off", "auto", "boost", "eco", "comfort"],
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": false,
+      "cooling_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 25.3,
+      "dhw_temperature": 52.9,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "return_temperature": 26.3,
+      "outdoor_air_temperature": 17.3
+    },
+    "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
+    },
+    "sensors": {
+      "outdoor_temperature": 15.5
+    }
+  }
+}
diff --git a/tests/data/anna/anna_v4.json b/tests/data/anna/anna_v4.json
new file mode 100644
index 000000000..fced6b820
--- /dev/null
+++ b/tests/data/anna/anna_v4.json
@@ -0,0 +1,78 @@
+{
+  "cd0e6156b1f04d5f952349ffbe397481": {
+    "dev_class": "heater_central",
+    "location": "94c107dc6ac84ed98e9f68c0dd06bf71",
+    "model": "2.32",
+    "name": "OpenTherm",
+    "vendor": "Bosch Thermotechniek B.V.",
+    "maximum_boiler_temperature": {
+      "setpoint": 70,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "max_dhw_temperature": {
+      "setpoint": 60,
+      "lower_bound": 30,
+      "upper_bound": 60,
+      "resolution": 0.01
+    },
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": true,
+      "flame_state": true
+    },
+    "sensors": {
+      "water_temperature": 52,
+      "intended_boiler_temperature": 48.6,
+      "modulation_level": 0,
+      "return_temperature": 42,
+      "water_pressure": 2.1
+    },
+    "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,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["vacation", "no_frost", "away", "asleep", "home"],
+    "active_preset": "home",
+    "available_schedules": ["Standaard", "Thuiswerken", "off"],
+    "select_schedule": "off",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 20.5,
+      "setpoint": 20.5,
+      "illuminance": 40.5
+    }
+  },
+  "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
+    }
+  }
+}
diff --git a/tests/data/anna/anna_v4_UPDATED_DATA.json b/tests/data/anna/anna_v4_UPDATED_DATA.json
new file mode 100644
index 000000000..b9776085c
--- /dev/null
+++ b/tests/data/anna/anna_v4_UPDATED_DATA.json
@@ -0,0 +1,52 @@
+{
+  "cd0e6156b1f04d5f952349ffbe397481": {
+    "maximum_boiler_temperature": {
+      "setpoint": 69,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "max_dhw_temperature": {
+      "setpoint": 59,
+      "lower_bound": 30,
+      "upper_bound": 60,
+      "resolution": 0.01
+    },
+    "binary_sensors": {
+      "dhw_state": false,
+      "heating_state": false,
+      "flame_state": false
+    },
+    "sensors": {
+      "water_temperature": 51,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "return_temperature": 41,
+      "water_pressure": 2.1
+    },
+    "switches": {
+      "dhw_cm_switch": true
+    }
+  },
+  "01b85360fdd243d0aaad4d6ac2a5ba7e": {
+    "thermostat": {
+      "setpoint": 19.5,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "active_preset": "away",
+    "select_schedule": "Standaard",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 19.5,
+      "setpoint": 19.5,
+      "illuminance": 39.5
+    }
+  },
+  "0466eae8520144c78afb29628384edeb": {
+    "sensors": {
+      "outdoor_temperature": 6.44
+    }
+  }
+}
diff --git a/tests/data/anna/anna_v4_dhw.json b/tests/data/anna/anna_v4_dhw.json
new file mode 100644
index 000000000..a70be4414
--- /dev/null
+++ b/tests/data/anna/anna_v4_dhw.json
@@ -0,0 +1,78 @@
+{
+  "cd0e6156b1f04d5f952349ffbe397481": {
+    "dev_class": "heater_central",
+    "location": "94c107dc6ac84ed98e9f68c0dd06bf71",
+    "model": "2.32",
+    "name": "OpenTherm",
+    "vendor": "Bosch Thermotechniek B.V.",
+    "maximum_boiler_temperature": {
+      "setpoint": 70,
+      "lower_bound": 0,
+      "upper_bound": 100,
+      "resolution": 1
+    },
+    "max_dhw_temperature": {
+      "setpoint": 60,
+      "lower_bound": 30,
+      "upper_bound": 60,
+      "resolution": 0.01
+    },
+    "available": true,
+    "binary_sensors": {
+      "dhw_state": true,
+      "heating_state": false,
+      "flame_state": true
+    },
+    "sensors": {
+      "water_temperature": 52,
+      "intended_boiler_temperature": 48.6,
+      "modulation_level": 0,
+      "return_temperature": 42,
+      "water_pressure": 2.1
+    },
+    "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,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["vacation", "no_frost", "away", "asleep", "home"],
+    "active_preset": "home",
+    "available_schedules": ["Standaard", "Thuiswerken", "off"],
+    "select_schedule": "off",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 20.5,
+      "setpoint": 20.5,
+      "illuminance": 40.5
+    }
+  },
+  "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
+    }
+  }
+}
diff --git a/tests/data/anna/anna_without_boiler_fw441.json b/tests/data/anna/anna_without_boiler_fw441.json
new file mode 100644
index 000000000..fbe3bd015
--- /dev/null
+++ b/tests/data/anna/anna_without_boiler_fw441.json
@@ -0,0 +1,52 @@
+{
+  "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
+    },
+    "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,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["no_frost", "asleep", "away", "vacation", "home"],
+    "active_preset": "home",
+    "available_schedules": ["Test", "Normaal", "off"],
+    "select_schedule": "Normaal",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 19.1,
+      "setpoint": 19,
+      "illuminance": 0.25
+    }
+  },
+  "c46b4794d28149699eacf053deedd003": {
+    "dev_class": "heater_central",
+    "location": "0f4f2ada20734a339fe353348fe87b96",
+    "model": "Unknown",
+    "name": "OnOff",
+    "binary_sensors": {
+      "heating_state": false
+    }
+  }
+}
diff --git a/tests/data/anna/legacy_anna.json b/tests/data/anna/legacy_anna.json
new file mode 100644
index 000000000..7f4edb342
--- /dev/null
+++ b/tests/data/anna/legacy_anna.json
@@ -0,0 +1,63 @@
+{
+  "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",
+    "binary_sensors": {
+      "plugwise_notification": false
+    }
+  },
+  "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,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["away", "vacation", "asleep", "home", "no_frost"],
+    "active_preset": "home",
+    "available_schedules": ["Thermostat schedule"],
+    "select_schedule": "Thermostat schedule",
+    "mode": "auto",
+    "sensors": {
+      "temperature": 20.4,
+      "illuminance": 151,
+      "setpoint": 20.5
+    }
+  },
+  "04e4cbfe7f4340f090f85ec3b9e6a950": {
+    "dev_class": "heater_central",
+    "location": "0000aaaa0000aaaa0000aaaa0000aa00",
+    "model": "4.21",
+    "name": "OpenTherm",
+    "vendor": "Bosch Thermotechniek B.V.",
+    "maximum_boiler_temperature": {
+      "setpoint": 50,
+      "lower_bound": 50,
+      "upper_bound": 90,
+      "resolution": 1
+    },
+    "binary_sensors": {
+      "flame_state": true,
+      "heating_state": true
+    },
+    "sensors": {
+      "water_temperature": 23.6,
+      "intended_boiler_temperature": 17,
+      "modulation_level": 0,
+      "return_temperature": 21.7,
+      "water_pressure": 1.2
+    }
+  }
+}
diff --git a/tests/data/anna/legacy_anna_2.json b/tests/data/anna/legacy_anna_2.json
new file mode 100644
index 000000000..9bcb1505a
--- /dev/null
+++ b/tests/data/anna/legacy_anna_2.json
@@ -0,0 +1,65 @@
+{
+  "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",
+    "binary_sensors": {
+      "plugwise_notification": false
+    },
+    "sensors": {
+      "outdoor_temperature": 21
+    }
+  },
+  "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,
+      "lower_bound": 4,
+      "upper_bound": 30,
+      "resolution": 0.1
+    },
+    "preset_modes": ["vacation", "away", "no_frost", "home", "asleep"],
+    "active_preset": null,
+    "available_schedules": ["Thermostat schedule"],
+    "select_schedule": "None",
+    "mode": "heat",
+    "sensors": {
+      "temperature": 21.4,
+      "illuminance": 19.5,
+      "setpoint": 15
+    }
+  },
+  "ea5d8a7177e541b0a4b52da815166de4": {
+    "dev_class": "heater_central",
+    "location": "be81e3f8275b4129852c4d8d550ae2eb",
+    "model": "Generic heater",
+    "name": "OpenTherm",
+    "maximum_boiler_temperature": {
+      "setpoint": 70,
+      "lower_bound": 50,
+      "upper_bound": 90,
+      "resolution": 1
+    },
+    "binary_sensors": {
+      "flame_state": false,
+      "heating_state": false
+    },
+    "sensors": {
+      "water_temperature": 54,
+      "intended_boiler_temperature": 0,
+      "modulation_level": 0,
+      "return_temperature": 0,
+      "water_pressure": 1.7
+    }
+  }
+}
diff --git a/tests/data/p1/p1v4.json b/tests/data/p1/p1v4.json
new file mode 100644
index 000000000..c9a4c12b0
--- /dev/null
+++ b/tests/data/p1/p1v4.json
@@ -0,0 +1,39 @@
+{
+  "a455b61e52394b2db5081ce025a430f3": {
+    "dev_class": "gateway",
+    "firmware": "4.1.1",
+    "hardware": "AME Smile 2.0 board",
+    "location": "a455b61e52394b2db5081ce025a430f3",
+    "mac_address": "012345670001",
+    "model": "Gateway",
+    "name": "Smile P1",
+    "vendor": "Plugwise",
+    "binary_sensors": {
+      "plugwise_notification": true
+    }
+  },
+  "ba4de7613517478da82dd9b6abea36af": {
+    "dev_class": "smartmeter",
+    "location": "a455b61e52394b2db5081ce025a430f3",
+    "model": "KFM5KAIFA-METER",
+    "name": "P1",
+    "vendor": "SHENZHEN KAIFA TECHNOLOGY CHENGDU CO.",
+    "available": false,
+    "sensors": {
+      "net_electricity_point": 548,
+      "electricity_consumed_peak_point": 548,
+      "electricity_consumed_off_peak_point": 0,
+      "net_electricity_cumulative": 20983.453,
+      "electricity_consumed_peak_cumulative": 9067.554,
+      "electricity_consumed_off_peak_cumulative": 11915.899,
+      "electricity_consumed_peak_interval": 335,
+      "electricity_consumed_off_peak_interval": 0,
+      "electricity_produced_peak_point": 0,
+      "electricity_produced_off_peak_point": 0,
+      "electricity_produced_peak_cumulative": 0,
+      "electricity_produced_off_peak_cumulative": 0,
+      "electricity_produced_peak_interval": 0,
+      "electricity_produced_off_peak_interval": 0
+    }
+  }
+}
diff --git a/tests/data/p1/p1v4_442_single.json b/tests/data/p1/p1v4_442_single.json
new file mode 100644
index 000000000..98158bda5
--- /dev/null
+++ b/tests/data/p1/p1v4_442_single.json
@@ -0,0 +1,41 @@
+{
+  "a455b61e52394b2db5081ce025a430f3": {
+    "dev_class": "gateway",
+    "firmware": "4.4.2",
+    "hardware": "AME Smile 2.0 board",
+    "location": "a455b61e52394b2db5081ce025a430f3",
+    "mac_address": "012345670001",
+    "model": "Gateway",
+    "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": 421,
+      "electricity_consumed_peak_point": 0,
+      "electricity_consumed_off_peak_point": 421,
+      "net_electricity_cumulative": 31610.113,
+      "electricity_consumed_peak_cumulative": 13966.608,
+      "electricity_consumed_off_peak_cumulative": 17643.505,
+      "electricity_consumed_peak_interval": 0,
+      "electricity_consumed_off_peak_interval": 21,
+      "electricity_produced_peak_point": 0,
+      "electricity_produced_off_peak_point": 0,
+      "electricity_produced_peak_cumulative": 0,
+      "electricity_produced_off_peak_cumulative": 0,
+      "electricity_produced_peak_interval": 0,
+      "electricity_produced_off_peak_interval": 0,
+      "electricity_phase_one_consumed": 413,
+      "electricity_phase_one_produced": 0
+    }
+  }
+}
diff --git a/tests/data/p1/p1v4_442_single_UPDATED_DATA.json b/tests/data/p1/p1v4_442_single_UPDATED_DATA.json
new file mode 100644
index 000000000..c8df13efe
--- /dev/null
+++ b/tests/data/p1/p1v4_442_single_UPDATED_DATA.json
@@ -0,0 +1,19 @@
+{
+  "ba4de7613517478da82dd9b6abea36af": {
+    "sensors": {
+      "net_electricity_point": -2248,
+      "electricity_consumed_peak_point": 0,
+      "electricity_consumed_off_peak_point": 0,
+      "electricity_consumed_peak_interval": 0,
+      "electricity_consumed_off_peak_interval": 0,
+      "electricity_produced_peak_point": 2248,
+      "electricity_produced_off_peak_point": 0,
+      "electricity_produced_peak_cumulative": 6.543,
+      "electricity_produced_off_peak_cumulative": 0,
+      "electricity_produced_peak_interval": 1345,
+      "electricity_produced_off_peak_interval": 0,
+      "electricity_phase_one_consumed": 0,
+      "electricity_phase_one_produced": 1998
+    }
+  }
+}
diff --git a/tests/data/p1/p1v4_442_triple.json b/tests/data/p1/p1v4_442_triple.json
new file mode 100644
index 000000000..3a56ac537
--- /dev/null
+++ b/tests/data/p1/p1v4_442_triple.json
@@ -0,0 +1,50 @@
+{
+  "03e65b16e4b247a29ae0d75a78cb492e": {
+    "dev_class": "gateway",
+    "firmware": "4.4.2",
+    "hardware": "AME Smile 2.0 board",
+    "location": "03e65b16e4b247a29ae0d75a78cb492e",
+    "mac_address": "012345670001",
+    "model": "Gateway",
+    "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,
+      "electricity_consumed_peak_point": 0,
+      "electricity_consumed_off_peak_point": 5553,
+      "net_electricity_cumulative": 231866.539,
+      "electricity_consumed_peak_cumulative": 161328.641,
+      "electricity_consumed_off_peak_cumulative": 70537.898,
+      "electricity_consumed_peak_interval": 0,
+      "electricity_consumed_off_peak_interval": 314,
+      "electricity_produced_peak_point": 0,
+      "electricity_produced_off_peak_point": 0,
+      "electricity_produced_peak_cumulative": 0,
+      "electricity_produced_off_peak_cumulative": 0,
+      "electricity_produced_peak_interval": 0,
+      "electricity_produced_off_peak_interval": 0,
+      "electricity_phase_one_consumed": 1763,
+      "electricity_phase_two_consumed": 1703,
+      "electricity_phase_three_consumed": 2080,
+      "electricity_phase_one_produced": 0,
+      "electricity_phase_two_produced": 0,
+      "electricity_phase_three_produced": 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
+    }
+  }
+}
diff --git a/tests/data/p1/smile_p1_v2.json b/tests/data/p1/smile_p1_v2.json
new file mode 100644
index 000000000..163114972
--- /dev/null
+++ b/tests/data/p1/smile_p1_v2.json
@@ -0,0 +1,34 @@
+{
+  "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,
+      "electricity_consumed_point": 458,
+      "net_electricity_cumulative": 1019.201,
+      "electricity_consumed_peak_cumulative": 1155.195,
+      "electricity_consumed_off_peak_cumulative": 1642.74,
+      "electricity_consumed_peak_interval": 250,
+      "electricity_consumed_off_peak_interval": 0,
+      "electricity_produced_point": 0,
+      "electricity_produced_peak_cumulative": 1296.136,
+      "electricity_produced_off_peak_cumulative": 482.598,
+      "electricity_produced_peak_interval": 0,
+      "electricity_produced_off_peak_interval": 0,
+      "gas_consumed_cumulative": 584.433,
+      "gas_consumed_interval": 0.016
+    }
+  }
+}
diff --git a/tests/data/p1/smile_p1_v2_2.json b/tests/data/p1/smile_p1_v2_2.json
new file mode 100644
index 000000000..44827f1ef
--- /dev/null
+++ b/tests/data/p1/smile_p1_v2_2.json
@@ -0,0 +1,34 @@
+{
+  "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,
+      "electricity_consumed_point": 458,
+      "net_electricity_cumulative": 1019.201,
+      "electricity_consumed_peak_cumulative": 1155.195,
+      "electricity_consumed_off_peak_cumulative": 1642.74,
+      "electricity_consumed_peak_interval": 250,
+      "electricity_consumed_off_peak_interval": 0,
+      "electricity_produced_point": 0,
+      "electricity_produced_peak_cumulative": 1296.136,
+      "electricity_produced_off_peak_cumulative": 482.598,
+      "electricity_produced_peak_interval": 0,
+      "electricity_produced_off_peak_interval": 0,
+      "gas_consumed_cumulative": 584.433,
+      "gas_consumed_interval": 0.016
+    }
+  }
+}
diff --git a/tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json b/tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json
new file mode 100644
index 000000000..ad3cd8c35
--- /dev/null
+++ b/tests/data/p1/smile_p1_v2_2_UPDATED_DATA.json
@@ -0,0 +1,16 @@
+{
+  "199aa40f126840f392983d171374ab0b": {
+    "sensors": {
+      "net_electricity_point": -2248,
+      "electricity_consumed_point": 0,
+      "net_electricity_cumulative": 1019.101,
+      "electricity_consumed_peak_cumulative": 1155.295,
+      "electricity_consumed_off_peak_cumulative": 1642.84,
+      "electricity_produced_point": 2248,
+      "electricity_produced_peak_cumulative": 1296.336,
+      "electricity_produced_off_peak_cumulative": 482.698,
+      "gas_consumed_cumulative": 585.433,
+      "gas_consumed_interval": 0
+    }
+  }
+}
diff --git a/tests/data/stretch/stretch_v23.json b/tests/data/stretch/stretch_v23.json
new file mode 100644
index 000000000..974f9bc94
--- /dev/null
+++ b/tests/data/stretch/stretch_v23.json
@@ -0,0 +1,333 @@
+{
+  "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "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
+    },
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0.58,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "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
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "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,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "f7b145c8492f4dd7a4de760456fdef3e": {
+    "dev_class": "switching",
+    "model": "Switchgroup",
+    "name": "Test",
+    "members": ["407aa1c1099d463c9137a3a9eda787fd"],
+    "switches": {
+      "relay": false
+    }
+  }
+}
diff --git a/tests/data/stretch/stretch_v27_no_domain.json b/tests/data/stretch/stretch_v27_no_domain.json
new file mode 100644
index 000000000..f8d9e1aa4
--- /dev/null
+++ b/tests/data/stretch/stretch_v27_no_domain.json
@@ -0,0 +1,36 @@
+{
+  "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,
+      "electricity_produced_interval": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "8b8d14b242e24cd789743c828b9a2ea9": {
+    "sensors": {
+      "electricity_consumed": 1.69
+    },
+    "switches": {
+      "lock": false,
+      "relay": true
+    }
+  },
+  "d0122ac66eba47b99d8e5fbd1e2f5932": {
+    "sensors": {
+      "electricity_consumed_interval": 2.21
+    }
+  }
+}
diff --git a/tests/data/stretch/stretch_v31.json b/tests/data/stretch/stretch_v31.json
new file mode 100644
index 000000000..423bc431e
--- /dev/null
+++ b/tests/data/stretch/stretch_v31.json
@@ -0,0 +1,134 @@
+{
+  "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,
+      "electricity_produced": 0
+    },
+    "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
+    },
+    "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,
+      "electricity_consumed_interval": 0.71,
+      "electricity_produced": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "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,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": false
+    }
+  },
+  "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
+    }
+  }
+}
diff --git a/tests/data/stretch/stretch_v31_UPDATED_DATA.json b/tests/data/stretch/stretch_v31_UPDATED_DATA.json
new file mode 100644
index 000000000..3b37765c1
--- /dev/null
+++ b/tests/data/stretch/stretch_v31_UPDATED_DATA.json
@@ -0,0 +1,44 @@
+{
+  "aac7b735042c4832ac9ff33aae4f453b": {
+    "sensors": {
+      "electricity_consumed": 1000,
+      "electricity_consumed_interval": 20.7,
+      "electricity_produced": 0
+    },
+    "switches": {
+      "relay": true,
+      "lock": true
+    }
+  },
+  "cfe95cf3de1948c0b8955125bf754614": {
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "switches": {
+      "relay": false,
+      "lock": false
+    }
+  },
+  "059e4d03c7a34d278add5c7a4a781d19": {
+    "sensors": {
+      "electricity_consumed": 0,
+      "electricity_consumed_interval": 0,
+      "electricity_produced": 0
+    },
+    "switches": {
+      "relay": false,
+      "lock": false
+    }
+  },
+  "d03738edfcc947f7b8f4573571d90d2d": {
+    "members": [
+      "059e4d03c7a34d278add5c7a4a781d19",
+      "cfe95cf3de1948c0b8955125bf754614"
+    ],
+    "switches": {
+      "relay": false
+    }
+  }
+}
diff --git a/tests/test_adam.py b/tests/test_adam.py
new file mode 100644
index 000000000..db3305d8c
--- /dev/null
+++ b/tests/test_adam.py
@@ -0,0 +1,398 @@
+"""Test Plugwise module Adam related functionality."""
+
+import pytest
+
+from .test_init import _LOGGER, TestPlugwise, pw_exceptions
+
+SMILE_TYPE = "adam"
+
+# Reoccuring constants
+BADKAMER_SCHEMA = "Badkamer Schema"
+CV_JESSIE = "CV Jessie"
+GF7_WOONKAMER = "GF7  Woonkamer"
+WERKDAG_SCHEMA = "Werkdag schema"
+
+
+class TestPlugwiseAdam(TestPlugwise):  # pylint: disable=attribute-defined-outside-init
+    """Tests for Adam standalone, i.e. not combined with Anna or Jip."""
+
+    @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 smile.device_items == 315
+
+        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
+        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)
+        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
+
+        try:
+            await smile.delete_notification()
+            notification_deletion = False  # pragma: no cover
+        except pw_exceptions.ResponseError:
+            notification_deletion = True
+
+        assert notification_deletion
+
+        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 smile.device_items == 315
+
+        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 smile.device_items == 413
+
+        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,
+            smile_legacy=None,
+        )
+
+        await self.device_test(smile, "2022-01-02 00:00:01", testdata)
+        assert smile.device_items == 54
+        assert smile._cooling_present
+        assert smile._cooling_enabled
+
+        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 smile.device_items == 70
+        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)
+        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_connect_adam_plus_anna_copy_with_error_domain_added(self):
+        """Test erroneous domain_objects file from user."""
+        testdata = {
+            # Central
+            "2743216f626f43948deec1f7ab3b3d70": {
+                "binary_sensors": {"heating_state": False},
+            },
+        }
+
+        self.smile_setup = "adam_plus_anna_copy_with_error_domain_added"
+        server, smile, client = await self.connect_wrapper()
+        assert smile.smile_hostname == "smile000000"
+
+        self.validate_test_basics(
+            _LOGGER,
+            smile,
+            smile_version="3.0.23",
+        )
+
+        await self.device_test(smile, "2020-03-22 00:00:01", testdata)
+        assert smile.device_items == 70
+
+        assert "3d28a20e17cb47dca210a132463721d5" in self.notifications
+
+        await smile.close_connection()
+        await self.disconnect(server, client)
+
+    @pytest.mark.asyncio
+    async def test_connect_adam_plus_anna_new(self):
+        """Test extended Adam (firmware 3.8) with Anna and a switch-group setup."""
+        self.smile_setup = "adam_plus_anna_new"
+
+        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=None,
+            smile_version="3.7.8",
+        )
+
+        await self.device_test(smile, "2023-12-17 00:00:01", testdata)
+        assert smile.gateway_id == "da224107914542988a88561b4452b0f6"
+        assert smile._last_active["f2bf9048bef64cc5b6d5110154e33c81"] == "Weekschema"
+        assert smile._last_active["f871b8c4d63549319221e294e4f88074"] == "Badkamer"
+        assert smile.device_items == 145
+        assert smile.device_list == [
+            "da224107914542988a88561b4452b0f6",
+            "056ee145a816487eaa69243c3280f8bf",
+            "67d73d0bd469422db25a618a5fb8eeb0",
+            "e2f4322d57924fa090fbbc48b3a140dc",
+            "854f8a9b0e7e425db97f1f110e1ce4b3",
+            "ad4838d7d35c4d6ea796ee12ae5aedf8",
+            "29542b2b6a6a4169acecc15c72a599b8",
+            "1772a4ea304041adb83f357b751341ff",
+            "2568cc4b9c1e401495d4741a5f89bee1",
+            "e8ef2a01ed3b4139a53bf749204fe6b4",
+        ]
+
+        result = await self.tinker_thermostat(
+            smile,
+            "f2bf9048bef64cc5b6d5110154e33c81",
+            good_schedules=["Weekschema", "Badkamer", "Test"],
+        )
+        assert result
+
+        # Special test-case for turning a schedule off based on only the location id.
+        await smile.set_schedule_state("f2bf9048bef64cc5b6d5110154e33c81", "off")
+
+        # Special test-case for turning a schedule off for a location via the option "off".
+        await smile.set_schedule_state("f2bf9048bef64cc5b6d5110154e33c81", "on", "off")
+
+        # bad schedule-state test
+        result = await self.tinker_thermostat_schedule(
+            smile,
+            "f2bf9048bef64cc5b6d5110154e33c81",
+            "bad",
+            good_schedules=["Badkamer"],
+            single=True,
+        )
+        assert result
+
+        smile._schedule_old_states["f2bf9048bef64cc5b6d5110154e33c81"][
+            "Badkamer"
+        ] = "off"
+        result_1 = await self.tinker_thermostat_schedule(
+            smile,
+            "f2bf9048bef64cc5b6d5110154e33c81",
+            "on",
+            good_schedules=["Badkamer"],
+            single=True,
+        )
+        result_2 = await self.tinker_thermostat_schedule(
+            smile,
+            "f2bf9048bef64cc5b6d5110154e33c81",
+            "on",
+            good_schedules=["Badkamer"],
+            single=True,
+        )
+        assert result_1 and result_2
+
+        switch_change = await self.tinker_switch(
+            smile,
+            "e8ef2a01ed3b4139a53bf749204fe6b4",
+            ["2568cc4b9c1e401495d4741a5f89bee1", "29542b2b6a6a4169acecc15c72a599b8"],
+        )
+        assert switch_change
+        switch_change = await self.tinker_switch(
+            smile, "056ee145a816487eaa69243c3280f8bf", model="dhw_cm_switch"
+        )
+        assert switch_change
+        switch_change = await self.tinker_switch(
+            smile, "854f8a9b0e7e425db97f1f110e1ce4b3", model="lock"
+        )
+        assert switch_change
+        switch_change = await self.tinker_switch(
+            smile, "2568cc4b9c1e401495d4741a5f89bee1"
+        )
+        assert not switch_change
+
+        await self.tinker_regulation_mode(smile)
+
+        await self.tinker_max_boiler_temp(smile)
+
+        # 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/adam_plus_anna_new"
+        await self.device_test(
+            smile, "2022-01-16 00:00:01", testdata_updated, initialize=False
+        )
+
+        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 smile.device_items == 219
+
+        # 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
new file mode 100644
index 000000000..03fb99911
--- /dev/null
+++ b/tests/test_anna.py
@@ -0,0 +1,599 @@
+"""Test Plugwise module Anna related functionality."""
+
+import pytest
+
+from .test_init import _LOGGER, TestPlugwise, pw_exceptions
+
+SMILE_TYPE = "anna"
+# Reoccuring constants
+THERMOSTAT_SCHEDULE = "Thermostat schedule"
+
+
+class TestPlugwiseAnna(TestPlugwise):  # pylint: disable=attribute-defined-outside-init
+    """Tests for Anna standalone, i.e. not combined with Adam."""
+
+    @pytest.mark.asyncio
+    async def test_connect_legacy_anna(self):
+        """Test a legacy Anna device."""
+        self.smile_setup = "legacy_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="1.8.22",
+            smile_legacy=True,
+        )
+
+        await self.device_test(smile, "2020-03-22 00:00:01", testdata)
+        assert smile.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00"
+        assert (
+            smile._last_active["0000aaaa0000aaaa0000aaaa0000aa00"]
+            == THERMOSTAT_SCHEDULE
+        )
+        assert smile.device_items == 44
+        assert not self.notifications
+
+        result = await self.tinker_thermostat(
+            smile,
+            "0000aaaa0000aaaa0000aaaa0000aa00",
+            good_schedules=[
+                THERMOSTAT_SCHEDULE,
+            ],
+        )
+        assert result
+        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)
+        result = await self.tinker_thermostat(
+            smile,
+            "0000aaaa0000aaaa0000aaaa0000aa00",
+            good_schedules=[
+                THERMOSTAT_SCHEDULE,
+            ],
+            unhappy=True,
+        )
+        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)
+        # LEFT: figure out why None becomes str instead of nonetype on this particular one
+        #       i.e. in JSON `9e7377867dc24e51b8098a5ba02bd89d`:select_schedule is now 'None' not null
+        server, smile, client = await self.connect_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 (
+            smile._last_active["be81e3f8275b4129852c4d8d550ae2eb"]
+            == THERMOSTAT_SCHEDULE
+        )
+        assert smile.device_items == 44
+        assert not self.notifications
+
+        result = await self.tinker_thermostat(
+            smile,
+            "be81e3f8275b4129852c4d8d550ae2eb",
+            good_schedules=[
+                THERMOSTAT_SCHEDULE,
+            ],
+        )
+        assert result
+
+        smile._schedule_old_states["be81e3f8275b4129852c4d8d550ae2eb"][
+            THERMOSTAT_SCHEDULE
+        ] = "off"
+        result_1 = await self.tinker_thermostat_schedule(
+            smile,
+            "be81e3f8275b4129852c4d8d550ae2eb",
+            "on",
+            good_schedules=[THERMOSTAT_SCHEDULE],
+            single=True,
+        )
+        result_2 = await self.tinker_thermostat_schedule(
+            smile,
+            "be81e3f8275b4129852c4d8d550ae2eb",
+            "on",
+            good_schedules=[THERMOSTAT_SCHEDULE],
+            single=True,
+        )
+        assert result_1 and result_2
+
+        await smile.close_connection()
+        await self.disconnect(server, client)
+
+    @pytest.mark.asyncio
+    async def test_connect_anna_v4(self):
+        """Test an Anna firmware 4 setup."""
+        self.smile_setup = "anna_v4"
+
+        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.gateway_id == "0466eae8520144c78afb29628384edeb"
+        assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard"
+        assert smile.device_items == 56
+        assert not self.notifications
+
+        assert not smile._cooling_present
+        assert not smile._cooling_active
+        assert not smile._cooling_enabled
+
+        result = await self.tinker_thermostat(
+            smile,
+            "eb5309212bf5407bb143e5bfa3b18aee",
+            schedule_on=False,
+            good_schedules=["Standaard", "Thuiswerken"],
+        )
+        assert result
+        result = await self.tinker_temp_offset(
+            smile, "01b85360fdd243d0aaad4d6ac2a5ba7e"
+        )
+        assert result
+        result = await self.tinker_temp_offset(
+            smile, "0466eae8520144c78afb29628384edeb"
+        )
+        assert not result
+
+        # 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/anna_v4"
+        await self.device_test(
+            smile, "2020-04-05 00:00:01", testdata_updated, initialize=False
+        )
+
+        await smile.close_connection()
+        await self.disconnect(server, client)
+
+        server, smile, client = await self.connect_wrapper(raise_timeout=True)
+        # Reset self.smile_setup
+        self.smile_setup = "anna_v4"
+        await self.device_test(smile, "2020-04-05 00:00:01", testdata)
+        result = await self.tinker_thermostat(
+            smile,
+            "eb5309212bf5407bb143e5bfa3b18aee",
+            schedule_on=False,
+            good_schedules=["Standaard", "Thuiswerken"],
+            unhappy=True,
+        )
+        assert result
+        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 smile.device_items == 56
+        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 smile.device_items == 56
+
+        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 smile.device_items == 38
+        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 smile.device_items == 66
+        assert not self.notifications
+        assert self.cooling_present
+        assert not smile._cooling_enabled
+        assert not smile._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 smile.device_items == 63
+        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 smile.device_items == 63
+        assert self.cooling_present
+        assert not self.notifications
+
+        assert smile._cooling_enabled
+        assert smile._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",
+            smile_legacy=None,
+        )
+
+        await self.device_test(smile, "2020-04-19 00:00:01", testdata)
+        assert smile.device_items == 63
+        assert smile._cooling_present
+        assert smile._cooling_enabled
+        assert smile._cooling_active
+
+        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 smile.device_items == 62
+        assert smile.gateway_id == "fb49af122f6e4b0f91267e1cf7666d6f"
+        assert self.cooling_present
+        assert not smile._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 smile._cooling_present
+        assert not smile._cooling_enabled
+        assert smile.device_items == 62
+
+        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",
+        )
+        assert not smile._smile_legacy
+
+        await self.device_test(smile, "2022-03-10 00:00:01", testdata)
+        assert (
+            smile._last_active["d3ce834534114348be628b61b26d9220"]
+            == THERMOSTAT_SCHEDULE
+        )
+        assert smile.device_items == 62
+        assert not self.notifications
+
+        assert self.cooling_present
+        assert smile._cooling_enabled
+        assert smile._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,
+            smile_legacy=None,
+        )
+
+        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
+        assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter"
+        assert smile.device_items == 63
+        assert smile._cooling_present
+        assert not smile._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
+
+        await self.tinker_dhw_mode(smile)
+
+        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,
+            smile_legacy=None,
+        )
+
+        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
+        assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter"
+        assert smile.device_items == 63
+        assert smile._cooling_present
+        assert smile._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,
+            smile_legacy=None,
+        )
+
+        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
+        assert smile.device_items == 63
+        assert smile._cooling_present
+        assert not smile._cooling_enabled
+
+        await smile.close_connection()
+        await self.disconnect(server, client)
diff --git a/tests/test_generic.py b/tests/test_generic.py
new file mode 100644
index 000000000..dcc00aa82
--- /dev/null
+++ b/tests/test_generic.py
@@ -0,0 +1,81 @@
+"""Test Plugwise module generic functionality."""
+
+from unittest.mock import patch
+
+import pytest
+
+import aiohttp
+
+from .test_init import _LOGGER, TestPlugwise, pw_exceptions
+
+
+class TestPlugwiseGeneric(
+    TestPlugwise
+):  # pylint: disable=attribute-defined-outside-init
+    """Tests for generic functionality."""
+
+    @pytest.mark.asyncio
+    async def test_fail_legacy_system(self):
+        """Test erroneous legacy stretch system."""
+        self.smile_setup = "faulty_stretch"
+        try:
+            _server, _smile, _client = await self.connect_wrapper()
+            setup_result = False  # pragma: no cover
+        except pw_exceptions.InvalidXMLError:
+            setup_result = True
+        assert setup_result
+
+    @pytest.mark.asyncio
+    async def test_fail_anna_connected_to_adam(self):
+        """Test erroneous adam with anna system."""
+        self.smile_setup = "anna_connected_to_adam"
+        try:
+            _server, _smile, _client = await self.connect_wrapper()
+            setup_result = False  # pragma: no cover
+        except pw_exceptions.InvalidSetupError:
+            setup_result = True
+        assert setup_result
+
+    @pytest.mark.asyncio
+    async def test_invalid_credentials(self):
+        """Test P1 with invalid credentials setup."""
+        self.smile_setup = "p1v4"
+        try:
+            await self.connect_wrapper(fail_auth=True)
+            setup_result = False  # pragma: no cover
+        except pw_exceptions.InvalidAuthentication:
+            _LOGGER.debug("InvalidAuthentication raised successfully")
+            setup_result = True
+        assert setup_result
+
+    @pytest.mark.asyncio
+    async def test_connect_fail_firmware(self):
+        """Test a P1 non existing firmware setup."""
+        self.smile_setup = "fail_firmware"
+        try:
+            await self.connect_wrapper()
+            setup_result = False  # pragma: no cover
+        except pw_exceptions.UnsupportedDeviceError:
+            setup_result = True
+        assert setup_result
+
+    # Test connect for timeout
+    @patch(
+        "plugwise.helper.ClientSession.get",
+        side_effect=aiohttp.ServerTimeoutError,
+    )
+    @pytest.mark.asyncio
+    async def test_connect_timeout(self, timeout_test):
+        """Wrap connect to raise timeout during get."""
+        # pylint: disable=unused-variable
+        try:
+            self.smile_setup = "p1v4"
+            (
+                server,
+                smile,
+                client,
+            ) = await self.connect_wrapper()
+            setup_result = False  # pragma: no cover
+        except pw_exceptions.PlugwiseException:
+            setup_result = True
+        assert setup_result
diff --git a/tests/test_init.py b/tests/test_init.py
new file mode 100644
index 000000000..0666dc826
--- /dev/null
+++ b/tests/test_init.py
@@ -0,0 +1,723 @@
+# pylint: disable=protected-access
+"""Test Plugwise Home Assistant module and generate test JSON fixtures."""
+import asyncio
+import importlib
+import json
+
+# Fixture writing
+import logging
+import os
+from pprint import PrettyPrinter
+
+# String generation
+import secrets
+import string
+
+import pytest
+
+# Testing
+import aiohttp
+from freezegun import freeze_time
+
+pw_constants = importlib.import_module("plugwise.constants")
+pw_exceptions = importlib.import_module("plugwise.exceptions")
+pw_smile = importlib.import_module("plugwise")
+
+pytestmark = pytest.mark.asyncio
+
+pp = PrettyPrinter(indent=8)
+
+CORE_LOCATIONS = "/core/locations"
+CORE_LOCATIONS_TAIL = "/core/locations{tail:.*}"
+CORE_APPLIANCES_TAIL = "/core/appliances{tail:.*}"
+CORE_NOTIFICATIONS_TAIL = "/core/notifications{tail:.*}"
+CORE_RULES_TAIL = "/core/rules{tail:.*}"
+EMPTY_XML = "<xml />"
+BOGUS = "!bogus"
+
+_LOGGER = logging.getLogger(__name__)
+_LOGGER.setLevel(logging.DEBUG)
+
+# Prepare aiohttp app routes
+# taking self.smile_setup (i.e. directory name under userdata/{smile_app}/
+# as inclusion point
+
+
+class TestPlugwise:  # pylint: disable=attribute-defined-outside-init
+    """Tests for Plugwise Smile."""
+
+    def _write_json(self, call, data):
+        """Store JSON data to per-setup files for HA component testing."""
+        path = os.path.join(
+            os.path.dirname(__file__), "../fixtures/" + self.smile_setup
+        )
+        datafile = os.path.join(path, call + ".json")
+        if not os.path.exists(path):  # pragma: no cover
+            os.mkdir(path)
+        if not os.path.exists(os.path.dirname(datafile)):  # pragma: no cover
+            os.mkdir(os.path.dirname(datafile))
+
+        with open(datafile, "w", encoding="utf-8") as fixture_file:
+            fixture_file.write(
+                json.dumps(
+                    data,
+                    indent=2,
+                    separators=(",", ": "),
+                    sort_keys=True,
+                    default=lambda x: list(x) if isinstance(x, set) else x,
+                )
+                + "\n"
+            )
+
+    def load_testdata(
+        self, smile_type: str = "adam", smile_setup: str = "adam_zone_per_device"
+    ):
+        """Load JSON data from setup, return as object."""
+        path = os.path.join(
+            os.path.dirname(__file__), f"../tests/data/{smile_type}/{smile_setup}.json"
+        )
+        with open(path, encoding="utf-8") as testdata_file:
+            return json.load(testdata_file)
+
+    async def setup_app(
+        self,
+        broken=False,
+        timeout=False,
+        raise_timeout=False,
+        fail_auth=False,
+        stretch=False,
+    ):
+        """Create mock webserver for Smile to interface with."""
+        app = aiohttp.web.Application()
+
+        if fail_auth:
+            app.router.add_get("/{tail:.*}", self.smile_fail_auth)
+            app.router.add_route("PUT", "/{tail:.*}", self.smile_fail_auth)
+            return app
+
+        app.router.add_get("/core/appliances", self.smile_appliances)
+        app.router.add_get("/core/domain_objects", self.smile_domain_objects)
+        app.router.add_get("/core/modules", self.smile_modules)
+        app.router.add_get("/system/status.xml", self.smile_status)
+        app.router.add_get("/system", self.smile_status)
+
+        if broken:
+            app.router.add_get(CORE_LOCATIONS, self.smile_broken)
+        elif timeout:
+            app.router.add_get(CORE_LOCATIONS, self.smile_timeout)
+        else:
+            app.router.add_get(CORE_LOCATIONS, self.smile_locations)
+
+        # Introducte timeout with 2 seconds, test by setting response to 10ms
+        # Don't actually wait 2 seconds as this will prolongue testing
+        if not raise_timeout:
+            app.router.add_route("PUT", CORE_LOCATIONS_TAIL, self.smile_http_accept)
+            app.router.add_route(
+                "DELETE", CORE_NOTIFICATIONS_TAIL, self.smile_http_accept
+            )
+            app.router.add_route("PUT", CORE_RULES_TAIL, self.smile_http_accept)
+            if not stretch:
+                app.router.add_route(
+                    "PUT", CORE_APPLIANCES_TAIL, self.smile_http_accept
+                )
+            else:
+                app.router.add_route("PUT", CORE_APPLIANCES_TAIL, self.smile_http_ok)
+        else:
+            app.router.add_route("PUT", CORE_LOCATIONS_TAIL, self.smile_timeout)
+            app.router.add_route("PUT", CORE_RULES_TAIL, self.smile_timeout)
+            app.router.add_route("PUT", CORE_APPLIANCES_TAIL, self.smile_timeout)
+            app.router.add_route(
+                "DELETE", "/core/notifications{tail:.*}", self.smile_timeout
+            )
+
+        return app
+
+    # Wrapper for appliances uri
+    async def smile_appliances(self, request):
+        """Render setup specific appliances endpoint."""
+        userdata = os.path.join(
+            os.path.dirname(__file__),
+            f"../userdata/{self.smile_setup}/core.appliances.xml",
+        )
+        with open(userdata, encoding="utf-8") as filedata:
+            data = filedata.read()
+        return aiohttp.web.Response(text=data)
+
+    async def smile_domain_objects(self, request):
+        """Render setup specific domain objects endpoint."""
+        userdata = os.path.join(
+            os.path.dirname(__file__),
+            f"../userdata/{self.smile_setup}/core.domain_objects.xml",
+        )
+        with open(userdata, encoding="utf-8") as filedata:
+            data = filedata.read()
+        return aiohttp.web.Response(text=data)
+
+    async def smile_locations(self, request):
+        """Render setup specific locations endpoint."""
+        userdata = os.path.join(
+            os.path.dirname(__file__),
+            f"../userdata/{self.smile_setup}/core.locations.xml",
+        )
+        with open(userdata, encoding="utf-8") as filedata:
+            data = filedata.read()
+        return aiohttp.web.Response(text=data)
+
+    async def smile_modules(self, request):
+        """Render setup specific modules endpoint."""
+        userdata = os.path.join(
+            os.path.dirname(__file__),
+            f"../userdata/{self.smile_setup}/core.modules.xml",
+        )
+        with open(userdata, encoding="utf-8") as filedata:
+            data = filedata.read()
+        return aiohttp.web.Response(text=data)
+
+    async def smile_status(self, request):
+        """Render setup specific status endpoint."""
+        try:
+            userdata = os.path.join(
+                os.path.dirname(__file__),
+                f"../userdata/{self.smile_setup}/system_status_xml.xml",
+            )
+            with open(userdata, encoding="utf-8") as filedata:
+                data = filedata.read()
+            return aiohttp.web.Response(text=data)
+        except OSError:
+            raise aiohttp.web.HTTPNotFound
+
+    @classmethod
+    async def smile_http_accept(cls, request):
+        """Render generic API calling endpoint."""
+        text = EMPTY_XML
+        raise aiohttp.web.HTTPAccepted(text=text)
+
+    @classmethod
+    async def smile_http_ok(cls, request):
+        """Render generic API calling endpoint."""
+        text = EMPTY_XML
+        raise aiohttp.web.HTTPOk(text=text)
+
+    @classmethod
+    async def smile_timeout(cls, request):
+        """Render timeout endpoint."""
+        raise asyncio.TimeoutError
+
+    @classmethod
+    async def smile_broken(cls, request):
+        """Render server error endpoint."""
+        raise aiohttp.web.HTTPInternalServerError(text="Internal Server Error")
+
+    @classmethod
+    async def smile_fail_auth(cls, request):
+        """Render authentication error endpoint."""
+        raise aiohttp.web.HTTPUnauthorized()
+
+    @staticmethod
+    def connect_status(broken, timeout, fail_auth):
+        """Determine assumed status from settings."""
+        assumed_status = 200
+        if broken:
+            assumed_status = 500
+        if timeout:
+            assumed_status = 504
+        if fail_auth:
+            assumed_status = 401
+        return assumed_status
+
+    async def connect(
+        self,
+        broken=False,
+        timeout=False,
+        raise_timeout=False,
+        fail_auth=False,
+        stretch=False,
+    ):
+        """Connect to a smile environment and perform basic asserts."""
+        port = aiohttp.test_utils.unused_port()
+        test_password = "".join(
+            secrets.choice(string.ascii_lowercase) for _ in range(8)
+        )
+
+        # Happy flow
+        app = await self.setup_app(broken, timeout, raise_timeout, fail_auth, stretch)
+
+        server = aiohttp.test_utils.TestServer(
+            app, port=port, scheme="http", host="127.0.0.1"
+        )
+        await server.start_server()
+
+        client = aiohttp.test_utils.TestClient(server)
+        websession = client.session
+
+        url = f"{server.scheme}://{server.host}:{server.port}{CORE_LOCATIONS}"
+
+        # Try/exceptpass to accommodate for Timeout of aoihttp
+        try:
+            resp = await websession.get(url)
+            assumed_status = self.connect_status(broken, timeout, fail_auth)
+            assert resp.status == assumed_status
+            timeoutpass_result = False
+            assert timeoutpass_result
+        except Exception:  # pylint: disable=broad-except
+            timeoutpass_result = True
+            assert timeoutpass_result
+
+        if not broken and not timeout and not fail_auth:
+            text = await resp.text()
+            assert "xml" in text
+
+        # Test lack of websession
+        try:
+            smile = pw_smile.Smile(
+                host=server.host,
+                username=pw_constants.DEFAULT_USERNAME,
+                password=test_password,
+                port=server.port,
+                websession=None,
+            )
+            lack_of_websession = False
+            assert lack_of_websession
+        except Exception:  # pylint: disable=broad-except
+            lack_of_websession = True
+            assert lack_of_websession
+
+        smile = pw_smile.Smile(
+            host=server.host,
+            username=pw_constants.DEFAULT_USERNAME,
+            password=test_password,
+            port=server.port,
+            websession=websession,
+        )
+
+        if not timeout:
+            assert smile._timeout == 30
+
+        # Connect to the smile
+        try:
+            connection_state = await smile.connect()
+            assert connection_state
+            return server, smile, client
+        except (
+            pw_exceptions.DeviceTimeoutError,
+            pw_exceptions.InvalidXMLError,
+            pw_exceptions.InvalidAuthentication,
+        ) as exception:
+            await self.disconnect(server, client)
+            raise exception
+
+    # Wrap connect for invalid connections
+    async def connect_wrapper(
+        self, raise_timeout=False, fail_auth=False, stretch=False
+    ):
+        """Wrap connect to try negative testing before positive testing."""
+        if fail_auth:
+            try:
+                _LOGGER.warning("Connecting to device with invalid credentials:")
+                await self.connect(fail_auth=fail_auth)
+                _LOGGER.error(" - invalid credentials not handled")  # pragma: no cover
+                raise self.ConnectError  # pragma: no cover
+            except pw_exceptions.InvalidAuthentication:
+                _LOGGER.info(" + successfully aborted on credentials missing.")
+                raise pw_exceptions.InvalidAuthentication
+
+        if raise_timeout:
+            _LOGGER.warning("Connecting to device exceeding timeout in handling:")
+            return await self.connect(raise_timeout=True)
+
+        try:
+            _LOGGER.warning("Connecting to device exceeding timeout in response:")
+            await self.connect(timeout=True)
+            _LOGGER.error(" - timeout not handled")  # pragma: no cover
+            raise self.ConnectError  # pragma: no cover
+        except (pw_exceptions.DeviceTimeoutError, pw_exceptions.ResponseError):
+            _LOGGER.info(" + successfully passed timeout handling.")
+
+        try:
+            _LOGGER.warning("Connecting to device with missing data:")
+            await self.connect(broken=True)
+            _LOGGER.error(" - broken information not handled")  # pragma: no cover
+            raise self.ConnectError  # pragma: no cover
+        except pw_exceptions.InvalidXMLError:
+            _LOGGER.info(" + successfully passed XML issue handling.")
+
+        _LOGGER.info("Connecting to functioning device:")
+        return await self.connect(stretch=stretch)
+
+    # Generic disconnect
+    @classmethod
+    @pytest.mark.asyncio
+    async def disconnect(cls, server, client):
+        """Disconnect from webserver."""
+        await client.session.close()
+        await server.close()
+
+    @staticmethod
+    def show_setup(location_list, device_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
+                    _LOGGER.info(
+                        "      + Device: %s",
+                        "{} ({} - {})".format(
+                            dev_info["name"], dev_info["dev_class"], dev_id
+                        ),
+                    )
+            if device_count == 0:  # pragma: no cover
+                _LOGGER.info("      ! no devices found in this location")
+                assert False
+
+    @pytest.mark.asyncio
+    async def device_test(
+        self,
+        smile=pw_smile.Smile,
+        test_time=None,
+        testdata=None,
+        initialize=True,
+    ):
+        """Perform basic device tests."""
+        bsw_list = ["binary_sensors", "central", "climate", "sensors", "switches"]
+
+        # pragma warning disable S3776
+
+        # Make sure to test thermostats with the day set to Monday, needed for full testcoverage of schedules_temps()
+        # Otherwise set the day to Sunday.
+        with freeze_time(test_time):
+            if initialize:
+                _LOGGER.info("Asserting testdata:")
+                await smile._full_update_device()
+                smile.get_all_devices()
+                data = await smile.async_update()
+            else:
+                _LOGGER.info("Asserting updated testdata:")
+                data = await smile.async_update()
+
+        if "heater_id" in data.gateway:
+            self.cooling_present = data.gateway["cooling_present"]
+        self.notifications = data.gateway["notifications"]
+        self._write_json("all_data", {"gateway": data.gateway, "devices": data.devices})
+        self._write_json("device_list", smile.device_list)
+        self._write_json("notifications", data.gateway["notifications"])
+
+        if "FIXTURES" in os.environ:
+            _LOGGER.info("Skipping tests: Requested fixtures only")  # pragma: no cover
+            return  # pragma: no cover
+
+        location_list = smile._thermo_locs
+
+        _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 list = %s", data.devices)
+        self.show_setup(location_list, data.devices)
+
+        # 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():
+                        _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 test-assert: %s", asserts)
+
+        # pragma warning restore S3776
+
+    @pytest.mark.asyncio
+    async def tinker_switch(
+        self, smile, dev_id=None, members=None, model="relay", unhappy=False
+    ):
+        """Turn a Switch on and off to test functionality."""
+        _LOGGER.info("Asserting modifying settings for switch devices:")
+        _LOGGER.info("- Devices (%s):", dev_id)
+        for new_state in [False, True, False]:
+            tinker_switch_passed = False
+            _LOGGER.info("- Switching %s", new_state)
+            try:
+                await smile.set_switch_state(dev_id, members, model, new_state)
+                tinker_switch_passed = True
+                _LOGGER.info("  + tinker_switch worked as intended")
+            except pw_exceptions.PlugwiseError:
+                _LOGGER.info("  + locked, not switched as expected")
+                return False
+            except (
+                pw_exceptions.ErrorSendingCommandError,
+                pw_exceptions.ResponseError,
+            ):
+                if unhappy:
+                    tinker_switch_passed = True  # test is pass!
+                    _LOGGER.info("  + failed as expected")
+                else:  # pragma: no cover
+                    _LOGGER.info("  - failed unexpectedly")
+                    return False
+
+        return tinker_switch_passed
+
+    @pytest.mark.asyncio
+    async def tinker_thermostat_temp(
+        self, smile, loc_id, block_cooling=False, unhappy=False
+    ):
+        """Toggle temperature to test functionality."""
+        _LOGGER.info("Asserting modifying settings in location (%s):", loc_id)
+        tinker_temp_passed = False
+        test_temp = {"setpoint": 22.9}
+        if smile._cooling_present and not block_cooling:
+            test_temp = {"setpoint_low": 19.5, "setpoint_high": 23.5}
+        _LOGGER.info("- Adjusting temperature to %s", test_temp)
+        try:
+            await smile.set_temperature(loc_id, test_temp)
+            _LOGGER.info("  + tinker_thermostat_temp worked as intended")
+            tinker_temp_passed = True
+        except (
+            pw_exceptions.ErrorSendingCommandError,
+            pw_exceptions.ResponseError,
+        ):
+            if unhappy:
+                _LOGGER.info("  + tinker_thermostat_temp failed as expected")
+                tinker_temp_passed = True
+            else:  # pragma: no cover
+                _LOGGER.info("  - tinker_thermostat_temp failed unexpectedly")
+                return False
+
+        return tinker_temp_passed
+
+    @pytest.mark.asyncio
+    async def tinker_thermostat_preset(self, smile, loc_id, unhappy=False):
+        """Toggle preset to test functionality."""
+        for new_preset in ["asleep", "home", BOGUS]:
+            tinker_preset_passed = False
+            warning = ""
+            if new_preset[0] == "!":
+                warning = " TTP Negative test"
+                new_preset = new_preset[1:]
+            _LOGGER.info("%s", f"- Adjusting preset to {new_preset}{warning}")
+            try:
+                await smile.set_preset(loc_id, new_preset)
+                tinker_preset_passed = True
+                _LOGGER.info("  + tinker_thermostat_preset worked as intended")
+            except pw_exceptions.PlugwiseError:
+                _LOGGER.info("  + found invalid preset, as expected")
+                tinker_preset_passed = True
+            except (
+                pw_exceptions.ErrorSendingCommandError,
+                pw_exceptions.ResponseError,
+            ):
+                if unhappy:
+                    tinker_preset_passed = True
+                    _LOGGER.info("  + tinker_thermostat_preset failed as expected")
+                else:  # pragma: no cover
+                    _LOGGER.info("  - tinker_thermostat_preset failed unexpectedly")
+                    return False
+
+        return tinker_preset_passed
+
+    @pytest.mark.asyncio
+    async def tinker_thermostat_schedule(
+        self, smile, loc_id, state, good_schedules=None, single=False, unhappy=False
+    ):
+        """Toggle schedules to test functionality."""
+        # pragma warning disable S3776
+        if good_schedules != []:
+            if not single and ("!VeryBogusSchedule" not in good_schedules):
+                good_schedules.append("!VeryBogusSchedule")
+            for new_schedule in good_schedules:
+                tinker_schedule_passed = False
+                warning = ""
+                if new_schedule is not None and new_schedule[0] == "!":
+                    warning = " TTS Negative test"
+                    new_schedule = new_schedule[1:]
+                _LOGGER.info("- Adjusting schedule to %s", f"{new_schedule}{warning}")
+                try:
+                    await smile.set_schedule_state(loc_id, state, new_schedule)
+                    tinker_schedule_passed = True
+                    _LOGGER.info("  + working as intended")
+                except pw_exceptions.PlugwiseError:
+                    _LOGGER.info("  + failed as expected")
+                    tinker_schedule_passed = True
+                except (
+                    pw_exceptions.ErrorSendingCommandError,
+                    pw_exceptions.ResponseError,
+                ):
+                    tinker_schedule_passed = False
+                    if unhappy:
+                        _LOGGER.info("  + failed as expected before intended failure")
+                        tinker_schedule_passed = True
+                    else:  # pragma: no cover
+                        _LOGGER.info("  - succeeded unexpectedly for some reason")
+                        return False
+
+            return tinker_schedule_passed
+
+        _LOGGER.info("- Skipping schedule adjustments")  # pragma: no cover
+        # pragma warning restore S3776
+
+    @pytest.mark.asyncio
+    async def tinker_thermostat(
+        self,
+        smile,
+        loc_id,
+        schedule_on=True,
+        good_schedules=None,
+        single=False,
+        block_cooling=False,
+        unhappy=False,
+    ):
+        """Toggle various climate settings to test functionality."""
+        if good_schedules is None:  # pragma: no cover
+            good_schedules = ["Weekschema"]
+
+        result_1 = await self.tinker_thermostat_temp(
+            smile, loc_id, block_cooling, unhappy
+        )
+        result_2 = await self.tinker_thermostat_preset(smile, loc_id, unhappy)
+        if smile._schedule_old_states != {}:
+            for item in smile._schedule_old_states[loc_id]:
+                smile._schedule_old_states[loc_id][item] = "off"
+        result_3 = await self.tinker_thermostat_schedule(
+            smile, loc_id, "on", good_schedules, single, unhappy
+        )
+        if schedule_on:
+            result_4 = await self.tinker_thermostat_schedule(
+                smile, loc_id, "off", good_schedules, single, unhappy
+            )
+            result_5 = await self.tinker_thermostat_schedule(
+                smile, loc_id, "on", good_schedules, single, unhappy
+            )
+            return result_1 and result_2 and result_3 and result_4 and result_5
+        return result_1 and result_2 and result_3
+
+    @staticmethod
+    async def tinker_dhw_mode(smile):
+        """Toggle dhw to test functionality."""
+        for mode in ["auto", "boost", BOGUS]:
+            warning = ""
+            if mode[0] == "!":
+                warning = " TD Negative test"
+                mode = mode[1:]
+            _LOGGER.info("%s", f"- Adjusting dhw mode to {mode}{warning}")
+            try:
+                await smile.set_dhw_mode(mode)
+                _LOGGER.info("  + tinker_dhw_mode worked as intended")
+            except pw_exceptions.PlugwiseError:
+                _LOGGER.info("  + tinker_dhw_mode found invalid mode, as expected")
+
+    @staticmethod
+    async def tinker_regulation_mode(smile):
+        """Toggle regulation_mode to test functionality."""
+        for mode in ["off", "heating", "bleeding_cold", BOGUS]:
+            warning = ""
+            if mode[0] == "!":
+                warning = " TR Negative test"
+                mode = mode[1:]
+            _LOGGER.info("%s", f"- Adjusting regulation mode to {mode}{warning}")
+            try:
+                await smile.set_regulation_mode(mode)
+                _LOGGER.info("  + tinker_regulation_mode worked as intended")
+            except pw_exceptions.PlugwiseError:
+                _LOGGER.info(
+                    "  + tinker_regulation_mode found invalid mode, as expected"
+                )
+
+    @staticmethod
+    async def tinker_max_boiler_temp(smile):
+        """Change max boiler temp setpoint to test functionality."""
+        new_temp = 60.0
+        dev_id = None
+        _LOGGER.info("- Adjusting temperature to %s", new_temp)
+        for test in ["maximum_boiler_temperature", "bogus_temperature"]:
+            try:
+                await smile.set_number_setpoint(test, dev_id, new_temp)
+                _LOGGER.info("  + tinker_max_boiler_temp worked as intended")
+            except pw_exceptions.PlugwiseError:
+                _LOGGER.info("  + tinker_max_boiler_temp failed as intended")
+
+    @staticmethod
+    async def tinker_temp_offset(smile, dev_id):
+        """Change temperature_offset to test functionality."""
+        new_offset = 1.0
+        _LOGGER.info("- Adjusting temperature offset to %s", new_offset)
+        try:
+            await smile.set_temperature_offset("dummy", dev_id, new_offset)
+            _LOGGER.info("  + tinker_temp_offset worked as intended")
+            return True
+        except pw_exceptions.PlugwiseError:
+            _LOGGER.info("  + tinker_temp_offset failed as intended")
+            return False
+
+    @staticmethod
+    def validate_test_basics(
+        parent_logger,
+        smile,
+        smile_type="thermostat",
+        smile_version=None,
+        smile_legacy=False,
+    ):
+        """Produce visual assertion of components base validation."""
+        parent_logger.info("Basics:")
+        if smile_type:
+            log_msg = f" # Assert type matching {smile_type}"
+            parent_logger.info(log_msg)
+            assert smile.smile_type == smile_type
+        if smile_version:
+            log_msg = f" # Assert version matching '{smile_version}"
+            parent_logger.info(log_msg)
+            assert smile.smile_version[0] == smile_version
+        if smile_version:
+            log_msg = f" # Assert legacy {smile_legacy}"
+            parent_logger.info(log_msg)
+            if smile_legacy:
+                assert smile._smile_legacy
+            else:
+                assert not smile._smile_legacy
+
+    class PlugwiseTestError(Exception):
+        """Plugwise test exceptions class."""
+
+    class ConnectError(PlugwiseTestError):
+        """Raised when connectivity test fails."""
+
+    class UnexpectedError(PlugwiseTestError):
+        """Raised when something went against logic."""
diff --git a/tests/test_p1.py b/tests/test_p1.py
new file mode 100644
index 000000000..d438720e8
--- /dev/null
+++ b/tests/test_p1.py
@@ -0,0 +1,152 @@
+"""Test Plugwise module P1 related functionality."""
+
+import pytest
+
+from .test_init import _LOGGER, TestPlugwise
+
+SMILE_TYPE = "p1"
+
+
+class TestPlugwiseP1(TestPlugwise):  # pylint: disable=attribute-defined-outside-init
+    """Tests for P1."""
+
+    @pytest.mark.asyncio
+    async def test_connect_smile_p1_v2(self):
+        """Test a legacy P1 device."""
+        self.smile_setup = "smile_p1_v2"
+
+        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="2.5.9",
+            smile_legacy=True,
+        )
+
+        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
+        assert smile.gateway_id == "aaaa0000aaaa0000aaaa0000aaaa00aa"
+        assert smile.device_items == 26
+        assert not self.notifications
+
+        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_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 smile.device_items == 26
+        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/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)
+
+    @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 smile.device_items == 29
+        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."""
+        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 smile.device_items == 31
+        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 smile.device_items == 40
+        assert self.notifications
+
+        await smile.close_connection()
+        await self.disconnect(server, client)
diff --git a/tests/test_smile.py b/tests/test_smile.py
deleted file mode 100644
index 4ef6d36d9..000000000
--- a/tests/test_smile.py
+++ /dev/null
@@ -1,5465 +0,0 @@
-# pylint: disable=protected-access
-"""Test Plugwise Home Assistant module and generate test JSON fixtures."""
-import asyncio
-import importlib
-import json
-
-# Fixture writing
-import logging
-import os
-from pprint import PrettyPrinter
-
-# String generation
-import random
-import string
-from unittest.mock import patch
-
-import pytest
-
-# Testing
-import aiohttp
-from freezegun import freeze_time
-
-pw_constants = importlib.import_module("plugwise.constants")
-pw_exceptions = importlib.import_module("plugwise.exceptions")
-pw_smile = importlib.import_module("plugwise")
-
-pytestmark = pytest.mark.asyncio
-
-pp = PrettyPrinter(indent=8)
-
-_LOGGER = logging.getLogger(__name__)
-_LOGGER.setLevel(logging.DEBUG)
-
-# Prepare aiohttp app routes
-# taking self.smile_setup (i.e. directory name under userdata/{smile_app}/
-# as inclusion point
-
-
-class TestPlugwise:  # pylint: disable=attribute-defined-outside-init
-    """Tests for Plugwise Smile."""
-
-    def _write_json(self, call, data):
-        """Store JSON data to per-setup files for HA component testing."""
-        path = os.path.join(
-            os.path.dirname(__file__), "../fixtures/" + self.smile_setup
-        )
-        datafile = os.path.join(path, call + ".json")
-        if not os.path.exists(path):  # pragma: no cover
-            os.mkdir(path)
-        if not os.path.exists(os.path.dirname(datafile)):  # pragma: no cover
-            os.mkdir(os.path.dirname(datafile))
-
-        with open(datafile, "w", encoding="utf-8") as fixture_file:
-            fixture_file.write(
-                json.dumps(
-                    data,
-                    indent=2,
-                    separators=(",", ": "),
-                    sort_keys=True,
-                    default=lambda x: list(x) if isinstance(x, set) else x,
-                )
-                + "\n"
-            )
-
-    async def setup_app(
-        self,
-        broken=False,
-        timeout=False,
-        raise_timeout=False,
-        fail_auth=False,
-        stretch=False,
-    ):
-        """Create mock webserver for Smile to interface with."""
-        app = aiohttp.web.Application()
-
-        if fail_auth:
-            app.router.add_get("/{tail:.*}", self.smile_fail_auth)
-            app.router.add_route("PUT", "/{tail:.*}", self.smile_fail_auth)
-            return app
-
-        app.router.add_get("/core/appliances", self.smile_appliances)
-        app.router.add_get("/core/domain_objects", self.smile_domain_objects)
-        app.router.add_get("/core/modules", self.smile_modules)
-        app.router.add_get("/system/status.xml", self.smile_status)
-        app.router.add_get("/system", self.smile_status)
-
-        if broken:
-            app.router.add_get("/core/locations", self.smile_broken)
-        elif timeout:
-            app.router.add_get("/core/locations", self.smile_timeout)
-        else:
-            app.router.add_get("/core/locations", self.smile_locations)
-
-        # Introducte timeout with 2 seconds, test by setting response to 10ms
-        # Don't actually wait 2 seconds as this will prolongue testing
-        if not raise_timeout:
-            app.router.add_route(
-                "PUT", "/core/locations{tail:.*}", self.smile_set_temp_or_preset
-            )
-            app.router.add_route(
-                "DELETE", "/core/notifications{tail:.*}", self.smile_del_notification
-            )
-            app.router.add_route("PUT", "/core/rules{tail:.*}", self.smile_set_schedule)
-            app.router.add_route(
-                "DELETE", "/core/notifications{tail:.*}", self.smile_del_notification
-            )
-            if not stretch:
-                app.router.add_route(
-                    "PUT", "/core/appliances{tail:.*}", self.smile_set_relay
-                )
-            else:
-                app.router.add_route(
-                    "PUT", "/core/appliances{tail:.*}", self.smile_set_relay_stretch
-                )
-        else:
-            app.router.add_route("PUT", "/core/locations{tail:.*}", self.smile_timeout)
-            app.router.add_route("PUT", "/core/rules{tail:.*}", self.smile_timeout)
-            app.router.add_route("PUT", "/core/appliances{tail:.*}", self.smile_timeout)
-            app.router.add_route(
-                "DELETE", "/core/notifications{tail:.*}", self.smile_timeout
-            )
-
-        return app
-
-    # Wrapper for appliances uri
-    async def smile_appliances(self, request):
-        """Render setup specific appliances endpoint."""
-        userdata = os.path.join(
-            os.path.dirname(__file__),
-            f"../userdata/{self.smile_setup}/core.appliances.xml",
-        )
-        with open(userdata, encoding="utf-8") as filedata:
-            data = filedata.read()
-        return aiohttp.web.Response(text=data)
-
-    async def smile_domain_objects(self, request):
-        """Render setup specific domain objects endpoint."""
-        userdata = os.path.join(
-            os.path.dirname(__file__),
-            f"../userdata/{self.smile_setup}/core.domain_objects.xml",
-        )
-        with open(userdata, encoding="utf-8") as filedata:
-            data = filedata.read()
-        return aiohttp.web.Response(text=data)
-
-    async def smile_locations(self, request):
-        """Render setup specific locations endpoint."""
-        userdata = os.path.join(
-            os.path.dirname(__file__),
-            f"../userdata/{self.smile_setup}/core.locations.xml",
-        )
-        with open(userdata, encoding="utf-8") as filedata:
-            data = filedata.read()
-        return aiohttp.web.Response(text=data)
-
-    async def smile_modules(self, request):
-        """Render setup specific modules endpoint."""
-        userdata = os.path.join(
-            os.path.dirname(__file__),
-            f"../userdata/{self.smile_setup}/core.modules.xml",
-        )
-        with open(userdata, encoding="utf-8") as filedata:
-            data = filedata.read()
-        return aiohttp.web.Response(text=data)
-
-    async def smile_status(self, request):
-        """Render setup specific status endpoint."""
-        try:
-            userdata = os.path.join(
-                os.path.dirname(__file__),
-                f"../userdata/{self.smile_setup}/system_status_xml.xml",
-            )
-            with open(userdata, encoding="utf-8") as filedata:
-                data = filedata.read()
-            return aiohttp.web.Response(text=data)
-        except OSError:
-            raise aiohttp.web.HTTPNotFound
-
-    @classmethod
-    async def smile_set_temp_or_preset(cls, request):
-        """Render generic API calling endpoint."""
-        text = "<xml />"
-        raise aiohttp.web.HTTPAccepted(text=text)
-
-    @classmethod
-    async def smile_set_schedule(cls, request):
-        """Render generic API calling endpoint."""
-        text = "<xml />"
-        raise aiohttp.web.HTTPAccepted(text=text)
-
-    @classmethod
-    async def smile_set_relay(cls, request):
-        """Render generic API calling endpoint."""
-        text = "<xml />"
-        raise aiohttp.web.HTTPAccepted(text=text)
-
-    @classmethod
-    async def smile_set_relay_stretch(cls, request):
-        """Render generic API calling endpoint."""
-        text = "<xml />"
-        raise aiohttp.web.HTTPOk(text=text)
-
-    @classmethod
-    async def smile_del_notification(cls, request):
-        """Render generic API calling endpoint."""
-        text = "<xml />"
-        raise aiohttp.web.HTTPAccepted(text=text)
-
-    @classmethod
-    async def smile_timeout(cls, request):
-        """Render timeout endpoint."""
-        raise asyncio.TimeoutError
-
-    @classmethod
-    async def smile_broken(cls, request):
-        """Render server error endpoint."""
-        raise aiohttp.web.HTTPInternalServerError(text="Internal Server Error")
-
-    @classmethod
-    async def smile_fail_auth(cls, request):
-        """Render authentication error endpoint."""
-        raise aiohttp.web.HTTPUnauthorized()
-
-    @staticmethod
-    def connect_status(broken, timeout, fail_auth):
-        """Determine assumed status from settings."""
-        assumed_status = 200
-        if broken:
-            assumed_status = 500
-        if timeout:
-            assumed_status = 504
-        if fail_auth:
-            assumed_status = 401
-        return assumed_status
-
-    async def connect(
-        self,
-        broken=False,
-        timeout=False,
-        raise_timeout=False,
-        fail_auth=False,
-        stretch=False,
-    ):
-        """Connect to a smile environment and perform basic asserts."""
-        port = aiohttp.test_utils.unused_port()
-        test_password = "".join(random.choice(string.ascii_lowercase) for i in range(8))
-
-        # Happy flow
-        app = await self.setup_app(broken, timeout, raise_timeout, fail_auth, stretch)
-
-        server = aiohttp.test_utils.TestServer(
-            app, port=port, scheme="http", host="127.0.0.1"
-        )
-        await server.start_server()
-
-        client = aiohttp.test_utils.TestClient(server)
-        websession = client.session
-
-        url = f"{server.scheme}://{server.host}:{server.port}/core/locations"
-
-        # Try/exceptpass to accommodate for Timeout of aoihttp
-        try:
-            resp = await websession.get(url)
-            assumed_status = self.connect_status(broken, timeout, fail_auth)
-            assert resp.status == assumed_status
-        except Exception:  # pylint: disable=broad-except
-            assert True
-
-        if not broken and not timeout and not fail_auth:
-            text = await resp.text()
-            assert "xml" in text
-
-        # Test lack of websession
-        try:
-            smile = pw_smile.Smile(
-                host=server.host,
-                username=pw_constants.DEFAULT_USERNAME,
-                password=test_password,
-                port=server.port,
-                websession=None,
-            )
-            assert False
-        except Exception:  # pylint: disable=broad-except
-            assert True
-
-        smile = pw_smile.Smile(
-            host=server.host,
-            username=pw_constants.DEFAULT_USERNAME,
-            password=test_password,
-            port=server.port,
-            websession=websession,
-        )
-
-        if not timeout:
-            assert smile._timeout == 30
-
-        # Connect to the smile
-        try:
-            connection_state = await smile.connect()
-            assert connection_state
-            return server, smile, client
-        except (
-            pw_exceptions.DeviceTimeoutError,
-            pw_exceptions.InvalidXMLError,
-            pw_exceptions.InvalidAuthentication,
-        ) as exception:
-            await self.disconnect(server, client)
-            raise exception
-
-    # Wrap connect for invalid connections
-    async def connect_wrapper(
-        self, raise_timeout=False, fail_auth=False, stretch=False
-    ):
-        """Wrap connect to try negative testing before positive testing."""
-        if fail_auth:
-            try:
-                _LOGGER.warning("Connecting to device with invalid credentials:")
-                await self.connect(fail_auth=fail_auth)
-                _LOGGER.error(" - invalid credentials not handled")  # pragma: no cover
-                raise self.ConnectError  # pragma: no cover
-            except pw_exceptions.InvalidAuthentication:
-                _LOGGER.info(" + successfully aborted on credentials missing.")
-                raise pw_exceptions.InvalidAuthentication
-
-        if raise_timeout:
-            _LOGGER.warning("Connecting to device exceeding timeout in handling:")
-            return await self.connect(raise_timeout=True)
-
-        try:
-            _LOGGER.warning("Connecting to device exceeding timeout in response:")
-            await self.connect(timeout=True)
-            _LOGGER.error(" - timeout not handled")  # pragma: no cover
-            raise self.ConnectError  # pragma: no cover
-        except (pw_exceptions.DeviceTimeoutError, pw_exceptions.ResponseError):
-            _LOGGER.info(" + successfully passed timeout handling.")
-
-        try:
-            _LOGGER.warning("Connecting to device with missing data:")
-            await self.connect(broken=True)
-            _LOGGER.error(" - broken information not handled")  # pragma: no cover
-            raise self.ConnectError  # pragma: no cover
-        except pw_exceptions.InvalidXMLError:
-            _LOGGER.info(" + successfully passed XML issue handling.")
-
-        _LOGGER.info("Connecting to functioning device:")
-        return await self.connect(stretch=stretch)
-
-    # Generic disconnect
-    @classmethod
-    @pytest.mark.asyncio
-    async def disconnect(cls, server, client):
-        """Disconnect from webserver."""
-        await client.session.close()
-        await server.close()
-
-    @staticmethod
-    def show_setup(location_list, device_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
-                    _LOGGER.info(
-                        "      + Device: %s",
-                        "{} ({} - {})".format(
-                            dev_info["name"], dev_info["dev_class"], dev_id
-                        ),
-                    )
-            if device_count == 0:  # pragma: no cover
-                _LOGGER.info("      ! no devices found in this location")
-                assert False
-
-    @pytest.mark.asyncio
-    async def device_test(
-        self,
-        smile=pw_smile.Smile,
-        test_time=None,
-        testdata=None,
-        initialize=True,
-    ):
-        """Perform basic device tests."""
-        bsw_list = ["binary_sensors", "central", "climate", "sensors", "switches"]
-        # Make sure to test thermostats with the day set to Monday, needed for full testcoverage of schedules_temps()
-        # Otherwise set the day to Sunday.
-        with freeze_time(test_time):
-            if initialize:
-                _LOGGER.info("Asserting testdata:")
-                await smile._full_update_device()
-                smile.get_all_devices()
-                data = await smile.async_update()
-            else:
-                _LOGGER.info("Asserting updated testdata:")
-                data = await smile.async_update()
-
-        if "heater_id" in data.gateway:
-            self.cooling_present = data.gateway["cooling_present"]
-        self.notifications = data.gateway["notifications"]
-        self._write_json("all_data", {"gateway": data.gateway, "devices": data.devices})
-        self._write_json("device_list", smile.device_list)
-        self._write_json("notifications", data.gateway["notifications"])
-
-        if "FIXTURES" in os.environ:
-            _LOGGER.info("Skipping tests: Requested fixtures only")  # pragma: no cover
-            return  # pragma: no cover
-
-        location_list = smile._thermo_locs
-
-        _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 list = %s", data.devices)
-        self.show_setup(location_list, data.devices)
-
-        # 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():
-                        _LOGGER.info(
-                            "%s",
-                            f"  + Testing {measure_key} (should be {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 test-assert: %s", asserts)
-
-    @pytest.mark.asyncio
-    async def tinker_switch(
-        self, smile, dev_id=None, members=None, model="relay", unhappy=False
-    ):
-        """Turn a Switch on and off to test functionality."""
-        _LOGGER.info("Asserting modifying settings for switch devices:")
-        _LOGGER.info("- Devices (%s):", dev_id)
-        for new_state in [False, True, False]:
-            tinker_switch_passed = False
-            _LOGGER.info("- Switching %s", new_state)
-            try:
-                await smile.set_switch_state(dev_id, members, model, new_state)
-                tinker_switch_passed = True
-                _LOGGER.info("  + worked as intended")
-            except pw_exceptions.PlugwiseError:
-                _LOGGER.info("  + locked, not switched as expected")
-                return False
-            except (
-                pw_exceptions.ErrorSendingCommandError,
-                pw_exceptions.ResponseError,
-            ):
-                if unhappy:
-                    tinker_switch_passed = True  # test is pass!
-                    _LOGGER.info("  + failed as expected")
-                else:  # pragma: no cover
-                    _LOGGER.info("  - failed unexpectedly")
-                    return False
-
-        return tinker_switch_passed
-
-    @pytest.mark.asyncio
-    async def tinker_thermostat_temp(
-        self, smile, loc_id, block_cooling=False, unhappy=False
-    ):
-        """Toggle temperature to test functionality."""
-        _LOGGER.info("Asserting modifying settings in location (%s):", loc_id)
-        test_temp = {"setpoint": 22.9}
-        if smile._cooling_present and not block_cooling:
-            test_temp = {"setpoint_low": 19.5, "setpoint_high": 23.5}
-        _LOGGER.info("- Adjusting temperature to %s", test_temp)
-        try:
-            await smile.set_temperature(loc_id, test_temp)
-            _LOGGER.info("  + worked as intended")
-            return True
-        except (
-            pw_exceptions.ErrorSendingCommandError,
-            pw_exceptions.ResponseError,
-        ):
-            if unhappy:
-                _LOGGER.info("  + failed as expected")
-                return True
-            else:  # pragma: no cover
-                _LOGGER.info("  - failed unexpectedly")
-                return True
-
-    @pytest.mark.asyncio
-    async def tinker_thermostat_preset(self, smile, loc_id, unhappy=False):
-        """Toggle preset to test functionality."""
-        for new_preset in ["asleep", "home", "!bogus"]:
-            tinker_preset_passed = False
-            warning = ""
-            if new_preset[0] == "!":
-                warning = " Negative test"
-                new_preset = new_preset[1:]
-            _LOGGER.info("%s", f"- Adjusting preset to {new_preset}{warning}")
-            try:
-                await smile.set_preset(loc_id, new_preset)
-                tinker_preset_passed = True
-                _LOGGER.info("  + worked as intended")
-            except pw_exceptions.PlugwiseError:
-                _LOGGER.info("  + found invalid preset, as expected")
-                tinker_preset_passed = True
-            except (
-                pw_exceptions.ErrorSendingCommandError,
-                pw_exceptions.ResponseError,
-            ):
-                if unhappy:
-                    tinker_preset_passed = True
-                    _LOGGER.info("  + failed as expected")
-                else:  # pragma: no cover
-                    _LOGGER.info("  - failed unexpectedly")
-                    return False
-
-        return tinker_preset_passed
-
-    @pytest.mark.asyncio
-    async def tinker_thermostat_schedule(
-        self, smile, loc_id, state, good_schedules=None, single=False, unhappy=False
-    ):
-        """Toggle schedules to test functionality."""
-        if good_schedules != []:
-            if not single and ("!VeryBogusSchedule" not in good_schedules):
-                good_schedules.append("!VeryBogusSchedule")
-            for new_schedule in good_schedules:
-                tinker_schedule_passed = False
-                warning = ""
-                if new_schedule is not None and new_schedule[0] == "!":
-                    warning = " Negative test"
-                    new_schedule = new_schedule[1:]
-                _LOGGER.info("- Adjusting schedule to %s", f"{new_schedule}{warning}")
-                try:
-                    await smile.set_schedule_state(loc_id, state, new_schedule)
-                    tinker_schedule_passed = True
-                    _LOGGER.info("  + working as intended")
-                except pw_exceptions.PlugwiseError:
-                    _LOGGER.info("  + failed as expected")
-                    tinker_schedule_passed = True
-                except (
-                    pw_exceptions.ErrorSendingCommandError,
-                    pw_exceptions.ResponseError,
-                ):
-                    tinker_schedule_passed = False
-                    if unhappy:
-                        _LOGGER.info("  + failed as expected before intended failure")
-                        tinker_schedule_passed = True
-                    else:  # pragma: no cover
-                        _LOGGER.info("  - succeeded unexpectedly for some reason")
-                        return False
-
-            return tinker_schedule_passed
-
-        _LOGGER.info("- Skipping schedule adjustments")  # pragma: no cover
-
-    @pytest.mark.asyncio
-    async def tinker_thermostat(
-        self,
-        smile,
-        loc_id,
-        schedule_on=True,
-        good_schedules=None,
-        single=False,
-        block_cooling=False,
-        unhappy=False,
-    ):
-        """Toggle various climate settings to test functionality."""
-        if good_schedules is None:  # pragma: no cover
-            good_schedules = ["Weekschema"]
-
-        result_1 = await self.tinker_thermostat_temp(
-            smile, loc_id, block_cooling, unhappy
-        )
-        result_2 = await self.tinker_thermostat_preset(smile, loc_id, unhappy)
-        if smile._schedule_old_states != {}:
-            for item in smile._schedule_old_states[loc_id]:
-                smile._schedule_old_states[loc_id][item] = "off"
-        result_3 = await self.tinker_thermostat_schedule(
-            smile, loc_id, "on", good_schedules, single, unhappy
-        )
-        if schedule_on:
-            result_4 = await self.tinker_thermostat_schedule(
-                smile, loc_id, "off", good_schedules, single, unhappy
-            )
-            result_5 = await self.tinker_thermostat_schedule(
-                smile, loc_id, "on", good_schedules, single, unhappy
-            )
-            return result_1 and result_2 and result_3 and result_4 and result_5
-        return result_1 and result_2 and result_3
-
-    @staticmethod
-    async def tinker_dhw_mode(smile):
-        """Toggle dhw to test functionality."""
-        for mode in ["auto", "boost", "!bogus"]:
-            warning = ""
-            if mode[0] == "!":
-                warning = " Negative test"
-                mode = mode[1:]
-            _LOGGER.info("%s", f"- Adjusting dhw mode to {mode}{warning}")
-            try:
-                await smile.set_dhw_mode(mode)
-                _LOGGER.info("  + worked as intended")
-            except pw_exceptions.PlugwiseError:
-                _LOGGER.info("  + found invalid mode, as expected")
-
-    @staticmethod
-    async def tinker_regulation_mode(smile):
-        """Toggle regulation_mode to test functionality."""
-        for mode in ["off", "heating", "bleeding_cold", "!bogus"]:
-            warning = ""
-            if mode[0] == "!":
-                warning = " Negative test"
-                mode = mode[1:]
-            _LOGGER.info("%s", f"- Adjusting regulation mode to {mode}{warning}")
-            try:
-                await smile.set_regulation_mode(mode)
-                _LOGGER.info("  + worked as intended")
-            except pw_exceptions.PlugwiseError:
-                _LOGGER.info("  + found invalid mode, as expected")
-
-    @staticmethod
-    async def tinker_max_boiler_temp(smile):
-        """Change max boiler temp setpoint to test functionality."""
-        new_temp = 60.0
-        dev_id = None
-        _LOGGER.info("- Adjusting temperature to %s", new_temp)
-        for test in ["maximum_boiler_temperature", "bogus_temperature"]:
-            try:
-                await smile.set_number_setpoint(test, dev_id, new_temp)
-                _LOGGER.info("  + worked as intended")
-            except pw_exceptions.PlugwiseError:
-                _LOGGER.info("  + failed as intended")
-
-    @staticmethod
-    async def tinker_temp_offset(smile, dev_id):
-        """Change temperature_offset to test functionality."""
-        new_offset = 1.0
-        _LOGGER.info("- Adjusting temperature offset to %s", new_offset)
-        try:
-            await smile.set_temperature_offset("dummy", dev_id, new_offset)
-            _LOGGER.info("  + worked as intended")
-            return True
-        except pw_exceptions.PlugwiseError:
-            _LOGGER.info("  + failed as intended")
-            return False
-
-    @pytest.mark.asyncio
-    async def test_connect_legacy_anna(self):
-        """Test a legacy Anna device."""
-        testdata = {
-            "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",
-                "binary_sensors": {"plugwise_notification": False},
-            },
-            "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,
-                },
-                "preset_modes": ["away", "vacation", "asleep", "home", "no_frost"],
-                "active_preset": "home",
-                "available_schedules": ["Thermostat schedule"],
-                "select_schedule": "Thermostat schedule",
-                "mode": "auto",
-                "sensors": {"temperature": 20.4, "illuminance": 151, "setpoint": 20.5},
-            },
-            "04e4cbfe7f4340f090f85ec3b9e6a950": {
-                "dev_class": "heater_central",
-                "location": "0000aaaa0000aaaa0000aaaa0000aa00",
-                "model": "4.21",
-                "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},
-                "sensors": {
-                    "water_temperature": 23.6,
-                    "intended_boiler_temperature": 17.0,
-                    "modulation_level": 0.0,
-                    "return_temperature": 21.7,
-                    "water_pressure": 1.2,
-                },
-            },
-        }
-
-        self.smile_setup = "legacy_anna"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "1.8.22"
-        _LOGGER.info(" # Assert legacy")
-        assert smile._smile_legacy
-
-        await self.device_test(smile, "2020-03-22 00:00:01", testdata)
-        assert smile.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00"
-        assert (
-            smile._last_active["0000aaaa0000aaaa0000aaaa0000aa00"]
-            == "Thermostat schedule"
-        )
-        assert smile.device_items == 44
-        assert not self.notifications
-
-        result = await self.tinker_thermostat(
-            smile,
-            "0000aaaa0000aaaa0000aaaa0000aa00",
-            good_schedules=[
-                "Thermostat schedule",
-            ],
-        )
-        assert result
-        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)
-        result = await self.tinker_thermostat(
-            smile,
-            "0000aaaa0000aaaa0000aaaa0000aa00",
-            good_schedules=[
-                "Thermostat schedule",
-            ],
-            unhappy=True,
-        )
-        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."""
-        testdata = {
-            "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",
-                "binary_sensors": {"plugwise_notification": False},
-                "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": None,
-                "available_schedules": ["Thermostat schedule"],
-                "select_schedule": "None",
-                "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,
-                },
-                "binary_sensors": {"flame_state": False, "heating_state": False},
-                "sensors": {
-                    "water_temperature": 54.0,
-                    "intended_boiler_temperature": 0.0,
-                    "modulation_level": 0.0,
-                    "return_temperature": 0.0,
-                    "water_pressure": 1.7,
-                },
-            },
-        }
-
-        self.smile_setup = "legacy_anna_2"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "1.8.22"
-        _LOGGER.info(" # Assert legacy")
-        assert smile._smile_legacy
-
-        await self.device_test(smile, "2020-05-03 00:00:01", testdata)
-
-        assert smile.gateway_id == "be81e3f8275b4129852c4d8d550ae2eb"
-        assert (
-            smile._last_active["be81e3f8275b4129852c4d8d550ae2eb"]
-            == "Thermostat schedule"
-        )
-        assert smile.device_items == 44
-        assert not self.notifications
-
-        result = await self.tinker_thermostat(
-            smile,
-            "be81e3f8275b4129852c4d8d550ae2eb",
-            good_schedules=[
-                "Thermostat schedule",
-            ],
-        )
-        assert result
-
-        smile._schedule_old_states["be81e3f8275b4129852c4d8d550ae2eb"][
-            "Thermostat schedule"
-        ] = "off"
-        result_1 = await self.tinker_thermostat_schedule(
-            smile,
-            "be81e3f8275b4129852c4d8d550ae2eb",
-            "on",
-            good_schedules=["Thermostat schedule"],
-            single=True,
-        )
-        result_2 = await self.tinker_thermostat_schedule(
-            smile,
-            "be81e3f8275b4129852c4d8d550ae2eb",
-            "on",
-            good_schedules=["Thermostat schedule"],
-            single=True,
-        )
-        assert result_1 and result_2
-
-        await smile.close_connection()
-        await self.disconnect(server, client)
-
-    @pytest.mark.asyncio
-    async def test_connect_smile_p1_v2(self):
-        """Test a legacy P1 device."""
-        testdata = {
-            "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,
-                    "electricity_consumed_point": 458,
-                    "net_electricity_cumulative": 1019.201,
-                    "electricity_consumed_peak_cumulative": 1155.195,
-                    "electricity_consumed_off_peak_cumulative": 1642.74,
-                    "electricity_consumed_peak_interval": 250,
-                    "electricity_consumed_off_peak_interval": 0,
-                    "electricity_produced_point": 0,
-                    "electricity_produced_peak_cumulative": 1296.136,
-                    "electricity_produced_off_peak_cumulative": 482.598,
-                    "electricity_produced_peak_interval": 0,
-                    "electricity_produced_off_peak_interval": 0,
-                    "gas_consumed_cumulative": 584.433,
-                    "gas_consumed_interval": 0.016,
-                },
-            },
-        }
-
-        self.smile_setup = "smile_p1_v2"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = power")
-        assert smile.smile_type == "power"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "2.5.9"
-        _LOGGER.info(" # Assert legacy")
-        assert smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.gateway_id == "aaaa0000aaaa0000aaaa0000aaaa00aa"
-        assert smile.device_items == 26
-        assert not self.notifications
-
-        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."""
-        testdata = {
-            "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,
-                    "electricity_consumed_point": 458,
-                    "net_electricity_cumulative": 1019.201,
-                    "electricity_consumed_peak_cumulative": 1155.195,
-                    "electricity_consumed_off_peak_cumulative": 1642.74,
-                    "electricity_consumed_peak_interval": 250,
-                    "electricity_consumed_off_peak_interval": 0,
-                    "electricity_produced_point": 0,
-                    "electricity_produced_peak_cumulative": 1296.136,
-                    "electricity_produced_off_peak_cumulative": 482.598,
-                    "electricity_produced_peak_interval": 0,
-                    "electricity_produced_off_peak_interval": 0,
-                    "gas_consumed_cumulative": 584.433,
-                    "gas_consumed_interval": 0.016,
-                },
-            },
-        }
-        testdata_updated = {
-            "199aa40f126840f392983d171374ab0b": {
-                "sensors": {
-                    "net_electricity_point": -2248,
-                    "electricity_consumed_point": 0,
-                    "net_electricity_cumulative": 1019.101,
-                    "electricity_consumed_peak_cumulative": 1155.295,
-                    "electricity_consumed_off_peak_cumulative": 1642.84,
-                    "electricity_produced_point": 2248,
-                    "electricity_produced_peak_cumulative": 1296.336,
-                    "electricity_produced_off_peak_cumulative": 482.698,
-                    "gas_consumed_cumulative": 585.433,
-                    "gas_consumed_interval": 0,
-                },
-            },
-        }
-
-        self.smile_setup = "smile_p1_v2_2"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = power")
-        assert smile.smile_type == "power"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "2.5.9"
-        _LOGGER.info(" # Assert legacy")
-        assert smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.device_items == 26
-        assert not self.notifications
-
-        # Now change some data and change directory reading xml from
-        # emulating reading newer dataset after an update_interval
-        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)
-
-    @pytest.mark.asyncio
-    async def test_connect_anna_v4(self):
-        """Test an Anna firmware 4 setup."""
-        testdata = {
-            "cd0e6156b1f04d5f952349ffbe397481": {
-                "dev_class": "heater_central",
-                "location": "94c107dc6ac84ed98e9f68c0dd06bf71",
-                "model": "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.0,
-                },
-                "max_dhw_temperature": {
-                    "setpoint": 60.0,
-                    "lower_bound": 30.0,
-                    "upper_bound": 60.0,
-                    "resolution": 0.01,
-                },
-                "available": True,
-                "binary_sensors": {
-                    "dhw_state": False,
-                    "heating_state": True,
-                    "flame_state": True,
-                },
-                "sensors": {
-                    "water_temperature": 52.0,
-                    "intended_boiler_temperature": 48.6,
-                    "modulation_level": 0.0,
-                    "return_temperature": 42.0,
-                    "water_pressure": 2.1,
-                },
-                "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",
-                "mode": "heat",
-                "sensors": {"temperature": 20.5, "setpoint": 20.5, "illuminance": 40.5},
-            },
-            "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},
-            },
-        }
-        testdata_updated = {
-            "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.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",
-                "mode": "auto",
-                "sensors": {"temperature": 19.5, "setpoint": 19.5, "illuminance": 39.5},
-            },
-            "0466eae8520144c78afb29628384edeb": {
-                "sensors": {"outdoor_temperature": 6.44},
-            },
-        }
-
-        self.smile_setup = "anna_v4"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.0.15"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2020-04-05 00:00:01", testdata)
-        assert smile.gateway_id == "0466eae8520144c78afb29628384edeb"
-        assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard"
-        assert smile.device_items == 56
-        assert not self.notifications
-
-        assert not smile._cooling_present
-        assert not smile._cooling_active
-        assert not smile._cooling_enabled
-
-        result = await self.tinker_thermostat(
-            smile,
-            "eb5309212bf5407bb143e5bfa3b18aee",
-            schedule_on=False,
-            good_schedules=["Standaard", "Thuiswerken"],
-        )
-        assert result
-        result = await self.tinker_temp_offset(
-            smile, "01b85360fdd243d0aaad4d6ac2a5ba7e"
-        )
-        assert result
-        result = await self.tinker_temp_offset(
-            smile, "0466eae8520144c78afb29628384edeb"
-        )
-        assert not result
-
-        # Now change some data and change directory reading xml from
-        # emulating reading newer dataset after an update_interval
-        self.smile_setup = "updated/anna_v4"
-        await self.device_test(
-            smile, "2020-04-05 00:00:01", testdata_updated, initialize=False
-        )
-
-        await smile.close_connection()
-        await self.disconnect(server, client)
-
-        server, smile, client = await self.connect_wrapper(raise_timeout=True)
-        # Reset self.smile_setup
-        self.smile_setup = "anna_v4"
-        await self.device_test(smile, "2020-04-05 00:00:01", testdata)
-        result = await self.tinker_thermostat(
-            smile,
-            "eb5309212bf5407bb143e5bfa3b18aee",
-            schedule_on=False,
-            good_schedules=["Standaard", "Thuiswerken"],
-            unhappy=True,
-        )
-        assert result
-        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."""
-        testdata = {
-            "cd0e6156b1f04d5f952349ffbe397481": {
-                "dev_class": "heater_central",
-                "location": "94c107dc6ac84ed98e9f68c0dd06bf71",
-                "model": "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.0,
-                },
-                "max_dhw_temperature": {
-                    "setpoint": 60.0,
-                    "lower_bound": 30.0,
-                    "upper_bound": 60.0,
-                    "resolution": 0.01,
-                },
-                "available": True,
-                "binary_sensors": {
-                    "dhw_state": True,
-                    "heating_state": False,
-                    "flame_state": True,
-                },
-                "sensors": {
-                    "water_temperature": 52.0,
-                    "intended_boiler_temperature": 48.6,
-                    "modulation_level": 0.0,
-                    "return_temperature": 42.0,
-                    "water_pressure": 2.1,
-                },
-                "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",
-                "mode": "heat",
-                "sensors": {"temperature": 20.5, "setpoint": 20.5, "illuminance": 40.5},
-            },
-            "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},
-            },
-        }
-
-        self.smile_setup = "anna_v4_dhw"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.0.15"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2020-04-05 00:00:01", testdata)
-        assert smile._last_active["eb5309212bf5407bb143e5bfa3b18aee"] == "Standaard"
-        assert smile.device_items == 56
-        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"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.0.15"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2020-04-05 00:00:01", testdata)
-        assert smile.device_items == 56
-
-        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."""
-        testdata = {
-            "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},
-                "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,
-                },
-                "preset_modes": ["no_frost", "asleep", "away", "vacation", "home"],
-                "active_preset": "home",
-                "available_schedules": ["Test", "Normaal", "off"],
-                "select_schedule": "Normaal",
-                "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},
-            },
-        }
-
-        self.smile_setup = "anna_without_boiler_fw441"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.4.1"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile._last_active["c34c6864216446528e95d88985e714cc"] == "Normaal"
-        assert smile.device_items == 38
-        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_adam_plus_anna(self):
-        """Test Adam (firmware 3.0) with Anna setup."""
-        testdata = {
-            "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,
-                },
-                "available": False,
-                "binary_sensors": {
-                    "dhw_state": False,
-                    "heating_state": False,
-                    "flame_state": False,
-                },
-                "sensors": {
-                    "water_temperature": 47.0,
-                    "intended_boiler_temperature": 0.0,
-                },
-                "switches": {"dhw_cm_switch": False},
-            },
-            "aa6b0002df0a46e1b1eb94beb61eddfe": {
-                "dev_class": "hometheater",
-                "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},
-                "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",
-                "mode": "auto",
-                "sensors": {"temperature": 20.5, "setpoint": 20.5},
-            },
-            "f2be121e4a9345ac83c6e99ed89a98be": {
-                "dev_class": "computer_desktop",
-                "firmware": "2019-06-21T02:00:00+02:00",
-                "location": "5ccb6c41a7d9403988d261ceee04239f",
-                "name": "Work-PC",
-                "zigbee_mac_address": "ABCD012345670A02",
-                "vendor": "Plugwise",
-                "available": True,
-                "sensors": {
-                    "electricity_consumed": 79.8,
-                    "electricity_consumed_interval": 7.03,
-                    "electricity_produced": 0.0,
-                    "electricity_produced_interval": 0.0,
-                },
-                "switches": {"relay": True, "lock": False},
-            },
-        }
-
-        self.smile_setup = "adam_plus_anna"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "3.0.15"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2020-03-22 00:00:01", testdata)
-        assert smile.gateway_id == "b128b4bbbd1f47e9bf4d756e8fb5ee94"
-        assert smile._last_active["009490cc2f674ce6b576863fbb64f867"] == "Weekschema"
-        assert smile.device_items == 70
-        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)
-        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_connect_adam_plus_anna_copy_with_error_domain_added(self):
-        """Test erroneous domain_objects file from user."""
-        testdata = {
-            # Central
-            "2743216f626f43948deec1f7ab3b3d70": {
-                "binary_sensors": {"heating_state": False},
-            },
-        }
-
-        self.smile_setup = "adam_plus_anna_copy_with_error_domain_added"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "3.0.23"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2020-03-22 00:00:01", testdata)
-        assert smile.device_items == 70
-
-        assert "3d28a20e17cb47dca210a132463721d5" in self.notifications
-
-        await smile.close_connection()
-        await self.disconnect(server, client)
-
-    @pytest.mark.asyncio
-    async def test_connect_adam_plus_anna_new(self):
-        """Test extended Adam (firmware 3.7) with Anna and a switch-group setup."""
-        testdata = {
-            "da224107914542988a88561b4452b0f6": {
-                "dev_class": "gateway",
-                "firmware": "3.7.8",
-                "hardware": "AME Smile 2.0 board",
-                "location": "bc93488efab249e5bc54fd7e175a6f91",
-                "mac_address": "012345679891",
-                "model": "Gateway",
-                "name": "Adam",
-                "zigbee_mac_address": "000D6F000D5A168D",
-                "vendor": "Plugwise",
-                "binary_sensors": {"plugwise_notification": False},
-                "sensors": {"outdoor_temperature": 9.19},
-                "select_regulation_mode": "heating",
-                "regulation_modes": ["bleeding_hot", "bleeding_cold", "off", "heating"],
-            },
-            "056ee145a816487eaa69243c3280f8bf": {
-                "dev_class": "heater_central",
-                "location": "bc93488efab249e5bc54fd7e175a6f91",
-                "model": "Generic heater",
-                "name": "OpenTherm",
-                "binary_sensors": {
-                    "dhw_state": False,
-                    "heating_state": True,
-                    "flame_state": True,
-                },
-                "sensors": {
-                    "water_temperature": 29.0,
-                    "intended_boiler_temperature": 20.0,
-                },
-                "switches": {"dhw_cm_switch": False},
-                "maximum_boiler_temperature": {
-                    "setpoint": 50.0,
-                    "resolution": 0.01,
-                    "lower_bound": 25.0,
-                    "upper_bound": 95.0,
-                },
-                "available": True,
-            },
-            "67d73d0bd469422db25a618a5fb8eeb0": {
-                "dev_class": "zz_misc",
-                "location": "b4f211175e124df59603412bafa77a34",
-                "model": "lumi.plug.maeu01",
-                "name": "SmartPlug Floor 0",
-                "zigbee_mac_address": "54EF4410002C97F2",
-                "vendor": "LUMI",
-                "sensors": {"electricity_consumed_interval": 0.0},
-                "switches": {"relay": True, "lock": False},
-                "available": True,
-            },
-            "e2f4322d57924fa090fbbc48b3a140dc": {
-                "dev_class": "zone_thermostat",
-                "firmware": "2016-10-10T02:00:00+02:00",
-                "hardware": "255",
-                "location": "f871b8c4d63549319221e294e4f88074",
-                "model": "Lisa",
-                "name": "Lisa Badkamer",
-                "zigbee_mac_address": "000D6F000C869B61",
-                "vendor": "Plugwise",
-                "sensors": {"temperature": 16.5, "setpoint": 18.0, "battery": 38},
-                "temperature_offset": {
-                    "lower_bound": -2.0,
-                    "resolution": 0.1,
-                    "upper_bound": 2.0,
-                    "setpoint": 0.0,
-                },
-                "thermostat": {
-                    "setpoint": 18.0,
-                    "resolution": 0.01,
-                    "lower_bound": 0.0,
-                    "upper_bound": 99.9,
-                },
-                "available": True,
-                "control_state": "preheating",
-                "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"],
-                "active_preset": "home",
-                "available_schedules": [
-                    "Badkamer",
-                    "Test",
-                    "Vakantie",
-                    "Weekschema",
-                    "off",
-                ],
-                "select_schedule": "Badkamer",
-                "mode": "auto",
-            },
-            "854f8a9b0e7e425db97f1f110e1ce4b3": {
-                "dev_class": "central_heating_pump",
-                "firmware": "2020-11-10T01:00:00+01:00",
-                "location": "f2bf9048bef64cc5b6d5110154e33c81",
-                "model": "Plug",
-                "name": "Plug Vloerverwarming",
-                "zigbee_mac_address": "000D6F000D13CB6F",
-                "vendor": "Plugwise",
-                "sensors": {
-                    "electricity_consumed": 43.8,
-                    "electricity_consumed_interval": 0.0,
-                    "electricity_produced": 0.0,
-                    "electricity_produced_interval": 0.0,
-                },
-                "switches": {"relay": True},
-                "available": True,
-            },
-            "ad4838d7d35c4d6ea796ee12ae5aedf8": {
-                "dev_class": "thermostat",
-                "location": "f2bf9048bef64cc5b6d5110154e33c81",
-                "model": "ThermoTouch",
-                "name": "Anna",
-                "vendor": "Plugwise",
-                "sensors": {"temperature": 18.4, "setpoint": 18.5},
-                "thermostat": {
-                    "setpoint": 18.5,
-                    "resolution": 0.01,
-                    "lower_bound": 1.0,
-                    "upper_bound": 35.0,
-                },
-                "control_state": "heating",
-                "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"],
-                "active_preset": "home",
-                "available_schedules": [
-                    "Badkamer",
-                    "Test",
-                    "Vakantie",
-                    "Weekschema",
-                    "off",
-                ],
-                "select_schedule": "Weekschema",
-                "mode": "auto",
-            },
-            "29542b2b6a6a4169acecc15c72a599b8": {
-                "dev_class": "computer_desktop",
-                "firmware": "2020-11-10T01:00:00+01:00",
-                "location": "f2bf9048bef64cc5b6d5110154e33c81",
-                "model": "Plug",
-                "name": "Plug Werkplek",
-                "zigbee_mac_address": "000D6F000D13CA9A",
-                "vendor": "Plugwise",
-                "sensors": {
-                    "electricity_consumed": 87.6,
-                    "electricity_consumed_interval": 23.0,
-                    "electricity_produced": 0.0,
-                    "electricity_produced_interval": 0.0,
-                },
-                "switches": {"relay": True, "lock": False},
-                "available": True,
-            },
-            "1772a4ea304041adb83f357b751341ff": {
-                "dev_class": "thermo_sensor",
-                "firmware": "2020-11-04T01:00:00+01:00",
-                "hardware": "1",
-                "location": "f871b8c4d63549319221e294e4f88074",
-                "model": "Tom/Floor",
-                "name": "Tom Badkamer",
-                "zigbee_mac_address": "000D6F000C8FF5EE",
-                "vendor": "Plugwise",
-                "sensors": {
-                    "temperature": 17.6,
-                    "setpoint": 18.0,
-                    "battery": 99,
-                    "temperature_difference": -0.2,
-                    "valve_position": 100,
-                },
-                "temperature_offset": {
-                    "lower_bound": -2.0,
-                    "resolution": 0.1,
-                    "upper_bound": 2.0,
-                    "setpoint": 0.1,
-                },
-                "available": True,
-            },
-            "2568cc4b9c1e401495d4741a5f89bee1": {
-                "dev_class": "hometheater",
-                "firmware": "2020-11-10T01:00:00+01:00",
-                "location": "f2bf9048bef64cc5b6d5110154e33c81",
-                "model": "Plug",
-                "name": "Plug MediaTV",
-                "zigbee_mac_address": "000D6F000D13CCFD",
-                "vendor": "Plugwise",
-                "sensors": {
-                    "electricity_consumed": 14.8,
-                    "electricity_consumed_interval": 3.0,
-                    "electricity_produced": 0.0,
-                    "electricity_produced_interval": 0.0,
-                },
-                "switches": {"relay": True, "lock": True},
-                "available": True,
-            },
-            "e8ef2a01ed3b4139a53bf749204fe6b4": {
-                "dev_class": "switching",
-                "model": "Switchgroup",
-                "name": "Test",
-                "members": [
-                    "2568cc4b9c1e401495d4741a5f89bee1",
-                    "29542b2b6a6a4169acecc15c72a599b8",
-                ],
-                "switches": {"relay": True},
-            },
-        }
-        testdata_updated = {
-            "67d73d0bd469422db25a618a5fb8eeb0": {
-                "switches": {"lock": True},
-            },
-            "ad4838d7d35c4d6ea796ee12ae5aedf8": {
-                "mode": "off",
-            },
-            "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": {
-                "mode": "off",
-            },
-            "da224107914542988a88561b4452b0f6": {
-                "binary_sensors": {"plugwise_notification": True},
-            },
-            "e8ef2a01ed3b4139a53bf749204fe6b4": {
-                "members": [
-                    "2568cc4b9c1e401495d4741a5f89bee1",
-                    "29542b2b6a6a4169acecc15c72a599b8",
-                ],
-                "switches": {"relay": False},
-            },
-        }
-
-        self.smile_setup = "adam_plus_anna_new"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "3.7.8"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2023-12-17 00:00:01", testdata)
-        assert smile.gateway_id == "da224107914542988a88561b4452b0f6"
-        assert smile._last_active["f2bf9048bef64cc5b6d5110154e33c81"] == "Weekschema"
-        assert smile._last_active["f871b8c4d63549319221e294e4f88074"] == "Badkamer"
-        assert smile.device_items == 145
-        assert smile.device_list == [
-            "da224107914542988a88561b4452b0f6",
-            "056ee145a816487eaa69243c3280f8bf",
-            "67d73d0bd469422db25a618a5fb8eeb0",
-            "e2f4322d57924fa090fbbc48b3a140dc",
-            "854f8a9b0e7e425db97f1f110e1ce4b3",
-            "ad4838d7d35c4d6ea796ee12ae5aedf8",
-            "29542b2b6a6a4169acecc15c72a599b8",
-            "1772a4ea304041adb83f357b751341ff",
-            "2568cc4b9c1e401495d4741a5f89bee1",
-            "e8ef2a01ed3b4139a53bf749204fe6b4",
-        ]
-
-        result = await self.tinker_thermostat(
-            smile,
-            "f2bf9048bef64cc5b6d5110154e33c81",
-            good_schedules=["Weekschema", "Badkamer", "Test"],
-        )
-        assert result
-
-        # Special test-case for turning a schedule off based on only the location id.
-        await smile.set_schedule_state("f2bf9048bef64cc5b6d5110154e33c81", "off")
-
-        # Special test-case for turning a schedule off for a location via the option "off".
-        await smile.set_schedule_state("f2bf9048bef64cc5b6d5110154e33c81", "on", "off")
-
-        # bad schedule-state test
-        result = await self.tinker_thermostat_schedule(
-            smile,
-            "f2bf9048bef64cc5b6d5110154e33c81",
-            "bad",
-            good_schedules=["Badkamer"],
-            single=True,
-        )
-        assert result
-
-        smile._schedule_old_states["f2bf9048bef64cc5b6d5110154e33c81"][
-            "Badkamer"
-        ] = "off"
-        result_1 = await self.tinker_thermostat_schedule(
-            smile,
-            "f2bf9048bef64cc5b6d5110154e33c81",
-            "on",
-            good_schedules=["Badkamer"],
-            single=True,
-        )
-        result_2 = await self.tinker_thermostat_schedule(
-            smile,
-            "f2bf9048bef64cc5b6d5110154e33c81",
-            "on",
-            good_schedules=["Badkamer"],
-            single=True,
-        )
-        assert result_1 and result_2
-
-        switch_change = await self.tinker_switch(
-            smile,
-            "e8ef2a01ed3b4139a53bf749204fe6b4",
-            ["2568cc4b9c1e401495d4741a5f89bee1", "29542b2b6a6a4169acecc15c72a599b8"],
-        )
-        assert switch_change
-        switch_change = await self.tinker_switch(
-            smile, "056ee145a816487eaa69243c3280f8bf", model="dhw_cm_switch"
-        )
-        assert switch_change
-        switch_change = await self.tinker_switch(
-            smile, "854f8a9b0e7e425db97f1f110e1ce4b3", model="lock"
-        )
-        assert switch_change
-        switch_change = await self.tinker_switch(
-            smile, "2568cc4b9c1e401495d4741a5f89bee1"
-        )
-        assert not switch_change
-
-        await self.tinker_regulation_mode(smile)
-
-        await self.tinker_max_boiler_temp(smile)
-
-        # Now change some data and change directory reading xml from
-        # emulating reading newer dataset after an update_interval
-        self.smile_setup = "updated/adam_plus_anna_new"
-        await self.device_test(
-            smile, "2023-12-17 00:00:01", testdata_updated, initialize=False
-        )
-
-        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."""
-        testdata = {
-            "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,
-                },
-                "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",
-                "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": 0.0,
-                },
-            },
-            "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.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,
-                },
-                "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",
-                "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},
-                "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.0,
-                },
-            },
-            "21f2b542c49845e6bb416884c55778d6": {
-                "dev_class": "game_console",
-                "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": 81.2,
-                    "electricity_consumed_interval": 12.7,
-                    "electricity_produced": 0.0,
-                    "electricity_produced_interval": 0.0,
-                },
-                "switches": {"relay": True, "lock": False},
-            },
-            "78d1126fc4c743db81b61c20e88342a7": {
-                "dev_class": "central_heating_pump",
-                "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,
-                },
-                "switches": {"relay": True},
-            },
-            "90986d591dcd426cae3ec3e8111ff730": {
-                "dev_class": "heater_central",
-                "location": "1f9dcf83fd4e4b66b72ff787957bfe5d",
-                "model": "Unknown",
-                "name": "OnOff",
-                "binary_sensors": {"heating_state": False},
-                "sensors": {
-                    "water_temperature": 70.0,
-                    "intended_boiler_temperature": 70.0,
-                    "modulation_level": 1,
-                },
-            },
-            "cd0ddb54ef694e11ac18ed1cbce5dbbd": {
-                "dev_class": "vcr",
-                "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,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "4a810418d5394b3f82727340b91ba740": {
-                "dev_class": "router",
-                "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,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "02cf28bfec924855854c544690a609ef": {
-                "dev_class": "vcr",
-                "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,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "a28f588dc4a049a483fd03a30361ad3a": {
-                "dev_class": "settop",
-                "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,
-                },
-                "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,
-                },
-                "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",
-                "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.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,
-                },
-                "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",
-                "mode": "auto",
-                "sensors": {"temperature": 18.8, "setpoint": 14.0, "battery": 92},
-            },
-            "675416a629f343c495449970e2ca37b5": {
-                "dev_class": "router",
-                "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,
-                },
-                "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,
-                },
-                "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",
-                "mode": "heat",
-                "sensors": {
-                    "temperature": 15.6,
-                    "setpoint": 5.5,
-                    "battery": 68,
-                    "temperature_difference": 0.1,
-                    "valve_position": 0.0,
-                },
-            },
-        }
-
-        self.smile_setup = "adam_zone_per_device"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "3.0.15"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        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 smile.device_items == 315
-
-        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
-        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)
-        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
-
-        try:
-            await smile.delete_notification()
-            assert False  # pragma: no cover
-        except pw_exceptions.ResponseError:
-            assert True
-
-        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."""
-        testdata = {
-            "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,
-                },
-                "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",
-                "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.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,
-                },
-                "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",
-                "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},
-                "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.0,
-                },
-            },
-            "21f2b542c49845e6bb416884c55778d6": {
-                "dev_class": "game_console",
-                "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": 82.6,
-                    "electricity_consumed_interval": 8.6,
-                    "electricity_produced": 0.0,
-                    "electricity_produced_interval": 0.0,
-                },
-                "switches": {"relay": True, "lock": False},
-            },
-            "78d1126fc4c743db81b61c20e88342a7": {
-                "dev_class": "central_heating_pump",
-                "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,
-                },
-                "switches": {"relay": True},
-            },
-            "90986d591dcd426cae3ec3e8111ff730": {
-                "dev_class": "heater_central",
-                "location": "1f9dcf83fd4e4b66b72ff787957bfe5d",
-                "model": "Unknown",
-                "name": "OnOff",
-                "binary_sensors": {"heating_state": True},
-                "sensors": {
-                    "water_temperature": 70.0,
-                    "intended_boiler_temperature": 70.0,
-                    "modulation_level": 1,
-                },
-            },
-            "cd0ddb54ef694e11ac18ed1cbce5dbbd": {
-                "dev_class": "vcr",
-                "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,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "4a810418d5394b3f82727340b91ba740": {
-                "dev_class": "router",
-                "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,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "02cf28bfec924855854c544690a609ef": {
-                "dev_class": "vcr",
-                "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,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "a28f588dc4a049a483fd03a30361ad3a": {
-                "dev_class": "settop",
-                "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,
-                },
-                "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,
-                },
-                "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",
-                "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.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,
-                },
-                "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",
-                "mode": "auto",
-                "sensors": {"temperature": 18.9, "setpoint": 14.0, "battery": 92},
-            },
-            "675416a629f343c495449970e2ca37b5": {
-                "dev_class": "router",
-                "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,
-                },
-                "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,
-                },
-                "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",
-                "mode": "heat",
-                "sensors": {
-                    "temperature": 15.6,
-                    "setpoint": 5.5,
-                    "battery": 68,
-                    "temperature_difference": 0.0,
-                    "valve_position": 0.0,
-                },
-            },
-        }
-
-        self.smile_setup = "adam_multiple_devices_per_zone"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "3.0.15"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        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 smile.device_items == 315
-
-        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."""
-        testdata = {
-            "0ca13e8176204ca7bf6f09de59f81c83": {
-                "available": True,
-                "binary_sensors": {
-                    "cooling_state": False,
-                    "dhw_state": False,
-                    "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": "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "hardware": "AME Smile 2.0 board",
-                "location": "eedadcb297564f1483faa509179aebed",
-                "mac_address": "012345670001",
-                "model": "Gateway",
-                "name": "Adam",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-                "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",
-            },
-        }
-
-        self.smile_setup = "adam_heatpump_cooling"
-        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 smile.device_items == 413
-
-        await smile.close_connection()
-        await self.disconnect(server, client)
-
-    @pytest.mark.asyncio
-    async def test_adam_plus_jip(self):
-        """Test Adam with Jip setup."""
-        testdata = {
-            "e4684553153b44afbef2200885f379dc": {
-                "dev_class": "heater_central",
-                "location": "9e4433a9d69f40b3aefd15e74395eaec",
-                "model": "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,
-                },
-                "max_dhw_temperature": {
-                    "setpoint": 60.0,
-                    "lower_bound": 40.0,
-                    "upper_bound": 60.0,
-                    "resolution": 0.01,
-                },
-                "available": True,
-                "binary_sensors": {
-                    "dhw_state": False,
-                    "heating_state": False,
-                    "flame_state": False,
-                },
-                "sensors": {
-                    "water_temperature": 37.3,
-                    "intended_boiler_temperature": 0.0,
-                    "modulation_level": 0.0,
-                    "return_temperature": 37.1,
-                    "water_pressure": 1.4,
-                },
-                "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": {
-                    "setpoint": 13.0,
-                    "lower_bound": 0.0,
-                    "upper_bound": 99.9,
-                    "resolution": 0.01,
-                },
-                "available": True,
-                "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
-                "active_preset": "home",
-                "available_schedules": ["None"],
-                "select_schedule": "None",
-                "control_state": "off",
-                "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,
-                },
-                "available": True,
-                "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
-                "active_preset": "no_frost",
-                "available_schedules": ["None"],
-                "select_schedule": "None",
-                "control_state": "off",
-                "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,
-                },
-                "available": True,
-                "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
-                "active_preset": "home",
-                "available_schedules": ["None"],
-                "select_schedule": "None",
-                "control_state": "off",
-                "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,
-                },
-                "available": True,
-                "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
-                "active_preset": "home",
-                "available_schedules": ["None"],
-                "select_schedule": "None",
-                "control_state": "off",
-                "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.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.3,
-                    "setpoint": 13.0,
-                    "temperature_difference": 1.7,
-                    "valve_position": 0.0,
-                },
-            },
-            "b5c2386c6f6342669e50fe49dd05b188": {
-                "dev_class": "gateway",
-                "firmware": "3.2.8",
-                "hardware": "AME Smile 2.0 board",
-                "location": "9e4433a9d69f40b3aefd15e74395eaec",
-                "mac_address": "012345670001",
-                "model": "Gateway",
-                "name": "Adam",
-                "zigbee_mac_address": "ABCD012345670101",
-                "vendor": "Plugwise",
-                "select_regulation_mode": "heating",
-                "regulation_modes": ["heating", "off", "bleeding_cold", "bleeding_hot"],
-                "binary_sensors": {"plugwise_notification": False},
-                "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.0,
-                },
-            },
-            "457ce8414de24596a2d5e7dbc9c7682f": {
-                "dev_class": "zz_misc",
-                "location": "9e4433a9d69f40b3aefd15e74395eaec",
-                "model": "lumi.plug.maeu01",
-                "name": "Plug",
-                "zigbee_mac_address": "ABCD012345670A06",
-                "vendor": "LUMI",
-                "available": True,
-                "sensors": {"electricity_consumed_interval": 0.0},
-                "switches": {"relay": False, "lock": True},
-            },
-        }
-
-        self.smile_setup = "adam_jip"
-        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 smile.device_items == 219
-
-        # 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)
-
-    @pytest.mark.asyncio
-    async def test_connect_anna_heatpump_heating(self):
-        """Test an Anna with Elga, cooling-mode off, in heating mode."""
-        testdata = {
-            "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},
-                "sensors": {"outdoor_temperature": 20.2},
-            },
-            "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,
-                },
-                "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,
-                    "cooling_state": False,
-                    "cooling_enabled": False,
-                    "slave_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_low": 20.5,
-                    "setpoint_high": 30.0,
-                    "lower_bound": 4.0,
-                    "upper_bound": 30.0,
-                    "resolution": 0.1,
-                },
-                "preset_modes": ["no_frost", "home", "away", "asleep", "vacation"],
-                "active_preset": "home",
-                "available_schedules": ["standaard", "off"],
-                "select_schedule": "standaard",
-                "mode": "auto",
-                "sensors": {
-                    "temperature": 19.3,
-                    "illuminance": 86.0,
-                    "cooling_activation_outdoor_temperature": 21.0,
-                    "cooling_deactivation_threshold": 4.0,
-                    "setpoint_low": 20.5,
-                    "setpoint_high": 30.0,
-                },
-            },
-        }
-        testdata_updated = {
-            "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,
-                    "slave_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},
-            },
-        }
-
-        self.smile_setup = "anna_heatpump_heating"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.0.15"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2020-04-12 00:00:01", testdata)
-        assert smile.gateway_id == "015ae9ea3f964e668e490fa39da3870b"
-        assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard"
-        assert smile.device_items == 66
-        assert not self.notifications
-        assert self.cooling_present
-        assert not smile._cooling_enabled
-        assert not smile._cooling_active
-
-        with pytest.raises(pw_exceptions.PlugwiseError) as exc:
-            await self.tinker_thermostat(
-                smile,
-                "c784ee9fdab44e1395b8dee7d7a497d5",
-                good_schedules=[
-                    "standaard",
-                ],
-            )
-        _LOGGER.debug("ERROR raised: %s", exc.value)
-
-        # 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
-        self.smile_setup = "updated/anna_heatpump_heating"
-        await self.device_test(
-            smile, "2020-04-13 00:00:01", testdata_updated, initialize=False
-        )
-        assert smile.device_items == 63
-        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.
-        """
-        testdata = {
-            "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},
-                "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,
-                    "slave_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,
-                },
-                "preset_modes": ["no_frost", "home", "away", "asleep", "vacation"],
-                "active_preset": "home",
-                "available_schedules": ["standaard", "off"],
-                "select_schedule": "off",
-                "mode": "heat_cool",
-                "sensors": {
-                    "temperature": 22.3,
-                    "illuminance": 25.5,
-                    "cooling_activation_outdoor_temperature": 21.0,
-                    "cooling_deactivation_threshold": 6.0,
-                    "setpoint_low": 4.0,
-                    "setpoint_high": 22.0,
-                },
-            },
-        }
-
-        self.smile_setup = "anna_heatpump_cooling"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.0.15"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2020-04-19 00:00:01", testdata)
-        assert smile._last_active["c784ee9fdab44e1395b8dee7d7a497d5"] == "standaard"
-        assert smile.device_items == 63
-        assert self.cooling_present
-        assert not self.notifications
-
-        assert smile._cooling_enabled
-        assert smile._cooling_active
-
-        with pytest.raises(pw_exceptions.PlugwiseError) as exc:
-            await self.tinker_thermostat(
-                smile,
-                "c784ee9fdab44e1395b8dee7d7a497d5",
-                good_schedules=[
-                    "standaard",
-                ],
-            )
-        _LOGGER.debug("ERROR raised: %s", exc.value)
-
-        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.
-        """
-        testdata = {
-            # Heater central
-            "1cbf783bb11e4a7c8a6843dee3a86927": {
-                "binary_sensors": {
-                    "cooling_enabled": True,
-                    "cooling_state": True,
-                    "dhw_state": False,
-                    "heating_state": False,
-                },
-                "sensors": {
-                    "modulation_level": 100,
-                },
-            },
-            # Gateway
-            "015ae9ea3f964e668e490fa39da3870b": {
-                "firmware": "4.10.10",
-            },
-        }
-
-        self.smile_setup = "anna_heatpump_cooling_fake_firmware"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.10.10"
-
-        await self.device_test(smile, "2020-04-19 00:00:01", testdata)
-        assert smile.device_items == 63
-        assert smile._cooling_present
-        assert smile._cooling_enabled
-        assert smile._cooling_active
-
-        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."""
-        testdata = {
-            # Heater central
-            "0ca13e8176204ca7bf6f09de59f81c83": {
-                "binary_sensors": {
-                    "cooling_state": True,
-                    "dhw_state": False,
-                    "heating_state": False,
-                },
-                "sensors": {
-                    "modulation_level": 0,
-                },
-            },
-        }
-
-        self.smile_setup = "adam_onoff_cooling_fake_firmware"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-
-        await self.device_test(smile, "2022-01-02 00:00:01", testdata)
-        assert smile.device_items == 54
-        assert smile._cooling_present
-        assert smile._cooling_enabled
-
-        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)."""
-        testdata = {
-            "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},
-                "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,
-                    "slave_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.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,
-                },
-                "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"],
-                "active_preset": "home",
-                "available_schedules": ["Thermostat schedule", "off"],
-                "select_schedule": "Thermostat schedule",
-                "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,
-                },
-            },
-        }
-
-        self.smile_setup = "anna_elga_2"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.2.1"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2022-03-13 00:00:01", testdata)
-        assert (
-            smile._last_active["d3ce834534114348be628b61b26d9220"]
-            == "Thermostat schedule"
-        )
-        assert smile.device_items == 62
-        assert smile.gateway_id == "fb49af122f6e4b0f91267e1cf7666d6f"
-        assert self.cooling_present
-        assert not smile._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."""
-        testdata = {
-            "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,
-                },
-                "preset_modes": ["away", "no_frost", "vacation", "home", "asleep"],
-                "active_preset": "home",
-                "available_schedules": ["Thermostat schedule", "off"],
-                "select_schedule": "off",
-                "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,
-                },
-            }
-        }
-
-        self.smile_setup = "anna_elga_2_schedule_off"
-        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 smile._cooling_present
-        assert not smile._cooling_enabled
-        assert smile.device_items == 62
-
-        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.
-        """
-        testdata = {
-            "573c152e7d4f4720878222bd75638f5b": {
-                "available": True,
-                "binary_sensors": {
-                    "compressor_state": True,
-                    "cooling_enabled": True,
-                    "cooling_state": True,
-                    "dhw_state": False,
-                    "flame_state": False,
-                    "heating_state": False,
-                    "slave_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",
-            },
-            "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",
-                "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",
-            },
-        }
-
-        self.smile_setup = "anna_elga_2_cooling"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.2.1"
-        _LOGGER.info(" # Assert no legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2022-03-10 00:00:01", testdata)
-        assert (
-            smile._last_active["d3ce834534114348be628b61b26d9220"]
-            == "Thermostat schedule"
-        )
-        assert smile.device_items == 62
-        assert not self.notifications
-
-        assert self.cooling_present
-        assert smile._cooling_enabled
-        assert smile._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."""
-        testdata = {
-            "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,
-                },
-                "preset_modes": ["away", "vacation", "no_frost", "home", "asleep"],
-                "active_preset": "home",
-                "available_schedules": ["Winter", "Test ", "off"],
-                "select_schedule": "Winter",
-                "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": "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,
-                    "flame_state": False,
-                },
-                "sensors": {
-                    "water_temperature": 25.3,
-                    "dhw_temperature": 52.9,
-                    "intended_boiler_temperature": 0.0,
-                    "modulation_level": 0.0,
-                    "return_temperature": 26.3,
-                    "outdoor_air_temperature": 17.3,
-                },
-                "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},
-                "sensors": {"outdoor_temperature": 15.5},
-            },
-        }
-
-        self.smile_setup = "anna_loria_heating_idle"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter"
-        assert smile.device_items == 63
-        assert smile._cooling_present
-        assert not smile._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: %s", exc.value)
-
-        with pytest.raises(pw_exceptions.PlugwiseError) as exc:
-            await self.tinker_thermostat_temp(
-                smile,
-                "15da035090b847e7a21f93e08c015ebc",
-                block_cooling=True,
-            )
-        _LOGGER.debug("ERROR raised: %s", exc.value)
-
-        await self.tinker_dhw_mode(smile)
-
-        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."""
-        testdata = {
-            "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,
-                },
-                "preset_modes": ["away", "vacation", "no_frost", "home", "asleep"],
-                "active_preset": "home",
-                "available_schedules": ["Winter", "Test ", "off"],
-                "select_schedule": "Winter",
-                "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": "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,
-                    "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.3,
-                },
-                "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},
-                "sensors": {"outdoor_temperature": 15.5},
-            },
-        }
-
-        self.smile_setup = "anna_loria_cooling_active"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile._last_active["15da035090b847e7a21f93e08c015ebc"] == "Winter"
-        assert smile.device_items == 63
-        assert smile._cooling_present
-        assert smile._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."""
-        testdata = {
-            "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",
-                "name": "Smile Anna",
-                "sensors": {"outdoor_temperature": 6.81},
-                "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",
-                "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_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": "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.63,
-                    "return_temperature": 23.0,
-                    "water_temperature": 23.3,
-                },
-                "switches": {"cooling_ena_switch": False, "dhw_cm_switch": True},
-                "vendor": "Atlantic",
-            },
-        }
-        self.smile_setup = "anna_loria_driessens"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "thermostat"
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.device_items == 63
-        assert smile._cooling_present
-        assert not smile._cooling_enabled
-
-        await smile.close_connection()
-        await self.disconnect(server, client)
-
-    @pytest.mark.asyncio
-    async def test_connect_stretch_v31(self):
-        """Test a legacy Stretch with firmware 3.1 setup."""
-        testdata = {
-            "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "switches": {"relay": True, "lock": False},
-            },
-            "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},
-            },
-        }
-        testdata_updated = {
-            "aac7b735042c4832ac9ff33aae4f453b": {
-                "sensors": {
-                    "electricity_consumed": 1000.0,
-                    "electricity_consumed_interval": 20.7,
-                    "electricity_produced": 0.0,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "cfe95cf3de1948c0b8955125bf754614": {
-                "sensors": {
-                    "electricity_consumed": 0.0,
-                    "electricity_consumed_interval": 0.0,
-                    "electricity_produced": 0.0,
-                },
-                "switches": {"relay": False, "lock": False},
-            },
-            "059e4d03c7a34d278add5c7a4a781d19": {
-                "sensors": {
-                    "electricity_consumed": 0.0,
-                    "electricity_consumed_interval": 0.0,
-                    "electricity_produced": 0.0,
-                },
-                "switches": {"relay": False, "lock": False},
-            },
-            "d03738edfcc947f7b8f4573571d90d2d": {
-                "members": [
-                    "059e4d03c7a34d278add5c7a4a781d19",
-                    "cfe95cf3de1948c0b8955125bf754614",
-                ],
-                "switches": {"relay": False},
-            },
-        }
-
-        self.smile_setup = "stretch_v31"
-        server, smile, client = await self.connect_wrapper(stretch=True)
-        assert smile.smile_hostname == "stretch000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "stretch"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "3.1.11"
-        _LOGGER.info(" # Assert legacy")
-        assert smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00"
-        assert smile.device_items == 83
-
-        # Now change some data and change directory reading xml from
-        # emulating reading newer dataset after an update_interval
-        self.smile_setup = "updated/stretch_v31"
-        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_stretch_v23(self):
-        """Test a legacy Stretch with firmware 2.3 setup."""
-        testdata = {
-            "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "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,
-                },
-                "switches": {"relay": True, "lock": True},
-            },
-            "f7b145c8492f4dd7a4de760456fdef3e": {
-                "dev_class": "switching",
-                "model": "Switchgroup",
-                "name": "Test",
-                "members": ["407aa1c1099d463c9137a3a9eda787fd"],
-                "switches": {"relay": False},
-            },
-        }
-
-        self.smile_setup = "stretch_v23"
-        server, smile, client = await self.connect_wrapper(stretch=True)
-        assert smile.smile_hostname == "stretch000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "stretch"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "2.3.12"
-        _LOGGER.info(" # Assert legacy")
-        assert smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.device_items == 229
-
-        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
-        testdata = {
-            # Circle+
-            "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},
-            },
-            # 76BF93
-            "8b8d14b242e24cd789743c828b9a2ea9": {
-                "sensors": {"electricity_consumed": 1.69},
-                "switches": {"lock": False, "relay": True},
-            },
-            # 25F66AD
-            "d0122ac66eba47b99d8e5fbd1e2f5932": {
-                "sensors": {"electricity_consumed_interval": 2.21}
-            },
-        }
-
-        self.smile_setup = "stretch_v27_no_domain"
-        server, smile, client = await self.connect_wrapper(stretch=True)
-        assert smile.smile_hostname == "stretch000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = thermostat")
-        assert smile.smile_type == "stretch"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "2.7.18"
-        _LOGGER.info(" # Assert legacy")
-        assert smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.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)
-
-    @pytest.mark.asyncio
-    async def test_connect_p1v4(self):
-        """Test a P1 firmware 4 setup."""
-        testdata = {
-            "a455b61e52394b2db5081ce025a430f3": {
-                "dev_class": "gateway",
-                "firmware": "4.1.1",
-                "hardware": "AME Smile 2.0 board",
-                "location": "a455b61e52394b2db5081ce025a430f3",
-                "mac_address": "012345670001",
-                "model": "Gateway",
-                "name": "Smile P1",
-                "vendor": "Plugwise",
-                "binary_sensors": {"plugwise_notification": True},
-            },
-            "ba4de7613517478da82dd9b6abea36af": {
-                "dev_class": "smartmeter",
-                "location": "a455b61e52394b2db5081ce025a430f3",
-                "model": "KFM5KAIFA-METER",
-                "name": "P1",
-                "vendor": "SHENZHEN KAIFA TECHNOLOGY CHENGDU CO.",
-                "available": False,
-                "sensors": {
-                    "net_electricity_point": 548,
-                    "electricity_consumed_peak_point": 548,
-                    "electricity_consumed_off_peak_point": 0,
-                    "net_electricity_cumulative": 20983.453,
-                    "electricity_consumed_peak_cumulative": 9067.554,
-                    "electricity_consumed_off_peak_cumulative": 11915.899,
-                    "electricity_consumed_peak_interval": 335,
-                    "electricity_consumed_off_peak_interval": 0,
-                    "electricity_produced_peak_point": 0,
-                    "electricity_produced_off_peak_point": 0,
-                    "electricity_produced_peak_cumulative": 0.0,
-                    "electricity_produced_off_peak_cumulative": 0.0,
-                    "electricity_produced_peak_interval": 0,
-                    "electricity_produced_off_peak_interval": 0,
-                },
-            },
-        }
-
-        self.smile_setup = "p1v4"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = power")
-        assert smile.smile_type == "power"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.1.1"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.gateway_id == "a455b61e52394b2db5081ce025a430f3"
-        assert smile.device_items == 29
-        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."""
-        testdata = {
-            "a455b61e52394b2db5081ce025a430f3": {
-                "dev_class": "gateway",
-                "firmware": "4.4.2",
-                "hardware": "AME Smile 2.0 board",
-                "location": "a455b61e52394b2db5081ce025a430f3",
-                "mac_address": "012345670001",
-                "model": "Gateway",
-                "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": 421,
-                    "electricity_consumed_peak_point": 0,
-                    "electricity_consumed_off_peak_point": 421,
-                    "net_electricity_cumulative": 31610.113,
-                    "electricity_consumed_peak_cumulative": 13966.608,
-                    "electricity_consumed_off_peak_cumulative": 17643.505,
-                    "electricity_consumed_peak_interval": 0,
-                    "electricity_consumed_off_peak_interval": 21,
-                    "electricity_produced_peak_point": 0,
-                    "electricity_produced_off_peak_point": 0,
-                    "electricity_produced_peak_cumulative": 0.0,
-                    "electricity_produced_off_peak_cumulative": 0.0,
-                    "electricity_produced_peak_interval": 0,
-                    "electricity_produced_off_peak_interval": 0,
-                    "electricity_phase_one_consumed": 413,
-                    "electricity_phase_one_produced": 0,
-                },
-            },
-        }
-        testdata_updated = {
-            "ba4de7613517478da82dd9b6abea36af": {
-                "sensors": {
-                    "net_electricity_point": -2248,
-                    "electricity_consumed_peak_point": 0,
-                    "electricity_consumed_off_peak_point": 0,
-                    "electricity_consumed_peak_interval": 0,
-                    "electricity_consumed_off_peak_interval": 0,
-                    "electricity_produced_peak_point": 2248,
-                    "electricity_produced_off_peak_point": 0,
-                    "electricity_produced_peak_cumulative": 6.543,
-                    "electricity_produced_off_peak_cumulative": 0.0,
-                    "electricity_produced_peak_interval": 1345,
-                    "electricity_produced_off_peak_interval": 0,
-                    "electricity_phase_one_consumed": 0,
-                    "electricity_phase_one_produced": 1998,
-                },
-            },
-        }
-
-        self.smile_setup = "p1v4_442_single"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = power")
-        assert smile.smile_type == "power"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.4.2"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.gateway_id == "a455b61e52394b2db5081ce025a430f3"
-        assert smile.device_items == 31
-        assert not self.notifications
-
-        # Now change some data and change directory reading xml from
-        # emulating reading newer dataset after an update_interval
-        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."""
-        testdata = {
-            "03e65b16e4b247a29ae0d75a78cb492e": {
-                "dev_class": "gateway",
-                "firmware": "4.4.2",
-                "hardware": "AME Smile 2.0 board",
-                "location": "03e65b16e4b247a29ae0d75a78cb492e",
-                "mac_address": "012345670001",
-                "model": "Gateway",
-                "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,
-                    "electricity_consumed_peak_point": 0,
-                    "electricity_consumed_off_peak_point": 5553,
-                    "net_electricity_cumulative": 231866.539,
-                    "electricity_consumed_peak_cumulative": 161328.641,
-                    "electricity_consumed_off_peak_cumulative": 70537.898,
-                    "electricity_consumed_peak_interval": 0,
-                    "electricity_consumed_off_peak_interval": 314,
-                    "electricity_produced_peak_point": 0,
-                    "electricity_produced_off_peak_point": 0,
-                    "electricity_produced_peak_cumulative": 0.0,
-                    "electricity_produced_off_peak_cumulative": 0.0,
-                    "electricity_produced_peak_interval": 0,
-                    "electricity_produced_off_peak_interval": 0,
-                    "electricity_phase_one_consumed": 1763,
-                    "electricity_phase_two_consumed": 1703,
-                    "electricity_phase_three_consumed": 2080,
-                    "electricity_phase_one_produced": 0,
-                    "electricity_phase_two_produced": 0,
-                    "electricity_phase_three_produced": 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,
-                },
-            },
-        }
-
-        self.smile_setup = "p1v4_442_triple"
-        server, smile, client = await self.connect_wrapper()
-        assert smile.smile_hostname == "smile000000"
-
-        _LOGGER.info("Basics:")
-        _LOGGER.info(" # Assert type = power")
-        assert smile.smile_type == "power"
-        _LOGGER.info(" # Assert version")
-        assert smile.smile_version[0] == "4.4.2"
-        _LOGGER.info(" # Assert legacy")
-        assert not smile._smile_legacy
-
-        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
-        assert smile.gateway_id == "03e65b16e4b247a29ae0d75a78cb492e"
-        assert smile.device_items == 40
-        assert self.notifications
-
-        await smile.close_connection()
-        await self.disconnect(server, client)
-
-    @pytest.mark.asyncio
-    async def test_fail_legacy_system(self):
-        """Test erroneous legacy stretch system."""
-        self.smile_setup = "faulty_stretch"
-        try:
-            _server, _smile, _client = await self.connect_wrapper()
-            assert False  # pragma: no cover
-        except pw_exceptions.InvalidXMLError:
-            assert True
-
-    @pytest.mark.asyncio
-    async def test_fail_anna_connected_to_adam(self):
-        """Test erroneous adam with anna system."""
-        self.smile_setup = "anna_connected_to_adam"
-        try:
-            _server, _smile, _client = await self.connect_wrapper()
-            assert False  # pragma: no cover
-        except pw_exceptions.InvalidSetupError:
-            assert True
-
-    @pytest.mark.asyncio
-    async def test_invalid_credentials(self):
-        """Test P1 with invalid credentials setup."""
-        self.smile_setup = "p1v4"
-        try:
-            await self.connect_wrapper(fail_auth=True)
-            assert False  # pragma: no cover
-        except pw_exceptions.InvalidAuthentication:
-            _LOGGER.debug("InvalidAuthentication raised successfully")
-            assert True
-
-    @pytest.mark.asyncio
-    async def test_connect_fail_firmware(self):
-        """Test a P1 non existing firmware setup."""
-        self.smile_setup = "fail_firmware"
-        try:
-            await self.connect_wrapper()
-            assert False  # pragma: no cover
-        except pw_exceptions.UnsupportedDeviceError:
-            assert True
-
-    # Test connect for timeout
-    @patch(
-        "plugwise.helper.ClientSession.get",
-        side_effect=aiohttp.ServerTimeoutError,
-    )
-    @pytest.mark.asyncio
-    async def test_connect_timeout(self, timeout_test):
-        """Wrap connect to raise timeout during get."""
-        # pylint: disable=unused-variable
-        try:
-            self.smile_setup = "p1v4"
-            (
-                server,
-                smile,
-                client,
-            ) = await self.connect_wrapper()
-            assert False  # pragma: no cover
-        except pw_exceptions.PlugwiseException:
-            assert True
-
-    class PlugwiseTestError(Exception):
-        """Plugwise test exceptions class."""
-
-    class ConnectError(PlugwiseTestError):
-        """Raised when connectivity test fails."""
-
-    class UnexpectedError(PlugwiseTestError):
-        """Raised when something went against logic."""
diff --git a/tests/test_stretch.py b/tests/test_stretch.py
new file mode 100644
index 000000000..aef3bc95c
--- /dev/null
+++ b/tests/test_stretch.py
@@ -0,0 +1,111 @@
+"""Test Plugwise module Stretch related functionality."""
+
+import pytest
+
+from .test_init import _LOGGER, TestPlugwise
+
+SMILE_TYPE = "stretch"
+
+
+class TestPlugwiseStretch(
+    TestPlugwise
+):  # pylint: disable=attribute-defined-outside-init
+    """Tests for Stretch."""
+
+    @pytest.mark.asyncio
+    async def test_connect_stretch_v31(self):
+        """Test a legacy Stretch with firmware 3.1 setup."""
+        self.smile_setup = "stretch_v31"
+
+        testdata = self.load_testdata(SMILE_TYPE, self.smile_setup)
+        server, smile, client = await self.connect_wrapper(stretch=True)
+        assert smile.smile_hostname == "stretch000000"
+
+        self.validate_test_basics(
+            _LOGGER,
+            smile,
+            smile_type="stretch",
+            smile_version="3.1.11",
+            smile_legacy=True,
+        )
+
+        await self.device_test(smile, "2022-05-16 00:00:01", testdata)
+        assert smile.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00"
+        assert smile.device_items == 83
+
+        # 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/stretch_v31"
+        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_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_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 smile.device_items == 229
+
+        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_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 smile.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)