plugwise 1.7.3a1__tar.gz → 1.7.3a3__tar.gz

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.
Files changed (33) hide show
  1. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/PKG-INFO +1 -1
  2. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/__init__.py +4 -12
  3. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/common.py +8 -0
  4. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/constants.py +0 -11
  5. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/data.py +2 -12
  6. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/helper.py +15 -5
  7. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/legacy/data.py +2 -12
  8. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/legacy/helper.py +19 -8
  9. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/legacy/smile.py +6 -4
  10. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/smile.py +11 -8
  11. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/util.py +21 -30
  12. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise.egg-info/PKG-INFO +1 -1
  13. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/pyproject.toml +1 -8
  14. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/LICENSE +0 -0
  15. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/README.md +0 -0
  16. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/exceptions.py +0 -0
  17. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/py.typed +0 -0
  18. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise/smilecomm.py +0 -0
  19. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise.egg-info/SOURCES.txt +0 -0
  20. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise.egg-info/dependency_links.txt +0 -0
  21. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise.egg-info/requires.txt +0 -0
  22. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/plugwise.egg-info/top_level.txt +0 -0
  23. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/setup.cfg +0 -0
  24. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/setup.py +0 -0
  25. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_adam.py +0 -0
  26. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_anna.py +0 -0
  27. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_generic.py +0 -0
  28. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_init.py +0 -0
  29. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_legacy_anna.py +0 -0
  30. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_legacy_generic.py +0 -0
  31. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_legacy_p1.py +0 -0
  32. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_legacy_stretch.py +0 -0
  33. {plugwise-1.7.3a1 → plugwise-1.7.3a3}/tests/test_p1.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: plugwise
3
- Version: 1.7.3a1
3
+ Version: 1.7.3a3
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
@@ -18,7 +18,6 @@ from plugwise.constants import (
18
18
  STATUS,
19
19
  SYSTEM,
20
20
  GwEntityData,
21
- SmileProps,
22
21
  ThermoLoc,
23
22
  )
24
23
  from plugwise.exceptions import (
@@ -69,7 +68,6 @@ class Smile(SmileComm):
69
68
  self._opentherm_device = False
70
69
  self._schedule_old_states: dict[str, dict[str, str]] = {}
71
70
  self._smile_api: SmileAPI | SmileLegacyAPI
72
- self._smile_props: SmileProps = {}
73
71
  self._stretch_v2 = False
74
72
  self._target_smile: str = NONE
75
73
  self.smile_hostname: str = NONE
@@ -86,26 +84,22 @@ class Smile(SmileComm):
86
84
  @property
87
85
  def cooling_present(self) -> bool:
88
86
  """Return the cooling capability."""
89
- if "cooling_present" in self._smile_props:
90
- return self._smile_props["cooling_present"]
91
- return False
87
+ return self._smile_api.cooling_present
92
88
 
93
89
  @property
94
90
  def gateway_id(self) -> str:
95
91
  """Return the gateway-id."""
96
- return self._smile_props["gateway_id"]
92
+ return self._smile_api.gateway_id
97
93
 
98
94
  @property
99
95
  def heater_id(self) -> str:
100
96
  """Return the heater-id."""
101
- if "heater_id" in self._smile_props:
102
- return self._smile_props["heater_id"]
103
- return NONE
97
+ return self._smile_api.heater_id
104
98
 
105
99
  @property
106
100
  def item_count(self) -> int:
107
101
  """Return the item-count."""
108
- return self._smile_props["item_count"]
102
+ return self._smile_api.item_count
109
103
 
110
104
  @property
111
105
  def reboot(self) -> bool:
@@ -162,7 +156,6 @@ class Smile(SmileComm):
162
156
  self._opentherm_device,
163
157
  self._request,
164
158
  self._schedule_old_states,
165
- self._smile_props,
166
159
  self.smile_hostname,
167
160
  self.smile_hw_version,
168
161
  self.smile_mac_address,
@@ -179,7 +172,6 @@ class Smile(SmileComm):
179
172
  self._on_off_device,
180
173
  self._opentherm_device,
181
174
  self._request,
182
- self._smile_props,
183
175
  self._stretch_v2,
184
176
  self._target_smile,
185
177
  self.smile_hostname,
@@ -58,6 +58,11 @@ class SmileCommon:
58
58
  self.smile_name: str
59
59
  self.smile_type: str
60
60
 
61
+ @property
62
+ def heater_id(self) -> str:
63
+ """Return the heater-id."""
64
+ return self._heater_id
65
+
61
66
  def smile(self, name: str) -> bool:
62
67
  """Helper-function checking the smile-name."""
63
68
  return self.smile_name == name
@@ -76,6 +81,9 @@ class SmileCommon:
76
81
  xml_2 = return_valid(xml_2, self._domain_objects)
77
82
  self._heater_id = check_heater_central(xml_2)
78
83
 
84
+ if self._heater_id == NONE:
85
+ return Munch() # pragma: no cover
86
+
79
87
  # Info for On-Off device
80
88
  if self._on_off_device:
81
89
  appl.name = "OnOff" # pragma: no cover
@@ -393,17 +393,6 @@ ZONE_THERMOSTATS: Final[tuple[str, ...]] = (
393
393
  )
394
394
 
395
395
 
396
- class SmileProps(TypedDict, total=False):
397
- """The SmileProps Data class."""
398
-
399
- cooling_present: bool
400
- gateway_id: str
401
- heater_id: str
402
- item_count: int
403
- reboot: bool
404
- smile_name: str
405
-
406
-
407
396
  class ModuleData(TypedDict):
408
397
  """The Module data class."""
409
398
 
@@ -16,7 +16,6 @@ from plugwise.constants import (
16
16
  OFF,
17
17
  ActuatorData,
18
18
  GwEntityData,
19
- SmileProps,
20
19
  )
21
20
  from plugwise.helper import SmileHelper
22
21
  from plugwise.util import remove_empty_platform_dicts
@@ -27,28 +26,19 @@ class SmileData(SmileHelper):
27
26
 
28
27
  def __init__(self) -> None:
29
28
  """Init."""
30
- self._smile_props: SmileProps
29
+ super().__init__()
31
30
  self._zones: dict[str, GwEntityData] = {}
32
- SmileHelper.__init__(self)
33
31
 
34
32
  def _all_entity_data(self) -> None:
35
33
  """Helper-function for get_all_gateway_entities().
36
34
 
37
- Collect data for each entity and add to self._smile_props and self.gw_entities.
35
+ Collect data for each entity and add to self.gw_entities.
38
36
  """
39
37
  self._update_gw_entities()
40
38
  if self.smile(ADAM):
41
39
  self._update_zones()
42
40
  self.gw_entities.update(self._zones)
43
41
 
44
- self._smile_props["gateway_id"] = self._gateway_id
45
- self._smile_props["item_count"] = self._count
46
- self._smile_props["reboot"] = True
47
- self._smile_props["smile_name"] = self.smile_name
48
- if self._is_thermostat:
49
- self._smile_props["heater_id"] = self._heater_id
50
- self._smile_props["cooling_present"] = self._cooling_present
51
-
52
42
  def _update_zones(self) -> None:
53
43
  """Helper-function for _all_entity_data() and async_update().
54
44
 
@@ -75,6 +75,7 @@ class SmileHelper(SmileCommon):
75
75
 
76
76
  def __init__(self) -> None:
77
77
  """Set the constructor for this class."""
78
+ super().__init__()
78
79
  self._endpoint: str
79
80
  self._elga: bool
80
81
  self._is_thermostat: bool
@@ -89,7 +90,16 @@ class SmileHelper(SmileCommon):
89
90
  self.smile_model: str
90
91
  self.smile_model_id: str | None
91
92
  self.smile_version: version.Version
92
- SmileCommon.__init__(self)
93
+
94
+ @property
95
+ def gateway_id(self) -> str:
96
+ """Return the gateway-id."""
97
+ return self._gateway_id
98
+
99
+ @property
100
+ def item_count(self) -> int:
101
+ """Return the item-count."""
102
+ return self._count
93
103
 
94
104
  def _all_appliances(self) -> None:
95
105
  """Collect all appliances with relevant info.
@@ -233,7 +243,7 @@ class SmileHelper(SmileCommon):
233
243
  appliance, "domestic_hot_water_mode_control_functionality"
234
244
  )
235
245
  # Skip orphaned heater_central (Core Issue #104433)
236
- if appl.entity_id != self._heater_id:
246
+ if appl.entity_id != self.heater_id:
237
247
  return Munch()
238
248
  return appl
239
249
  case _ as s if s.endswith("_plug"):
@@ -253,7 +263,7 @@ class SmileHelper(SmileCommon):
253
263
  appl.zigbee_mac = module_data["zigbee_mac_address"]
254
264
  return appl
255
265
  case _: # pragma: no cover
256
- return appl
266
+ return Munch()
257
267
 
258
268
  def _appl_gateway_info(self, appl: Munch, appliance: etree.Element) -> Munch:
259
269
  """Helper-function for _appliance_info_finder()."""
@@ -344,7 +354,7 @@ class SmileHelper(SmileCommon):
344
354
 
345
355
  # Get non-P1 data from APPLIANCES
346
356
  measurements = DEVICE_MEASUREMENTS
347
- if self._is_thermostat and entity_id == self._heater_id:
357
+ if self._is_thermostat and entity_id == self.heater_id:
348
358
  measurements = HEATER_CENTRAL_MEASUREMENTS
349
359
  # Show the allowed dhw_modes (Loria only)
350
360
  if self._dhw_allowed_modes:
@@ -619,7 +629,7 @@ class SmileHelper(SmileCommon):
619
629
 
620
630
  Support added for Techneco Elga and Thercon Loria/Thermastage.
621
631
  """
622
- if entity_id != self._heater_id:
632
+ if entity_id != self.heater_id:
623
633
  return
624
634
 
625
635
  if "elga_status_code" in data:
@@ -7,7 +7,7 @@ from __future__ import annotations
7
7
 
8
8
  # Dict as class
9
9
  # Version detection
10
- from plugwise.constants import NONE, OFF, GwEntityData, SmileProps
10
+ from plugwise.constants import NONE, OFF, GwEntityData
11
11
  from plugwise.legacy.helper import SmileLegacyHelper
12
12
  from plugwise.util import remove_empty_platform_dicts
13
13
 
@@ -15,22 +15,12 @@ from plugwise.util import remove_empty_platform_dicts
15
15
  class SmileLegacyData(SmileLegacyHelper):
16
16
  """The Plugwise Smile main class."""
17
17
 
18
- def __init__(self) -> None:
19
- """Init."""
20
- self._smile_props: SmileProps
21
- SmileLegacyHelper.__init__(self)
22
-
23
18
  def _all_entity_data(self) -> None:
24
19
  """Helper-function for get_all_gateway_entities().
25
20
 
26
- Collect data for each entity and add to self._smile_props and self.gw_entities.
21
+ Collect data for each entity and add to self.gw_entities.
27
22
  """
28
23
  self._update_gw_entities()
29
- self._smile_props["gateway_id"] = self.gateway_id
30
- self._smile_props["item_count"] = self._count
31
- self._smile_props["smile_name"] = self.smile_name
32
- if self._is_thermostat:
33
- self._smile_props["heater_id"] = self._heater_id
34
24
 
35
25
  def _update_gw_entities(self) -> None:
36
26
  """Helper-function for _all_entity_data() and async_update().
@@ -64,7 +64,9 @@ class SmileLegacyHelper(SmileCommon):
64
64
 
65
65
  def __init__(self) -> None:
66
66
  """Set the constructor for this class."""
67
+ super().__init__()
67
68
  self._appliances: etree.Element
69
+ self._gateway_id: str = NONE
68
70
  self._is_thermostat: bool
69
71
  self._loc_data: dict[str, ThermoLoc]
70
72
  self._locations: etree.Element
@@ -75,7 +77,16 @@ class SmileLegacyHelper(SmileCommon):
75
77
  self.smile_model: str
76
78
  self.smile_version: Version
77
79
  self.smile_zigbee_mac_address: str | None
78
- SmileCommon.__init__(self)
80
+
81
+ @property
82
+ def gateway_id(self) -> str:
83
+ """Return the gateway-id."""
84
+ return self._gateway_id
85
+
86
+ @property
87
+ def item_count(self) -> int:
88
+ """Return the item-count."""
89
+ return self._count
79
90
 
80
91
  def _all_appliances(self) -> None:
81
92
  """Collect all appliances with relevant info."""
@@ -125,7 +136,7 @@ class SmileLegacyHelper(SmileCommon):
125
136
  continue
126
137
 
127
138
  # Skip orphaned heater_central (Core Issue #104433)
128
- if appl.pwclass == "heater_central" and appl.entity_id != self._heater_id:
139
+ if appl.pwclass == "heater_central" and appl.entity_id != self.heater_id:
129
140
  continue # pragma: no cover
130
141
 
131
142
  self._create_gw_entities(appl)
@@ -173,11 +184,11 @@ class SmileLegacyHelper(SmileCommon):
173
184
 
174
185
  Use the home_location or FAKE_APPL as entity id.
175
186
  """
176
- self.gateway_id = self._home_loc_id
187
+ self._gateway_id = self._home_loc_id
177
188
  if self.smile_type == "power":
178
- self.gateway_id = FAKE_APPL
189
+ self._gateway_id = FAKE_APPL
179
190
 
180
- self.gw_entities[self.gateway_id] = {"dev_class": "gateway"}
191
+ self.gw_entities[self._gateway_id] = {"dev_class": "gateway"}
181
192
  self._count += 1
182
193
  for key, value in {
183
194
  "firmware": str(self.smile_version),
@@ -190,7 +201,7 @@ class SmileLegacyHelper(SmileCommon):
190
201
  }.items():
191
202
  if value is not None:
192
203
  gw_key = cast(ApplianceType, key)
193
- self.gw_entities[self.gateway_id][gw_key] = value
204
+ self.gw_entities[self._gateway_id][gw_key] = value
194
205
  self._count += 1
195
206
 
196
207
  def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
@@ -268,7 +279,7 @@ class SmileLegacyHelper(SmileCommon):
268
279
  return data
269
280
 
270
281
  measurements = DEVICE_MEASUREMENTS
271
- if self._is_thermostat and entity_id == self._heater_id:
282
+ if self._is_thermostat and entity_id == self.heater_id:
272
283
  measurements = HEATER_CENTRAL_MEASUREMENTS
273
284
 
274
285
  if (
@@ -282,7 +293,7 @@ class SmileLegacyHelper(SmileCommon):
282
293
 
283
294
  # Anna: the Smile outdoor_temperature is present in the Home location
284
295
  # For some Anna's LOCATIONS is empty, falling back to domain_objects!
285
- if self._is_thermostat and entity_id == self.gateway_id:
296
+ if self._is_thermostat and entity_id == self._gateway_id:
286
297
  locator = f"./location[@id='{self._home_loc_id}']/logs/point_log[type='outdoor_temperature']/period/measurement"
287
298
  if (found := self._domain_objects.find(locator)) is not None:
288
299
  value = format_measure(found.text, NONE)
@@ -19,7 +19,6 @@ from plugwise.constants import (
19
19
  REQUIRE_APPLIANCES,
20
20
  RULES,
21
21
  GwEntityData,
22
- SmileProps,
23
22
  ThermoLoc,
24
23
  )
25
24
  from plugwise.exceptions import ConnectionFailedError, DataMissingError, PlugwiseError
@@ -41,7 +40,6 @@ class SmileLegacyAPI(SmileLegacyData):
41
40
  _on_off_device: bool,
42
41
  _opentherm_device: bool,
43
42
  _request: Callable[..., Awaitable[Any]],
44
- _smile_props: SmileProps,
45
43
  _stretch_v2: bool,
46
44
  _target_smile: str,
47
45
  smile_hostname: str,
@@ -54,13 +52,13 @@ class SmileLegacyAPI(SmileLegacyData):
54
52
  smile_zigbee_mac_address: str | None,
55
53
  ) -> None:
56
54
  """Set the constructor for this class."""
55
+ super().__init__()
57
56
  self._cooling_present = False
58
57
  self._is_thermostat = _is_thermostat
59
58
  self._loc_data = _loc_data
60
59
  self._on_off_device = _on_off_device
61
60
  self._opentherm_device = _opentherm_device
62
61
  self._request = _request
63
- self._smile_props = _smile_props
64
62
  self._stretch_v2 = _stretch_v2
65
63
  self._target_smile = _target_smile
66
64
  self.smile_hostname = smile_hostname
@@ -71,11 +69,15 @@ class SmileLegacyAPI(SmileLegacyData):
71
69
  self.smile_type = smile_type
72
70
  self.smile_version = smile_version
73
71
  self.smile_zigbee_mac_address = smile_zigbee_mac_address
74
- SmileLegacyData.__init__(self)
75
72
 
76
73
  self._first_update = True
77
74
  self._previous_day_number: str = "0"
78
75
 
76
+ @property
77
+ def cooling_present(self) -> bool:
78
+ """Return the cooling capability."""
79
+ return False
80
+
79
81
  async def full_xml_update(self) -> None:
80
82
  """Perform a first fetch of the Plugwise server XML data."""
81
83
  self._domain_objects = await self._request(DOMAIN_OBJECTS)
@@ -18,11 +18,11 @@ from plugwise.constants import (
18
18
  LOCATIONS,
19
19
  MAX_SETPOINT,
20
20
  MIN_SETPOINT,
21
+ NONE,
21
22
  NOTIFICATIONS,
22
23
  OFF,
23
24
  RULES,
24
25
  GwEntityData,
25
- SmileProps,
26
26
  ThermoLoc,
27
27
  )
28
28
  from plugwise.data import SmileData
@@ -51,7 +51,6 @@ class SmileAPI(SmileData):
51
51
  _opentherm_device: bool,
52
52
  _request: Callable[..., Awaitable[Any]],
53
53
  _schedule_old_states: dict[str, dict[str, str]],
54
- _smile_props: SmileProps,
55
54
  smile_hostname: str | None,
56
55
  smile_hw_version: str | None,
57
56
  smile_mac_address: str | None,
@@ -62,6 +61,7 @@ class SmileAPI(SmileData):
62
61
  smile_version: Version,
63
62
  ) -> None:
64
63
  """Set the constructor for this class."""
64
+ super().__init__()
65
65
  self._cooling_present = _cooling_present
66
66
  self._elga = _elga
67
67
  self._is_thermostat = _is_thermostat
@@ -71,7 +71,6 @@ class SmileAPI(SmileData):
71
71
  self._opentherm_device = _opentherm_device
72
72
  self._request = _request
73
73
  self._schedule_old_states = _schedule_old_states
74
- self._smile_props = _smile_props
75
74
  self.smile_hostname = smile_hostname
76
75
  self.smile_hw_version = smile_hw_version
77
76
  self.smile_mac_address = smile_mac_address
@@ -81,7 +80,11 @@ class SmileAPI(SmileData):
81
80
  self.smile_type = smile_type
82
81
  self.smile_version = smile_version
83
82
  self.therms_with_offset_func: list[str] = []
84
- SmileData.__init__(self)
83
+
84
+ @property
85
+ def cooling_present(self) -> bool:
86
+ """Return the cooling capability."""
87
+ return self._cooling_present
85
88
 
86
89
  async def full_xml_update(self) -> None:
87
90
  """Perform a first fetch of the Plugwise server XML data."""
@@ -121,8 +124,8 @@ class SmileAPI(SmileData):
121
124
  self.get_all_gateway_entities()
122
125
  # Set self._cooling_enabled - required for set_temperature(),
123
126
  # also, check for a failed data-retrieval
124
- if "heater_id" in self._smile_props:
125
- heat_cooler = self.gw_entities[self._smile_props["heater_id"]]
127
+ if self.heater_id != NONE:
128
+ heat_cooler = self.gw_entities[self.heater_id]
126
129
  if (
127
130
  "binary_sensors" in heat_cooler
128
131
  and "cooling_enabled" in heat_cooler["binary_sensors"]
@@ -131,7 +134,7 @@ class SmileAPI(SmileData):
131
134
  "cooling_enabled"
132
135
  ]
133
136
  else: # cover failed data-retrieval for P1
134
- _ = self.gw_entities[self._smile_props["gateway_id"]]["location"]
137
+ _ = self.gw_entities[self.gateway_id]["location"]
135
138
  except KeyError as err:
136
139
  raise DataMissingError("No Plugwise actual data received") from err
137
140
 
@@ -273,7 +276,7 @@ class SmileAPI(SmileData):
273
276
  f"{valid}"
274
277
  "</gateway_mode_control_functionality>"
275
278
  )
276
- uri = f"{APPLIANCES};id={self._smile_props['gateway_id']}/gateway_mode_control"
279
+ uri = f"{APPLIANCES};id={self.gateway_id}/gateway_mode_control"
277
280
  await self.call_request(uri, method="put", data=data)
278
281
 
279
282
  async def set_regulation_mode(self, mode: str) -> None:
@@ -13,6 +13,7 @@ from plugwise.constants import (
13
13
  ELECTRIC_POTENTIAL_VOLT,
14
14
  ENERGY_KILO_WATT_HOUR,
15
15
  HW_MODELS,
16
+ NONE,
16
17
  OBSOLETE_MEASUREMENTS,
17
18
  PERCENTAGE,
18
19
  POWER_WATT,
@@ -93,14 +94,16 @@ def check_heater_central(xml: etree.Element) -> str:
93
94
  if heater_central.find("name").text == "Central heating boiler":
94
95
  hc_list.append({hc_id: has_actuators})
95
96
 
97
+ if not hc_list:
98
+ return NONE # pragma: no cover
99
+
96
100
  heater_central_id = list(hc_list[0].keys())[0]
97
101
  if hc_count > 1:
98
- for item in hc_list: # pragma: no cover
99
- for key, value in item.items(): # pragma: no cover
100
- if value: # pragma: no cover
101
- heater_central_id = key # pragma: no cover
102
- # Stop when a valid id is found
103
- break # pragma: no cover
102
+ for item in hc_list:
103
+ hc_id, has_actuators = next(iter(item.items()))
104
+ if has_actuators:
105
+ heater_central_id = hc_id
106
+ break
104
107
 
105
108
  return heater_central_id
106
109
 
@@ -135,7 +138,7 @@ def collect_power_values(
135
138
  if not loc.found:
136
139
  continue
137
140
 
138
- data = power_data_energy_diff(loc.measurement, loc.net_string, loc.f_val, data)
141
+ power_data_energy_diff(loc.measurement, loc.net_string, loc.f_val, data)
139
142
  key = cast(SensorType, loc.key_string)
140
143
  data["sensors"][key] = loc.f_val
141
144
 
@@ -192,8 +195,6 @@ def escape_illegal_xml_characters(xmldata: str) -> str:
192
195
 
193
196
  def format_measure(measure: str, unit: str) -> float | int:
194
197
  """Format measure to correct type."""
195
- result: float | int = 0
196
-
197
198
  float_measure = float(measure)
198
199
  if unit == PERCENTAGE and 0 < float_measure <= 1:
199
200
  return int(float_measure * 100)
@@ -202,13 +203,13 @@ def format_measure(measure: str, unit: str) -> float | int:
202
203
  float_measure = float_measure / 1000
203
204
 
204
205
  if unit in SPECIAL_FORMAT:
205
- result = float(f"{round(float_measure, 3):.3f}")
206
+ result = round(float_measure, 3)
206
207
  elif unit == ELECTRIC_POTENTIAL_VOLT:
207
- result = float(f"{round(float_measure, 1):.1f}")
208
+ result = round(float_measure, 1)
208
209
  elif abs(float_measure) < 10:
209
- result = float(f"{round(float_measure, 2):.2f}")
210
- elif abs(float_measure) >= 10:
211
- result = float(f"{round(float_measure, 1):.1f}")
210
+ result = round(float_measure, 2)
211
+ else: # abs(float_measure) >= 10
212
+ result = round(float_measure, 1)
212
213
 
213
214
  return result
214
215
 
@@ -228,31 +229,21 @@ def power_data_energy_diff(
228
229
  net_string: SensorType,
229
230
  f_val: float | int,
230
231
  data: GwEntityData,
231
- ) -> GwEntityData:
232
+ ) -> None:
232
233
  """Calculate differential energy."""
233
234
  if (
234
235
  "electricity" in measurement
235
236
  and "phase" not in measurement
236
237
  and "interval" not in net_string
237
238
  ):
238
- diff = 1
239
- if "produced" in measurement:
240
- diff = -1
241
- if net_string not in data["sensors"]:
242
- tmp_val: float | int = 0
243
- else:
244
- tmp_val = data["sensors"][net_string]
245
-
246
- if isinstance(f_val, int):
247
- tmp_val += f_val * diff
248
- else:
249
- tmp_val += float(f_val * diff)
250
- tmp_val = float(f"{round(tmp_val, 3):.3f}")
239
+ diff = 1 if "consumed" in measurement else -1
240
+ tmp_val = data["sensors"].get(net_string, 0)
241
+ tmp_val += f_val * diff
242
+ if isinstance(f_val, float):
243
+ tmp_val = round(tmp_val, 3)
251
244
 
252
245
  data["sensors"][net_string] = tmp_val
253
246
 
254
- return data
255
-
256
247
 
257
248
  def power_data_local_format(
258
249
  attrs: dict[str, str], key_string: str, val: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: plugwise
3
- Version: 1.7.3a1
3
+ Version: 1.7.3a3
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "plugwise"
7
- version = "1.7.3a1"
7
+ version = "1.7.3a3"
8
8
  license = {file = "LICENSE"}
9
9
  description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
10
10
  readme = "README.md"
@@ -75,7 +75,6 @@ init-hook = """\
75
75
  load-plugins = [
76
76
  "pylint.extensions.code_style",
77
77
  "pylint.extensions.typing",
78
- "pylint_per_file_ignores",
79
78
  ]
80
79
  persistent = false
81
80
  extension-pkg-allow-list = [
@@ -366,12 +365,6 @@ enable = [
366
365
  #"useless-suppression", # temporarily every now and then to clean them up
367
366
  "use-symbolic-message-instead",
368
367
  ]
369
- per-file-ignores = [
370
- # redefined-outer-name: Tests reference fixtures in the test function
371
- # use-implicit-booleaness-not-comparison: Tests need to validate that a list
372
- # or a dict is returned
373
- "/tests/:redefined-outer-name,use-implicit-booleaness-not-comparison",
374
- ]
375
368
 
376
369
  [tool.pylint.REPORTS]
377
370
  score = false
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes