plugwise 1.5.1a3__py3-none-any.whl → 1.5.2__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/common.py +8 -10
- plugwise/constants.py +26 -25
- plugwise/helper.py +7 -32
- plugwise/legacy/helper.py +3 -3
- plugwise/util.py +2 -4
- {plugwise-1.5.1a3.dist-info → plugwise-1.5.2.dist-info}/METADATA +1 -1
- plugwise-1.5.2.dist-info/RECORD +17 -0
- {plugwise-1.5.1a3.dist-info → plugwise-1.5.2.dist-info}/WHEEL +1 -1
- plugwise-1.5.1a3.dist-info/RECORD +0 -17
- {plugwise-1.5.1a3.dist-info → plugwise-1.5.2.dist-info}/LICENSE +0 -0
- {plugwise-1.5.1a3.dist-info → plugwise-1.5.2.dist-info}/top_level.txt +0 -0
plugwise/common.py
CHANGED
@@ -73,13 +73,12 @@ class SmileCommon:
|
|
73
73
|
appl.name = "OpenTherm"
|
74
74
|
locator_1 = "./logs/point_log[type='flame_state']/boiler_state"
|
75
75
|
locator_2 = "./services/boiler_state"
|
76
|
-
mod_type = "boiler_state"
|
77
76
|
# xml_1: appliance
|
78
77
|
# xml_3: self._modules for legacy, self._domain_objects for actual
|
79
78
|
xml_3 = return_valid(xml_3, self._domain_objects)
|
80
|
-
module_data = self._get_module_data(xml_1, locator_1,
|
79
|
+
module_data = self._get_module_data(xml_1, locator_1, xml_3)
|
81
80
|
if not module_data["contents"]:
|
82
|
-
module_data = self._get_module_data(xml_1, locator_2,
|
81
|
+
module_data = self._get_module_data(xml_1, locator_2, xml_3)
|
83
82
|
appl.vendor_name = module_data["vendor_name"]
|
84
83
|
appl.hardware = module_data["hardware_version"]
|
85
84
|
appl.model_id = module_data["vendor_model"] if not legacy else None
|
@@ -94,15 +93,15 @@ class SmileCommon:
|
|
94
93
|
def _appl_thermostat_info(self, appl: Munch, xml_1: etree, xml_2: etree = None) -> Munch:
|
95
94
|
"""Helper-function for _appliance_info_finder()."""
|
96
95
|
locator = "./logs/point_log[type='thermostat']/thermostat"
|
97
|
-
mod_type = "thermostat"
|
98
96
|
xml_2 = return_valid(xml_2, self._domain_objects)
|
99
|
-
module_data = self._get_module_data(xml_1, locator,
|
97
|
+
module_data = self._get_module_data(xml_1, locator, xml_2)
|
100
98
|
appl.vendor_name = module_data["vendor_name"]
|
101
99
|
appl.model = module_data["vendor_model"]
|
102
100
|
if appl.model != "ThermoTouch": # model_id for Anna not present as stand-alone device
|
103
101
|
appl.model_id = appl.model
|
104
102
|
appl.model = check_model(appl.model, appl.vendor_name)
|
105
103
|
|
104
|
+
appl.available = module_data["reachable"]
|
106
105
|
appl.hardware = module_data["hardware_version"]
|
107
106
|
appl.firmware = module_data["firmware_version"]
|
108
107
|
appl.zigbee_mac = module_data["zigbee_mac_address"]
|
@@ -192,6 +191,7 @@ class SmileCommon:
|
|
192
191
|
self.gw_devices[appl.dev_id] = {"dev_class": appl.pwclass}
|
193
192
|
self._count += 1
|
194
193
|
for key, value in {
|
194
|
+
"available": appl.available,
|
195
195
|
"firmware": appl.firmware,
|
196
196
|
"hardware": appl.hardware,
|
197
197
|
"location": appl.location,
|
@@ -278,7 +278,6 @@ class SmileCommon:
|
|
278
278
|
self,
|
279
279
|
xml_1: etree,
|
280
280
|
locator: str,
|
281
|
-
mod_type: str,
|
282
281
|
xml_2: etree = None,
|
283
282
|
legacy: bool = False,
|
284
283
|
) -> ModelData:
|
@@ -295,12 +294,11 @@ class SmileCommon:
|
|
295
294
|
"vendor_model": None,
|
296
295
|
"zigbee_mac_address": None,
|
297
296
|
}
|
298
|
-
|
297
|
+
|
299
298
|
if (appl_search := xml_1.find(locator)) is not None:
|
299
|
+
link_tag = appl_search.tag
|
300
300
|
link_id = appl_search.attrib["id"]
|
301
|
-
loc = f".//services/{
|
302
|
-
if legacy:
|
303
|
-
loc = f".//{mod_type}[@id='{link_id}']...."
|
301
|
+
loc = f".//services/{link_tag}[@id='{link_id}']...."
|
304
302
|
# Not possible to walrus for some reason...
|
305
303
|
# xml_2: self._modules for legacy, self._domain_objects for actual
|
306
304
|
search = return_valid(xml_2, self._domain_objects)
|
plugwise/constants.py
CHANGED
@@ -81,6 +81,7 @@ HW_MODELS: Final[dict[str, str]] = {
|
|
81
81
|
|
82
82
|
MAX_SETPOINT: Final[float] = 30.0
|
83
83
|
MIN_SETPOINT: Final[float] = 4.0
|
84
|
+
MODULE_LOCATOR: Final = "./logs/point_log/*[@id]"
|
84
85
|
NONE: Final = "None"
|
85
86
|
OFF: Final = "off"
|
86
87
|
|
@@ -123,7 +124,7 @@ P1_LEGACY_MEASUREMENTS: Final[dict[str, UOM]] = {
|
|
123
124
|
# radiator_valve: 'uncorrected_temperature', 'temperature_offset'
|
124
125
|
|
125
126
|
DEVICE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = {
|
126
|
-
"humidity": UOM(
|
127
|
+
"humidity": UOM(NONE), # Specific for a Jip
|
127
128
|
"illuminance": UOM(UNIT_LUMEN), # Specific for an Anna
|
128
129
|
"temperature": UOM(TEMP_CELSIUS), # HA Core thermostat current_temperature
|
129
130
|
"thermostat": DATA("setpoint", TEMP_CELSIUS), # HA Core thermostat setpoint
|
@@ -425,44 +426,44 @@ class SmileBinarySensors(TypedDict, total=False):
|
|
425
426
|
class SmileSensors(TypedDict, total=False):
|
426
427
|
"""Smile Sensors class."""
|
427
428
|
|
428
|
-
battery:
|
429
|
+
battery: int
|
429
430
|
cooling_activation_outdoor_temperature: float
|
430
431
|
cooling_deactivation_threshold: float
|
431
432
|
dhw_temperature: float
|
432
433
|
domestic_hot_water_setpoint: float
|
433
434
|
temperature: float
|
434
|
-
electricity_consumed:
|
435
|
-
electricity_consumed_interval:
|
435
|
+
electricity_consumed: float
|
436
|
+
electricity_consumed_interval: float
|
436
437
|
electricity_consumed_off_peak_cumulative: float
|
437
|
-
electricity_consumed_off_peak_interval:
|
438
|
-
electricity_consumed_off_peak_point:
|
438
|
+
electricity_consumed_off_peak_interval: float
|
439
|
+
electricity_consumed_off_peak_point: float
|
439
440
|
electricity_consumed_peak_cumulative: float
|
440
|
-
electricity_consumed_peak_interval:
|
441
|
-
electricity_consumed_peak_point:
|
442
|
-
electricity_consumed_point:
|
443
|
-
electricity_phase_one_consumed:
|
444
|
-
electricity_phase_two_consumed:
|
445
|
-
electricity_phase_three_consumed:
|
446
|
-
electricity_phase_one_produced:
|
447
|
-
electricity_phase_two_produced:
|
448
|
-
electricity_phase_three_produced:
|
449
|
-
electricity_produced:
|
450
|
-
electricity_produced_interval:
|
441
|
+
electricity_consumed_peak_interval: float
|
442
|
+
electricity_consumed_peak_point: float
|
443
|
+
electricity_consumed_point: float
|
444
|
+
electricity_phase_one_consumed: float
|
445
|
+
electricity_phase_two_consumed: float
|
446
|
+
electricity_phase_three_consumed: float
|
447
|
+
electricity_phase_one_produced: float
|
448
|
+
electricity_phase_two_produced: float
|
449
|
+
electricity_phase_three_produced: float
|
450
|
+
electricity_produced: float
|
451
|
+
electricity_produced_interval: float
|
451
452
|
electricity_produced_off_peak_cumulative: float
|
452
|
-
electricity_produced_off_peak_interval:
|
453
|
-
electricity_produced_off_peak_point:
|
453
|
+
electricity_produced_off_peak_interval: float
|
454
|
+
electricity_produced_off_peak_point: float
|
454
455
|
electricity_produced_peak_cumulative: float
|
455
|
-
electricity_produced_peak_interval:
|
456
|
-
electricity_produced_peak_point:
|
457
|
-
electricity_produced_point:
|
456
|
+
electricity_produced_peak_interval: float
|
457
|
+
electricity_produced_peak_point: float
|
458
|
+
electricity_produced_point: float
|
458
459
|
gas_consumed_cumulative: float
|
459
460
|
gas_consumed_interval: float
|
460
461
|
humidity: float
|
461
462
|
illuminance: float
|
462
463
|
intended_boiler_temperature: float
|
463
|
-
modulation_level:
|
464
|
+
modulation_level: int
|
464
465
|
net_electricity_cumulative: float
|
465
|
-
net_electricity_point:
|
466
|
+
net_electricity_point: float
|
466
467
|
outdoor_air_temperature: float
|
467
468
|
outdoor_temperature: float
|
468
469
|
return_temperature: float
|
@@ -470,7 +471,7 @@ class SmileSensors(TypedDict, total=False):
|
|
470
471
|
setpoint_high: float
|
471
472
|
setpoint_low: float
|
472
473
|
temperature_difference: float
|
473
|
-
valve_position:
|
474
|
+
valve_position: int
|
474
475
|
voltage_phase_one: float
|
475
476
|
voltage_phase_two: float
|
476
477
|
voltage_phase_three: float
|
plugwise/helper.py
CHANGED
@@ -24,6 +24,7 @@ from plugwise.constants import (
|
|
24
24
|
LIMITS,
|
25
25
|
LOCATIONS,
|
26
26
|
LOGGER,
|
27
|
+
MODULE_LOCATOR,
|
27
28
|
NONE,
|
28
29
|
OFF,
|
29
30
|
P1_MEASUREMENTS,
|
@@ -299,6 +300,7 @@ class SmileHelper(SmileCommon):
|
|
299
300
|
if appl.pwclass in THERMOSTAT_CLASSES and appl.location is None:
|
300
301
|
continue
|
301
302
|
|
303
|
+
appl.available = None
|
302
304
|
appl.dev_id = appliance.attrib["id"]
|
303
305
|
appl.name = appliance.find("name").text
|
304
306
|
appl.model = None
|
@@ -356,9 +358,8 @@ class SmileHelper(SmileCommon):
|
|
356
358
|
"""Collect P1 DSMR SmartMeter info."""
|
357
359
|
loc_id = next(iter(self.loc_data.keys()))
|
358
360
|
location = self._domain_objects.find(f'./location[@id="{loc_id}"]')
|
359
|
-
locator =
|
360
|
-
|
361
|
-
module_data = self._get_module_data(location, locator, mod_type)
|
361
|
+
locator = MODULE_LOCATOR
|
362
|
+
module_data = self._get_module_data(location, locator)
|
362
363
|
if not module_data["contents"]:
|
363
364
|
LOGGER.error("No module data found for SmartMeter") # pragma: no cover
|
364
365
|
return None # pragma: no cover
|
@@ -396,13 +397,13 @@ class SmileHelper(SmileCommon):
|
|
396
397
|
return appl
|
397
398
|
case _ as s if s.endswith("_plug"):
|
398
399
|
# Collect info from plug-types (Plug, Aqara Smart Plug)
|
399
|
-
locator =
|
400
|
-
|
401
|
-
module_data = self._get_module_data(appliance, locator, mod_type)
|
400
|
+
locator = MODULE_LOCATOR
|
401
|
+
module_data = self._get_module_data(appliance, locator)
|
402
402
|
# A plug without module-data is orphaned/ no present
|
403
403
|
if not module_data["contents"]:
|
404
404
|
return Munch()
|
405
405
|
|
406
|
+
appl.available = module_data["reachable"]
|
406
407
|
appl.firmware = module_data["firmware_version"]
|
407
408
|
appl.hardware = module_data["hardware_version"]
|
408
409
|
appl.model_id = module_data["vendor_model"]
|
@@ -515,9 +516,6 @@ class SmileHelper(SmileCommon):
|
|
515
516
|
if appliance.find("type").text in ACTUATOR_CLASSES:
|
516
517
|
self._get_actuator_functionalities(appliance, device, data)
|
517
518
|
|
518
|
-
# Collect availability-status for wireless connected devices to Adam
|
519
|
-
self._wireless_availability(appliance, data)
|
520
|
-
|
521
519
|
if dev_id == self.gateway_id and self.smile(ADAM):
|
522
520
|
self._get_regulation_mode(appliance, data)
|
523
521
|
self._get_gateway_mode(appliance, data)
|
@@ -710,29 +708,6 @@ class SmileHelper(SmileCommon):
|
|
710
708
|
act_item = cast(ActuatorType, item)
|
711
709
|
data[act_item] = temp_dict
|
712
710
|
|
713
|
-
def _wireless_availability(self, appliance: etree, data: DeviceData) -> None:
|
714
|
-
"""Helper-function for _get_measurement_data().
|
715
|
-
|
716
|
-
Collect the availability-status for wireless connected devices.
|
717
|
-
"""
|
718
|
-
if self.smile(ADAM):
|
719
|
-
# Try collecting for a Plug
|
720
|
-
locator = "./logs/interval_log/electricity_interval_meter"
|
721
|
-
mod_type = "electricity_interval_meter"
|
722
|
-
module_data = self._get_module_data(appliance, locator, mod_type)
|
723
|
-
if not module_data["contents"]:
|
724
|
-
# Try collecting for a wireless thermostat
|
725
|
-
locator = "./logs/point_log[type='thermostat']/thermostat"
|
726
|
-
mod_type = "thermostat"
|
727
|
-
module_data = self._get_module_data(appliance, locator, mod_type)
|
728
|
-
if not module_data["contents"]:
|
729
|
-
LOGGER.error("No module data found for Plug or wireless thermostat") # pragma: no cover
|
730
|
-
return None # pragma: no cover
|
731
|
-
|
732
|
-
if module_data["reachable"] is not None:
|
733
|
-
data["available"] = module_data["reachable"]
|
734
|
-
self._count += 1
|
735
|
-
|
736
711
|
def _get_regulation_mode(self, appliance: etree, data: DeviceData) -> None:
|
737
712
|
"""Helper-function for _get_measurement_data().
|
738
713
|
|
plugwise/legacy/helper.py
CHANGED
@@ -125,6 +125,7 @@ class SmileLegacyHelper(SmileCommon):
|
|
125
125
|
appl.pwclass = "heater_central_plug"
|
126
126
|
|
127
127
|
appl.model = appl.pwclass.replace("_", " ").title()
|
128
|
+
appl.available = None
|
128
129
|
appl.model_id = None
|
129
130
|
appl.firmware = None
|
130
131
|
appl.hardware = None
|
@@ -230,9 +231,7 @@ class SmileLegacyHelper(SmileCommon):
|
|
230
231
|
"""
|
231
232
|
if self.smile_type in ("power", "stretch"):
|
232
233
|
locator = "./services/electricity_point_meter"
|
233
|
-
|
234
|
-
|
235
|
-
module_data = self._get_module_data(appliance, locator, mod_type, self._modules, legacy=True)
|
234
|
+
module_data = self._get_module_data(appliance, locator, self._modules, legacy=True)
|
236
235
|
appl.zigbee_mac = module_data["zigbee_mac_address"]
|
237
236
|
# Filter appliance without zigbee_mac, it's an orphaned device
|
238
237
|
if appl.zigbee_mac is None and self.smile_type != "power":
|
@@ -253,6 +252,7 @@ class SmileLegacyHelper(SmileCommon):
|
|
253
252
|
def _p1_smartmeter_info_finder(self, appl: Munch) -> None:
|
254
253
|
"""Collect P1 DSMR Smartmeter info."""
|
255
254
|
loc_id = next(iter(self.loc_data.keys()))
|
255
|
+
appl.available = None
|
256
256
|
appl.dev_id = loc_id
|
257
257
|
appl.location = loc_id
|
258
258
|
appl.mac = None
|
plugwise/util.py
CHANGED
@@ -115,7 +115,7 @@ def check_model(name: str | None, vendor_name: str | None) -> str | None:
|
|
115
115
|
if name is not None and "lumi.plug" in name:
|
116
116
|
return "Aqara Smart Plug"
|
117
117
|
|
118
|
-
return
|
118
|
+
return None
|
119
119
|
|
120
120
|
|
121
121
|
def common_match_cases(
|
@@ -173,10 +173,8 @@ def format_measure(measure: str, unit: str) -> float | int:
|
|
173
173
|
result = float(f"{round(float_measure, 1):.1f}")
|
174
174
|
elif abs(float_measure) < 10:
|
175
175
|
result = float(f"{round(float_measure, 2):.2f}")
|
176
|
-
elif abs(float_measure) >= 10
|
176
|
+
elif abs(float_measure) >= 10:
|
177
177
|
result = float(f"{round(float_measure, 1):.1f}")
|
178
|
-
elif abs(float_measure) >= 100:
|
179
|
-
result = int(round(float_measure))
|
180
178
|
|
181
179
|
return result
|
182
180
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
plugwise/__init__.py,sha256=_AYvIt5rOBksqxp5Lrr7iv11i3mXXJpEQ6Q40pqtOPk,17147
|
2
|
+
plugwise/common.py,sha256=lNiW2CrrGEdbluZ4-7CSL1EzXWNoGlIDpVSsSSoWDGQ,12494
|
3
|
+
plugwise/constants.py,sha256=Hu0RSIKWgE-oOfCpQQZ9lDy7BQH45gOS4j_9YRZoLg8,16806
|
4
|
+
plugwise/data.py,sha256=SgfwTGKwtZnXI8KGePTCoMODn8GQLq4YkKwf697--ds,10782
|
5
|
+
plugwise/exceptions.py,sha256=Ce-tO9uNsMB-8FP6VAxBvsHNJ-NIM9F0onUZOdZI4Ys,1110
|
6
|
+
plugwise/helper.py,sha256=NBn25AvllW_hF9pLVy4UhwEsvV7uYc8k5kVa5yjnk2Q,43025
|
7
|
+
plugwise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
plugwise/smile.py,sha256=BALKDMY730C-vHCnOadnaM9ezv0iIEnu-V-BsHJRewY,18729
|
9
|
+
plugwise/util.py,sha256=Sh-r_MoNf0kSS_MKYINwd-VjYklX6MM1FQvsbS7t1DI,8045
|
10
|
+
plugwise/legacy/data.py,sha256=8QRzW7TlOGTs1UdMRPMm2PZTJxYnmF3ARnW8_STV65A,3072
|
11
|
+
plugwise/legacy/helper.py,sha256=B1z9bC_7LfAPUTLlto4JpqUNXC2QARrieXAe8o32aUI,18362
|
12
|
+
plugwise/legacy/smile.py,sha256=E_Zc1muzylyRMeYYbP4QhGBUQf_KaUUnbPAuIhH8WxY,11208
|
13
|
+
plugwise-1.5.2.dist-info/LICENSE,sha256=mL22BjmXtg_wnoDnnaqps5_Bg_VGj_yHueX5lsKwbCc,1144
|
14
|
+
plugwise-1.5.2.dist-info/METADATA,sha256=ICuFVndIsPayyvM0zMWKAX5BY7HkK2X0PVg4tYZbSnw,9097
|
15
|
+
plugwise-1.5.2.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
16
|
+
plugwise-1.5.2.dist-info/top_level.txt,sha256=MYOmktMFf8ZmX6_OE1y9MoCZFfY-L8DA0F2tA2IvE4s,9
|
17
|
+
plugwise-1.5.2.dist-info/RECORD,,
|
@@ -1,17 +0,0 @@
|
|
1
|
-
plugwise/__init__.py,sha256=_AYvIt5rOBksqxp5Lrr7iv11i3mXXJpEQ6Q40pqtOPk,17147
|
2
|
-
plugwise/common.py,sha256=WltDqYlW5D3KqIcm5U_gVY4izLZSk_Uk-MEJl6RDNbs,12592
|
3
|
-
plugwise/constants.py,sha256=iGOBzNok11T5dk-AFVARwNR6qmfLQoOm2YWs5IG2u2o,16725
|
4
|
-
plugwise/data.py,sha256=SgfwTGKwtZnXI8KGePTCoMODn8GQLq4YkKwf697--ds,10782
|
5
|
-
plugwise/exceptions.py,sha256=Ce-tO9uNsMB-8FP6VAxBvsHNJ-NIM9F0onUZOdZI4Ys,1110
|
6
|
-
plugwise/helper.py,sha256=nJ3wUZuQqJRhjjxk5dm5dGyQv1BK8KKvs5s7LQPtAEg,44386
|
7
|
-
plugwise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
plugwise/smile.py,sha256=BALKDMY730C-vHCnOadnaM9ezv0iIEnu-V-BsHJRewY,18729
|
9
|
-
plugwise/util.py,sha256=Ls9ULWVH6vTv65ixkoWzGRmRCZ5AJ36gUWxzAiUJ-Rw,8181
|
10
|
-
plugwise/legacy/data.py,sha256=8QRzW7TlOGTs1UdMRPMm2PZTJxYnmF3ARnW8_STV65A,3072
|
11
|
-
plugwise/legacy/helper.py,sha256=HI9EvtTWfzKH5nX4G-YtLpn9Qvi50OLMRRIaN5v7rqU,18358
|
12
|
-
plugwise/legacy/smile.py,sha256=E_Zc1muzylyRMeYYbP4QhGBUQf_KaUUnbPAuIhH8WxY,11208
|
13
|
-
plugwise-1.5.1a3.dist-info/LICENSE,sha256=mL22BjmXtg_wnoDnnaqps5_Bg_VGj_yHueX5lsKwbCc,1144
|
14
|
-
plugwise-1.5.1a3.dist-info/METADATA,sha256=NseSe1bvvUEFR1qE9R-RbtKOcX3a_V0o_GCyBQzbEdw,9099
|
15
|
-
plugwise-1.5.1a3.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
16
|
-
plugwise-1.5.1a3.dist-info/top_level.txt,sha256=MYOmktMFf8ZmX6_OE1y9MoCZFfY-L8DA0F2tA2IvE4s,9
|
17
|
-
plugwise-1.5.1a3.dist-info/RECORD,,
|
File without changes
|
File without changes
|