plugwise 1.4.1__tar.gz → 1.4.2a2__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 (32) hide show
  1. {plugwise-1.4.1 → plugwise-1.4.2a2}/PKG-INFO +1 -1
  2. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/__init__.py +9 -11
  3. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/common.py +0 -4
  4. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/helper.py +10 -3
  5. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/legacy/helper.py +7 -0
  6. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/legacy/smile.py +5 -5
  7. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/smile.py +10 -7
  8. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/util.py +3 -1
  9. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise.egg-info/PKG-INFO +1 -1
  10. {plugwise-1.4.1 → plugwise-1.4.2a2}/pyproject.toml +9 -8
  11. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_init.py +11 -6
  12. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_legacy_stretch.py +1 -1
  13. {plugwise-1.4.1 → plugwise-1.4.2a2}/LICENSE +0 -0
  14. {plugwise-1.4.1 → plugwise-1.4.2a2}/README.md +0 -0
  15. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/constants.py +0 -0
  16. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/data.py +0 -0
  17. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/exceptions.py +0 -0
  18. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/legacy/data.py +0 -0
  19. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise/py.typed +0 -0
  20. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise.egg-info/SOURCES.txt +0 -0
  21. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise.egg-info/dependency_links.txt +0 -0
  22. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise.egg-info/requires.txt +0 -0
  23. {plugwise-1.4.1 → plugwise-1.4.2a2}/plugwise.egg-info/top_level.txt +0 -0
  24. {plugwise-1.4.1 → plugwise-1.4.2a2}/setup.cfg +0 -0
  25. {plugwise-1.4.1 → plugwise-1.4.2a2}/setup.py +0 -0
  26. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_adam.py +0 -0
  27. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_anna.py +0 -0
  28. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_generic.py +0 -0
  29. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_legacy_anna.py +0 -0
  30. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_legacy_generic.py +0 -0
  31. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_legacy_p1.py +0 -0
  32. {plugwise-1.4.1 → plugwise-1.4.2a2}/tests/test_p1.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plugwise
3
- Version: 1.4.1
3
+ Version: 1.4.2a2
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
@@ -5,7 +5,6 @@ Plugwise backend module for Home Assistant Core.
5
5
  from __future__ import annotations
6
6
 
7
7
  from plugwise.constants import (
8
- DEFAULT_LEGACY_TIMEOUT,
9
8
  DEFAULT_PORT,
10
9
  DEFAULT_TIMEOUT,
11
10
  DEFAULT_USERNAME,
@@ -44,28 +43,27 @@ class Smile(SmileComm):
44
43
  self,
45
44
  host: str,
46
45
  password: str,
46
+ timeout: int,
47
47
  websession: aiohttp.ClientSession,
48
- username: str = DEFAULT_USERNAME,
49
48
  port: int = DEFAULT_PORT,
50
- timeout: float = DEFAULT_LEGACY_TIMEOUT,
51
-
49
+ username: str = DEFAULT_USERNAME,
52
50
  ) -> None:
53
51
  """Set the constructor for this class."""
54
52
  super().__init__(
55
53
  host,
56
54
  password,
57
- websession,
58
- username,
59
55
  port,
60
56
  timeout,
61
- )
57
+ username,
58
+ websession,
59
+ )
62
60
 
63
61
  self._host = host
64
62
  self._passwd = password
65
- self._websession = websession
66
- self._user = username
67
63
  self._port = port
68
64
  self._timeout = timeout
65
+ self._user = username
66
+ self._websession = websession
69
67
 
70
68
  self._cooling_present = False
71
69
  self._elga = False
@@ -149,8 +147,8 @@ class Smile(SmileComm):
149
147
  self.smile_model_id,
150
148
  self.smile_name,
151
149
  self.smile_type,
152
- self._user,
153
150
  self._port,
151
+ self._user,
154
152
  ) if not self.smile_legacy else SmileLegacyAPI(
155
153
  self._host,
156
154
  self._passwd,
@@ -170,8 +168,8 @@ class Smile(SmileComm):
170
168
  self.smile_name,
171
169
  self.smile_type,
172
170
  self.smile_zigbee_mac_address,
173
- self._user,
174
171
  self._port,
172
+ self._user,
175
173
  )
176
174
 
177
175
  # Update all endpoints on first connect
@@ -57,10 +57,6 @@ class SmileCommon:
57
57
  xml_3: etree = None,
58
58
  ) -> Munch:
59
59
  """Helper-function for _appliance_info_finder()."""
60
- # Remove heater_central when no active device present
61
- if not self._opentherm_device and not self._on_off_device:
62
- return None
63
-
64
60
  # Find the valid heater_central
65
61
  # xml_2 self._appliances for legacy, self._domain_objects for actual
66
62
  xml_2 = return_valid(xml_2, self._domain_objects)
@@ -71,10 +71,10 @@ class SmileComm:
71
71
  self,
72
72
  host: str,
73
73
  password: str,
74
- websession: ClientSession | None,
75
- username: str,
76
74
  port: int,
77
- timeout: float,
75
+ timeout: int,
76
+ username: str,
77
+ websession: ClientSession | None,
78
78
  ) -> None:
79
79
  """Set the constructor for this class."""
80
80
  if not websession:
@@ -269,6 +269,13 @@ class SmileHelper(SmileCommon):
269
269
  for appliance in self._domain_objects.findall("./appliance"):
270
270
  appl = Munch()
271
271
  appl.pwclass = appliance.find("type").text
272
+ # Extend device_class name of Plugs (Plugwise and Aqara) - Pw-Beta Issue #739
273
+ description = appliance.find("description").text
274
+ if description is not None and (
275
+ "ZigBee protocol" in description or "smart plug" in description
276
+ ):
277
+ appl.pwclass = f"{appl.pwclass}_plug"
278
+
272
279
  # Skip thermostats that have this key, should be an orphaned device (Core #81712)
273
280
  if (
274
281
  appl.pwclass == "thermostat"
@@ -116,6 +116,13 @@ class SmileLegacyHelper(SmileCommon):
116
116
  appl.location = self._home_location
117
117
  appl.dev_id = appliance.attrib["id"]
118
118
  appl.name = appliance.find("name").text
119
+ # Extend device_class name when a Circle/Stealth is type heater_central -- Pw-Beta Issue #739
120
+ if (
121
+ appl.pwclass == "heater_central"
122
+ and appl.name != "Central heating boiler"
123
+ ):
124
+ appl.pwclass = "heater_central_plug"
125
+
119
126
  appl.model = appl.pwclass.replace("_", " ").title()
120
127
  appl.model_id = None
121
128
  appl.firmware = None
@@ -40,7 +40,7 @@ class SmileLegacyAPI(SmileComm, SmileLegacyData):
40
40
  self,
41
41
  host: str,
42
42
  password: str,
43
- timeout: float,
43
+ timeout: int,
44
44
  websession: aiohttp.ClientSession,
45
45
  _is_thermostat: bool,
46
46
  _on_off_device: bool,
@@ -56,18 +56,18 @@ class SmileLegacyAPI(SmileComm, SmileLegacyData):
56
56
  smile_name: str,
57
57
  smile_type: str,
58
58
  smile_zigbee_mac_address: str | None,
59
- username: str = DEFAULT_USERNAME,
60
59
  port: int = DEFAULT_PORT,
60
+ username: str = DEFAULT_USERNAME,
61
61
  ) -> None:
62
62
  """Set the constructor for this class."""
63
63
  super().__init__(
64
64
  host,
65
65
  password,
66
- websession,
67
- username,
68
66
  port,
69
67
  timeout,
70
- )
68
+ username,
69
+ websession,
70
+ )
71
71
  SmileLegacyData.__init__(self)
72
72
 
73
73
  self._cooling_present = False
@@ -46,7 +46,7 @@ class SmileAPI(SmileComm, SmileData):
46
46
  self,
47
47
  host: str,
48
48
  password: str,
49
- timeout: float,
49
+ timeout: int,
50
50
  websession: aiohttp.ClientSession,
51
51
  _cooling_present: bool,
52
52
  _elga: bool,
@@ -65,17 +65,17 @@ class SmileAPI(SmileComm, SmileData):
65
65
  smile_model_id: str | None,
66
66
  smile_name: str,
67
67
  smile_type: str,
68
- username: str = DEFAULT_USERNAME,
69
68
  port: int = DEFAULT_PORT,
69
+ username: str = DEFAULT_USERNAME,
70
70
  ) -> None:
71
71
  """Set the constructor for this class."""
72
72
  super().__init__(
73
73
  host,
74
74
  password,
75
- websession,
76
- username,
77
75
  port,
78
76
  timeout,
77
+ username,
78
+ websession,
79
79
  )
80
80
  SmileData.__init__(self)
81
81
 
@@ -137,9 +137,12 @@ class SmileAPI(SmileComm, SmileData):
137
137
  await self.full_update_device()
138
138
  self.get_all_devices()
139
139
  if "heater_id" in self.gw_data:
140
- self._heater_id = self.gw_data["heater_id"]
141
- if "cooling_enabled" in self.gw_devices[self._heater_id]["binary_sensors"]:
142
- self._cooling_enabled = self.gw_devices[self._heater_id]["binary_sensors"]["cooling_enabled"]
140
+ heat_cooler = self.gw_devices[self.gw_data["heater_id"]]
141
+ if (
142
+ "binary_sensors" in heat_cooler
143
+ and "cooling_enabled" in heat_cooler["binary_sensors"]
144
+ ):
145
+ self._cooling_enabled = heat_cooler["binary_sensors"]["cooling_enabled"]
143
146
  except KeyError as err:
144
147
  raise DataMissingError("No Plugwise data received") from err
145
148
 
@@ -91,7 +91,9 @@ def check_heater_central(xml: etree) -> str:
91
91
  has_actuators: bool = (
92
92
  heater_central.find("actuator_functionalities/") is not None
93
93
  )
94
- hc_list.append({hc_id: has_actuators})
94
+ # Filter for Plug/Circle/Stealth heater_central -- Pw-Beta Issue #739
95
+ if heater_central.find("name").text == "Central heating boiler":
96
+ hc_list.append({hc_id: has_actuators})
95
97
 
96
98
  heater_central_id = list(hc_list[0].keys())[0]
97
99
  if hc_count > 1:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plugwise
3
- Version: 1.4.1
3
+ Version: 1.4.2a2
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.4.1"
7
+ version = "1.4.2a2"
8
8
  license = {file = "LICENSE"}
9
9
  description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
10
10
  readme = "README.md"
@@ -112,33 +112,34 @@ good-names = [
112
112
  # too-many-ancestors - it's too strict.
113
113
  # wrong-import-order - isort guards this
114
114
  disable = [
115
- "format",
116
115
  "abstract-method",
117
116
  "consider-using-f-string",
118
117
  "cyclic-import",
119
118
  "duplicate-code",
120
119
  "fixme",
120
+ "format",
121
121
  "inconsistent-return-statements",
122
122
  "locally-disabled",
123
+ "missing-class-docstring",
124
+ "missing-function-docstring",
125
+ "missing-module-docstring",
123
126
  "not-context-manager",
127
+ "raise-missing-from",
124
128
  "too-few-public-methods",
125
129
  "too-many-ancestors",
126
130
  "too-many-arguments",
131
+ "too-many-boolean-expressions",
127
132
  "too-many-branches",
128
133
  "too-many-instance-attributes",
129
134
  "too-many-lines",
130
135
  "too-many-locals",
136
+ "too-many-positional-arguments",
131
137
  "too-many-public-methods",
132
138
  "too-many-return-statements",
133
139
  "too-many-statements",
134
- "too-many-boolean-expressions",
140
+ "too-many-nested-blocks",
135
141
  "unused-argument",
136
142
  "wrong-import-order",
137
- "raise-missing-from",
138
- "missing-class-docstring",
139
- "missing-function-docstring",
140
- "missing-module-docstring",
141
- "too-many-nested-blocks",
142
143
  ]
143
144
  # for now (20201031) added the below while we are codemerging/-improving
144
145
  # missing-class-docstring
@@ -322,6 +322,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
322
322
  username=pw_constants.DEFAULT_USERNAME,
323
323
  password=test_password,
324
324
  port=server.port,
325
+ timeout=pw_constants.DEFAULT_TIMEOUT,
325
326
  websession=None,
326
327
  )
327
328
  lack_of_websession = False
@@ -335,11 +336,12 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
335
336
  username=pw_constants.DEFAULT_USERNAME,
336
337
  password=test_password,
337
338
  port=server.port,
339
+ timeout=pw_constants.DEFAULT_TIMEOUT,
338
340
  websession=websession,
339
341
  )
340
342
 
341
343
  if not timeout:
342
- assert smile._timeout == 30
344
+ assert smile._timeout == 10
343
345
 
344
346
  # Connect to the smile
345
347
  try:
@@ -403,6 +405,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
403
405
  username=pw_constants.DEFAULT_USERNAME,
404
406
  password=test_password,
405
407
  port=server.port,
408
+ timeout=pw_constants.DEFAULT_LEGACY_TIMEOUT,
406
409
  websession=None,
407
410
  )
408
411
  lack_of_websession = False
@@ -416,6 +419,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
416
419
  username=pw_constants.DEFAULT_USERNAME,
417
420
  password=test_password,
418
421
  port=server.port,
422
+ timeout=pw_constants.DEFAULT_LEGACY_TIMEOUT,
419
423
  websession=websession,
420
424
  )
421
425
 
@@ -570,11 +574,12 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
570
574
  self._cooling_active = False
571
575
  self._cooling_enabled = False
572
576
  if "heater_id" in data.gateway:
573
- heater_id = data.gateway["heater_id"]
574
- if "cooling_enabled" in data.devices[heater_id]["binary_sensors"]:
575
- self._cooling_enabled = data.devices[heater_id]["binary_sensors"]["cooling_enabled"]
576
- if "cooling_state" in data.devices[heater_id]["binary_sensors"]:
577
- self._cooling_active = data.devices[heater_id]["binary_sensors"]["cooling_state"]
577
+ heat_cooler = data.devices[data.gateway["heater_id"]]
578
+ if "binary_sensors" in heat_cooler:
579
+ if "cooling_enabled" in heat_cooler["binary_sensors"]:
580
+ self._cooling_enabled = heat_cooler["binary_sensors"]["cooling_enabled"]
581
+ if "cooling_state" in heat_cooler["binary_sensors"]:
582
+ self._cooling_active = heat_cooler["binary_sensors"]["cooling_state"]
578
583
 
579
584
  self._write_json("all_data", {"gateway": data.gateway, "devices": data.devices})
580
585
 
@@ -69,7 +69,7 @@ class TestPlugwiseStretch(
69
69
  )
70
70
 
71
71
  await self.device_test(smile, "2022-05-16 00:00:01", testdata)
72
- assert self.device_items == 229
72
+ assert self.device_items == 243
73
73
 
74
74
  switch_change = await self.tinker_switch(
75
75
  smile, "2587a7fcdd7e482dab03fda256076b4b"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes