plugwise 1.7.4__tar.gz → 1.7.6__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.
- {plugwise-1.7.4 → plugwise-1.7.6}/PKG-INFO +2 -3
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/__init__.py +16 -3
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/constants.py +2 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/legacy/smile.py +31 -18
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/smile.py +52 -29
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise.egg-info/PKG-INFO +2 -3
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise.egg-info/SOURCES.txt +0 -1
- {plugwise-1.7.4 → plugwise-1.7.6}/pyproject.toml +4 -6
- plugwise-1.7.6/setup.cfg +4 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_adam.py +24 -3
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_init.py +23 -7
- plugwise-1.7.4/setup.cfg +0 -9
- {plugwise-1.7.4 → plugwise-1.7.6}/LICENSE +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/README.md +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/common.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/data.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/exceptions.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/helper.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/legacy/data.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/legacy/helper.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/py.typed +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/smilecomm.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise/util.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise.egg-info/dependency_links.txt +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise.egg-info/requires.txt +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/plugwise.egg-info/top_level.txt +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_anna.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_generic.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_legacy_anna.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_legacy_generic.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_legacy_p1.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_legacy_stretch.py +0 -0
- {plugwise-1.7.4 → plugwise-1.7.6}/tests/test_p1.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: plugwise
|
3
|
-
Version: 1.7.
|
3
|
+
Version: 1.7.6
|
4
4
|
Summary: Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3.
|
5
5
|
Author: Plugwise device owners
|
6
6
|
Maintainer: bouwew, CoMPaTech
|
@@ -11,10 +11,9 @@ Keywords: home,automation,plugwise,module
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
12
12
|
Classifier: Intended Audience :: Developers
|
13
13
|
Classifier: Operating System :: OS Independent
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
15
14
|
Classifier: Programming Language :: Python :: 3.13
|
16
15
|
Classifier: Topic :: Home Automation
|
17
|
-
Requires-Python: >=3.
|
16
|
+
Requires-Python: >=3.13
|
18
17
|
Description-Content-Type: text/markdown
|
19
18
|
License-File: LICENSE
|
20
19
|
Requires-Dist: aiohttp
|
@@ -15,6 +15,8 @@ from plugwise.constants import (
|
|
15
15
|
MODULES,
|
16
16
|
NONE,
|
17
17
|
SMILES,
|
18
|
+
STATE_OFF,
|
19
|
+
STATE_ON,
|
18
20
|
STATUS,
|
19
21
|
SYSTEM,
|
20
22
|
GwEntityData,
|
@@ -398,10 +400,21 @@ class Smile(SmileComm):
|
|
398
400
|
|
399
401
|
async def set_switch_state(
|
400
402
|
self, appl_id: str, members: list[str] | None, model: str, state: str
|
401
|
-
) ->
|
402
|
-
"""Set the given State of the relevant Switch.
|
403
|
+
) -> bool:
|
404
|
+
"""Set the given State of the relevant Switch.
|
405
|
+
|
406
|
+
Return the result:
|
407
|
+
- True when switched to state on,
|
408
|
+
- False when switched to state off,
|
409
|
+
- the unchanged state when the switch is for instance locked.
|
410
|
+
"""
|
411
|
+
if state not in (STATE_OFF, STATE_ON):
|
412
|
+
raise PlugwiseError("Invalid state supplied to set_switch_state")
|
413
|
+
|
403
414
|
try:
|
404
|
-
await self._smile_api.set_switch_state(
|
415
|
+
return await self._smile_api.set_switch_state(
|
416
|
+
appl_id, members, model, state
|
417
|
+
)
|
405
418
|
except ConnectionFailedError as exc:
|
406
419
|
raise ConnectionFailedError(
|
407
420
|
f"Failed to set switch state: {str(exc)}"
|
@@ -23,6 +23,8 @@ POWER_WATT: Final = "W"
|
|
23
23
|
PRESET_AWAY: Final = "away"
|
24
24
|
PRESSURE_BAR: Final = "bar"
|
25
25
|
SIGNAL_STRENGTH_DECIBELS_MILLIWATT: Final = "dBm"
|
26
|
+
STATE_OFF: Final = "off"
|
27
|
+
STATE_ON: Final = "on"
|
26
28
|
TEMP_CELSIUS: Final = "°C"
|
27
29
|
TEMP_KELVIN: Final = "°K"
|
28
30
|
TIME_MILLISECONDS: Final = "ms"
|
@@ -18,6 +18,8 @@ from plugwise.constants import (
|
|
18
18
|
OFF,
|
19
19
|
REQUIRE_APPLIANCES,
|
20
20
|
RULES,
|
21
|
+
STATE_OFF,
|
22
|
+
STATE_ON,
|
21
23
|
GwEntityData,
|
22
24
|
ThermoLoc,
|
23
25
|
)
|
@@ -195,7 +197,7 @@ class SmileLegacyAPI(SmileLegacyData):
|
|
195
197
|
Determined from - DOMAIN_OBJECTS.
|
196
198
|
Used in HA Core to set the hvac_mode: in practice switch between schedule on - off.
|
197
199
|
"""
|
198
|
-
if state not in (
|
200
|
+
if state not in (STATE_OFF, STATE_ON):
|
199
201
|
raise PlugwiseError("Plugwise: invalid schedule state.")
|
200
202
|
|
201
203
|
# Handle no schedule-name / Off-schedule provided
|
@@ -214,7 +216,7 @@ class SmileLegacyAPI(SmileLegacyData):
|
|
214
216
|
) # pragma: no cover
|
215
217
|
|
216
218
|
new_state = "false"
|
217
|
-
if state ==
|
219
|
+
if state == STATE_ON:
|
218
220
|
new_state = "true"
|
219
221
|
|
220
222
|
locator = f'.//*[@id="{schedule_rule_id}"]/template'
|
@@ -234,13 +236,16 @@ class SmileLegacyAPI(SmileLegacyData):
|
|
234
236
|
|
235
237
|
async def set_switch_state(
|
236
238
|
self, appl_id: str, members: list[str] | None, model: str, state: str
|
237
|
-
) ->
|
239
|
+
) -> bool:
|
238
240
|
"""Set the given state of the relevant switch.
|
239
241
|
|
240
242
|
For individual switches, sets the state directly.
|
241
243
|
For group switches, sets the state for each member in the group separately.
|
242
244
|
For switch-locks, sets the lock state using a different data format.
|
245
|
+
Return the requested state when succesful, the current state otherwise.
|
243
246
|
"""
|
247
|
+
current_state = self.gw_entities[appl_id]["switches"]["relay"]
|
248
|
+
requested_state = state == STATE_ON
|
244
249
|
switch = Munch()
|
245
250
|
switch.actuator = "actuator_functionalities"
|
246
251
|
switch.func_type = "relay_functionality"
|
@@ -250,7 +255,7 @@ class SmileLegacyAPI(SmileLegacyData):
|
|
250
255
|
|
251
256
|
# Handle switch-lock
|
252
257
|
if model == "lock":
|
253
|
-
state = "
|
258
|
+
state = "true" if state == STATE_ON else "false"
|
254
259
|
appliance = self._appliances.find(f'appliance[@id="{appl_id}"]')
|
255
260
|
appl_name = appliance.find("name").text
|
256
261
|
appl_type = appliance.find("type").text
|
@@ -269,37 +274,45 @@ class SmileLegacyAPI(SmileLegacyData):
|
|
269
274
|
"</appliances>"
|
270
275
|
)
|
271
276
|
await self.call_request(APPLIANCES, method="post", data=data)
|
272
|
-
return
|
277
|
+
return requested_state
|
273
278
|
|
274
279
|
# Handle group of switches
|
275
280
|
data = f"<{switch.func_type}><state>{state}</state></{switch.func_type}>"
|
276
281
|
if members is not None:
|
277
282
|
return await self._set_groupswitch_member_state(
|
278
|
-
data, members, state, switch
|
283
|
+
appl_id, data, members, state, switch
|
279
284
|
)
|
280
285
|
|
281
286
|
# Handle individual relay switches
|
282
287
|
uri = f"{APPLIANCES};id={appl_id}/relay"
|
283
|
-
if model == "relay":
|
284
|
-
locator = (
|
285
|
-
f'appliance[@id="{appl_id}"]/{switch.actuator}/{switch.func_type}/lock'
|
286
|
-
)
|
288
|
+
if model == "relay" and self.gw_entities[appl_id]["switches"]["lock"]:
|
287
289
|
# Don't bother switching a relay when the corresponding lock-state is true
|
288
|
-
|
289
|
-
raise PlugwiseError("Plugwise: the locked Relay was not switched.")
|
290
|
+
return current_state
|
290
291
|
|
291
292
|
await self.call_request(uri, method="put", data=data)
|
293
|
+
return requested_state
|
292
294
|
|
293
295
|
async def _set_groupswitch_member_state(
|
294
|
-
self, data: str, members: list[str], state: str, switch: Munch
|
295
|
-
) ->
|
296
|
+
self, appl_id: str, data: str, members: list[str], state: str, switch: Munch
|
297
|
+
) -> bool:
|
296
298
|
"""Helper-function for set_switch_state().
|
297
299
|
|
298
|
-
Set the
|
300
|
+
Set the requested state of the relevant switch within a group of switches.
|
301
|
+
Return the current group-state when none of the switches has changed its state, the requested state otherwise.
|
299
302
|
"""
|
303
|
+
current_state = self.gw_entities[appl_id]["switches"]["relay"]
|
304
|
+
requested_state = state == STATE_ON
|
305
|
+
switched = 0
|
300
306
|
for member in members:
|
301
|
-
|
302
|
-
|
307
|
+
if not self.gw_entities[member]["switches"]["lock"]:
|
308
|
+
uri = f"{APPLIANCES};id={member}/relay"
|
309
|
+
await self.call_request(uri, method="put", data=data)
|
310
|
+
switched += 1
|
311
|
+
|
312
|
+
if switched > 0:
|
313
|
+
return requested_state
|
314
|
+
|
315
|
+
return current_state # pragma: no cover
|
303
316
|
|
304
317
|
async def set_temperature(self, _: str, items: dict[str, float]) -> None:
|
305
318
|
"""Set the given Temperature on the relevant Thermostat."""
|
@@ -310,7 +323,7 @@ class SmileLegacyAPI(SmileLegacyData):
|
|
310
323
|
if setpoint is None:
|
311
324
|
raise PlugwiseError(
|
312
325
|
"Plugwise: failed setting temperature: no valid input provided"
|
313
|
-
) # pragma: no cover
|
326
|
+
) # pragma: no cover
|
314
327
|
|
315
328
|
temperature = str(setpoint)
|
316
329
|
data = (
|
@@ -7,7 +7,7 @@ from __future__ import annotations
|
|
7
7
|
|
8
8
|
from collections.abc import Awaitable, Callable
|
9
9
|
import datetime as dt
|
10
|
-
from typing import Any
|
10
|
+
from typing import Any, cast
|
11
11
|
|
12
12
|
from plugwise.constants import (
|
13
13
|
ADAM,
|
@@ -22,7 +22,10 @@ from plugwise.constants import (
|
|
22
22
|
NOTIFICATIONS,
|
23
23
|
OFF,
|
24
24
|
RULES,
|
25
|
+
STATE_OFF,
|
26
|
+
STATE_ON,
|
25
27
|
GwEntityData,
|
28
|
+
SwitchType,
|
26
29
|
ThermoLoc,
|
27
30
|
)
|
28
31
|
from plugwise.data import SmileData
|
@@ -309,12 +312,12 @@ class SmileAPI(SmileData):
|
|
309
312
|
Used in HA Core to set the hvac_mode: in practice switch between schedule on - off.
|
310
313
|
"""
|
311
314
|
# Input checking
|
312
|
-
if new_state not in (
|
315
|
+
if new_state not in (STATE_OFF, STATE_ON):
|
313
316
|
raise PlugwiseError("Plugwise: invalid schedule state.")
|
314
317
|
|
315
318
|
# Translate selection of Off-schedule-option to disabling the active schedule
|
316
319
|
if name == OFF:
|
317
|
-
new_state =
|
320
|
+
new_state = STATE_OFF
|
318
321
|
|
319
322
|
# Handle no schedule-name / Off-schedule provided
|
320
323
|
if name is None or name == OFF:
|
@@ -367,18 +370,27 @@ class SmileAPI(SmileData):
|
|
367
370
|
subject = f'<context><zone><location id="{loc_id}" /></zone></context>'
|
368
371
|
subject = etree.fromstring(subject)
|
369
372
|
|
370
|
-
if state ==
|
373
|
+
if state == STATE_OFF:
|
371
374
|
self._last_active[loc_id] = name
|
372
375
|
contexts.remove(subject)
|
373
|
-
if state ==
|
376
|
+
if state == STATE_ON:
|
374
377
|
contexts.append(subject)
|
375
378
|
|
376
379
|
return str(etree.tostring(contexts, encoding="unicode").rstrip())
|
377
380
|
|
378
381
|
async def set_switch_state(
|
379
382
|
self, appl_id: str, members: list[str] | None, model: str, state: str
|
380
|
-
) ->
|
381
|
-
"""Set the given
|
383
|
+
) -> bool:
|
384
|
+
"""Set the given state of the relevant Switch.
|
385
|
+
|
386
|
+
For individual switches, sets the state directly.
|
387
|
+
For group switches, sets the state for each member in the group separately.
|
388
|
+
For switch-locks, sets the lock state using a different data format.
|
389
|
+
Return the requested state when succesful, the current state otherwise.
|
390
|
+
"""
|
391
|
+
model_type = cast(SwitchType, model)
|
392
|
+
current_state = self.gw_entities[appl_id]["switches"][model_type]
|
393
|
+
requested_state = state == STATE_ON
|
382
394
|
switch = Munch()
|
383
395
|
switch.actuator = "actuator_functionalities"
|
384
396
|
switch.device = "relay"
|
@@ -396,10 +408,18 @@ class SmileAPI(SmileData):
|
|
396
408
|
|
397
409
|
if model == "lock":
|
398
410
|
switch.func = "lock"
|
399
|
-
state = "
|
411
|
+
state = "true" if state == STATE_ON else "false"
|
412
|
+
|
413
|
+
data = (
|
414
|
+
f"<{switch.func_type}>"
|
415
|
+
f"<{switch.func}>{state}</{switch.func}>"
|
416
|
+
f"</{switch.func_type}>"
|
417
|
+
)
|
400
418
|
|
401
419
|
if members is not None:
|
402
|
-
return await self._set_groupswitch_member_state(
|
420
|
+
return await self._set_groupswitch_member_state(
|
421
|
+
appl_id, data, members, state, switch
|
422
|
+
)
|
403
423
|
|
404
424
|
locator = f'appliance[@id="{appl_id}"]/{switch.actuator}/{switch.func_type}'
|
405
425
|
found = self._domain_objects.findall(locator)
|
@@ -412,39 +432,42 @@ class SmileAPI(SmileData):
|
|
412
432
|
else: # actuators with a single item like relay_functionality
|
413
433
|
switch_id = item.attrib["id"]
|
414
434
|
|
415
|
-
data = (
|
416
|
-
f"<{switch.func_type}>"
|
417
|
-
f"<{switch.func}>{state}</{switch.func}>"
|
418
|
-
f"</{switch.func_type}>"
|
419
|
-
)
|
420
435
|
uri = f"{APPLIANCES};id={appl_id}/{switch.device};id={switch_id}"
|
421
436
|
if model == "relay":
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
raise PlugwiseError("Plugwise: the locked Relay was not switched.")
|
437
|
+
lock_blocked = self.gw_entities[appl_id]["switches"].get("lock")
|
438
|
+
if lock_blocked or lock_blocked is None:
|
439
|
+
# Don't switch a relay when its corresponding lock-state is true or no
|
440
|
+
# lock is present. That means the relay can't be controlled by the user.
|
441
|
+
return current_state
|
428
442
|
|
429
443
|
await self.call_request(uri, method="put", data=data)
|
444
|
+
return requested_state
|
430
445
|
|
431
446
|
async def _set_groupswitch_member_state(
|
432
|
-
self, members: list[str], state: str, switch: Munch
|
433
|
-
) ->
|
447
|
+
self, appl_id: str, data: str, members: list[str], state: str, switch: Munch
|
448
|
+
) -> bool:
|
434
449
|
"""Helper-function for set_switch_state().
|
435
450
|
|
436
|
-
Set the
|
451
|
+
Set the requested state of the relevant switch within a group of switches.
|
452
|
+
Return the current group-state when none of the switches has changed its state, the requested state otherwise.
|
437
453
|
"""
|
454
|
+
current_state = self.gw_entities[appl_id]["switches"]["relay"]
|
455
|
+
requested_state = state == STATE_ON
|
456
|
+
switched = 0
|
438
457
|
for member in members:
|
439
458
|
locator = f'appliance[@id="{member}"]/{switch.actuator}/{switch.func_type}'
|
440
459
|
switch_id = self._domain_objects.find(locator).attrib["id"]
|
441
460
|
uri = f"{APPLIANCES};id={member}/{switch.device};id={switch_id}"
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
461
|
+
lock_blocked = self.gw_entities[member]["switches"].get("lock")
|
462
|
+
# Assume Plugs under Plugwise control are not part of a group
|
463
|
+
if lock_blocked is not None and not lock_blocked:
|
464
|
+
await self.call_request(uri, method="put", data=data)
|
465
|
+
switched += 1
|
466
|
+
|
467
|
+
if switched > 0:
|
468
|
+
return requested_state
|
469
|
+
|
470
|
+
return current_state
|
448
471
|
|
449
472
|
async def set_temperature(self, loc_id: str, items: dict[str, float]) -> None:
|
450
473
|
"""Set the given Temperature on the relevant Thermostat."""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: plugwise
|
3
|
-
Version: 1.7.
|
3
|
+
Version: 1.7.6
|
4
4
|
Summary: Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3.
|
5
5
|
Author: Plugwise device owners
|
6
6
|
Maintainer: bouwew, CoMPaTech
|
@@ -11,10 +11,9 @@ Keywords: home,automation,plugwise,module
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
12
12
|
Classifier: Intended Audience :: Developers
|
13
13
|
Classifier: Operating System :: OS Independent
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
15
14
|
Classifier: Programming Language :: Python :: 3.13
|
16
15
|
Classifier: Topic :: Home Automation
|
17
|
-
Requires-Python: >=3.
|
16
|
+
Requires-Python: >=3.13
|
18
17
|
Description-Content-Type: text/markdown
|
19
18
|
License-File: LICENSE
|
20
19
|
Requires-Dist: aiohttp
|
@@ -1,10 +1,10 @@
|
|
1
1
|
[build-system]
|
2
|
-
requires = ["setuptools~=
|
2
|
+
requires = ["setuptools~=80.0"]
|
3
3
|
build-backend = "setuptools.build_meta"
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "plugwise"
|
7
|
-
version = "1.7.
|
7
|
+
version = "1.7.6"
|
8
8
|
license = "MIT"
|
9
9
|
description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
|
10
10
|
readme = "README.md"
|
@@ -13,7 +13,6 @@ classifiers = [
|
|
13
13
|
"Development Status :: 5 - Production/Stable",
|
14
14
|
"Intended Audience :: Developers",
|
15
15
|
"Operating System :: OS Independent",
|
16
|
-
"Programming Language :: Python :: 3.12",
|
17
16
|
"Programming Language :: Python :: 3.13",
|
18
17
|
"Topic :: Home Automation",
|
19
18
|
]
|
@@ -24,7 +23,7 @@ maintainers = [
|
|
24
23
|
{ name = "bouwew"},
|
25
24
|
{ name = "CoMPaTech" }
|
26
25
|
]
|
27
|
-
requires-python = ">=3.
|
26
|
+
requires-python = ">=3.13"
|
28
27
|
dependencies = [
|
29
28
|
"aiohttp",
|
30
29
|
"defusedxml",
|
@@ -52,7 +51,7 @@ include = ["plugwise*"]
|
|
52
51
|
# 20241208: W0201 / attribute-defined-outside-init
|
53
52
|
# 20241208: R1702 / too-many-nested-blocks # too many nested blocks in test_init 8/5
|
54
53
|
# 20241208: R6102 / consider-using-tuple
|
55
|
-
# 20241208: Recommended disabling => "implicit-str-concat", # ISC001 - 2
|
54
|
+
# 20241208: Recommended disabling => "implicit-str-concat", # ISC001 - 2 occurrences!
|
56
55
|
##
|
57
56
|
|
58
57
|
[tool.pylint.MAIN]
|
@@ -466,7 +465,6 @@ lint.select = [
|
|
466
465
|
"S317", # suspicious-xml-sax-usage
|
467
466
|
"S318", # suspicious-xml-mini-dom-usage
|
468
467
|
"S319", # suspicious-xml-pull-dom-usage
|
469
|
-
"S320", # suspicious-xmle-tree-usage
|
470
468
|
"S601", # paramiko-call
|
471
469
|
"S602", # subprocess-popen-with-shell-equals-true
|
472
470
|
"S604", # call-with-shell-equals-true
|
plugwise-1.7.6/setup.cfg
ADDED
@@ -106,14 +106,27 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
106
106
|
smile, "056ee145a816487eaa69243c3280f8bf", model="dhw_cm_switch"
|
107
107
|
)
|
108
108
|
assert switch_change
|
109
|
+
# Test relay without lock-attribute
|
109
110
|
switch_change = await self.tinker_switch(
|
110
|
-
smile,
|
111
|
+
smile,
|
112
|
+
"854f8a9b0e7e425db97f1f110e1ce4b3",
|
111
113
|
)
|
112
|
-
assert switch_change
|
114
|
+
assert not switch_change
|
113
115
|
switch_change = await self.tinker_switch(
|
114
116
|
smile, "2568cc4b9c1e401495d4741a5f89bee1"
|
115
117
|
)
|
116
118
|
assert not switch_change
|
119
|
+
switch_change = await self.tinker_switch(
|
120
|
+
smile,
|
121
|
+
"2568cc4b9c1e401495d4741a5f89bee1",
|
122
|
+
model="lock",
|
123
|
+
)
|
124
|
+
assert switch_change
|
125
|
+
|
126
|
+
assert await self.tinker_switch_bad_input(
|
127
|
+
smile,
|
128
|
+
"854f8a9b0e7e425db97f1f110e1ce4b3",
|
129
|
+
)
|
117
130
|
|
118
131
|
tinkered = await self.tinker_gateway_mode(smile)
|
119
132
|
assert not tinkered
|
@@ -288,7 +301,7 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
288
301
|
assert smile._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE
|
289
302
|
assert smile._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA
|
290
303
|
assert smile._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA
|
291
|
-
assert self.entity_items ==
|
304
|
+
assert self.entity_items == 375
|
292
305
|
|
293
306
|
assert "af82e4ccf9c548528166d38e560662a4" in self.notifications
|
294
307
|
|
@@ -304,6 +317,14 @@ class TestPlugwiseAdam(TestPlugwise): # pylint: disable=attribute-defined-outsi
|
|
304
317
|
smile, "675416a629f343c495449970e2ca37b5"
|
305
318
|
)
|
306
319
|
assert not switch_change
|
320
|
+
# Test a blocked group-change, both relays are locked.
|
321
|
+
group_change = await self.tinker_switch(
|
322
|
+
smile,
|
323
|
+
"e8ef2a01ed3b4139a53bf749204fe6b4",
|
324
|
+
["02cf28bfec924855854c544690a609ef", "4a810418d5394b3f82727340b91ba740"],
|
325
|
+
)
|
326
|
+
assert not group_change
|
327
|
+
|
307
328
|
await smile.close_connection()
|
308
329
|
await self.disconnect(server, client)
|
309
330
|
|
@@ -684,16 +684,18 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
|
|
684
684
|
"""Turn a Switch on and off to test functionality."""
|
685
685
|
_LOGGER.info("Asserting modifying settings for switch devices:")
|
686
686
|
_LOGGER.info("- Devices (%s):", dev_id)
|
687
|
+
convert = {"on": True, "off": False}
|
687
688
|
tinker_switch_passed = False
|
688
|
-
for new_state in ["
|
689
|
+
for new_state in ["off", "on", "off"]:
|
689
690
|
_LOGGER.info("- Switching %s", new_state)
|
690
691
|
try:
|
691
|
-
await smile.set_switch_state(dev_id, members, model, new_state)
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
692
|
+
result = await smile.set_switch_state(dev_id, members, model, new_state)
|
693
|
+
if result == convert[new_state]:
|
694
|
+
tinker_switch_passed = True
|
695
|
+
_LOGGER.info(" + tinker_switch worked as intended")
|
696
|
+
else:
|
697
|
+
_LOGGER.info(" + tinker_switch failed unexpectedly")
|
698
|
+
return False
|
697
699
|
except (
|
698
700
|
pw_exceptions.ConnectionFailedError
|
699
701
|
): # leave for-loop at connect-error
|
@@ -706,6 +708,20 @@ class TestPlugwise: # pylint: disable=attribute-defined-outside-init
|
|
706
708
|
|
707
709
|
return tinker_switch_passed
|
708
710
|
|
711
|
+
@pytest.mark.asyncio
|
712
|
+
async def tinker_switch_bad_input(
|
713
|
+
self, smile, dev_id=None, members=None, model="relay", unhappy=False
|
714
|
+
):
|
715
|
+
"""Enter a wrong state as input to toggle a Switch."""
|
716
|
+
_LOGGER.info("Test entering bad input set_switch_state:")
|
717
|
+
_LOGGER.info("- Devices (%s):", dev_id)
|
718
|
+
new_state = "false"
|
719
|
+
try:
|
720
|
+
await smile.set_switch_state(dev_id, members, model, new_state)
|
721
|
+
except pw_exceptions.PlugwiseError:
|
722
|
+
_LOGGER.info(" + failed input-check as expected")
|
723
|
+
return True # test is pass!
|
724
|
+
|
709
725
|
@pytest.mark.asyncio
|
710
726
|
async def tinker_thermostat_temp(
|
711
727
|
self, smile, loc_id, block_cooling=False, fail_cooling=False, unhappy=False
|
plugwise-1.7.4/setup.cfg
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
[codespell]
|
2
|
-
ignore-words-list = additionals,alle,alot,ba,bre,bund,currenty,datas,dof,dur,ether,farenheit,falsy,fo,haa,hass,hist,iam,iff,iif,incomfort,ines,ist,leeg,lightsensor,mut,nam,nd,pres,pullrequests,referer,resset,rime,ser,serie,sur,te,technik,ue,uint,unsecure,visability,wan,wanna,withing,zar
|
3
|
-
skip = ./.*,*.csv,*.json
|
4
|
-
quiet-level = 2
|
5
|
-
|
6
|
-
[egg_info]
|
7
|
-
tag_build =
|
8
|
-
tag_date = 0
|
9
|
-
|
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
|
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
|
File without changes
|