plugwise 1.5.1a3__py3-none-any.whl → 1.6.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/__init__.py +10 -10
- plugwise/common.py +68 -60
- plugwise/constants.py +47 -34
- plugwise/data.py +95 -67
- plugwise/helper.py +199 -168
- plugwise/legacy/data.py +23 -23
- plugwise/legacy/helper.py +57 -58
- plugwise/legacy/smile.py +18 -16
- plugwise/smile.py +24 -21
- plugwise/util.py +7 -9
- {plugwise-1.5.1a3.dist-info → plugwise-1.6.0.dist-info}/METADATA +1 -1
- plugwise-1.6.0.dist-info/RECORD +17 -0
- {plugwise-1.5.1a3.dist-info → plugwise-1.6.0.dist-info}/WHEEL +1 -1
- plugwise-1.5.1a3.dist-info/RECORD +0 -17
- {plugwise-1.5.1a3.dist-info → plugwise-1.6.0.dist-info}/LICENSE +0 -0
- {plugwise-1.5.1a3.dist-info → plugwise-1.6.0.dist-info}/top_level.txt +0 -0
plugwise/__init__.py
CHANGED
@@ -69,6 +69,7 @@ class Smile(SmileComm):
|
|
69
69
|
self._elga = False
|
70
70
|
self._is_thermostat = False
|
71
71
|
self._last_active: dict[str, str | None] = {}
|
72
|
+
self._loc_data: dict[str, ThermoLoc] = {}
|
72
73
|
self._on_off_device = False
|
73
74
|
self._opentherm_device = False
|
74
75
|
self._schedule_old_states: dict[str, dict[str, str]] = {}
|
@@ -76,7 +77,6 @@ class Smile(SmileComm):
|
|
76
77
|
self._stretch_v2 = False
|
77
78
|
self._target_smile: str = NONE
|
78
79
|
self.gateway_id: str = NONE
|
79
|
-
self.loc_data: dict[str, ThermoLoc] = {}
|
80
80
|
self.smile_fw_version: Version | None = None
|
81
81
|
self.smile_hostname: str = NONE
|
82
82
|
self.smile_hw_version: str | None = None
|
@@ -134,11 +134,11 @@ class Smile(SmileComm):
|
|
134
134
|
self._elga,
|
135
135
|
self._is_thermostat,
|
136
136
|
self._last_active,
|
137
|
+
self._loc_data,
|
137
138
|
self._on_off_device,
|
138
139
|
self._opentherm_device,
|
139
140
|
self._schedule_old_states,
|
140
141
|
self.gateway_id,
|
141
|
-
self.loc_data,
|
142
142
|
self.smile_fw_version,
|
143
143
|
self.smile_hostname,
|
144
144
|
self.smile_hw_version,
|
@@ -155,11 +155,11 @@ class Smile(SmileComm):
|
|
155
155
|
self._request,
|
156
156
|
self._websession,
|
157
157
|
self._is_thermostat,
|
158
|
+
self._loc_data,
|
158
159
|
self._on_off_device,
|
159
160
|
self._opentherm_device,
|
160
161
|
self._stretch_v2,
|
161
162
|
self._target_smile,
|
162
|
-
self.loc_data,
|
163
163
|
self.smile_fw_version,
|
164
164
|
self.smile_hostname,
|
165
165
|
self.smile_hw_version,
|
@@ -173,7 +173,7 @@ class Smile(SmileComm):
|
|
173
173
|
)
|
174
174
|
|
175
175
|
# Update all endpoints on first connect
|
176
|
-
await self._smile_api.
|
176
|
+
await self._smile_api.full_xml_update()
|
177
177
|
|
178
178
|
return self.smile_version
|
179
179
|
|
@@ -298,17 +298,17 @@ class Smile(SmileComm):
|
|
298
298
|
self.smile_legacy = True
|
299
299
|
return return_model
|
300
300
|
|
301
|
-
async def
|
301
|
+
async def full_xml_update(self) -> None:
|
302
302
|
"""Helper-function used for testing."""
|
303
|
-
await self._smile_api.
|
303
|
+
await self._smile_api.full_xml_update()
|
304
304
|
|
305
|
-
def
|
305
|
+
def get_all_gateway_entities(self) -> None:
|
306
306
|
"""Helper-function used for testing."""
|
307
|
-
self._smile_api.
|
307
|
+
self._smile_api.get_all_gateway_entities()
|
308
308
|
|
309
309
|
async def async_update(self) -> PlugwiseData:
|
310
|
-
"""
|
311
|
-
data = PlugwiseData({}, {})
|
310
|
+
"""Update the various entities and their states."""
|
311
|
+
data = PlugwiseData(devices={}, gateway={})
|
312
312
|
try:
|
313
313
|
data = await self._smile_api.async_update()
|
314
314
|
self.gateway_id = data.gateway["gateway_id"]
|
plugwise/common.py
CHANGED
@@ -11,8 +11,8 @@ from plugwise.constants import (
|
|
11
11
|
SPECIAL_PLUG_TYPES,
|
12
12
|
SWITCH_GROUP_TYPES,
|
13
13
|
ApplianceType,
|
14
|
-
|
15
|
-
|
14
|
+
GwEntityData,
|
15
|
+
ModuleData,
|
16
16
|
SensorType,
|
17
17
|
)
|
18
18
|
from plugwise.util import (
|
@@ -40,7 +40,7 @@ class SmileCommon:
|
|
40
40
|
self._heater_id: str
|
41
41
|
self._on_off_device: bool
|
42
42
|
self._opentherm_device: bool
|
43
|
-
self.
|
43
|
+
self.gw_entities: dict[str, GwEntityData]
|
44
44
|
self.smile_name: str
|
45
45
|
self.smile_type: str
|
46
46
|
|
@@ -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,22 +93,22 @@ 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"]
|
109
108
|
|
110
109
|
return appl
|
111
110
|
|
112
|
-
def _collect_power_values(self, data:
|
111
|
+
def _collect_power_values(self, data: GwEntityData, loc: Munch, tariff: str, legacy: bool = False) -> None:
|
113
112
|
"""Something."""
|
114
113
|
for loc.peak_select in ("nl_peak", "nl_offpeak"):
|
115
114
|
loc.locator = (
|
@@ -132,6 +131,19 @@ class SmileCommon:
|
|
132
131
|
key = cast(SensorType, loc.key_string)
|
133
132
|
data["sensors"][key] = loc.f_val
|
134
133
|
|
134
|
+
def _count_data_items(self, data: GwEntityData) -> None:
|
135
|
+
"""When present, count the binary_sensors, sensors and switches dict-items, don't count the dicts.
|
136
|
+
|
137
|
+
Also, count the remaining single data items, the amount of dicts present have already been pre-subtracted in the previous step.
|
138
|
+
"""
|
139
|
+
if "binary_sensors" in data:
|
140
|
+
self._count += len(data["binary_sensors"]) - 1
|
141
|
+
if "sensors" in data:
|
142
|
+
self._count += len(data["sensors"]) - 1
|
143
|
+
if "switches" in data:
|
144
|
+
self._count += len(data["switches"]) - 1
|
145
|
+
self._count += len(data)
|
146
|
+
|
135
147
|
def _power_data_peak_value(self, loc: Munch, legacy: bool) -> Munch:
|
136
148
|
"""Helper-function for _power_data_from_location() and _power_data_from_modules()."""
|
137
149
|
loc.found = True
|
@@ -161,8 +173,8 @@ class SmileCommon:
|
|
161
173
|
measurement: str,
|
162
174
|
net_string: SensorType,
|
163
175
|
f_val: float | int,
|
164
|
-
|
165
|
-
) ->
|
176
|
+
data: GwEntityData,
|
177
|
+
) -> GwEntityData:
|
166
178
|
"""Calculate differential energy."""
|
167
179
|
if (
|
168
180
|
"electricity" in measurement
|
@@ -172,10 +184,10 @@ class SmileCommon:
|
|
172
184
|
diff = 1
|
173
185
|
if "produced" in measurement:
|
174
186
|
diff = -1
|
175
|
-
if net_string not in
|
187
|
+
if net_string not in data["sensors"]:
|
176
188
|
tmp_val: float | int = 0
|
177
189
|
else:
|
178
|
-
tmp_val =
|
190
|
+
tmp_val = data["sensors"][net_string]
|
179
191
|
|
180
192
|
if isinstance(f_val, int):
|
181
193
|
tmp_val += f_val * diff
|
@@ -183,15 +195,16 @@ class SmileCommon:
|
|
183
195
|
tmp_val += float(f_val * diff)
|
184
196
|
tmp_val = float(f"{round(tmp_val, 3):.3f}")
|
185
197
|
|
186
|
-
|
198
|
+
data["sensors"][net_string] = tmp_val
|
187
199
|
|
188
|
-
return
|
200
|
+
return data
|
189
201
|
|
190
|
-
def
|
191
|
-
"""Helper-function for creating/updating
|
192
|
-
self.
|
202
|
+
def _create_gw_entities(self, appl: Munch) -> None:
|
203
|
+
"""Helper-function for creating/updating gw_entities."""
|
204
|
+
self.gw_entities[appl.entity_id] = {"dev_class": appl.pwclass}
|
193
205
|
self._count += 1
|
194
206
|
for key, value in {
|
207
|
+
"available": appl.available,
|
195
208
|
"firmware": appl.firmware,
|
196
209
|
"hardware": appl.hardware,
|
197
210
|
"location": appl.location,
|
@@ -204,30 +217,30 @@ class SmileCommon:
|
|
204
217
|
}.items():
|
205
218
|
if value is not None or key == "location":
|
206
219
|
appl_key = cast(ApplianceType, key)
|
207
|
-
self.
|
220
|
+
self.gw_entities[appl.entity_id][appl_key] = value
|
208
221
|
self._count += 1
|
209
222
|
|
210
|
-
def
|
211
|
-
self,
|
223
|
+
def _entity_switching_group(
|
224
|
+
self, entity: GwEntityData, data: GwEntityData
|
212
225
|
) -> None:
|
213
|
-
"""Helper-function for
|
226
|
+
"""Helper-function for _get_device_zone_data().
|
214
227
|
|
215
228
|
Determine switching group device data.
|
216
229
|
"""
|
217
|
-
if
|
230
|
+
if entity["dev_class"] in SWITCH_GROUP_TYPES:
|
218
231
|
counter = 0
|
219
|
-
for member in
|
220
|
-
if self.
|
232
|
+
for member in entity["members"]:
|
233
|
+
if self.gw_entities[member]["switches"].get("relay"):
|
221
234
|
counter += 1
|
222
235
|
data["switches"]["relay"] = counter != 0
|
223
236
|
self._count += 1
|
224
237
|
|
225
|
-
def _get_group_switches(self) -> dict[str,
|
226
|
-
"""Helper-function for smile.py:
|
238
|
+
def _get_group_switches(self) -> dict[str, GwEntityData]:
|
239
|
+
"""Helper-function for smile.py: get_all_gateway_entities().
|
227
240
|
|
228
241
|
Collect switching- or pump-group info.
|
229
242
|
"""
|
230
|
-
switch_groups: dict[str,
|
243
|
+
switch_groups: dict[str, GwEntityData] = {}
|
231
244
|
# P1 and Anna don't have switchgroups
|
232
245
|
if self.smile_type == "power" or self.smile(ANNA):
|
233
246
|
return switch_groups
|
@@ -240,25 +253,22 @@ class SmileCommon:
|
|
240
253
|
group_appliances = group.findall("appliances/appliance")
|
241
254
|
for item in group_appliances:
|
242
255
|
# Check if members are not orphaned - stretch
|
243
|
-
if item.attrib["id"] in self.
|
256
|
+
if item.attrib["id"] in self.gw_entities:
|
244
257
|
members.append(item.attrib["id"])
|
245
258
|
|
246
259
|
if group_type in SWITCH_GROUP_TYPES and members:
|
247
|
-
switch_groups
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
},
|
255
|
-
},
|
256
|
-
)
|
260
|
+
switch_groups[group_id] = {
|
261
|
+
"dev_class": group_type,
|
262
|
+
"model": "Switchgroup",
|
263
|
+
"name": group_name,
|
264
|
+
"members": members,
|
265
|
+
"vendor": "Plugwise",
|
266
|
+
}
|
257
267
|
self._count += 4
|
258
268
|
|
259
269
|
return switch_groups
|
260
270
|
|
261
|
-
def _get_lock_state(self, xml: etree, data:
|
271
|
+
def _get_lock_state(self, xml: etree, data: GwEntityData, stretch_v2: bool = False) -> None:
|
262
272
|
"""Helper-function for _get_measurement_data().
|
263
273
|
|
264
274
|
Adam & Stretches: obtain the relay-switch lock state.
|
@@ -278,15 +288,14 @@ class SmileCommon:
|
|
278
288
|
self,
|
279
289
|
xml_1: etree,
|
280
290
|
locator: str,
|
281
|
-
mod_type: str,
|
282
291
|
xml_2: etree = None,
|
283
292
|
legacy: bool = False,
|
284
|
-
) ->
|
293
|
+
) -> ModuleData:
|
285
294
|
"""Helper-function for _energy_device_info_finder() and _appliance_info_finder().
|
286
295
|
|
287
296
|
Collect requested info from MODULES.
|
288
297
|
"""
|
289
|
-
|
298
|
+
module_data: ModuleData = {
|
290
299
|
"contents": False,
|
291
300
|
"firmware_version": None,
|
292
301
|
"hardware_version": None,
|
@@ -295,36 +304,35 @@ class SmileCommon:
|
|
295
304
|
"vendor_model": None,
|
296
305
|
"zigbee_mac_address": None,
|
297
306
|
}
|
298
|
-
|
307
|
+
|
299
308
|
if (appl_search := xml_1.find(locator)) is not None:
|
309
|
+
link_tag = appl_search.tag
|
300
310
|
link_id = appl_search.attrib["id"]
|
301
|
-
loc = f".//services/{
|
302
|
-
if legacy:
|
303
|
-
loc = f".//{mod_type}[@id='{link_id}']...."
|
311
|
+
loc = f".//services/{link_tag}[@id='{link_id}']...."
|
304
312
|
# Not possible to walrus for some reason...
|
305
313
|
# xml_2: self._modules for legacy, self._domain_objects for actual
|
306
314
|
search = return_valid(xml_2, self._domain_objects)
|
307
315
|
module = search.find(loc)
|
308
316
|
if module is not None: # pylint: disable=consider-using-assignment-expr
|
309
|
-
|
310
|
-
get_vendor_name(module,
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
self._get_zigbee_data(module,
|
317
|
+
module_data["contents"] = True
|
318
|
+
get_vendor_name(module, module_data)
|
319
|
+
module_data["vendor_model"] = module.find("vendor_model").text
|
320
|
+
module_data["hardware_version"] = module.find("hardware_version").text
|
321
|
+
module_data["firmware_version"] = module.find("firmware_version").text
|
322
|
+
self._get_zigbee_data(module, module_data, legacy)
|
315
323
|
|
316
|
-
return
|
324
|
+
return module_data
|
317
325
|
|
318
|
-
def _get_zigbee_data(self, module: etree,
|
319
|
-
"""Helper-function for
|
326
|
+
def _get_zigbee_data(self, module: etree, module_data: ModuleData, legacy: bool) -> None:
|
327
|
+
"""Helper-function for _get_module_data()."""
|
320
328
|
if legacy:
|
321
329
|
# Stretches
|
322
330
|
if (router := module.find("./protocols/network_router")) is not None:
|
323
|
-
|
331
|
+
module_data["zigbee_mac_address"] = router.find("mac_address").text
|
324
332
|
# Also look for the Circle+/Stealth M+
|
325
333
|
if (coord := module.find("./protocols/network_coordinator")) is not None:
|
326
|
-
|
334
|
+
module_data["zigbee_mac_address"] = coord.find("mac_address").text
|
327
335
|
# Adam
|
328
336
|
elif (zb_node := module.find("./protocols/zig_bee_node")) is not None:
|
329
|
-
|
330
|
-
|
337
|
+
module_data["zigbee_mac_address"] = zb_node.find("mac_address").text
|
338
|
+
module_data["reachable"] = zb_node.find("reachable").text == "true"
|
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
|
@@ -189,6 +190,14 @@ OBSOLETE_MEASUREMENTS: Final[tuple[str, ...]] = (
|
|
189
190
|
"outdoor_temperature",
|
190
191
|
)
|
191
192
|
|
193
|
+
# Zone/climate related measurements
|
194
|
+
ZONE_MEASUREMENTS: Final[dict[str, DATA | UOM]] = {
|
195
|
+
"electricity_consumed": UOM(POWER_WATT),
|
196
|
+
"electricity_produced": UOM(POWER_WATT),
|
197
|
+
"relay": UOM(NONE),
|
198
|
+
"temperature": UOM(TEMP_CELSIUS), # HA Core thermostat current_temperature
|
199
|
+
}
|
200
|
+
|
192
201
|
# Literals
|
193
202
|
SMILE_P1 = "Smile P1"
|
194
203
|
POWER = "power"
|
@@ -396,8 +405,8 @@ class GatewayData(TypedDict, total=False):
|
|
396
405
|
smile_name: str
|
397
406
|
|
398
407
|
|
399
|
-
class
|
400
|
-
"""The
|
408
|
+
class ModuleData(TypedDict):
|
409
|
+
"""The Module data class."""
|
401
410
|
|
402
411
|
contents: bool
|
403
412
|
firmware_version: str | None
|
@@ -425,44 +434,44 @@ class SmileBinarySensors(TypedDict, total=False):
|
|
425
434
|
class SmileSensors(TypedDict, total=False):
|
426
435
|
"""Smile Sensors class."""
|
427
436
|
|
428
|
-
battery:
|
437
|
+
battery: int
|
429
438
|
cooling_activation_outdoor_temperature: float
|
430
439
|
cooling_deactivation_threshold: float
|
431
440
|
dhw_temperature: float
|
432
441
|
domestic_hot_water_setpoint: float
|
433
442
|
temperature: float
|
434
|
-
electricity_consumed:
|
435
|
-
electricity_consumed_interval:
|
443
|
+
electricity_consumed: float
|
444
|
+
electricity_consumed_interval: float
|
436
445
|
electricity_consumed_off_peak_cumulative: float
|
437
|
-
electricity_consumed_off_peak_interval:
|
438
|
-
electricity_consumed_off_peak_point:
|
446
|
+
electricity_consumed_off_peak_interval: float
|
447
|
+
electricity_consumed_off_peak_point: float
|
439
448
|
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:
|
449
|
+
electricity_consumed_peak_interval: float
|
450
|
+
electricity_consumed_peak_point: float
|
451
|
+
electricity_consumed_point: float
|
452
|
+
electricity_phase_one_consumed: float
|
453
|
+
electricity_phase_two_consumed: float
|
454
|
+
electricity_phase_three_consumed: float
|
455
|
+
electricity_phase_one_produced: float
|
456
|
+
electricity_phase_two_produced: float
|
457
|
+
electricity_phase_three_produced: float
|
458
|
+
electricity_produced: float
|
459
|
+
electricity_produced_interval: float
|
451
460
|
electricity_produced_off_peak_cumulative: float
|
452
|
-
electricity_produced_off_peak_interval:
|
453
|
-
electricity_produced_off_peak_point:
|
461
|
+
electricity_produced_off_peak_interval: float
|
462
|
+
electricity_produced_off_peak_point: float
|
454
463
|
electricity_produced_peak_cumulative: float
|
455
|
-
electricity_produced_peak_interval:
|
456
|
-
electricity_produced_peak_point:
|
457
|
-
electricity_produced_point:
|
464
|
+
electricity_produced_peak_interval: float
|
465
|
+
electricity_produced_peak_point: float
|
466
|
+
electricity_produced_point: float
|
458
467
|
gas_consumed_cumulative: float
|
459
468
|
gas_consumed_interval: float
|
460
469
|
humidity: float
|
461
470
|
illuminance: float
|
462
471
|
intended_boiler_temperature: float
|
463
|
-
modulation_level:
|
472
|
+
modulation_level: int
|
464
473
|
net_electricity_cumulative: float
|
465
|
-
net_electricity_point:
|
474
|
+
net_electricity_point: float
|
466
475
|
outdoor_air_temperature: float
|
467
476
|
outdoor_temperature: float
|
468
477
|
return_temperature: float
|
@@ -470,7 +479,7 @@ class SmileSensors(TypedDict, total=False):
|
|
470
479
|
setpoint_high: float
|
471
480
|
setpoint_low: float
|
472
481
|
temperature_difference: float
|
473
|
-
valve_position:
|
482
|
+
valve_position: int
|
474
483
|
voltage_phase_one: float
|
475
484
|
voltage_phase_two: float
|
476
485
|
voltage_phase_three: float
|
@@ -491,9 +500,9 @@ class ThermoLoc(TypedDict, total=False):
|
|
491
500
|
"""Thermo Location class."""
|
492
501
|
|
493
502
|
name: str
|
494
|
-
primary: str
|
503
|
+
primary: list[str]
|
495
504
|
primary_prio: int
|
496
|
-
secondary:
|
505
|
+
secondary: list[str]
|
497
506
|
|
498
507
|
|
499
508
|
class ActuatorData(TypedDict, total=False):
|
@@ -507,8 +516,11 @@ class ActuatorData(TypedDict, total=False):
|
|
507
516
|
upper_bound: float
|
508
517
|
|
509
518
|
|
510
|
-
class
|
511
|
-
"""The
|
519
|
+
class GwEntityData(TypedDict, total=False):
|
520
|
+
"""The Gateway Entity data class.
|
521
|
+
|
522
|
+
Covering the collected output-data per device or location.
|
523
|
+
"""
|
512
524
|
|
513
525
|
# Appliance base data
|
514
526
|
dev_class: str
|
@@ -543,13 +555,13 @@ class DeviceData(TypedDict, total=False):
|
|
543
555
|
select_gateway_mode: str
|
544
556
|
select_regulation_mode: str
|
545
557
|
|
546
|
-
#
|
558
|
+
# Thermostat-related
|
559
|
+
thermostats: dict[str, list[str]]
|
547
560
|
# Presets:
|
548
561
|
active_preset: str | None
|
549
562
|
preset_modes: list[str] | None
|
550
563
|
# Schedules:
|
551
564
|
available_schedules: list[str]
|
552
|
-
last_used: str | None
|
553
565
|
select_schedule: str
|
554
566
|
|
555
567
|
climate_mode: str
|
@@ -570,5 +582,6 @@ class DeviceData(TypedDict, total=False):
|
|
570
582
|
class PlugwiseData:
|
571
583
|
"""Plugwise data provided as output."""
|
572
584
|
|
585
|
+
devices: dict[str, GwEntityData]
|
573
586
|
gateway: GatewayData
|
574
|
-
|
587
|
+
|