plugwise 1.5.1a3__py3-none-any.whl → 1.6.0__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/legacy/data.py CHANGED
@@ -6,7 +6,7 @@ from __future__ import annotations
6
6
 
7
7
  # Dict as class
8
8
  # Version detection
9
- from plugwise.constants import NONE, OFF, DeviceData
9
+ from plugwise.constants import NONE, OFF, GwEntityData
10
10
  from plugwise.legacy.helper import SmileLegacyHelper
11
11
  from plugwise.util import remove_empty_platform_dicts
12
12
 
@@ -18,12 +18,12 @@ class SmileLegacyData(SmileLegacyHelper):
18
18
  """Init."""
19
19
  SmileLegacyHelper.__init__(self)
20
20
 
21
- def _all_device_data(self) -> None:
22
- """Helper-function for get_all_devices().
21
+ def _all_entity_data(self) -> None:
22
+ """Helper-function for get_all_gateway_entities().
23
23
 
24
- Collect data for each device and add to self.gw_data and self.gw_devices.
24
+ Collect data for each entity and add to self.gw_data and self.gw_entities.
25
25
  """
26
- self._update_gw_devices()
26
+ self._update_gw_entities()
27
27
  self.gw_data.update(
28
28
  {
29
29
  "gateway_id": self.gateway_id,
@@ -36,40 +36,40 @@ class SmileLegacyData(SmileLegacyHelper):
36
36
  {"heater_id": self._heater_id, "cooling_present": False}
37
37
  )
38
38
 
39
- def _update_gw_devices(self) -> None:
40
- """Helper-function for _all_device_data() and async_update().
39
+ def _update_gw_entities(self) -> None:
40
+ """Helper-function for _all_entity_data() and async_update().
41
41
 
42
- Collect data for each device and add to self.gw_devices.
42
+ Collect data for each entity and add to self.gw_entities.
43
43
  """
44
- for device_id, device in self.gw_devices.items():
45
- data = self._get_device_data(device_id)
46
- device.update(data)
47
- remove_empty_platform_dicts(device)
44
+ for entity_id, entity in self.gw_entities.items():
45
+ data = self._get_entity_data(entity_id)
46
+ entity.update(data)
47
+ remove_empty_platform_dicts(entity)
48
48
 
49
- def _get_device_data(self, dev_id: str) -> DeviceData:
50
- """Helper-function for _all_device_data() and async_update().
49
+ def _get_entity_data(self, entity_id: str) -> GwEntityData:
50
+ """Helper-function for _all_entity_data() and async_update().
51
51
 
52
- Provide device-data, based on Location ID (= dev_id), from APPLIANCES.
52
+ Provide entity-data, based on Location ID (= entity_id), from APPLIANCES.
53
53
  """
54
- device = self.gw_devices[dev_id]
55
- data = self._get_measurement_data(dev_id)
54
+ entity = self.gw_entities[entity_id]
55
+ data = self._get_measurement_data(entity_id)
56
56
 
57
57
  # Switching groups data
58
- self._device_data_switching_group(device, data)
58
+ self._entity_switching_group(entity, data)
59
59
 
60
60
  # Skip obtaining data when not a thermostat
61
- if device["dev_class"] != "thermostat":
61
+ if entity["dev_class"] != "thermostat":
62
62
  return data
63
63
 
64
64
  # Thermostat data (presets, temperatures etc)
65
- self._device_data_climate(device, data)
65
+ self._climate_data(entity, data)
66
66
 
67
67
  return data
68
68
 
69
- def _device_data_climate(self, device: DeviceData, data: DeviceData) -> None:
70
- """Helper-function for _get_device_data().
69
+ def _climate_data(self, entity: GwEntityData, data: GwEntityData) -> None:
70
+ """Helper-function for _get_entity_data().
71
71
 
72
- Determine climate-control device data.
72
+ Determine climate-control entity data.
73
73
  """
74
74
  # Presets
75
75
  data["preset_modes"] = None
plugwise/legacy/helper.py CHANGED
@@ -29,8 +29,8 @@ from plugwise.constants import (
29
29
  ActuatorDataType,
30
30
  ActuatorType,
31
31
  ApplianceType,
32
- DeviceData,
33
32
  GatewayData,
33
+ GwEntityData,
34
34
  SensorType,
35
35
  ThermoLoc,
36
36
  )
@@ -68,6 +68,7 @@ class SmileLegacyHelper(SmileCommon):
68
68
  self._home_location: str
69
69
  self._is_thermostat: bool
70
70
  self._last_modified: dict[str, str] = {}
71
+ self._loc_data: dict[str, ThermoLoc]
71
72
  self._locations: etree
72
73
  self._modules: etree
73
74
  self._notifications: dict[str, dict[str, str]] = {}
@@ -80,8 +81,7 @@ class SmileLegacyHelper(SmileCommon):
80
81
 
81
82
  self.gateway_id: str
82
83
  self.gw_data: GatewayData = {}
83
- self.gw_devices: dict[str, DeviceData] = {}
84
- self.loc_data: dict[str, ThermoLoc]
84
+ self.gw_entities: dict[str, GwEntityData] = {}
85
85
  self.smile_fw_version: Version | None
86
86
  self.smile_hw_version: str | None
87
87
  self.smile_mac_address: str | None
@@ -115,7 +115,7 @@ class SmileLegacyHelper(SmileCommon):
115
115
  continue # pragma: no cover
116
116
 
117
117
  appl.location = self._home_location
118
- appl.dev_id = appliance.attrib["id"]
118
+ appl.entity_id = appliance.attrib["id"]
119
119
  appl.name = appliance.find("name").text
120
120
  # Extend device_class name when a Circle/Stealth is type heater_central -- Pw-Beta Issue #739
121
121
  if (
@@ -125,6 +125,7 @@ class SmileLegacyHelper(SmileCommon):
125
125
  appl.pwclass = "heater_central_plug"
126
126
 
127
127
  appl.model = appl.pwclass.replace("_", " ").title()
128
+ appl.available = None
128
129
  appl.model_id = None
129
130
  appl.firmware = None
130
131
  appl.hardware = None
@@ -138,20 +139,20 @@ class SmileLegacyHelper(SmileCommon):
138
139
  continue
139
140
 
140
141
  # Skip orphaned heater_central (Core Issue #104433)
141
- if appl.pwclass == "heater_central" and appl.dev_id != self._heater_id:
142
+ if appl.pwclass == "heater_central" and appl.entity_id != self._heater_id:
142
143
  continue # pragma: no cover
143
144
 
144
- self._create_gw_devices(appl)
145
+ self._create_gw_entities(appl)
145
146
 
146
147
  # Place the gateway and optional heater_central devices as 1st and 2nd
147
148
  for dev_class in ("heater_central", "gateway"):
148
- for dev_id, device in dict(self.gw_devices).items():
149
- if device["dev_class"] == dev_class:
150
- tmp_device = device
151
- self.gw_devices.pop(dev_id)
152
- cleared_dict = self.gw_devices
153
- add_to_front = {dev_id: tmp_device}
154
- self.gw_devices = {**add_to_front, **cleared_dict}
149
+ for entity_id, entity in dict(self.gw_entities).items():
150
+ if entity["dev_class"] == dev_class:
151
+ tmp_entity = entity
152
+ self.gw_entities.pop(entity_id)
153
+ cleared_dict = self.gw_entities
154
+ add_to_front = {entity_id: tmp_entity}
155
+ self.gw_entities = {**add_to_front, **cleared_dict}
155
156
 
156
157
  def _all_locations(self) -> None:
157
158
  """Collect all locations."""
@@ -160,7 +161,7 @@ class SmileLegacyHelper(SmileCommon):
160
161
  # Legacy Anna without outdoor_temp and Stretches have no locations, create fake location-data
161
162
  if not (locations := self._locations.findall("./location")):
162
163
  self._home_location = FAKE_LOC
163
- self.loc_data[FAKE_LOC] = {"name": "Home"}
164
+ self._loc_data[FAKE_LOC] = {"name": "Home"}
164
165
  return
165
166
 
166
167
  for location in locations:
@@ -181,18 +182,18 @@ class SmileLegacyHelper(SmileCommon):
181
182
  loc.name = "Home"
182
183
  self._home_location = loc.loc_id
183
184
 
184
- self.loc_data[loc.loc_id] = {"name": loc.name}
185
+ self._loc_data[loc.loc_id] = {"name": loc.name}
185
186
 
186
187
  def _create_legacy_gateway(self) -> None:
187
- """Create the (missing) gateway devices for legacy Anna, P1 and Stretch.
188
+ """Create the (missing) gateway entities for legacy Anna, P1 and Stretch.
188
189
 
189
- Use the home_location or FAKE_APPL as device id.
190
+ Use the home_location or FAKE_APPL as entity id.
190
191
  """
191
192
  self.gateway_id = self._home_location
192
193
  if self.smile_type == "power":
193
194
  self.gateway_id = FAKE_APPL
194
195
 
195
- self.gw_devices[self.gateway_id] = {"dev_class": "gateway"}
196
+ self.gw_entities[self.gateway_id] = {"dev_class": "gateway"}
196
197
  self._count += 1
197
198
  for key, value in {
198
199
  "firmware": str(self.smile_fw_version),
@@ -205,34 +206,32 @@ class SmileLegacyHelper(SmileCommon):
205
206
  }.items():
206
207
  if value is not None:
207
208
  gw_key = cast(ApplianceType, key)
208
- self.gw_devices[self.gateway_id][gw_key] = value
209
+ self.gw_entities[self.gateway_id][gw_key] = value
209
210
  self._count += 1
210
211
 
211
212
  def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
212
- """Collect device info (Smile/Stretch, Thermostats, OpenTherm/On-Off): firmware, model and vendor name."""
213
+ """Collect entity info (Smile/Stretch, Thermostats, OpenTherm/On-Off): firmware, model and vendor name."""
213
214
  match appl.pwclass:
214
- # Collect thermostat device info
215
+ # Collect thermostat entity info
215
216
  case _ as dev_class if dev_class in THERMOSTAT_CLASSES:
216
217
  return self._appl_thermostat_info(appl, appliance, self._modules)
217
- # Collect heater_central device info
218
+ # Collect heater_central entity info
218
219
  case "heater_central":
219
220
  return self._appl_heater_central_info(
220
221
  appl, appliance, True, self._appliances, self._modules
221
222
  ) # True means legacy device
222
223
  # Collect info from Stretches
223
224
  case _:
224
- return self._energy_device_info_finder(appliance, appl)
225
+ return self._energy_entity_info_finder(appliance, appl)
225
226
 
226
- def _energy_device_info_finder(self, appliance: etree, appl: Munch) -> Munch:
227
+ def _energy_entity_info_finder(self, appliance: etree, appl: Munch) -> Munch:
227
228
  """Helper-function for _appliance_info_finder().
228
229
 
229
- Collect energy device info (Smartmeter, Circle, Stealth, etc.): firmware, model and vendor name.
230
+ Collect energy entity info (Smartmeter, Circle, Stealth, etc.): firmware, model and vendor name.
230
231
  """
231
232
  if self.smile_type in ("power", "stretch"):
232
233
  locator = "./services/electricity_point_meter"
233
- mod_type = "electricity_point_meter"
234
-
235
- module_data = self._get_module_data(appliance, locator, mod_type, self._modules, legacy=True)
234
+ module_data = self._get_module_data(appliance, locator, self._modules, legacy=True)
236
235
  appl.zigbee_mac = module_data["zigbee_mac_address"]
237
236
  # Filter appliance without zigbee_mac, it's an orphaned device
238
237
  if appl.zigbee_mac is None and self.smile_type != "power":
@@ -252,8 +251,9 @@ class SmileLegacyHelper(SmileCommon):
252
251
 
253
252
  def _p1_smartmeter_info_finder(self, appl: Munch) -> None:
254
253
  """Collect P1 DSMR Smartmeter info."""
255
- loc_id = next(iter(self.loc_data.keys()))
256
- appl.dev_id = loc_id
254
+ loc_id = next(iter(self._loc_data.keys()))
255
+ appl.available = None
256
+ appl.entity_id = loc_id
257
257
  appl.location = loc_id
258
258
  appl.mac = None
259
259
  appl.model = self.smile_model
@@ -262,41 +262,41 @@ class SmileLegacyHelper(SmileCommon):
262
262
  appl.pwclass = "smartmeter"
263
263
  appl.zigbee_mac = None
264
264
  location = self._locations.find(f'./location[@id="{loc_id}"]')
265
- appl = self._energy_device_info_finder(location, appl)
265
+ appl = self._energy_entity_info_finder(location, appl)
266
266
 
267
- self._create_gw_devices(appl)
267
+ self._create_gw_entities(appl)
268
268
 
269
- def _get_measurement_data(self, dev_id: str) -> DeviceData:
270
- """Helper-function for smile.py: _get_device_data().
269
+ def _get_measurement_data(self, entity_id: str) -> GwEntityData:
270
+ """Helper-function for smile.py: _get_entity_data().
271
271
 
272
- Collect the appliance-data based on device id.
272
+ Collect the appliance-data based on entity_id.
273
273
  """
274
- data: DeviceData = {"binary_sensors": {}, "sensors": {}, "switches": {}}
274
+ data: GwEntityData = {"binary_sensors": {}, "sensors": {}, "switches": {}}
275
275
  # Get P1 smartmeter data from LOCATIONS or MODULES
276
- device = self.gw_devices[dev_id]
276
+ entity = self.gw_entities[entity_id]
277
277
  # !! DON'T CHANGE below two if-lines, will break stuff !!
278
278
  if self.smile_type == "power":
279
- if device["dev_class"] == "smartmeter":
279
+ if entity["dev_class"] == "smartmeter":
280
280
  data.update(self._power_data_from_modules())
281
281
 
282
282
  return data
283
283
 
284
284
  measurements = DEVICE_MEASUREMENTS
285
- if self._is_thermostat and dev_id == self._heater_id:
285
+ if self._is_thermostat and entity_id == self._heater_id:
286
286
  measurements = HEATER_CENTRAL_MEASUREMENTS
287
287
 
288
288
  if (
289
- appliance := self._appliances.find(f'./appliance[@id="{dev_id}"]')
289
+ appliance := self._appliances.find(f'./appliance[@id="{entity_id}"]')
290
290
  ) is not None:
291
291
  self._appliance_measurements(appliance, data, measurements)
292
292
  self._get_lock_state(appliance, data, self._stretch_v2)
293
293
 
294
294
  if appliance.find("type").text in ACTUATOR_CLASSES:
295
- self._get_actuator_functionalities(appliance, device, data)
295
+ self._get_actuator_functionalities(appliance, entity, data)
296
296
 
297
297
  # Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS - under Home
298
298
  # The outdoor_temperature present in APPLIANCES is a local sensor connected to the active device
299
- if self._is_thermostat and dev_id == self.gateway_id:
299
+ if self._is_thermostat and entity_id == self.gateway_id:
300
300
  outdoor_temperature = self._object_value(
301
301
  self._home_location, "outdoor_temperature"
302
302
  )
@@ -310,12 +310,12 @@ class SmileLegacyHelper(SmileCommon):
310
310
 
311
311
  return data
312
312
 
313
- def _power_data_from_modules(self) -> DeviceData:
314
- """Helper-function for smile.py: _get_device_data().
313
+ def _power_data_from_modules(self) -> GwEntityData:
314
+ """Helper-function for smile.py: _get_entity_data().
315
315
 
316
316
  Collect the power-data from MODULES (P1 legacy only).
317
317
  """
318
- direct_data: DeviceData = {"sensors": {}}
318
+ data: GwEntityData = {"sensors": {}}
319
319
  loc = Munch()
320
320
  mod_list: list[str] = ["interval_meter", "cumulative_meter", "point_meter"]
321
321
  t_string = "tariff_indicator"
@@ -326,15 +326,15 @@ class SmileLegacyHelper(SmileCommon):
326
326
  loc.meas_list = loc.measurement.split("_")
327
327
  for loc.logs in mod_logs:
328
328
  for loc.log_type in mod_list:
329
- self._collect_power_values(direct_data, loc, t_string, legacy=True)
329
+ self._collect_power_values(data, loc, t_string, legacy=True)
330
330
 
331
- self._count += len(direct_data["sensors"])
332
- return direct_data
331
+ self._count += len(data["sensors"])
332
+ return data
333
333
 
334
334
  def _appliance_measurements(
335
335
  self,
336
336
  appliance: etree,
337
- data: DeviceData,
337
+ data: GwEntityData,
338
338
  measurements: dict[str, DATA | UOM],
339
339
  ) -> None:
340
340
  """Helper-function for _get_measurement_data() - collect appliance measurement data."""
@@ -359,21 +359,20 @@ class SmileLegacyHelper(SmileCommon):
359
359
  appl_i_loc.text, ENERGY_WATT_HOUR
360
360
  )
361
361
 
362
- self._count += len(data["binary_sensors"])
363
- self._count += len(data["sensors"])
364
- self._count += len(data["switches"])
365
- # Don't count the above top-level dicts, only the remaining single items
366
- self._count += len(data) - 3
362
+ self._count_data_items(data)
367
363
 
368
364
  def _get_actuator_functionalities(
369
- self, xml: etree, device: DeviceData, data: DeviceData
365
+ self,
366
+ xml: etree,
367
+ entity: GwEntityData,
368
+ data: GwEntityData
370
369
  ) -> None:
371
370
  """Helper-function for _get_measurement_data()."""
372
371
  for item in ACTIVE_ACTUATORS:
373
372
  # Skip max_dhw_temperature, not initially valid,
374
373
  # skip thermostat for thermo_sensors
375
374
  if item == "max_dhw_temperature" or (
376
- item == "thermostat" and device["dev_class"] == "thermo_sensor"
375
+ item == "thermostat" and entity["dev_class"] == "thermo_sensor"
377
376
  ):
378
377
  continue
379
378
 
@@ -401,7 +400,7 @@ class SmileLegacyHelper(SmileCommon):
401
400
  data[act_item] = temp_dict
402
401
 
403
402
  def _object_value(self, obj_id: str, measurement: str) -> float | int | None:
404
- """Helper-function for smile.py: _get_device_data() and _device_data_anna().
403
+ """Helper-function for smile.py: _get_entity_data().
405
404
 
406
405
  Obtain the value/state for the given object from a location in DOMAIN_OBJECTS
407
406
  """
@@ -415,7 +414,7 @@ class SmileLegacyHelper(SmileCommon):
415
414
  return val
416
415
 
417
416
  def _preset(self) -> str | None:
418
- """Helper-function for smile.py: device_data_climate().
417
+ """Helper-function for smile.py: _climate_data().
419
418
 
420
419
  Collect the active preset based on the active rule.
421
420
  """
plugwise/legacy/smile.py CHANGED
@@ -19,8 +19,8 @@ from plugwise.constants import (
19
19
  OFF,
20
20
  REQUIRE_APPLIANCES,
21
21
  RULES,
22
- DeviceData,
23
22
  GatewayData,
23
+ GwEntityData,
24
24
  PlugwiseData,
25
25
  ThermoLoc,
26
26
  )
@@ -44,11 +44,11 @@ class SmileLegacyAPI(SmileLegacyData):
44
44
  request: Callable[..., Awaitable[Any]],
45
45
  websession: aiohttp.ClientSession,
46
46
  _is_thermostat: bool,
47
+ _loc_data: dict[str, ThermoLoc],
47
48
  _on_off_device: bool,
48
49
  _opentherm_device: bool,
49
50
  _stretch_v2: bool,
50
51
  _target_smile: str,
51
- loc_data: dict[str, ThermoLoc],
52
52
  smile_fw_version: Version | None,
53
53
  smile_hostname: str,
54
54
  smile_hw_version: str | None,
@@ -61,15 +61,13 @@ class SmileLegacyAPI(SmileLegacyData):
61
61
  username: str = DEFAULT_USERNAME,
62
62
  ) -> None:
63
63
  """Set the constructor for this class."""
64
- SmileLegacyData.__init__(self)
65
-
66
64
  self._cooling_present = False
67
65
  self._is_thermostat = _is_thermostat
66
+ self._loc_data = _loc_data
68
67
  self._on_off_device = _on_off_device
69
68
  self._opentherm_device = _opentherm_device
70
69
  self._stretch_v2 = _stretch_v2
71
70
  self._target_smile = _target_smile
72
- self.loc_data = loc_data
73
71
  self.request = request
74
72
  self.smile_fw_version = smile_fw_version
75
73
  self.smile_hostname = smile_hostname
@@ -79,10 +77,11 @@ class SmileLegacyAPI(SmileLegacyData):
79
77
  self.smile_name = smile_name
80
78
  self.smile_type = smile_type
81
79
  self.smile_zigbee_mac_address = smile_zigbee_mac_address
80
+ SmileLegacyData.__init__(self)
82
81
 
83
82
  self._previous_day_number: str = "0"
84
83
 
85
- async def full_update_device(self) -> None:
84
+ async def full_xml_update(self) -> None:
86
85
  """Perform a first fetch of all XML data, needed for initialization."""
87
86
  self._domain_objects = await self.request(DOMAIN_OBJECTS)
88
87
  self._locations = await self.request(LOCATIONS)
@@ -91,8 +90,8 @@ class SmileLegacyAPI(SmileLegacyData):
91
90
  if self.smile_type != "power":
92
91
  self._appliances = await self.request(APPLIANCES)
93
92
 
94
- def get_all_devices(self) -> None:
95
- """Determine the evices present from the obtained XML-data.
93
+ def get_all_gateway_entities(self) -> None:
94
+ """Collect the gateway entities from the received raw XML-data.
96
95
 
97
96
  Run this functions once to gather the initial device configuration,
98
97
  then regularly run async_update() to refresh the device data.
@@ -102,10 +101,10 @@ class SmileLegacyAPI(SmileLegacyData):
102
101
 
103
102
  # Collect and add switching- and/or pump-group devices
104
103
  if group_data := self._get_group_switches():
105
- self.gw_devices.update(group_data)
104
+ self.gw_entities.update(group_data)
106
105
 
107
- # Collect the remaining data for all devices
108
- self._all_device_data()
106
+ # Collect the remaining data for all entities
107
+ self._all_entity_data()
109
108
 
110
109
  async def async_update(self) -> PlugwiseData:
111
110
  """Perform an incremental update for updating the various device states."""
@@ -119,9 +118,9 @@ class SmileLegacyAPI(SmileLegacyData):
119
118
  "Performing daily full-update, reload the Plugwise integration when a single entity becomes unavailable."
120
119
  )
121
120
  self.gw_data: GatewayData = {}
122
- self.gw_devices: dict[str, DeviceData] = {}
123
- await self.full_update_device()
124
- self.get_all_devices()
121
+ self.gw_entities: dict[str, GwEntityData] = {}
122
+ await self.full_xml_update()
123
+ self.get_all_gateway_entities()
125
124
  # Otherwise perform an incremental update
126
125
  else:
127
126
  self._domain_objects = await self.request(DOMAIN_OBJECTS)
@@ -131,10 +130,13 @@ class SmileLegacyAPI(SmileLegacyData):
131
130
  case self._target_smile if self._target_smile in REQUIRE_APPLIANCES:
132
131
  self._appliances = await self.request(APPLIANCES)
133
132
 
134
- self._update_gw_devices()
133
+ self._update_gw_entities()
135
134
 
136
135
  self._previous_day_number = day_number
137
- return PlugwiseData(self.gw_data, self.gw_devices)
136
+ return PlugwiseData(
137
+ devices=self.gw_entities,
138
+ gateway=self.gw_data,
139
+ )
138
140
 
139
141
  ########################################################################################################
140
142
  ### API Set and HA Service-related Functions ###
plugwise/smile.py CHANGED
@@ -22,8 +22,8 @@ from plugwise.constants import (
22
22
  NOTIFICATIONS,
23
23
  OFF,
24
24
  RULES,
25
- DeviceData,
26
25
  GatewayData,
26
+ GwEntityData,
27
27
  PlugwiseData,
28
28
  ThermoLoc,
29
29
  )
@@ -53,11 +53,11 @@ class SmileAPI(SmileData):
53
53
  _elga: bool,
54
54
  _is_thermostat: bool,
55
55
  _last_active: dict[str, str | None],
56
+ _loc_data: dict[str, ThermoLoc],
56
57
  _on_off_device: bool,
57
58
  _opentherm_device: bool,
58
59
  _schedule_old_states: dict[str, dict[str, str]],
59
60
  gateway_id: str,
60
- loc_data: dict[str, ThermoLoc],
61
61
  smile_fw_version: Version | None,
62
62
  smile_hostname: str | None,
63
63
  smile_hw_version: str | None,
@@ -70,17 +70,17 @@ class SmileAPI(SmileData):
70
70
  username: str = DEFAULT_USERNAME,
71
71
  ) -> None:
72
72
  """Set the constructor for this class."""
73
- SmileData.__init__(self)
74
-
73
+ self._cooling_enabled = False
75
74
  self._cooling_present = _cooling_present
76
75
  self._elga = _elga
76
+ self._heater_id: str
77
77
  self._is_thermostat = _is_thermostat
78
78
  self._last_active = _last_active
79
+ self._loc_data = _loc_data
79
80
  self._on_off_device = _on_off_device
80
81
  self._opentherm_device = _opentherm_device
81
82
  self._schedule_old_states = _schedule_old_states
82
83
  self.gateway_id = gateway_id
83
- self.loc_data = loc_data
84
84
  self.request = request
85
85
  self.smile_fw_version = smile_fw_version
86
86
  self.smile_hostname = smile_hostname
@@ -90,22 +90,21 @@ class SmileAPI(SmileData):
90
90
  self.smile_model_id = smile_model_id
91
91
  self.smile_name = smile_name
92
92
  self.smile_type = smile_type
93
+ SmileData.__init__(self)
93
94
 
94
- self._heater_id: str
95
- self._cooling_enabled = False
96
95
 
97
- async def full_update_device(self) -> None:
96
+ async def full_xml_update(self) -> None:
98
97
  """Perform a first fetch of all XML data, needed for initialization."""
99
98
  self._domain_objects = await self.request(DOMAIN_OBJECTS)
100
99
  self._get_plugwise_notifications()
101
100
 
102
- def get_all_devices(self) -> None:
103
- """Determine the evices present from the obtained XML-data.
101
+ def get_all_gateway_entities(self) -> None:
102
+ """Collect the gateway entities from the received raw XML-data.
104
103
 
105
- Run this functions once to gather the initial device configuration,
106
- then regularly run async_update() to refresh the device data.
104
+ Run this functions once to gather the initial configuration,
105
+ then regularly run async_update() to refresh the entity data.
107
106
  """
108
- # Gather all the devices and their initial data
107
+ # Gather all the entities and their initial data
109
108
  self._all_appliances()
110
109
  if self._is_thermostat:
111
110
  if self.smile(ADAM):
@@ -117,20 +116,21 @@ class SmileAPI(SmileData):
117
116
 
118
117
  # Collect and add switching- and/or pump-group devices
119
118
  if group_data := self._get_group_switches():
120
- self.gw_devices.update(group_data)
119
+ self.gw_entities.update(group_data)
121
120
 
122
- # Collect the remaining data for all devices
123
- self._all_device_data()
121
+ # Collect the remaining data for all entities
122
+ self._all_entity_data()
124
123
 
125
124
  async def async_update(self) -> PlugwiseData:
126
125
  """Perform an incremental update for updating the various device states."""
127
126
  self.gw_data: GatewayData = {}
128
- self.gw_devices: dict[str, DeviceData] = {}
127
+ self.gw_entities: dict[str, GwEntityData] = {}
128
+ self._zones: dict[str, GwEntityData] = {}
129
129
  try:
130
- await self.full_update_device()
131
- self.get_all_devices()
130
+ await self.full_xml_update()
131
+ self.get_all_gateway_entities()
132
132
  if "heater_id" in self.gw_data:
133
- heat_cooler = self.gw_devices[self.gw_data["heater_id"]]
133
+ heat_cooler = self.gw_entities[self.gw_data["heater_id"]]
134
134
  if (
135
135
  "binary_sensors" in heat_cooler
136
136
  and "cooling_enabled" in heat_cooler["binary_sensors"]
@@ -139,7 +139,10 @@ class SmileAPI(SmileData):
139
139
  except KeyError as err:
140
140
  raise DataMissingError("No Plugwise data received") from err
141
141
 
142
- return PlugwiseData(self.gw_data, self.gw_devices)
142
+ return PlugwiseData(
143
+ devices=self.gw_entities,
144
+ gateway=self.gw_data,
145
+ )
143
146
 
144
147
  ########################################################################################################
145
148
  ### API Set and HA Service-related Functions ###
plugwise/util.py CHANGED
@@ -22,8 +22,8 @@ from plugwise.constants import (
22
22
  TEMP_CELSIUS,
23
23
  UOM,
24
24
  BinarySensorType,
25
- DeviceData,
26
- ModelData,
25
+ GwEntityData,
26
+ ModuleData,
27
27
  SensorType,
28
28
  SpecialType,
29
29
  SwitchType,
@@ -115,14 +115,14 @@ def check_model(name: str | None, vendor_name: str | None) -> str | None:
115
115
  if name is not None and "lumi.plug" in name:
116
116
  return "Aqara Smart Plug"
117
117
 
118
- return name # pragma: no cover
118
+ return None
119
119
 
120
120
 
121
121
  def common_match_cases(
122
122
  measurement: str,
123
123
  attrs: DATA | UOM,
124
124
  location: etree,
125
- data: DeviceData,
125
+ data: GwEntityData,
126
126
  ) -> None:
127
127
  """Helper-function for common match-case execution."""
128
128
  value = location.text in ("on", "true")
@@ -173,15 +173,13 @@ def format_measure(measure: str, unit: str) -> float | int:
173
173
  result = float(f"{round(float_measure, 1):.1f}")
174
174
  elif abs(float_measure) < 10:
175
175
  result = float(f"{round(float_measure, 2):.2f}")
176
- elif abs(float_measure) >= 10 and abs(float_measure) < 100:
176
+ elif abs(float_measure) >= 10:
177
177
  result = float(f"{round(float_measure, 1):.1f}")
178
- elif abs(float_measure) >= 100:
179
- result = int(round(float_measure))
180
178
 
181
179
  return result
182
180
 
183
181
 
184
- def get_vendor_name(module: etree, model_data: ModelData) -> ModelData:
182
+ def get_vendor_name(module: etree, model_data: ModuleData) -> ModuleData:
185
183
  """Helper-function for _get_model_data()."""
186
184
  if (vendor_name := module.find("vendor_name").text) is not None:
187
185
  model_data["vendor_name"] = vendor_name
@@ -204,7 +202,7 @@ def power_data_local_format(
204
202
  return format_measure(val, attrs_uom)
205
203
 
206
204
 
207
- def remove_empty_platform_dicts(data: DeviceData) -> None:
205
+ def remove_empty_platform_dicts(data: GwEntityData) -> None:
208
206
  """Helper-function for removing any empty platform dicts."""
209
207
  if not data["binary_sensors"]:
210
208
  data.pop("binary_sensors")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plugwise
3
- Version: 1.5.1a3
3
+ Version: 1.6.0
4
4
  Summary: Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3.
5
5
  Home-page: https://github.com/plugwise/python-plugwise
6
6
  Author: Plugwise device owners