plugwise 0.37.6__tar.gz → 0.37.8__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-0.37.6 → plugwise-0.37.8}/PKG-INFO +1 -1
  2. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/__init__.py +13 -3
  3. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/data.py +4 -3
  4. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/legacy/data.py +4 -3
  5. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/legacy/smile.py +6 -0
  6. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/smile.py +48 -34
  7. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise.egg-info/PKG-INFO +1 -1
  8. {plugwise-0.37.6 → plugwise-0.37.8}/pyproject.toml +1 -1
  9. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_adam.py +1 -1
  10. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_init.py +5 -5
  11. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_legacy_anna.py +1 -1
  12. {plugwise-0.37.6 → plugwise-0.37.8}/LICENSE +0 -0
  13. {plugwise-0.37.6 → plugwise-0.37.8}/README.md +0 -0
  14. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/common.py +0 -0
  15. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/constants.py +0 -0
  16. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/exceptions.py +0 -0
  17. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/helper.py +0 -0
  18. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/legacy/helper.py +0 -0
  19. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/py.typed +0 -0
  20. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise/util.py +0 -0
  21. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise.egg-info/SOURCES.txt +0 -0
  22. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise.egg-info/dependency_links.txt +0 -0
  23. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise.egg-info/requires.txt +0 -0
  24. {plugwise-0.37.6 → plugwise-0.37.8}/plugwise.egg-info/top_level.txt +0 -0
  25. {plugwise-0.37.6 → plugwise-0.37.8}/setup.cfg +0 -0
  26. {plugwise-0.37.6 → plugwise-0.37.8}/setup.py +0 -0
  27. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_anna.py +0 -0
  28. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_generic.py +0 -0
  29. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_legacy_generic.py +0 -0
  30. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_legacy_p1.py +0 -0
  31. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_legacy_stretch.py +0 -0
  32. {plugwise-0.37.6 → plugwise-0.37.8}/tests/test_p1.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plugwise
3
- Version: 0.37.6
3
+ Version: 0.37.8
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
@@ -306,6 +306,16 @@ class Smile(SmileComm):
306
306
  ### API Set and HA Service-related Functions ###
307
307
  ########################################################################################################
308
308
 
309
+ async def set_select(
310
+ self,
311
+ key: str,
312
+ loc_id: str,
313
+ option: str,
314
+ name: str | None = None,
315
+ ) -> None:
316
+ """Set the selected option for the applicable Select."""
317
+ await self._smile_api.set_select(key, loc_id, option, name)
318
+
309
319
  async def set_schedule_state(
310
320
  self,
311
321
  loc_id: str,
@@ -344,15 +354,15 @@ class Smile(SmileComm):
344
354
 
345
355
  async def set_gateway_mode(self, mode: str) -> None:
346
356
  """Set the gateway mode."""
347
- await self._smile_api.set_gateway_mode(mode)
357
+ await self._smile_api.set_gateway_mode(mode) # pragma: no cover
348
358
 
349
359
  async def set_regulation_mode(self, mode: str) -> None:
350
360
  """Set the heating regulation mode."""
351
- await self._smile_api.set_regulation_mode(mode)
361
+ await self._smile_api.set_regulation_mode(mode) # pragma: no cover
352
362
 
353
363
  async def set_dhw_mode(self, mode: str) -> None:
354
364
  """Set the domestic hot water heating regulation mode."""
355
- await self._smile_api.set_dhw_mode(mode)
365
+ await self._smile_api.set_dhw_mode(mode) # pragma: no cover
356
366
 
357
367
  async def delete_notification(self) -> None:
358
368
  """Delete the active Plugwise Notification."""
@@ -197,9 +197,10 @@ class SmileData(SmileHelper):
197
197
 
198
198
  # Schedule
199
199
  avail_schedules, sel_schedule = self._schedules(loc_id)
200
- data["available_schedules"] = avail_schedules
201
- data["select_schedule"] = sel_schedule
202
- self._count += 2
200
+ if avail_schedules != [NONE]:
201
+ data["available_schedules"] = avail_schedules
202
+ data["select_schedule"] = sel_schedule
203
+ self._count += 2
203
204
 
204
205
  # Operation modes: auto, heat, heat_cool, cool and off
205
206
  data["mode"] = "auto"
@@ -81,9 +81,10 @@ class SmileLegacyData(SmileLegacyHelper):
81
81
 
82
82
  # Schedule
83
83
  avail_schedules, sel_schedule = self._schedules()
84
- data["available_schedules"] = avail_schedules
85
- data["select_schedule"] = sel_schedule
86
- self._count += 2
84
+ if avail_schedules != [NONE]:
85
+ data["available_schedules"] = avail_schedules
86
+ data["select_schedule"] = sel_schedule
87
+ self._count += 2
87
88
 
88
89
  # Operation modes: auto, heat
89
90
  data["mode"] = "auto"
@@ -182,6 +182,12 @@ class SmileLegacyAPI(SmileComm, SmileLegacyData):
182
182
  async def set_regulation_mode(self, mode: str) -> None:
183
183
  """Set-function placeholder for legacy devices."""
184
184
 
185
+ async def set_select(self, key: str, loc_id: str, option: str, name: str | None) -> None:
186
+ """Set the thermostat schedule option."""
187
+ # schedule state corresponds to select option
188
+ # schedule name corresponds to select name
189
+ await self.set_schedule_state("dummy", option, name)
190
+
185
191
  async def set_schedule_state(self, _: str, state: str, name: str | None) -> None:
186
192
  """Activate/deactivate the Schedule.
187
193
 
@@ -149,39 +149,6 @@ class SmileAPI(SmileComm, SmileData):
149
149
  """Delete the active Plugwise Notification."""
150
150
  await self._request(NOTIFICATIONS, method="delete")
151
151
 
152
- async def set_dhw_mode(self, mode: str) -> None:
153
- """Set the domestic hot water heating regulation mode."""
154
- if mode not in self._dhw_allowed_modes:
155
- raise PlugwiseError("Plugwise: invalid dhw mode.")
156
-
157
- uri = f"{APPLIANCES};type=heater_central/domestic_hot_water_mode_control"
158
- data = f"<domestic_hot_water_mode_control_functionality><mode>{mode}</mode></domestic_hot_water_mode_control_functionality>"
159
-
160
- await self._request(uri, method="put", data=data)
161
-
162
- async def set_gateway_mode(self, mode: str) -> None:
163
- """Set the gateway mode."""
164
- if mode not in self._gw_allowed_modes:
165
- raise PlugwiseError("Plugwise: invalid gateway mode.")
166
-
167
- end_time = "2037-04-21T08:00:53.000Z"
168
- valid = ""
169
- if mode == "away":
170
- time_1 = self._domain_objects.find("./gateway/time").text
171
- away_time = dt.datetime.fromisoformat(time_1).astimezone(dt.UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z")
172
- valid = (
173
- f"<valid_from>{away_time}</valid_from><valid_to>{end_time}</valid_to>"
174
- )
175
- if mode == "vacation":
176
- time_2 = str(dt.date.today() - dt.timedelta(1))
177
- vacation_time = time_2 + "T23:00:00.000Z"
178
- valid = f"<valid_from>{vacation_time}</valid_from><valid_to>{end_time}</valid_to>"
179
-
180
- uri = f"{APPLIANCES};id={self.gateway_id}/gateway_mode_control"
181
- data = f"<gateway_mode_control_functionality><mode>{mode}</mode>{valid}</gateway_mode_control_functionality>"
182
-
183
- await self._request(uri, method="put", data=data)
184
-
185
152
  async def set_number(
186
153
  self,
187
154
  dev_id: str,
@@ -241,6 +208,53 @@ class SmileAPI(SmileComm, SmileData):
241
208
 
242
209
  await self._request(uri, method="put", data=data)
243
210
 
211
+ async def set_select(self, key: str, loc_id: str, option: str, name: str | None) -> None:
212
+ """Set a dhw/gateway/regulation mode or the thermostat schedule option."""
213
+ match key:
214
+ case "select_dhw_mode":
215
+ await self.set_dhw_mode(option)
216
+ case "select_gateway_mode":
217
+ await self.set_gateway_mode(option)
218
+ case "select_regulation_mode":
219
+ await self.set_regulation_mode(option)
220
+ case "select_schedule":
221
+ # schedule state corresponds to select option
222
+ # schedule name corresponds to select name
223
+ await self.set_schedule_state(loc_id, option, name)
224
+
225
+ async def set_dhw_mode(self, mode: str) -> None:
226
+ """Set the domestic hot water heating regulation mode."""
227
+ if mode not in self._dhw_allowed_modes:
228
+ raise PlugwiseError("Plugwise: invalid dhw mode.")
229
+
230
+ uri = f"{APPLIANCES};type=heater_central/domestic_hot_water_mode_control"
231
+ data = f"<domestic_hot_water_mode_control_functionality><mode>{mode}</mode></domestic_hot_water_mode_control_functionality>"
232
+
233
+ await self._request(uri, method="put", data=data)
234
+
235
+ async def set_gateway_mode(self, mode: str) -> None:
236
+ """Set the gateway mode."""
237
+ if mode not in self._gw_allowed_modes:
238
+ raise PlugwiseError("Plugwise: invalid gateway mode.")
239
+
240
+ end_time = "2037-04-21T08:00:53.000Z"
241
+ valid = ""
242
+ if mode == "away":
243
+ time_1 = self._domain_objects.find("./gateway/time").text
244
+ away_time = dt.datetime.fromisoformat(time_1).astimezone(dt.UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z")
245
+ valid = (
246
+ f"<valid_from>{away_time}</valid_from><valid_to>{end_time}</valid_to>"
247
+ )
248
+ if mode == "vacation":
249
+ time_2 = str(dt.date.today() - dt.timedelta(1))
250
+ vacation_time = time_2 + "T23:00:00.000Z"
251
+ valid = f"<valid_from>{vacation_time}</valid_from><valid_to>{end_time}</valid_to>"
252
+
253
+ uri = f"{APPLIANCES};id={self.gateway_id}/gateway_mode_control"
254
+ data = f"<gateway_mode_control_functionality><mode>{mode}</mode>{valid}</gateway_mode_control_functionality>"
255
+
256
+ await self._request(uri, method="put", data=data)
257
+
244
258
  async def set_regulation_mode(self, mode: str) -> None:
245
259
  """Set the heating regulation mode."""
246
260
  if mode not in self._reg_allowed_modes:
@@ -258,7 +272,7 @@ class SmileAPI(SmileComm, SmileData):
258
272
  self,
259
273
  loc_id: str,
260
274
  new_state: str,
261
- name: str | None = None,
275
+ name: str | None,
262
276
  ) -> None:
263
277
  """Activate/deactivate the Schedule, with the given name, on the relevant Thermostat.
264
278
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plugwise
3
- Version: 0.37.6
3
+ Version: 0.37.8
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 = "0.37.6"
7
+ version = "0.37.8"
8
8
  license = {file = "LICENSE"}
9
9
  description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
10
10
  readme = "README.md"
@@ -347,7 +347,7 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
347
347
  assert smile._last_active["06aecb3d00354375924f50c47af36bd2"] is None
348
348
  assert smile._last_active["d27aede973b54be484f6842d1b2802ad"] is None
349
349
  assert smile._last_active["13228dab8ce04617af318a2888b3c548"] is None
350
- assert self.device_items == 221
350
+ assert self.device_items == 213
351
351
 
352
352
  # Negative test
353
353
  result = await self.tinker_thermostat(
@@ -733,7 +733,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
733
733
  new_schedule = new_schedule[1:]
734
734
  _LOGGER.info("- Adjusting schedule to %s", f"{new_schedule}{warning}")
735
735
  try:
736
- await smile.set_schedule_state(loc_id, state, new_schedule)
736
+ await smile.set_select("select_schedule", loc_id, state, new_schedule)
737
737
  tinker_schedule_passed = True
738
738
  _LOGGER.info(" + working as intended")
739
739
  except pw_exceptions.PlugwiseError:
@@ -763,7 +763,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
763
763
  for state in states:
764
764
  _LOGGER.info("- Adjusting schedule to state %s", state)
765
765
  try:
766
- await smile.set_schedule_state(None, state)
766
+ await smile.set_select("select_schedule", "dummy", state)
767
767
  tinker_schedule_passed = True
768
768
  _LOGGER.info(" + working as intended")
769
769
  except pw_exceptions.PlugwiseError:
@@ -847,7 +847,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
847
847
  mode = mode[1:]
848
848
  _LOGGER.info("%s", f"- Adjusting dhw mode to {mode}{warning}")
849
849
  try:
850
- await smile.set_dhw_mode(mode)
850
+ await smile.set_select("select_dhw_mode", "dummy", mode)
851
851
  _LOGGER.info(" + tinker_dhw_mode worked as intended")
852
852
  except pw_exceptions.PlugwiseError:
853
853
  _LOGGER.info(" + tinker_dhw_mode found invalid mode, as expected")
@@ -862,7 +862,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
862
862
  mode = mode[1:]
863
863
  _LOGGER.info("%s", f"- Adjusting regulation mode to {mode}{warning}")
864
864
  try:
865
- await smile.set_regulation_mode(mode)
865
+ await smile.set_select("select_regulation_mode", "dummy", mode)
866
866
  _LOGGER.info(" + tinker_regulation_mode worked as intended")
867
867
  except pw_exceptions.PlugwiseError:
868
868
  _LOGGER.info(
@@ -904,7 +904,7 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
904
904
  mode = mode[1:]
905
905
  _LOGGER.info("%s", f"- Adjusting gateway mode to {mode}{warning}")
906
906
  try:
907
- await smile.set_gateway_mode(mode)
907
+ await smile.set_select("select_gateway_mode", "dummy", mode)
908
908
  _LOGGER.info(" + worked as intended")
909
909
  except pw_exceptions.PlugwiseError:
910
910
  _LOGGER.info(" + found invalid mode, as expected")
@@ -30,7 +30,7 @@ class TestPlugwiseAnna(TestPlugwise): # pylint: disable=attribute-defined-outsi
30
30
 
31
31
  await self.device_test(smile, "2020-03-22 00:00:01", testdata)
32
32
  assert smile.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00"
33
- assert self.device_items == 43
33
+ assert self.device_items == 41
34
34
 
35
35
  result = await self.tinker_legacy_thermostat(smile, schedule_on=False)
36
36
  assert result
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
File without changes