|
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 | 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, |
32 | 28 | ActuatorData, |
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 @@ def _appliance_measurements( |
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,33 +430,32 @@ def _presets(self) -> dict[str, list[float]]: |
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" |
466 | 445 | active = False |
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 |
|
477 | 457 | def _thermostat_uri(self) -> str: |
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" |
0 commit comments