Skip to content

Commit 7e5aa32

Browse files
authored
Merge pull request #180 from plugwise/various-fixes
Corrections, fixes, etc.
2 parents 96110ad + a3ca8f2 commit 7e5aa32

File tree

6 files changed

+99
-64
lines changed

6 files changed

+99
-64
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
# v0.17.7: Smile: Corrections, fixes, clean up
4+
- Move compressor_state into binary_sensors
5+
- Adam: add missing zigbee_mac to wireless thermostats
6+
- Stretch & Adam: don't show devices without a zigbee_mac, should be orphaned devices
7+
- Harmonize appliance dicts for legacy devices
8+
- Typing improvements
9+
- Fix related test asserts
10+
311
# v0.17.6: Smile: revert removing LOGGER.error messages
412

513
# v0.17.5: Smile: rework to raise instead of return

plugwise/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Plugwise module."""
22

3-
__version__ = "0.17.6"
3+
__version__ = "0.17.7a0"
44

55
from plugwise.smile import Smile
66
from plugwise.stick import Stick

plugwise/constants.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""Plugwise Stick and Smile constants."""
2+
from __future__ import annotations
3+
24
import logging
35
from typing import Any, Final
46

@@ -402,7 +404,7 @@
402404
STATUS: Final = "/system/status.xml"
403405

404406
# P1 related measurements:
405-
HOME_MEASUREMENTS: Final[dict[str, Any]] = {
407+
HOME_MEASUREMENTS: Final[dict[str, dict[str, str]]] = {
406408
"electricity_consumed": {
407409
ATTR_TYPE: "power",
408410
ATTR_UNIT_OF_MEASUREMENT: POWER_WATT,
@@ -421,7 +423,7 @@
421423
# Excluded:
422424
# zone_thermosstat: 'temperature_offset'
423425
# radiator_valve: 'uncorrected_temperature', 'temperature_offset'
424-
DEVICE_MEASUREMENTS: Final[dict[str, Any]] = {
426+
DEVICE_MEASUREMENTS: Final[dict[str, dict[str, str | None]]] = {
425427
# HA Core thermostat current_temperature
426428
"temperature": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
427429
# HA Core thermostat setpoint
@@ -452,7 +454,7 @@
452454
}
453455

454456
# Heater Central related measurements
455-
HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, Any]] = {
457+
HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, dict[str, str | None]]] = {
456458
"boiler_temperature": {
457459
ATTR_NAME: "water_temperature",
458460
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
@@ -508,7 +510,7 @@
508510
}
509511

510512
# Known types of Smiles and Stretches
511-
SMILES: Final[dict[str, Any]] = {
513+
SMILES: Final[dict[str, dict[str, Any]]] = {
512514
"smile_open_therm_v3": {
513515
"type": "thermostat",
514516
"friendly_name": "Adam",
@@ -551,6 +553,7 @@
551553
# All available Binary Sensor, Sensor, and Switch Types
552554

553555
BINARY_SENSORS: Final[list[str]] = [
556+
"compressor_state",
554557
"cooling_state",
555558
"dhw_state",
556559
"flame_state",

plugwise/helper.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def schedules_schedule_temp(schedules: dict[str, Any], name: str) -> Any:
125125
return None
126126

127127

128-
def types_finder(data: etree) -> set[str]:
128+
def types_finder(data: etree) -> set[str | None]:
129129
"""Detect types within locations from logs."""
130130
types = set()
131131
for measure, attrs in HOME_MEASUREMENTS.items():
@@ -449,42 +449,50 @@ def _get_module_data(
449449

450450
return model_data
451451

452-
def _energy_device_info_finder(self, appliance: etree, appl: Munch) -> Munch:
452+
def _energy_device_info_finder(self, appliance: etree, appl: Munch) -> Munch | None:
453453
"""Helper-function for _appliance_info_finder().
454454
Collect energy device info (Circle, Plug, Stealth): firmware, model and vendor name.
455455
"""
456456
if self._stretch_v2 or self._stretch_v3:
457457
locator = "./services/electricity_point_meter"
458458
mod_type = "electricity_point_meter"
459+
459460
module_data = self._get_module_data(appliance, locator, mod_type)
460-
if not module_data["contents"]:
461+
# Filter appliance without zigbee_mac, it's an orphaned device
462+
appl.zigbee_mac = module_data["zigbee_mac_address"]
463+
if appl.zigbee_mac is None:
461464
return None
462465

463466
appl.v_name = module_data["vendor_name"]
464-
if appl.model != "Switchgroup":
465-
appl.model = None
466467
appl.hw = module_data["hardware_version"]
467468
if appl.hw:
468469
hw_version = module_data["hardware_version"].replace("-", "")
469470
appl.model = version_to_model(hw_version)
470471
appl.fw = module_data["firmware_version"]
471-
appl.zigbee_mac = module_data["zigbee_mac_address"]
472+
472473
return appl
473474

474475
if self.smile_type != "stretch" and "plug" in appl.types:
475476
locator = "./logs/point_log/electricity_point_meter"
476477
mod_type = "electricity_point_meter"
477478
module_data = self._get_module_data(appliance, locator, mod_type)
479+
# Filter appliance without zigbee_mac, it's an orphaned device
480+
appl.zigbee_mac = module_data["zigbee_mac_address"]
481+
if appl.zigbee_mac is None:
482+
return None
483+
478484
appl.v_name = module_data["vendor_name"]
479485
appl.model = version_to_model(module_data["vendor_model"])
480486
appl.hw = module_data["hardware_version"]
481487
appl.fw = module_data["firmware_version"]
482-
appl.zigbee_mac = module_data["zigbee_mac_address"]
488+
483489
return appl
484490

491+
return appl # pragma: no cover
492+
485493
def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
486494
"""Collect device info (Smile/Stretch, Thermostats, OpenTherm/On-Off): firmware, model and vendor name."""
487-
# Find gateway and heater_central devices
495+
# Collect gateway device info
488496
if appl.pwclass == "gateway":
489497
self.gateway_id = appliance.attrib["id"]
490498
appl.fw = self.smile_fw_version
@@ -511,6 +519,7 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
511519

512520
return appl
513521

522+
# Collect thermostat device info
514523
if appl.pwclass in THERMOSTAT_CLASSES:
515524
locator = "./logs/point_log[type='thermostat']/thermostat"
516525
mod_type = "thermostat"
@@ -519,23 +528,25 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
519528
appl.model = check_model(module_data["vendor_model"], appl.v_name)
520529
appl.hw = module_data["hardware_version"]
521530
appl.fw = module_data["firmware_version"]
531+
appl.zigbee_mac = module_data["zigbee_mac_address"]
522532

523533
return appl
524534

535+
# Collect heater_central device info
525536
if appl.pwclass == "heater_central":
526537
# Remove heater_central when no active device present
527538
if not self._opentherm_device and not self._on_off_device:
528539
return None
529540

530541
self._heater_id = appliance.attrib["id"]
531-
# info for On-Off device
542+
# Info for On-Off device
532543
if self._on_off_device:
533544
appl.name = "OnOff"
534545
appl.v_name = None
535546
appl.model = "Unknown"
536547
return appl
537548

538-
# Obtain info for OpenTherm device
549+
# Info for OpenTherm device
539550
appl.name = "OpenTherm"
540551
locator1 = "./logs/point_log[type='flame_state']/boiler_state"
541552
locator2 = "./services/boiler_state"
@@ -554,13 +565,10 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
554565
)
555566
return appl
556567

557-
# Handle stretches
568+
# Collect info from Stretches
558569
appl = self._energy_device_info_finder(appliance, appl)
559-
if not appl:
560-
return None
561570

562-
# Cornercase just return existing dict-object
563-
return appl # pragma: no cover
571+
return appl
564572

565573
def _appliance_types_finder(self, appliance: etree, appl: Munch) -> Munch:
566574
"""Helper-function for _all_appliances() - determine type(s) per appliance."""
@@ -600,29 +608,29 @@ def _all_appliances(self) -> None:
600608
"class": "gateway",
601609
"fw": self.smile_fw_version,
602610
"hw": self.smile_hw_version,
603-
"mac_address": self.smile_mac_address,
604611
"location": self._home_location,
605-
"vendor": "Plugwise B.V.",
612+
"mac_address": self.smile_mac_address,
606613
}
607614
self.gateway_id = self._home_location
608615

609616
if self.smile_type == "power":
610617
self._appl_data[self._home_location].update(
611-
{"model": "P1", "name": "P1"}
618+
{"model": "P1", "name": "P1", "vendor": "Plugwise B.V."}
612619
)
613620
# legacy p1 has no more devices
614621
return
615622

616623
if self.smile_type == "thermostat":
617624
self._appl_data[self._home_location].update(
618-
{"model": "Anna", "name": "Anna"}
625+
{"model": "Anna", "name": "Anna", "vendor": "Plugwise B.V."}
619626
)
620627

621628
if self.smile_type == "stretch":
622629
self._appl_data[self._home_location].update(
623630
{
624631
"model": "Stretch",
625632
"name": "Stretch",
633+
"vendor": "Plugwise B.V.",
626634
"zigbee_mac_address": self.smile_zigbee_mac_address,
627635
}
628636
)
@@ -666,7 +674,7 @@ def _all_appliances(self) -> None:
666674
# Determine class for this appliance
667675
appl = self._appliance_info_finder(appliance, appl)
668676
# Skip on heater_central when no active device present or on orphaned stretch devices
669-
if not appl:
677+
if appl is None:
670678
continue
671679

672680
if appl.pwclass == "gateway":
@@ -1019,7 +1027,6 @@ def _group_switches(self) -> dict[str, dict[str, Any]]:
10191027
"model": "Switchgroup",
10201028
"name": group_name,
10211029
"members": members,
1022-
"types": {"switch_group"},
10231030
"vendor": None,
10241031
}
10251032

plugwise/smile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ async def _smile_detect(self, result: etree, dsmrmain: etree) -> None:
386386
self.smile_version = (self.smile_fw_version, ver)
387387

388388
if "legacy" in SMILES[target_smile]:
389-
self._smile_legacy = SMILES[target_smile].get("legacy")
389+
self._smile_legacy = SMILES[target_smile]["legacy"]
390390

391391
if self.smile_type == "stretch":
392392
self._stretch_v2 = self.smile_version[1].major == 2

0 commit comments

Comments
 (0)