plugwise 1.1.0a0__py3-none-any.whl → 1.3.0__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 CHANGED
@@ -52,6 +52,7 @@ class SmileCommon:
52
52
  self,
53
53
  appl: Munch,
54
54
  xml_1: etree,
55
+ legacy: bool,
55
56
  xml_2: etree = None,
56
57
  xml_3: etree = None,
57
58
  ) -> Munch:
@@ -68,8 +69,8 @@ class SmileCommon:
68
69
  # Info for On-Off device
69
70
  if self._on_off_device:
70
71
  appl.name = "OnOff" # pragma: no cover
71
- appl.vendor_name = None # pragma: no cover
72
72
  appl.model = "Unknown" # pragma: no cover
73
+ appl.vendor_name = None # pragma: no cover
73
74
  return appl # pragma: no cover
74
75
 
75
76
  # Info for OpenTherm device
@@ -85,13 +86,12 @@ class SmileCommon:
85
86
  module_data = self._get_module_data(xml_1, locator_2, mod_type, xml_3)
86
87
  appl.vendor_name = module_data["vendor_name"]
87
88
  appl.hardware = module_data["hardware_version"]
88
- appl.model = module_data["vendor_model"]
89
- if appl.model is None:
90
- appl.model = (
91
- "Generic heater/cooler"
92
- if self._cooling_present
93
- else "Generic heater"
94
- )
89
+ appl.model_id = module_data["vendor_model"] if not legacy else None
90
+ appl.model = (
91
+ "Generic heater/cooler"
92
+ if self._cooling_present
93
+ else "Generic heater"
94
+ )
95
95
 
96
96
  return appl
97
97
 
@@ -102,7 +102,11 @@ class SmileCommon:
102
102
  xml_2 = return_valid(xml_2, self._domain_objects)
103
103
  module_data = self._get_module_data(xml_1, locator, mod_type, xml_2)
104
104
  appl.vendor_name = module_data["vendor_name"]
105
- appl.model = check_model(module_data["vendor_model"], appl.vendor_name)
105
+ appl.model = module_data["vendor_model"]
106
+ if appl.model != "ThermoTouch": # model_id for Anna not present as stand-alone device
107
+ appl.model_id = appl.model
108
+ appl.model = check_model(appl.model, appl.vendor_name)
109
+
106
110
  appl.hardware = module_data["hardware_version"]
107
111
  appl.firmware = module_data["firmware_version"]
108
112
  appl.zigbee_mac = module_data["zigbee_mac_address"]
@@ -197,6 +201,7 @@ class SmileCommon:
197
201
  "location": appl.location,
198
202
  "mac_address": appl.mac,
199
203
  "model": appl.model,
204
+ "model_id": appl.model_id,
200
205
  "name": appl.name,
201
206
  "zigbee_mac_address": appl.zigbee_mac,
202
207
  "vendor": appl.vendor_name,
plugwise/constants.py CHANGED
@@ -258,13 +258,13 @@ ApplianceType = Literal[
258
258
  ]
259
259
 
260
260
  BinarySensorType = Literal[
261
- "battery_state",
262
261
  "compressor_state",
263
262
  "cooling_enabled",
264
263
  "cooling_state",
265
264
  "dhw_state",
266
265
  "flame_state",
267
266
  "heating_state",
267
+ "low_battery",
268
268
  "plugwise_notification",
269
269
  "secondary_boiler_state",
270
270
  ]
@@ -410,13 +410,13 @@ class ModelData(TypedDict):
410
410
  class SmileBinarySensors(TypedDict, total=False):
411
411
  """Smile Binary Sensors class."""
412
412
 
413
- battery_state: bool
414
413
  compressor_state: bool
415
414
  cooling_enabled: bool
416
415
  cooling_state: bool
417
416
  dhw_state: bool
418
417
  flame_state: bool
419
418
  heating_state: bool
419
+ low_battery: bool
420
420
  plugwise_notification: bool
421
421
  secondary_boiler_state: bool
422
422
 
plugwise/data.py CHANGED
@@ -62,25 +62,21 @@ class SmileData(SmileHelper):
62
62
  self._add_or_update_notifications(device_id, device, data)
63
63
 
64
64
  device.update(data)
65
-
66
65
  is_battery_low = (
67
66
  mac_list
68
- and "battery_state" in device["binary_sensors"]
67
+ and "low_battery" in device["binary_sensors"]
69
68
  and device["zigbee_mac_address"] in mac_list
70
- and (
71
- (device["dev_class"] in ("thermo_sensor", "thermostatic_radiator_valve") and device["sensors"]["battery"] < 30)
72
- or (device["dev_class"] in ("zone_thermometer", "zone_thermostat") and device["sensors"]["battery"] < 15)
73
- )
69
+ and device["dev_class"] in ("thermo_sensor", "thermostatic_radiator_valve", "zone_thermometer", "zone_thermostat")
74
70
  )
75
71
  if is_battery_low:
76
- device["binary_sensors"]["battery_state"] = True
72
+ device["binary_sensors"]["low_battery"] = True
77
73
 
78
74
  self._update_for_cooling(device)
79
75
 
80
76
  remove_empty_platform_dicts(device)
81
77
 
82
78
  def _detect_low_batteries(self) -> list[str]:
83
- """Helper-function updating the battery_state binary_sensor status from a Battery-is-low message."""
79
+ """Helper-function updating the low-battery binary_sensor status from a Battery-is-low message."""
84
80
  mac_address_list: list[str] = []
85
81
  mac_pattern = re.compile(r"(?:[0-9A-F]{2}){8}")
86
82
  matches = ["Battery", "below"]
@@ -88,12 +84,15 @@ class SmileData(SmileHelper):
88
84
  for msg_id, notification in list(self._notifications.items()):
89
85
  mac_address: str | None = None
90
86
  message: str | None = notification.get("message")
91
- if message is not None and all(x in message for x in matches) and (mac_addresses := mac_pattern.findall(message)):
87
+ warning: str | None = notification.get("warning")
88
+ notify = message or warning
89
+ if notify is not None and all(x in notify for x in matches) and (mac_addresses := mac_pattern.findall(notify)):
92
90
  mac_address = mac_addresses[0] # re.findall() outputs a list
93
91
 
94
92
  if mac_address is not None:
95
- self._notifications.pop(msg_id)
96
93
  mac_address_list.append(mac_address)
94
+ if message is not None: # only block message-type notifications
95
+ self._notifications.pop(msg_id)
97
96
 
98
97
  return mac_address_list
99
98
 
plugwise/helper.py CHANGED
@@ -285,7 +285,8 @@ class SmileHelper(SmileCommon):
285
285
 
286
286
  appl.dev_id = appliance.attrib["id"]
287
287
  appl.name = appliance.find("name").text
288
- appl.model = appl.pwclass.replace("_", " ").title()
288
+ appl.model = None
289
+ appl.model_id = None
289
290
  appl.firmware = None
290
291
  appl.hardware = None
291
292
  appl.mac = None
@@ -350,7 +351,8 @@ class SmileHelper(SmileCommon):
350
351
  appl.dev_id = self.gateway_id
351
352
  appl.location = loc_id
352
353
  appl.mac = None
353
- appl.model = self.smile_model
354
+ appl.model = self._domain_objects.find("./gateway/vendor_model").text
355
+ appl.model_id = None
354
356
  appl.name = "P1"
355
357
  appl.pwclass = "smartmeter"
356
358
  appl.zigbee_mac = None
@@ -370,7 +372,7 @@ class SmileHelper(SmileCommon):
370
372
  return self._appl_thermostat_info(appl, appliance)
371
373
  case "heater_central":
372
374
  # Collect heater_central device info
373
- self._appl_heater_central_info(appl, appliance)
375
+ self._appl_heater_central_info(appl, appliance, False) # False means non-legacy device
374
376
  self._appl_dhw_mode_info(appl, appliance)
375
377
  return appl
376
378
  case _:
@@ -380,14 +382,14 @@ class SmileHelper(SmileCommon):
380
382
  def _energy_device_info_finder(self, appl: Munch, appliance: etree) -> Munch:
381
383
  """Helper-function for _appliance_info_finder().
382
384
 
383
- Collect energy device info (Smartmeter, Plug): firmware, model and vendor name.
385
+ Collect energy device info (Smartmeter): firmware, model and vendor name.
384
386
  """
385
387
  if self.smile_type == "power":
386
388
  locator = "./logs/point_log/electricity_point_meter"
387
389
  mod_type = "electricity_point_meter"
388
390
  module_data = self._get_module_data(appliance, locator, mod_type)
389
391
  appl.hardware = module_data["hardware_version"]
390
- appl.model = module_data["vendor_model"]
392
+ appl.model = module_data["vendor_model"] # don't use model_id for Smartmeter
391
393
  appl.vendor_name = module_data["vendor_name"]
392
394
  appl.firmware = module_data["firmware_version"]
393
395
 
@@ -403,7 +405,8 @@ class SmileHelper(SmileCommon):
403
405
  return None
404
406
 
405
407
  appl.vendor_name = module_data["vendor_name"]
406
- appl.model = check_model(module_data["vendor_model"], appl.vendor_name)
408
+ appl.model_id = module_data["vendor_model"]
409
+ appl.model = check_model(appl.model_id, appl.vendor_name)
407
410
  appl.hardware = module_data["hardware_version"]
408
411
  appl.firmware = module_data["firmware_version"]
409
412
 
@@ -418,6 +421,7 @@ class SmileHelper(SmileCommon):
418
421
  appl.hardware = self.smile_hw_version
419
422
  appl.mac = self.smile_mac_address
420
423
  appl.model = self.smile_model
424
+ appl.model_id = self._domain_objects.find("./gateway/vendor_model").text
421
425
  appl.name = self.smile_name
422
426
  appl.vendor_name = "Plugwise"
423
427
 
plugwise/legacy/helper.py CHANGED
@@ -117,6 +117,7 @@ class SmileLegacyHelper(SmileCommon):
117
117
  appl.dev_id = appliance.attrib["id"]
118
118
  appl.name = appliance.find("name").text
119
119
  appl.model = appl.pwclass.replace("_", " ").title()
120
+ appl.model_id = None
120
121
  appl.firmware = None
121
122
  appl.hardware = None
122
123
  appl.mac = None
@@ -207,7 +208,9 @@ class SmileLegacyHelper(SmileCommon):
207
208
  return self._appl_thermostat_info(appl, appliance, self._modules)
208
209
  # Collect heater_central device info
209
210
  case "heater_central":
210
- return self._appl_heater_central_info(appl, appliance, self._appliances, self._modules)
211
+ return self._appl_heater_central_info(
212
+ appl, appliance, True, self._appliances, self._modules
213
+ ) # True means legacy device
211
214
  # Collect info from Stretches
212
215
  case _:
213
216
  return self._energy_device_info_finder(appliance, appl)
@@ -246,6 +249,7 @@ class SmileLegacyHelper(SmileCommon):
246
249
  appl.location = loc_id
247
250
  appl.mac = None
248
251
  appl.model = self.smile_model
252
+ appl.model_id = None
249
253
  appl.name = "P1"
250
254
  appl.pwclass = "smartmeter"
251
255
  appl.zigbee_mac = None
plugwise/util.py CHANGED
@@ -110,6 +110,9 @@ def check_model(name: str | None, vendor_name: str | None) -> str | None:
110
110
  if vendor_name == "Plugwise" and ((model := version_to_model(name)) != "Unknown"):
111
111
  return model
112
112
 
113
+ if name is not None and "lumi.plug" in name:
114
+ return "Aqara Smart Plug"
115
+
113
116
  return name
114
117
 
115
118
 
@@ -139,7 +142,7 @@ def common_match_cases(
139
142
  data[sp_key] = value
140
143
 
141
144
  if "battery" in data["sensors"]:
142
- data["binary_sensors"]["battery_state"] = False
145
+ data["binary_sensors"]["low_battery"] = False
143
146
 
144
147
 
145
148
  def escape_illegal_xml_characters(xmldata: str) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plugwise
3
- Version: 1.1.0a0
3
+ Version: 1.3.0
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
@@ -0,0 +1,17 @@
1
+ plugwise/__init__.py,sha256=EXiTp-N8kQqOUAaczDbULS176NwA2C1FcfWiKkBzNdI,16887
2
+ plugwise/common.py,sha256=geZd-kVQ0F1OTJoUd2WMPxNBVpSLgZ2ID_47ainOMnk,12746
3
+ plugwise/constants.py,sha256=O2sEAUjoOgvuM5dsS7jzZOMDcy6h8WI1p-od9WzJvQ4,16722
4
+ plugwise/data.py,sha256=I4w3ABqmcj_uSnfxTWPYQH8WP6HaywVMx1aQ-feBdU0,10734
5
+ plugwise/exceptions.py,sha256=Ce-tO9uNsMB-8FP6VAxBvsHNJ-NIM9F0onUZOdZI4Ys,1110
6
+ plugwise/helper.py,sha256=2oSUV2Wj0LkfhAvfXwMvfDrJ9x5SWlen4IVCs4twYSU,44123
7
+ plugwise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ plugwise/smile.py,sha256=TyDXl1NSMFxsZehtopawpYpL6vie3NM3gVcez_bfjvA,18681
9
+ plugwise/util.py,sha256=lCasQDzYO3CNAIHbLKTK16YJxQKoBrTQkJ1nCMmF17g,8006
10
+ plugwise/legacy/data.py,sha256=DsHR9xgiFDg_Vh_6ZpOskw8ZhNQ3CmwjstI3yiH6MEk,3048
11
+ plugwise/legacy/helper.py,sha256=7QCJyaR9FaM4EEQxGt2oFJac6Pu5OKoi_LG_GQKzRs4,18012
12
+ plugwise/legacy/smile.py,sha256=7oaPZuvxrYRvoA8qWFvtWSwQRFfQl1XXpPjWXn3_xFs,11314
13
+ plugwise-1.3.0.dist-info/LICENSE,sha256=mL22BjmXtg_wnoDnnaqps5_Bg_VGj_yHueX5lsKwbCc,1144
14
+ plugwise-1.3.0.dist-info/METADATA,sha256=7JzpaCXGkFUFcdvHvbCjsKLbKKackFQFjC9moyvg60o,9097
15
+ plugwise-1.3.0.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
16
+ plugwise-1.3.0.dist-info/top_level.txt,sha256=MYOmktMFf8ZmX6_OE1y9MoCZFfY-L8DA0F2tA2IvE4s,9
17
+ plugwise-1.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.2.0)
2
+ Generator: setuptools (74.1.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,17 +0,0 @@
1
- plugwise/__init__.py,sha256=EXiTp-N8kQqOUAaczDbULS176NwA2C1FcfWiKkBzNdI,16887
2
- plugwise/common.py,sha256=P4sUYzgVcFsIR2DmQxeVeOiZvFZWpZXgwHA3XRc1Sx0,12538
3
- plugwise/constants.py,sha256=Vuy_N7ZXxO3y2Z2BdlkOia82IPuHD3gNtMyxPmS4zcE,16726
4
- plugwise/data.py,sha256=zNNhl2Y0fl8TJvMexVdPYd7QM_3fAxfiYKeG9GjCDlI,10712
5
- plugwise/exceptions.py,sha256=Ce-tO9uNsMB-8FP6VAxBvsHNJ-NIM9F0onUZOdZI4Ys,1110
6
- plugwise/helper.py,sha256=NFcxVtY9qdM2TtBbGs-_eh7xKO6G_M3Q4W9bXUCpH84,43861
7
- plugwise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- plugwise/smile.py,sha256=TyDXl1NSMFxsZehtopawpYpL6vie3NM3gVcez_bfjvA,18681
9
- plugwise/util.py,sha256=nuFJccqrvHv7s8Ox24NQvDKMRXjFLKAwsgQ7nYaJne0,7924
10
- plugwise/legacy/data.py,sha256=DsHR9xgiFDg_Vh_6ZpOskw8ZhNQ3CmwjstI3yiH6MEk,3048
11
- plugwise/legacy/helper.py,sha256=6-tYQMEXepE5rec-hn6lt2EeknADI3J8UFuBSLgu8dk,17878
12
- plugwise/legacy/smile.py,sha256=7oaPZuvxrYRvoA8qWFvtWSwQRFfQl1XXpPjWXn3_xFs,11314
13
- plugwise-1.1.0a0.dist-info/LICENSE,sha256=mL22BjmXtg_wnoDnnaqps5_Bg_VGj_yHueX5lsKwbCc,1144
14
- plugwise-1.1.0a0.dist-info/METADATA,sha256=6BXYBWp6gBDkWiE1DrEinbUtLpHf7G7WqpJjHZfU5U8,9099
15
- plugwise-1.1.0a0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
16
- plugwise-1.1.0a0.dist-info/top_level.txt,sha256=MYOmktMFf8ZmX6_OE1y9MoCZFfY-L8DA0F2tA2IvE4s,9
17
- plugwise-1.1.0a0.dist-info/RECORD,,