plugwise 0.37.4.1__py3-none-any.whl → 0.37.6__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/__init__.py +10 -5
- plugwise/constants.py +2 -2
- plugwise/data.py +1 -1
- plugwise/helper.py +9 -31
- plugwise/legacy/data.py +2 -2
- plugwise/legacy/helper.py +18 -39
- plugwise/legacy/smile.py +16 -7
- plugwise/smile.py +24 -18
- plugwise/util.py +38 -1
- {plugwise-0.37.4.1.dist-info → plugwise-0.37.6.dist-info}/METADATA +1 -1
- plugwise-0.37.6.dist-info/RECORD +17 -0
- plugwise-0.37.4.1.dist-info/RECORD +0 -17
- {plugwise-0.37.4.1.dist-info → plugwise-0.37.6.dist-info}/LICENSE +0 -0
- {plugwise-0.37.4.1.dist-info → plugwise-0.37.6.dist-info}/WHEEL +0 -0
- {plugwise-0.37.4.1.dist-info → plugwise-0.37.6.dist-info}/top_level.txt +0 -0
plugwise/__init__.py
CHANGED
@@ -323,13 +323,18 @@ class Smile(SmileComm):
|
|
323
323
|
"""Set the given Temperature on the relevant Thermostat."""
|
324
324
|
await self._smile_api.set_temperature(loc_id, items)
|
325
325
|
|
326
|
-
async def
|
327
|
-
|
328
|
-
|
326
|
+
async def set_number(
|
327
|
+
self,
|
328
|
+
dev_id: str,
|
329
|
+
key: str,
|
330
|
+
temperature: float,
|
331
|
+
) -> None:
|
332
|
+
"""Set the maximum boiler- or DHW-setpoint on the Central Heating boiler or the temperature-offset on a Thermostat."""
|
333
|
+
await self._smile_api.set_number(dev_id, key, temperature)
|
329
334
|
|
330
|
-
async def set_temperature_offset(self,
|
335
|
+
async def set_temperature_offset(self, dev_id: str, offset: float) -> None:
|
331
336
|
"""Set the Temperature offset for thermostats that support this feature."""
|
332
|
-
await self._smile_api.
|
337
|
+
await self._smile_api.set_offset(dev_id, offset) # pragma: no cover
|
333
338
|
|
334
339
|
async def set_switch_state(
|
335
340
|
self, appl_id: str, members: list[str] | None, model: str, state: str
|
plugwise/constants.py
CHANGED
@@ -207,13 +207,13 @@ SMILES: Final[dict[str, SMILE]] = {
|
|
207
207
|
"stretch_v2": SMILE(STRETCH, "Stretch"),
|
208
208
|
"stretch_v3": SMILE(STRETCH, "Stretch"),
|
209
209
|
}
|
210
|
-
REQUIRE_APPLIANCES: Final[
|
210
|
+
REQUIRE_APPLIANCES: Final[tuple[str, ...]] = (
|
211
211
|
"smile_thermo_v1",
|
212
212
|
"smile_thermo_v3",
|
213
213
|
"smile_thermo_v4",
|
214
214
|
"stretch_v2",
|
215
215
|
"stretch_v3",
|
216
|
-
|
216
|
+
)
|
217
217
|
|
218
218
|
# Class, Literal and related tuple-definitions
|
219
219
|
|
plugwise/data.py
CHANGED
@@ -204,7 +204,7 @@ class SmileData(SmileHelper):
|
|
204
204
|
# Operation modes: auto, heat, heat_cool, cool and off
|
205
205
|
data["mode"] = "auto"
|
206
206
|
self._count += 1
|
207
|
-
if sel_schedule
|
207
|
+
if sel_schedule in (NONE, OFF):
|
208
208
|
data["mode"] = "heat"
|
209
209
|
if self._cooling_present:
|
210
210
|
data["mode"] = "cool" if self.check_reg_mode("cooling") else "heat_cool"
|
plugwise/helper.py
CHANGED
@@ -15,8 +15,6 @@ from plugwise.constants import (
|
|
15
15
|
ADAM,
|
16
16
|
ANNA,
|
17
17
|
ATTR_NAME,
|
18
|
-
ATTR_UNIT_OF_MEASUREMENT,
|
19
|
-
BINARY_SENSORS,
|
20
18
|
DATA,
|
21
19
|
DEVICE_MEASUREMENTS,
|
22
20
|
DHW_SETPOINT,
|
@@ -29,9 +27,6 @@ from plugwise.constants import (
|
|
29
27
|
NONE,
|
30
28
|
OFF,
|
31
29
|
P1_MEASUREMENTS,
|
32
|
-
SENSORS,
|
33
|
-
SPECIALS,
|
34
|
-
SWITCHES,
|
35
30
|
TEMP_CELSIUS,
|
36
31
|
THERMOSTAT_CLASSES,
|
37
32
|
TOGGLES,
|
@@ -39,12 +34,9 @@ from plugwise.constants import (
|
|
39
34
|
ActuatorData,
|
40
35
|
ActuatorDataType,
|
41
36
|
ActuatorType,
|
42
|
-
BinarySensorType,
|
43
37
|
DeviceData,
|
44
38
|
GatewayData,
|
45
39
|
SensorType,
|
46
|
-
SpecialType,
|
47
|
-
SwitchType,
|
48
40
|
ThermoLoc,
|
49
41
|
ToggleNameType,
|
50
42
|
)
|
@@ -56,6 +48,7 @@ from plugwise.exceptions import (
|
|
56
48
|
)
|
57
49
|
from plugwise.util import (
|
58
50
|
check_model,
|
51
|
+
common_match_cases,
|
59
52
|
escape_illegal_xml_characters,
|
60
53
|
format_measure,
|
61
54
|
skip_obsolete_measurements,
|
@@ -214,7 +207,7 @@ class SmileHelper(SmileCommon):
|
|
214
207
|
self._thermo_locs: dict[str, ThermoLoc] = {}
|
215
208
|
###################################################################
|
216
209
|
# '_cooling_enabled' can refer to the state of the Elga heatpump
|
217
|
-
# connected to an Anna. For Elga, 'elga_status_code' in
|
210
|
+
# connected to an Anna. For Elga, 'elga_status_code' in (8, 9)
|
218
211
|
# means cooling mode is available, next to heating mode.
|
219
212
|
# 'elga_status_code' = 8 means cooling is active, 9 means idle.
|
220
213
|
#
|
@@ -523,7 +516,7 @@ class SmileHelper(SmileCommon):
|
|
523
516
|
# Techneco Elga has cooling-capability
|
524
517
|
self._cooling_present = True
|
525
518
|
data["model"] = "Generic heater/cooler"
|
526
|
-
self._cooling_enabled = data["elga_status_code"] in
|
519
|
+
self._cooling_enabled = data["elga_status_code"] in (8, 9)
|
527
520
|
data["binary_sensors"]["cooling_state"] = self._cooling_active = (
|
528
521
|
data["elga_status_code"] == 8
|
529
522
|
)
|
@@ -585,29 +578,12 @@ class SmileHelper(SmileCommon):
|
|
585
578
|
measurement = new_name
|
586
579
|
|
587
580
|
match measurement:
|
588
|
-
# measurements with states "on" or "off" that need to be passed directly
|
589
|
-
case "select_dhw_mode":
|
590
|
-
data["select_dhw_mode"] = appl_p_loc.text
|
591
|
-
case _ as measurement if measurement in BINARY_SENSORS:
|
592
|
-
bs_key = cast(BinarySensorType, measurement)
|
593
|
-
bs_value = appl_p_loc.text in ["on", "true"]
|
594
|
-
data["binary_sensors"][bs_key] = bs_value
|
595
|
-
case _ as measurement if measurement in SENSORS:
|
596
|
-
s_key = cast(SensorType, measurement)
|
597
|
-
s_value = format_measure(
|
598
|
-
appl_p_loc.text, getattr(attrs, ATTR_UNIT_OF_MEASUREMENT)
|
599
|
-
)
|
600
|
-
data["sensors"][s_key] = s_value
|
601
|
-
case _ as measurement if measurement in SWITCHES:
|
602
|
-
sw_key = cast(SwitchType, measurement)
|
603
|
-
sw_value = appl_p_loc.text in ["on", "true"]
|
604
|
-
data["switches"][sw_key] = sw_value
|
605
|
-
case _ as measurement if measurement in SPECIALS:
|
606
|
-
sp_key = cast(SpecialType, measurement)
|
607
|
-
sp_value = appl_p_loc.text in ["on", "true"]
|
608
|
-
data[sp_key] = sp_value
|
609
581
|
case "elga_status_code":
|
610
582
|
data["elga_status_code"] = int(appl_p_loc.text)
|
583
|
+
case "select_dhw_mode":
|
584
|
+
data["select_dhw_mode"] = appl_p_loc.text
|
585
|
+
|
586
|
+
common_match_cases(measurement, attrs, appl_p_loc, data)
|
611
587
|
|
612
588
|
i_locator = f'.//logs/interval_log[type="{measurement}"]/period/measurement'
|
613
589
|
if (appl_i_loc := appliance.find(i_locator)) is not None:
|
@@ -1014,6 +990,8 @@ class SmileHelper(SmileCommon):
|
|
1014
990
|
if schedules:
|
1015
991
|
available.remove(NONE)
|
1016
992
|
available.append(OFF)
|
993
|
+
if selected == NONE:
|
994
|
+
selected = OFF
|
1017
995
|
if self._last_active.get(location) is None:
|
1018
996
|
self._last_active[location] = self._last_used_schedule(schedules)
|
1019
997
|
|
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, DeviceData
|
9
|
+
from plugwise.constants import NONE, OFF, DeviceData
|
10
10
|
from plugwise.legacy.helper import SmileLegacyHelper
|
11
11
|
from plugwise.util import remove_empty_platform_dicts
|
12
12
|
|
@@ -88,5 +88,5 @@ class SmileLegacyData(SmileLegacyHelper):
|
|
88
88
|
# Operation modes: auto, heat
|
89
89
|
data["mode"] = "auto"
|
90
90
|
self._count += 1
|
91
|
-
if sel_schedule
|
91
|
+
if sel_schedule in (NONE, OFF):
|
92
92
|
data["mode"] = "heat"
|
plugwise/legacy/helper.py
CHANGED
@@ -12,8 +12,6 @@ from plugwise.constants import (
|
|
12
12
|
ACTUATOR_CLASSES,
|
13
13
|
APPLIANCES,
|
14
14
|
ATTR_NAME,
|
15
|
-
ATTR_UNIT_OF_MEASUREMENT,
|
16
|
-
BINARY_SENSORS,
|
17
15
|
DATA,
|
18
16
|
DEVICE_MEASUREMENTS,
|
19
17
|
ENERGY_WATT_HOUR,
|
@@ -22,10 +20,8 @@ from plugwise.constants import (
|
|
22
20
|
HEATER_CENTRAL_MEASUREMENTS,
|
23
21
|
LIMITS,
|
24
22
|
NONE,
|
23
|
+
OFF,
|
25
24
|
P1_LEGACY_MEASUREMENTS,
|
26
|
-
SENSORS,
|
27
|
-
SPECIALS,
|
28
|
-
SWITCHES,
|
29
25
|
TEMP_CELSIUS,
|
30
26
|
THERMOSTAT_CLASSES,
|
31
27
|
UOM,
|
@@ -33,15 +29,17 @@ from plugwise.constants import (
|
|
33
29
|
ActuatorDataType,
|
34
30
|
ActuatorType,
|
35
31
|
ApplianceType,
|
36
|
-
BinarySensorType,
|
37
32
|
DeviceData,
|
38
33
|
GatewayData,
|
39
34
|
SensorType,
|
40
|
-
SpecialType,
|
41
|
-
SwitchType,
|
42
35
|
ThermoLoc,
|
43
36
|
)
|
44
|
-
from plugwise.util import
|
37
|
+
from plugwise.util import (
|
38
|
+
common_match_cases,
|
39
|
+
format_measure,
|
40
|
+
skip_obsolete_measurements,
|
41
|
+
version_to_model,
|
42
|
+
)
|
45
43
|
|
46
44
|
# This way of importing aiohttp is because of patch/mocking in testing (aiohttp timeouts)
|
47
45
|
from defusedxml import ElementTree as etree
|
@@ -340,25 +338,7 @@ class SmileLegacyHelper(SmileCommon):
|
|
340
338
|
if new_name := getattr(attrs, ATTR_NAME, None):
|
341
339
|
measurement = new_name
|
342
340
|
|
343
|
-
|
344
|
-
case _ as measurement if measurement in BINARY_SENSORS:
|
345
|
-
bs_key = cast(BinarySensorType, measurement)
|
346
|
-
bs_value = appl_p_loc.text in ["on", "true"]
|
347
|
-
data["binary_sensors"][bs_key] = bs_value
|
348
|
-
case _ as measurement if measurement in SENSORS:
|
349
|
-
s_key = cast(SensorType, measurement)
|
350
|
-
s_value = format_measure(
|
351
|
-
appl_p_loc.text, getattr(attrs, ATTR_UNIT_OF_MEASUREMENT)
|
352
|
-
)
|
353
|
-
data["sensors"][s_key] = s_value
|
354
|
-
case _ as measurement if measurement in SWITCHES:
|
355
|
-
sw_key = cast(SwitchType, measurement)
|
356
|
-
sw_value = appl_p_loc.text in ["on", "true"]
|
357
|
-
data["switches"][sw_key] = sw_value
|
358
|
-
case _ as measurement if measurement in SPECIALS:
|
359
|
-
sp_key = cast(SpecialType, measurement)
|
360
|
-
sp_value = appl_p_loc.text in ["on", "true"]
|
361
|
-
data[sp_key] = sp_value
|
341
|
+
common_match_cases(measurement, attrs, appl_p_loc, data)
|
362
342
|
|
363
343
|
i_locator = f'.//logs/interval_log[type="{measurement}"]/period/measurement'
|
364
344
|
if (appl_i_loc := appliance.find(i_locator)) is not None:
|
@@ -450,16 +430,15 @@ class SmileLegacyHelper(SmileCommon):
|
|
450
430
|
return presets
|
451
431
|
|
452
432
|
def _schedules(self) -> tuple[list[str], str]:
|
453
|
-
"""Collect
|
433
|
+
"""Collect the schedule for the legacy thermostat."""
|
454
434
|
available: list[str] = [NONE]
|
455
|
-
selected = NONE
|
435
|
+
rule_id = selected = NONE
|
456
436
|
name: str | None = None
|
457
437
|
|
458
438
|
search = self._domain_objects
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
name = rule_name
|
439
|
+
if (result := search.find("./rule[name='Thermostat schedule']")) is not None:
|
440
|
+
name = "Thermostat schedule"
|
441
|
+
rule_id = result.attrib["id"]
|
463
442
|
|
464
443
|
log_type = "schedule_state"
|
465
444
|
locator = f"./appliance[type='thermostat']/logs/point_log[type='{log_type}']/period/measurement"
|
@@ -467,10 +446,11 @@ class SmileLegacyHelper(SmileCommon):
|
|
467
446
|
if (result := search.find(locator)) is not None:
|
468
447
|
active = result.text == "on"
|
469
448
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
449
|
+
# Show an empty schedule as no schedule found
|
450
|
+
directives = search.find(f'./rule[@id="{rule_id}"]/directives/when/then') is not None
|
451
|
+
if directives and name is not None:
|
452
|
+
available = [name, OFF]
|
453
|
+
selected = name if active else OFF
|
474
454
|
|
475
455
|
return available, selected
|
476
456
|
|
@@ -478,5 +458,4 @@ class SmileLegacyHelper(SmileCommon):
|
|
478
458
|
"""Determine the location-set_temperature uri - from APPLIANCES."""
|
479
459
|
locator = "./appliance[type='thermostat']"
|
480
460
|
appliance_id = self._appliances.find(locator).attrib["id"]
|
481
|
-
|
482
461
|
return f"{APPLIANCES};id={appliance_id}/thermostat"
|
plugwise/legacy/smile.py
CHANGED
@@ -15,6 +15,7 @@ from plugwise.constants import (
|
|
15
15
|
LOCATIONS,
|
16
16
|
LOGGER,
|
17
17
|
MODULES,
|
18
|
+
OFF,
|
18
19
|
REQUIRE_APPLIANCES,
|
19
20
|
RULES,
|
20
21
|
DeviceData,
|
@@ -154,7 +155,15 @@ class SmileLegacyAPI(SmileComm, SmileLegacyData):
|
|
154
155
|
async def set_gateway_mode(self, mode: str) -> None:
|
155
156
|
"""Set-function placeholder for legacy devices."""
|
156
157
|
|
157
|
-
async def
|
158
|
+
async def set_number(
|
159
|
+
self,
|
160
|
+
dev_id: str,
|
161
|
+
key: str,
|
162
|
+
temperature: float,
|
163
|
+
) -> None:
|
164
|
+
"""Set-function placeholder for legacy devices."""
|
165
|
+
|
166
|
+
async def set_offset(self, dev_id: str, offset: float) -> None:
|
158
167
|
"""Set-function placeholder for legacy devices."""
|
159
168
|
|
160
169
|
async def set_preset(self, _: str, preset: str) -> None:
|
@@ -173,16 +182,19 @@ class SmileLegacyAPI(SmileComm, SmileLegacyData):
|
|
173
182
|
async def set_regulation_mode(self, mode: str) -> None:
|
174
183
|
"""Set-function placeholder for legacy devices."""
|
175
184
|
|
176
|
-
async def set_schedule_state(self, _: str, state: str,
|
185
|
+
async def set_schedule_state(self, _: str, state: str, name: str | None) -> None:
|
177
186
|
"""Activate/deactivate the Schedule.
|
178
187
|
|
179
188
|
Determined from - DOMAIN_OBJECTS.
|
180
189
|
Used in HA Core to set the hvac_mode: in practice switch between schedule on - off.
|
181
190
|
"""
|
182
|
-
if state not in
|
191
|
+
if state not in ("on", "off"):
|
183
192
|
raise PlugwiseError("Plugwise: invalid schedule state.")
|
184
193
|
|
185
|
-
name
|
194
|
+
# Handle no schedule-name / Off-schedule provided
|
195
|
+
if name is None or name == OFF:
|
196
|
+
name = "Thermostat schedule"
|
197
|
+
|
186
198
|
schedule_rule_id: str | None = None
|
187
199
|
for rule in self._domain_objects.findall("rule"):
|
188
200
|
if rule.find("name").text == name:
|
@@ -268,6 +280,3 @@ class SmileLegacyAPI(SmileComm, SmileLegacyData):
|
|
268
280
|
)
|
269
281
|
|
270
282
|
await self._request(uri, method="put", data=data)
|
271
|
-
|
272
|
-
async def set_temperature_offset(self, dev_id: str, offset: float) -> None:
|
273
|
-
"""Set-function placeholder for legacy devices."""
|
plugwise/smile.py
CHANGED
@@ -182,10 +182,16 @@ class SmileAPI(SmileComm, SmileData):
|
|
182
182
|
|
183
183
|
await self._request(uri, method="put", data=data)
|
184
184
|
|
185
|
-
async def
|
186
|
-
|
187
|
-
|
188
|
-
|
185
|
+
async def set_number(
|
186
|
+
self,
|
187
|
+
dev_id: str,
|
188
|
+
key: str,
|
189
|
+
temperature: float,
|
190
|
+
) -> None:
|
191
|
+
"""Set the maximum boiler- or DHW-setpoint on the Central Heating boiler or the temperature-offset on a Thermostat."""
|
192
|
+
if key == "temperature_offset":
|
193
|
+
await self.set_offset(dev_id, temperature)
|
194
|
+
return
|
189
195
|
|
190
196
|
temp = str(temperature)
|
191
197
|
thermostat_id: str | None = None
|
@@ -202,6 +208,19 @@ class SmileAPI(SmileComm, SmileData):
|
|
202
208
|
data = f"<thermostat_functionality><setpoint>{temp}</setpoint></thermostat_functionality>"
|
203
209
|
await self._request(uri, method="put", data=data)
|
204
210
|
|
211
|
+
async def set_offset(self, dev_id: str, offset: float) -> None:
|
212
|
+
"""Set the Temperature offset for thermostats that support this feature."""
|
213
|
+
if dev_id not in self.therms_with_offset_func:
|
214
|
+
raise PlugwiseError(
|
215
|
+
"Plugwise: this device does not have temperature-offset capability."
|
216
|
+
)
|
217
|
+
|
218
|
+
value = str(offset)
|
219
|
+
uri = f"{APPLIANCES};id={dev_id}/offset;type=temperature_offset"
|
220
|
+
data = f"<offset_functionality><offset>{value}</offset></offset_functionality>"
|
221
|
+
|
222
|
+
await self._request(uri, method="put", data=data)
|
223
|
+
|
205
224
|
async def set_preset(self, loc_id: str, preset: str) -> None:
|
206
225
|
"""Set the given Preset on the relevant Thermostat - from LOCATIONS."""
|
207
226
|
if (presets := self._presets(loc_id)) is None:
|
@@ -247,7 +266,7 @@ class SmileAPI(SmileComm, SmileData):
|
|
247
266
|
Used in HA Core to set the hvac_mode: in practice switch between schedule on - off.
|
248
267
|
"""
|
249
268
|
# Input checking
|
250
|
-
if new_state not in
|
269
|
+
if new_state not in ("on", "off"):
|
251
270
|
raise PlugwiseError("Plugwise: invalid schedule state.")
|
252
271
|
|
253
272
|
# Translate selection of Off-schedule-option to disabling the active schedule
|
@@ -413,16 +432,3 @@ class SmileAPI(SmileComm, SmileData):
|
|
413
432
|
)
|
414
433
|
|
415
434
|
await self._request(uri, method="put", data=data)
|
416
|
-
|
417
|
-
async def set_temperature_offset(self, dev_id: str, offset: float) -> None:
|
418
|
-
"""Set the Temperature offset for thermostats that support this feature."""
|
419
|
-
if dev_id not in self.therms_with_offset_func:
|
420
|
-
raise PlugwiseError(
|
421
|
-
"Plugwise: this device does not have temperature-offset capability."
|
422
|
-
)
|
423
|
-
|
424
|
-
value = str(offset)
|
425
|
-
uri = f"{APPLIANCES};id={dev_id}/offset;type=temperature_offset"
|
426
|
-
data = f"<offset_functionality><offset>{value}</offset></offset_functionality>"
|
427
|
-
|
428
|
-
await self._request(uri, method="put", data=data)
|
plugwise/util.py
CHANGED
@@ -3,19 +3,30 @@ from __future__ import annotations
|
|
3
3
|
|
4
4
|
import datetime as dt
|
5
5
|
import re
|
6
|
+
from typing import cast
|
6
7
|
|
7
8
|
from plugwise.constants import (
|
8
9
|
ATTR_UNIT_OF_MEASUREMENT,
|
10
|
+
BINARY_SENSORS,
|
11
|
+
DATA,
|
9
12
|
ELECTRIC_POTENTIAL_VOLT,
|
10
13
|
ENERGY_KILO_WATT_HOUR,
|
11
14
|
HW_MODELS,
|
12
15
|
OBSOLETE_MEASUREMENTS,
|
13
16
|
PERCENTAGE,
|
14
17
|
POWER_WATT,
|
18
|
+
SENSORS,
|
15
19
|
SPECIAL_FORMAT,
|
20
|
+
SPECIALS,
|
21
|
+
SWITCHES,
|
16
22
|
TEMP_CELSIUS,
|
23
|
+
UOM,
|
24
|
+
BinarySensorType,
|
17
25
|
DeviceData,
|
18
26
|
ModelData,
|
27
|
+
SensorType,
|
28
|
+
SpecialType,
|
29
|
+
SwitchType,
|
19
30
|
)
|
20
31
|
|
21
32
|
from defusedxml import ElementTree as etree
|
@@ -23,7 +34,7 @@ from munch import Munch
|
|
23
34
|
|
24
35
|
|
25
36
|
def check_alternative_location(loc: Munch, legacy: bool) -> Munch:
|
26
|
-
"""
|
37
|
+
"""Helper-function for _power_data_peak_value()."""
|
27
38
|
if in_alternative_location(loc, legacy):
|
28
39
|
# Avoid double processing by skipping one peak-list option
|
29
40
|
if loc.peak_select == "nl_offpeak":
|
@@ -102,6 +113,32 @@ def check_model(name: str | None, vendor_name: str | None) -> str | None:
|
|
102
113
|
return name
|
103
114
|
|
104
115
|
|
116
|
+
def common_match_cases(
|
117
|
+
measurement: str,
|
118
|
+
attrs: DATA | UOM,
|
119
|
+
location: etree,
|
120
|
+
data: DeviceData,
|
121
|
+
) -> None:
|
122
|
+
"""Helper-function for common match-case execution."""
|
123
|
+
value = location.text in ("on", "true")
|
124
|
+
match measurement:
|
125
|
+
case _ as measurement if measurement in BINARY_SENSORS:
|
126
|
+
bs_key = cast(BinarySensorType, measurement)
|
127
|
+
data["binary_sensors"][bs_key] = value
|
128
|
+
case _ as measurement if measurement in SENSORS:
|
129
|
+
s_key = cast(SensorType, measurement)
|
130
|
+
s_value = format_measure(
|
131
|
+
location.text, getattr(attrs, ATTR_UNIT_OF_MEASUREMENT)
|
132
|
+
)
|
133
|
+
data["sensors"][s_key] = s_value
|
134
|
+
case _ as measurement if measurement in SWITCHES:
|
135
|
+
sw_key = cast(SwitchType, measurement)
|
136
|
+
data["switches"][sw_key] = value
|
137
|
+
case _ as measurement if measurement in SPECIALS:
|
138
|
+
sp_key = cast(SpecialType, measurement)
|
139
|
+
data[sp_key] = value
|
140
|
+
|
141
|
+
|
105
142
|
def escape_illegal_xml_characters(xmldata: str) -> str:
|
106
143
|
"""Replace illegal &-characters."""
|
107
144
|
return re.sub(r"&([^a-zA-Z#])", r"&\1", xmldata)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
plugwise/__init__.py,sha256=KMLU90T2k_z1MuZGEPnLPtHoNbw32kboeGK8rCqjibE,14084
|
2
|
+
plugwise/common.py,sha256=P4sUYzgVcFsIR2DmQxeVeOiZvFZWpZXgwHA3XRc1Sx0,12538
|
3
|
+
plugwise/constants.py,sha256=dvafW3u7LBbWUN05D1Tss7s4jxEDJiZDqnh4-q9isUM,16580
|
4
|
+
plugwise/data.py,sha256=uS-W2pw7WcIrXsRZ03c24iw9fuyxKeCw2WUnIc4YVZk,8972
|
5
|
+
plugwise/exceptions.py,sha256=rymGtWnXosdFkzSehc_41HVl2jXJEg_9Hq9APDEUwrk,1223
|
6
|
+
plugwise/helper.py,sha256=nF1xJEw-frvuGMAydFAJrz_tN24Q3PcBnYNIwPeueZg,42817
|
7
|
+
plugwise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
plugwise/smile.py,sha256=9eJR8iLyYOMrWq8MMw3-uQrN8fS5sZCHdJpp5Kspszo,17177
|
9
|
+
plugwise/util.py,sha256=9ld46KJHWFze2eUrVSgUYn0g3zNerlpboM0iUa0H3ak,7830
|
10
|
+
plugwise/legacy/data.py,sha256=piVgGLBvjMbTYIvTK__-s3ueKqoQ6wIt8o1jny9_udk,2998
|
11
|
+
plugwise/legacy/helper.py,sha256=6-tYQMEXepE5rec-hn6lt2EeknADI3J8UFuBSLgu8dk,17878
|
12
|
+
plugwise/legacy/smile.py,sha256=Jo0ynhhxfOC6NGemgVNN-LBwUWmA736lHTO5WXQ65r4,10492
|
13
|
+
plugwise-0.37.6.dist-info/LICENSE,sha256=mL22BjmXtg_wnoDnnaqps5_Bg_VGj_yHueX5lsKwbCc,1144
|
14
|
+
plugwise-0.37.6.dist-info/METADATA,sha256=zSU-2UB8vhgVJ0kC65-AJyrMLptwcx8SpNU0rGzoqfs,8939
|
15
|
+
plugwise-0.37.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
16
|
+
plugwise-0.37.6.dist-info/top_level.txt,sha256=MYOmktMFf8ZmX6_OE1y9MoCZFfY-L8DA0F2tA2IvE4s,9
|
17
|
+
plugwise-0.37.6.dist-info/RECORD,,
|
@@ -1,17 +0,0 @@
|
|
1
|
-
plugwise/__init__.py,sha256=A0XCK9xmhzLGSsy0bAGr2tnKfGDUlJ7WzQfeIqCCd8A,14004
|
2
|
-
plugwise/common.py,sha256=P4sUYzgVcFsIR2DmQxeVeOiZvFZWpZXgwHA3XRc1Sx0,12538
|
3
|
-
plugwise/constants.py,sha256=adi2UFHJUcPRWNz1bn155NC9DLzhYbeNriMKTpSyWAg,16574
|
4
|
-
plugwise/data.py,sha256=OTkPJ80b1L1h_TeddfvmUPX1-jBacTjbHKD0XgUIfeg,8965
|
5
|
-
plugwise/exceptions.py,sha256=rymGtWnXosdFkzSehc_41HVl2jXJEg_9Hq9APDEUwrk,1223
|
6
|
-
plugwise/helper.py,sha256=bNT_Tdc0LAxmVZEikMgKm461jeGP-WY-cI1r3JGgIcI,44037
|
7
|
-
plugwise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
plugwise/smile.py,sha256=2pjpIXIwCRaDdabjZiCiG5a9ErxSfh5xk-glsyxhsiQ,17075
|
9
|
-
plugwise/util.py,sha256=w24CiW-xSV3ARZAeNYZ9T5C4kJpYGCcBoIlX2BhNOYg,6618
|
10
|
-
plugwise/legacy/data.py,sha256=y7gBG9Sg40lltB3B5CpWPtAXggMbcx2IMay-mwvOB1M,2986
|
11
|
-
plugwise/legacy/helper.py,sha256=tSrqA2UeMO7HSYudQHAxBThBTevAOKIxHqN6NCN-r5k,18947
|
12
|
-
plugwise/legacy/smile.py,sha256=JlJGg2TNl1uBeW-vLzsHzrpeizKpZqN9coiDYcedHuc,10347
|
13
|
-
plugwise-0.37.4.1.dist-info/LICENSE,sha256=mL22BjmXtg_wnoDnnaqps5_Bg_VGj_yHueX5lsKwbCc,1144
|
14
|
-
plugwise-0.37.4.1.dist-info/METADATA,sha256=nCzwqoFjAaK3Wro085Rs1ALtXGfZP2xzOO9ndX8toXA,8941
|
15
|
-
plugwise-0.37.4.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
16
|
-
plugwise-0.37.4.1.dist-info/top_level.txt,sha256=MYOmktMFf8ZmX6_OE1y9MoCZFfY-L8DA0F2tA2IvE4s,9
|
17
|
-
plugwise-0.37.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|