plugwise 0.37.1a2__py3-none-any.whl → 0.37.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
plugwise/common.py CHANGED
@@ -4,11 +4,23 @@ Plugwise Smile protocol helpers.
4
4
  """
5
5
  from __future__ import annotations
6
6
 
7
- from plugwise.constants import ModelData
7
+ from typing import cast
8
+
9
+ from plugwise.constants import (
10
+ ANNA,
11
+ SPECIAL_PLUG_TYPES,
12
+ SWITCH_GROUP_TYPES,
13
+ ApplianceType,
14
+ DeviceData,
15
+ ModelData,
16
+ SensorType,
17
+ )
8
18
  from plugwise.util import (
19
+ check_alternative_location,
9
20
  check_heater_central,
10
21
  check_model,
11
22
  get_vendor_name,
23
+ power_data_local_format,
12
24
  return_valid,
13
25
  )
14
26
 
@@ -22,31 +34,20 @@ class SmileCommon:
22
34
  def __init__(self) -> None:
23
35
  """Init."""
24
36
  self._appliances: etree
37
+ self._count: int
25
38
  self._domain_objects: etree
26
39
  self._cooling_present: bool
27
40
  self._heater_id: str
28
41
  self._on_off_device: bool
29
42
  self._opentherm_device: bool
43
+ self.gw_devices: dict[str, DeviceData]
30
44
  self.smile_name: str
45
+ self.smile_type: str
31
46
 
32
47
  def smile(self, name: str) -> bool:
33
48
  """Helper-function checking the smile-name."""
34
49
  return self.smile_name == name
35
50
 
36
- def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) -> Munch:
37
- """Helper-function for _appliance_info_finder()."""
38
- locator = "./logs/point_log[type='thermostat']/thermostat"
39
- mod_type = "thermostat"
40
- xml_2 = return_valid(xml_2, self._domain_objects)
41
- module_data = self._get_module_data(xml_1, locator, mod_type, xml_2)
42
- appl.vendor_name = module_data["vendor_name"]
43
- appl.model = check_model(module_data["vendor_model"], appl.vendor_name)
44
- appl.hardware = module_data["hardware_version"]
45
- appl.firmware = module_data["firmware_version"]
46
- appl.zigbee_mac = module_data["zigbee_mac_address"]
47
-
48
- return appl
49
-
50
51
  def _appl_heater_central_info(
51
52
  self,
52
53
  appl: Munch,
@@ -94,6 +95,184 @@ class SmileCommon:
94
95
 
95
96
  return appl
96
97
 
98
+ def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) -> Munch:
99
+ """Helper-function for _appliance_info_finder()."""
100
+ locator = "./logs/point_log[type='thermostat']/thermostat"
101
+ mod_type = "thermostat"
102
+ xml_2 = return_valid(xml_2, self._domain_objects)
103
+ module_data = self._get_module_data(xml_1, locator, mod_type, xml_2)
104
+ appl.vendor_name = module_data["vendor_name"]
105
+ appl.model = check_model(module_data["vendor_model"], appl.vendor_name)
106
+ appl.hardware = module_data["hardware_version"]
107
+ appl.firmware = module_data["firmware_version"]
108
+ appl.zigbee_mac = module_data["zigbee_mac_address"]
109
+
110
+ return appl
111
+
112
+ def _collect_power_values(self, data: DeviceData, loc: Munch, tariff: str, legacy: bool = False) -> None:
113
+ """Something."""
114
+ for loc.peak_select in ("nl_peak", "nl_offpeak"):
115
+ loc.locator = (
116
+ f'./{loc.log_type}[type="{loc.measurement}"]/period/'
117
+ f'measurement[@{tariff}="{loc.peak_select}"]'
118
+ )
119
+ if legacy:
120
+ loc.locator = (
121
+ f"./{loc.meas_list[0]}_{loc.log_type}/measurement"
122
+ f'[@directionality="{loc.meas_list[1]}"][@{tariff}="{loc.peak_select}"]'
123
+ )
124
+
125
+ loc = self._power_data_peak_value(loc, legacy)
126
+ if not loc.found:
127
+ continue
128
+
129
+ data = self._power_data_energy_diff(
130
+ loc.measurement, loc.net_string, loc.f_val, data
131
+ )
132
+ key = cast(SensorType, loc.key_string)
133
+ data["sensors"][key] = loc.f_val
134
+
135
+ def _power_data_peak_value(self, loc: Munch, legacy: bool) -> Munch:
136
+ """Helper-function for _power_data_from_location() and _power_data_from_modules()."""
137
+ loc.found = True
138
+ if loc.logs.find(loc.locator) is None:
139
+ loc = check_alternative_location(loc, legacy)
140
+ if not loc.found:
141
+ return loc
142
+
143
+ if (peak := loc.peak_select.split("_")[1]) == "offpeak":
144
+ peak = "off_peak"
145
+ log_found = loc.log_type.split("_")[0]
146
+ loc.key_string = f"{loc.measurement}_{peak}_{log_found}"
147
+ if "gas" in loc.measurement or loc.log_type == "point_meter":
148
+ loc.key_string = f"{loc.measurement}_{log_found}"
149
+ # Only for P1 Actual -------------------#
150
+ if "phase" in loc.measurement:
151
+ loc.key_string = f"{loc.measurement}"
152
+ # --------------------------------------#
153
+ loc.net_string = f"net_electricity_{log_found}"
154
+ val = loc.logs.find(loc.locator).text
155
+ loc.f_val = power_data_local_format(loc.attrs, loc.key_string, val)
156
+
157
+ return loc
158
+
159
+ def _power_data_energy_diff(
160
+ self,
161
+ measurement: str,
162
+ net_string: SensorType,
163
+ f_val: float | int,
164
+ direct_data: DeviceData,
165
+ ) -> DeviceData:
166
+ """Calculate differential energy."""
167
+ if (
168
+ "electricity" in measurement
169
+ and "phase" not in measurement
170
+ and "interval" not in net_string
171
+ ):
172
+ diff = 1
173
+ if "produced" in measurement:
174
+ diff = -1
175
+ if net_string not in direct_data["sensors"]:
176
+ tmp_val: float | int = 0
177
+ else:
178
+ tmp_val = direct_data["sensors"][net_string]
179
+
180
+ if isinstance(f_val, int):
181
+ tmp_val += f_val * diff
182
+ else:
183
+ tmp_val += float(f_val * diff)
184
+ tmp_val = float(f"{round(tmp_val, 3):.3f}")
185
+
186
+ direct_data["sensors"][net_string] = tmp_val
187
+
188
+ return direct_data
189
+
190
+ def _create_gw_devices(self, appl: Munch) -> None:
191
+ """Helper-function for creating/updating gw_devices."""
192
+ self.gw_devices[appl.dev_id] = {"dev_class": appl.pwclass}
193
+ self._count += 1
194
+ for key, value in {
195
+ "firmware": appl.firmware,
196
+ "hardware": appl.hardware,
197
+ "location": appl.location,
198
+ "mac_address": appl.mac,
199
+ "model": appl.model,
200
+ "name": appl.name,
201
+ "zigbee_mac_address": appl.zigbee_mac,
202
+ "vendor": appl.vendor_name,
203
+ }.items():
204
+ if value is not None or key == "location":
205
+ appl_key = cast(ApplianceType, key)
206
+ self.gw_devices[appl.dev_id][appl_key] = value
207
+ self._count += 1
208
+
209
+ def _device_data_switching_group(
210
+ self, device: DeviceData, data: DeviceData
211
+ ) -> None:
212
+ """Helper-function for _get_device_data().
213
+
214
+ Determine switching group device data.
215
+ """
216
+ if device["dev_class"] in SWITCH_GROUP_TYPES:
217
+ counter = 0
218
+ for member in device["members"]:
219
+ if self.gw_devices[member]["switches"].get("relay"):
220
+ counter += 1
221
+ data["switches"]["relay"] = counter != 0
222
+ self._count += 1
223
+
224
+ def _get_group_switches(self) -> dict[str, DeviceData]:
225
+ """Helper-function for smile.py: get_all_devices().
226
+
227
+ Collect switching- or pump-group info.
228
+ """
229
+ switch_groups: dict[str, DeviceData] = {}
230
+ # P1 and Anna don't have switchgroups
231
+ if self.smile_type == "power" or self.smile(ANNA):
232
+ return switch_groups
233
+
234
+ for group in self._domain_objects.findall("./group"):
235
+ members: list[str] = []
236
+ group_id = group.attrib["id"]
237
+ group_name = group.find("name").text
238
+ group_type = group.find("type").text
239
+ group_appliances = group.findall("appliances/appliance")
240
+ for item in group_appliances:
241
+ # Check if members are not orphaned - stretch
242
+ if item.attrib["id"] in self.gw_devices:
243
+ members.append(item.attrib["id"])
244
+
245
+ if group_type in SWITCH_GROUP_TYPES and members:
246
+ switch_groups.update(
247
+ {
248
+ group_id: {
249
+ "dev_class": group_type,
250
+ "model": "Switchgroup",
251
+ "name": group_name,
252
+ "members": members,
253
+ },
254
+ },
255
+ )
256
+ self._count += 4
257
+
258
+ return switch_groups
259
+
260
+ def _get_lock_state(self, xml: etree, data: DeviceData, stretch_v2: bool = False) -> None:
261
+ """Helper-function for _get_measurement_data().
262
+
263
+ Adam & Stretches: obtain the relay-switch lock state.
264
+ """
265
+ actuator = "actuator_functionalities"
266
+ func_type = "relay_functionality"
267
+ if stretch_v2:
268
+ actuator = "actuators"
269
+ func_type = "relay"
270
+ if xml.find("type").text not in SPECIAL_PLUG_TYPES:
271
+ locator = f"./{actuator}/{func_type}/lock"
272
+ if (found := xml.find(locator)) is not None:
273
+ data["switches"]["lock"] = found.text == "true"
274
+ self._count += 1
275
+
97
276
  def _get_module_data(
98
277
  self,
99
278
  xml_1: etree,
@@ -148,4 +327,3 @@ class SmileCommon:
148
327
  elif (zb_node := module.find("./protocols/zig_bee_node")) is not None:
149
328
  model_data["zigbee_mac_address"] = zb_node.find("mac_address").text
150
329
  model_data["reachable"] = zb_node.find("reachable").text == "true"
151
-
plugwise/constants.py CHANGED
@@ -121,21 +121,20 @@ P1_LEGACY_MEASUREMENTS: Final[dict[str, UOM]] = {
121
121
  # radiator_valve: 'uncorrected_temperature', 'temperature_offset'
122
122
 
123
123
  DEVICE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = {
124
- # HA Core thermostat current_temperature
125
- "temperature": UOM(TEMP_CELSIUS),
126
- # HA Core thermostat setpoint
127
- "thermostat": DATA("setpoint", TEMP_CELSIUS),
128
- # Specific for an Anna
129
- "illuminance": UOM(UNIT_LUMEN),
124
+ "humidity": UOM(PERCENTAGE), # Specific for a Jip
125
+ "illuminance": UOM(UNIT_LUMEN), # Specific for an Anna
126
+ "temperature": UOM(TEMP_CELSIUS), # HA Core thermostat current_temperature
127
+ "thermostat": DATA("setpoint", TEMP_CELSIUS), # HA Core thermostat setpoint
128
+ ########################################################
130
129
  # Specific for an Anna with heatpump extension installed
131
130
  "cooling_activation_outdoor_temperature": UOM(TEMP_CELSIUS),
132
131
  "cooling_deactivation_threshold": UOM(TEMP_CELSIUS),
133
- # Specific for a Lisa a Tom/Floor
132
+ ##################################
133
+ # Specific for a Lisa or Tom/Floor
134
134
  "battery": UOM(PERCENTAGE),
135
135
  "temperature_difference": UOM(DEGREE),
136
136
  "valve_position": UOM(PERCENTAGE),
137
- # Specific for a Jip
138
- "humidity": UOM(PERCENTAGE),
137
+ #####################
139
138
  # Specific for a Plug
140
139
  "electricity_consumed": UOM(POWER_WATT),
141
140
  "electricity_produced": UOM(POWER_WATT),
@@ -144,39 +143,43 @@ DEVICE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = {
144
143
 
145
144
  # Heater Central related measurements
146
145
  HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, DATA | UOM]] = {
146
+ "boiler_state": DATA(
147
+ "flame_state", NONE
148
+ ), # Legacy Anna: similar to flame-state on Anna/Adam
147
149
  "boiler_temperature": DATA("water_temperature", TEMP_CELSIUS),
150
+ "central_heating_state": DATA(
151
+ "c_heating_state", NONE
152
+ ), # For Elga (heatpump) use this instead of intended_central_heating_state
153
+ "central_heater_water_pressure": DATA("water_pressure", PRESSURE_BAR),
154
+ "compressor_state": UOM(NONE), # present with heatpump
155
+ "cooling_enabled": UOM(
156
+ NONE
157
+ ), # Available with the Loria and Elga (newer Anna firmware) heatpumps
158
+ "cooling_state": UOM(NONE),
148
159
  "domestic_hot_water_mode": DATA("select_dhw_mode", NONE),
149
160
  "domestic_hot_water_setpoint": UOM(TEMP_CELSIUS),
150
161
  "domestic_hot_water_state": DATA("dhw_state", NONE),
151
162
  "domestic_hot_water_temperature": DATA("dhw_temperature", TEMP_CELSIUS),
152
163
  "elga_status_code": UOM(NONE),
164
+ "intended_boiler_state": DATA(
165
+ "heating_state", NONE
166
+ ), # Legacy Anna: shows when heating is active, we don't show dhw_state, cannot be determined reliably
167
+ "flame_state": UOM(
168
+ NONE
169
+ ), # Also present when there is a single gas-heater
153
170
  "intended_boiler_temperature": UOM(
154
171
  TEMP_CELSIUS
155
172
  ), # Non-zero when heating, zero when dhw-heating
156
- "central_heating_state": DATA(
157
- "c_heating_state", NONE
158
- ), # For Elga (heatpump) use this instead of intended_central_heating_state
159
173
  "intended_central_heating_state": DATA(
160
174
  "heating_state", NONE
161
175
  ), # This key shows in general the heating-behavior better than c-h_state. except when connected to a heatpump
162
176
  "modulation_level": UOM(PERCENTAGE),
163
177
  "return_water_temperature": DATA("return_temperature", TEMP_CELSIUS),
164
- # Used with the Elga heatpump - marcelveldt
165
- "compressor_state": UOM(NONE),
166
- "cooling_state": UOM(NONE),
167
- "thermostat_supports_cooling": UOM(NONE),
168
- # Available with the Loria and Elga (newer Anna firmware) heatpumps
169
- "cooling_enabled": UOM(NONE),
170
- # Next 2 keys are used to show the state of the gas-heater used next to the Elga heatpump - marcelveldt
171
- "slave_boiler_state": UOM(NONE),
172
- "flame_state": UOM(NONE), # Also present when there is a single gas-heater
173
- "central_heater_water_pressure": DATA("water_pressure", PRESSURE_BAR),
174
- # Legacy Anna: similar to flame-state on Anna/Adam
175
- "boiler_state": DATA("flame_state", NONE),
176
- # Legacy Anna: shows when heating is active, we don't show dhw_state, cannot be determined reliably
177
- "intended_boiler_state": DATA("heating_state", NONE),
178
- # Outdoor temperature from APPLIANCES - present for a heatpump
179
- "outdoor_temperature": DATA("outdoor_air_temperature", TEMP_CELSIUS),
178
+ "outdoor_temperature": DATA(
179
+ "outdoor_air_temperature", TEMP_CELSIUS
180
+ ), # Outdoor temperature from APPLIANCES - present for a heatpump
181
+ "slave_boiler_state": DATA("secondary_boiler_state", NONE),
182
+ "thermostat_supports_cooling": UOM(NONE), # present with heatpump
180
183
  }
181
184
 
182
185
  OBSOLETE_MEASUREMENTS: Final[tuple[str, ...]] = (
@@ -253,22 +256,22 @@ ApplianceType = Literal[
253
256
  ]
254
257
 
255
258
  BinarySensorType = Literal[
256
- "cooling_enabled",
257
259
  "compressor_state",
260
+ "cooling_enabled",
258
261
  "cooling_state",
259
262
  "dhw_state",
260
263
  "flame_state",
261
264
  "heating_state",
262
265
  "plugwise_notification",
263
- "slave_boiler_state",
266
+ "secondary_boiler_state",
264
267
  ]
265
268
  BINARY_SENSORS: Final[tuple[str, ...]] = get_args(BinarySensorType)
266
269
 
267
270
  LIMITS: Final[tuple[str, ...]] = (
271
+ "lower_bound",
268
272
  "offset",
269
- "setpoint",
270
273
  "resolution",
271
- "lower_bound",
274
+ "setpoint",
272
275
  "upper_bound",
273
276
  )
274
277
 
@@ -329,8 +332,8 @@ SENSORS: Final[tuple[str, ...]] = get_args(SensorType)
329
332
 
330
333
  SPECIAL_PLUG_TYPES: Final[tuple[str, ...]] = (
331
334
  "central_heating_pump",
332
- "valve_actuator",
333
335
  "heater_electric",
336
+ "valve_actuator",
334
337
  )
335
338
 
336
339
  SpecialType = Literal[
@@ -350,14 +353,14 @@ SwitchType = Literal[
350
353
  ]
351
354
  SWITCHES: Final[tuple[str, ...]] = get_args(SwitchType)
352
355
 
353
- SWITCH_GROUP_TYPES: Final[tuple[str, ...]] = ("switching", "report")
356
+ SWITCH_GROUP_TYPES: Final[tuple[str, ...]] = ("report", "switching")
354
357
 
355
358
  THERMOSTAT_CLASSES: Final[tuple[str, ...]] = (
356
359
  "thermostat",
360
+ "thermostatic_radiator_valve",
357
361
  "thermo_sensor",
358
362
  "zone_thermometer",
359
363
  "zone_thermostat",
360
- "thermostatic_radiator_valve",
361
364
  )
362
365
 
363
366
  ToggleNameType = Literal[
@@ -392,25 +395,25 @@ class ModelData(TypedDict):
392
395
  """The ModelData class."""
393
396
 
394
397
  contents: bool
395
- vendor_name: str | None
396
- vendor_model: str | None
397
- hardware_version: str | None
398
398
  firmware_version: str | None
399
- zigbee_mac_address: str | None
399
+ hardware_version: str | None
400
400
  reachable: bool | None
401
+ vendor_model: str | None
402
+ vendor_name: str | None
403
+ zigbee_mac_address: str | None
401
404
 
402
405
 
403
406
  class SmileBinarySensors(TypedDict, total=False):
404
407
  """Smile Binary Sensors class."""
405
408
 
406
- cooling_enabled: bool
407
409
  compressor_state: bool
410
+ cooling_enabled: bool
408
411
  cooling_state: bool
409
412
  dhw_state: bool
410
413
  flame_state: bool
411
414
  heating_state: bool
412
415
  plugwise_notification: bool
413
- slave_boiler_state: bool
416
+ secondary_boiler_state: bool
414
417
 
415
418
 
416
419
  class SmileSensors(TypedDict, total=False):
@@ -482,9 +485,9 @@ class ThermoLoc(TypedDict, total=False):
482
485
  """Thermo Location class."""
483
486
 
484
487
  name: str
485
- master: str | None
486
- master_prio: int
487
- slaves: set[str]
488
+ primary: str | None
489
+ primary_prio: int
490
+ secondary: set[str]
488
491
 
489
492
 
490
493
  class ActuatorData(TypedDict, total=False):
plugwise/data.py CHANGED
@@ -11,7 +11,6 @@ from plugwise.constants import (
11
11
  MIN_SETPOINT,
12
12
  NONE,
13
13
  OFF,
14
- SWITCH_GROUP_TYPES,
15
14
  ZONE_THERMOSTATS,
16
15
  ActuatorData,
17
16
  DeviceData,
@@ -28,6 +27,25 @@ class SmileData(SmileHelper):
28
27
  SmileHelper.__init__(self)
29
28
 
30
29
 
30
+ def _all_device_data(self) -> None:
31
+ """Helper-function for get_all_devices().
32
+
33
+ Collect data for each device and add to self.gw_data and self.gw_devices.
34
+ """
35
+ self._update_gw_devices()
36
+ self.gw_data.update(
37
+ {
38
+ "gateway_id": self.gateway_id,
39
+ "item_count": self._count,
40
+ "notifications": self._notifications,
41
+ "smile_name": self.smile_name,
42
+ }
43
+ )
44
+ if self._is_thermostat:
45
+ self.gw_data.update(
46
+ {"heater_id": self._heater_id, "cooling_present": self._cooling_present}
47
+ )
48
+
31
49
  def _update_gw_devices(self) -> None:
32
50
  """Helper-function for _all_device_data() and async_update().
33
51
 
@@ -84,39 +102,52 @@ class SmileData(SmileHelper):
84
102
  sensors["setpoint_high"] = temp_dict["setpoint_high"]
85
103
  self._count += 2
86
104
 
87
- def _all_device_data(self) -> None:
88
- """Helper-function for get_all_devices().
105
+ def _get_device_data(self, dev_id: str) -> DeviceData:
106
+ """Helper-function for _all_device_data() and async_update().
89
107
 
90
- Collect data for each device and add to self.gw_data and self.gw_devices.
108
+ Provide device-data, based on Location ID (= dev_id), from APPLIANCES.
91
109
  """
92
- self._update_gw_devices()
93
- self.gw_data.update(
94
- {
95
- "gateway_id": self.gateway_id,
96
- "item_count": self._count,
97
- "notifications": self._notifications,
98
- "smile_name": self.smile_name,
99
- }
110
+ device = self.gw_devices[dev_id]
111
+ data = self._get_measurement_data(dev_id)
112
+
113
+ # Check availability of wired-connected devices
114
+ # Smartmeter
115
+ self._check_availability(
116
+ device, "smartmeter", data, "P1 does not seem to be connected"
100
117
  )
101
- if self._is_thermostat:
102
- self.gw_data.update(
103
- {"heater_id": self._heater_id, "cooling_present": self._cooling_present}
118
+ # OpenTherm device
119
+ if device["name"] != "OnOff":
120
+ self._check_availability(
121
+ device, "heater_central", data, "no OpenTherm communication"
104
122
  )
105
123
 
106
- def _device_data_switching_group(
107
- self, device: DeviceData, data: DeviceData
124
+ # Switching groups data
125
+ self._device_data_switching_group(device, data)
126
+ # Adam data
127
+ self._device_data_adam(device, data)
128
+ # Skip obtaining data for (Adam) secondary thermostats
129
+ if device["dev_class"] not in ZONE_THERMOSTATS:
130
+ return data
131
+
132
+ # Thermostat data (presets, temperatures etc)
133
+ self._device_data_climate(device, data)
134
+
135
+ return data
136
+
137
+ def _check_availability(
138
+ self, device: DeviceData, dev_class: str, data: DeviceData, message: str
108
139
  ) -> None:
109
140
  """Helper-function for _get_device_data().
110
141
 
111
- Determine switching group device data.
142
+ Provide availability status for the wired-commected devices.
112
143
  """
113
- if device["dev_class"] in SWITCH_GROUP_TYPES:
114
- counter = 0
115
- for member in device["members"]:
116
- if self.gw_devices[member]["switches"].get("relay"):
117
- counter += 1
118
- data["switches"]["relay"] = counter != 0
144
+ if device["dev_class"] == dev_class:
145
+ data["available"] = True
119
146
  self._count += 1
147
+ for item in self._notifications.values():
148
+ for msg in item.values():
149
+ if message in msg:
150
+ data["available"] = False
120
151
 
121
152
  def _device_data_adam(self, device: DeviceData, data: DeviceData) -> None:
122
153
  """Helper-function for _get_device_data().
@@ -133,7 +164,7 @@ class SmileData(SmileHelper):
133
164
  ):
134
165
  data["binary_sensors"]["heating_state"] = self._heating_valves() != 0
135
166
 
136
- # Show the allowed regulation modes and gateway_modes
167
+ # Show the allowed regulation_modes and gateway_modes
137
168
  if device["dev_class"] == "gateway":
138
169
  if self._reg_allowed_modes:
139
170
  data["regulation_modes"] = self._reg_allowed_modes
@@ -142,7 +173,7 @@ class SmileData(SmileHelper):
142
173
  data["gateway_modes"] = self._gw_allowed_modes
143
174
  self._count += 1
144
175
 
145
- # Control_state, only for Adam master thermostats
176
+ # Control_state, only available for Adam primary thermostats
146
177
  if device["dev_class"] in ZONE_THERMOSTATS:
147
178
  loc_id = device["location"]
148
179
  if ctrl_state := self._control_state(loc_id):
@@ -213,50 +244,3 @@ class SmileData(SmileHelper):
213
244
  all_off = False
214
245
  if all_off:
215
246
  data["select_schedule"] = OFF
216
-
217
- def _check_availability(
218
- self, device: DeviceData, dev_class: str, data: DeviceData, message: str
219
- ) -> None:
220
- """Helper-function for _get_device_data().
221
-
222
- Provide availability status for the wired-commected devices.
223
- """
224
- if device["dev_class"] == dev_class:
225
- data["available"] = True
226
- self._count += 1
227
- for item in self._notifications.values():
228
- for msg in item.values():
229
- if message in msg:
230
- data["available"] = False
231
-
232
- def _get_device_data(self, dev_id: str) -> DeviceData:
233
- """Helper-function for _all_device_data() and async_update().
234
-
235
- Provide device-data, based on Location ID (= dev_id), from APPLIANCES.
236
- """
237
- device = self.gw_devices[dev_id]
238
- data = self._get_measurement_data(dev_id)
239
-
240
- # Check availability of wired-connected devices
241
- # Smartmeter
242
- self._check_availability(
243
- device, "smartmeter", data, "P1 does not seem to be connected"
244
- )
245
- # OpenTherm device
246
- if device["name"] != "OnOff":
247
- self._check_availability(
248
- device, "heater_central", data, "no OpenTherm communication"
249
- )
250
-
251
- # Switching groups data
252
- self._device_data_switching_group(device, data)
253
- # Adam data
254
- self._device_data_adam(device, data)
255
- # Skip obtaining data for non master-thermostats
256
- if device["dev_class"] not in ZONE_THERMOSTATS:
257
- return data
258
-
259
- # Thermostat data (presets, temperatures etc)
260
- self._device_data_climate(device, data)
261
-
262
- return data