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 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 set_number_setpoint(self, key: str, _: str, temperature: float) -> None:
327
- """Set the max. Boiler or DHW setpoint on the Central Heating boiler."""
328
- await self._smile_api.set_number_setpoint(key, temperature)
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, _: str, dev_id: str, offset: float) -> None:
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.set_temperature_offset(dev_id, offset)
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[list[str]] = [
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 == NONE:
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 [8, 9]
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 [8, 9]
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 == NONE:
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 format_measure, skip_obsolete_measurements, version_to_model
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
- match measurement:
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 available schedules/schedules for the legacy thermostat."""
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
- for schedule in search.findall("./rule"):
460
- if rule_name := schedule.find("name").text:
461
- if "preset" not in rule_name:
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
- if name is not None:
471
- available = [name]
472
- if active:
473
- selected = name
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 set_number_setpoint(self, key: str, temperature: float) -> None:
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, __: str | None) -> None:
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 ["on", "off"]:
191
+ if state not in ("on", "off"):
183
192
  raise PlugwiseError("Plugwise: invalid schedule state.")
184
193
 
185
- name = "Thermostat schedule"
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 set_number_setpoint(self, key: str, temperature: float) -> None:
186
- """Set the max. Boiler or DHW setpoint on the Central Heating boiler."""
187
- if key == "max_dhw_temperature":
188
- key = "domestic_hot_water_setpoint"
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 ["on", "off"]:
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
- """Try."""
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"&amp;\1", xmldata)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plugwise
3
- Version: 0.37.4.1
3
+ Version: 0.37.6
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=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,,