Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Ongoing

- Continuous improvements

## v1.6.3

- Implement cooling-related fixes, trying to solve HA Core issue [#132479](https://github.com/home-assistant/core/issues/132479)
Expand Down
107 changes: 64 additions & 43 deletions plugwise/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@
from packaging import version


def search_actuator_functionalities(appliance: etree, actuator: str) -> etree | None:
"""Helper-function for finding the relevant actuator xml-structure."""
locator = f"./actuator_functionalities/{actuator}"
if (search := appliance.find(locator)) is not None:
return search

return None


class SmileComm:
"""The SmileComm class."""

Expand Down Expand Up @@ -398,7 +407,9 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch:
self._appl_heater_central_info(
appl, appliance, False
) # False means non-legacy device
self._appl_dhw_mode_info(appl, appliance)
self._dhw_allowed_modes = self._get_appl_actuator_modes(
appliance, "domestic_hot_water_mode_control_functionality"
)
# Skip orphaned heater_central (Core Issue #104433)
if appl.entity_id != self._heater_id:
return Munch()
Expand Down Expand Up @@ -441,7 +452,9 @@ def _appl_gateway_info(self, appl: Munch, appliance: etree) -> Munch:
appl.zigbee_mac = found.find("mac_address").text

# Also, collect regulation_modes and check for cooling, indicating cooling-mode is present
self._appl_regulation_mode_info(appliance)
self._reg_allowed_modes = self._get_appl_actuator_modes(
appliance, "regulation_mode_control_functionality"
)

# Finally, collect the gateway_modes
self._gw_allowed_modes = []
Expand All @@ -452,34 +465,24 @@ def _appl_gateway_info(self, appl: Munch, appliance: etree) -> Munch:

return appl

def _appl_regulation_mode_info(self, appliance: etree) -> None:
"""Helper-function for _appliance_info_finder()."""
reg_mode_list: list[str] = []
locator = "./actuator_functionalities/regulation_mode_control_functionality"
if (search := appliance.find(locator)) is not None:
if search.find("allowed_modes") is not None:
for mode in search.find("allowed_modes"):
reg_mode_list.append(mode.text)
if mode.text == "cooling":
self._cooling_present = True
self._reg_allowed_modes = reg_mode_list

def _appl_dhw_mode_info(self, appl: Munch, appliance: etree) -> Munch:
"""Helper-function for _appliance_info_finder().

Collect dhw control operation modes - Anna + Loria.
"""
dhw_mode_list: list[str] = []
locator = (
"./actuator_functionalities/domestic_hot_water_mode_control_functionality"
)
if (search := appliance.find(locator)) is not None:
if search.find("allowed_modes") is not None:
for mode in search.find("allowed_modes"):
dhw_mode_list.append(mode.text)
self._dhw_allowed_modes = dhw_mode_list
def _get_appl_actuator_modes(
self, appliance: etree, actuator_type: str
) -> list[str]:
"""Get allowed modes for the given actuator type."""
mode_list: list[str] = []
if (
search := search_actuator_functionalities(appliance, actuator_type)
) is not None and (modes := search.find("allowed_modes")) is not None:
for mode in modes:
mode_list.append(mode.text)
self._check_cooling_mode(mode.text)

return appl
return mode_list

def _check_cooling_mode(self, mode: str) -> None:
"""Check if cooling mode is present and update state."""
if mode == "cooling":
self._cooling_present = True

def _get_appliances_with_offset_functionality(self) -> list[str]:
"""Helper-function collecting all appliance that have offset_functionality."""
Expand Down Expand Up @@ -645,7 +648,10 @@ def _get_plugwise_notifications(self) -> None:
def _get_actuator_functionalities(
self, xml: etree, entity: GwEntityData, data: GwEntityData
) -> None:
"""Helper-function for _get_measurement_data()."""
"""Get and process the actuator_functionalities details for an entity.

Add the resulting dict(s) to the entity's data.
"""
for item in ACTIVE_ACTUATORS:
# Skip max_dhw_temperature, not initially valid,
# skip thermostat for all but zones with thermostats
Expand Down Expand Up @@ -701,21 +707,36 @@ def _get_actuator_functionalities(
act_item = cast(ActuatorType, item)
data[act_item] = temp_dict

def _get_actuator_mode(
self, appliance: etree, entity_id: str, key: str
) -> str | None:
"""Helper-function for _get_regulation_mode and _get_gateway_mode.

Collect the requested gateway mode.
"""
if not (self.smile(ADAM) and entity_id == self.gateway_id):
return None

if (search := search_actuator_functionalities(appliance, key)) is not None:
return str(search.find("mode").text)

return None

def _get_regulation_mode(
self, appliance: etree, entity_id: str, data: GwEntityData
) -> None:
"""Helper-function for _get_measurement_data().

Adam: collect the gateway regulation_mode.
"""
if not (self.smile(ADAM) and entity_id == self.gateway_id):
return

locator = "./actuator_functionalities/regulation_mode_control_functionality"
if (search := appliance.find(locator)) is not None:
data["select_regulation_mode"] = search.find("mode").text
if (
mode := self._get_actuator_mode(
appliance, entity_id, "regulation_mode_control_functionality"
)
) is not None:
data["select_regulation_mode"] = mode
self._count += 1
self._cooling_enabled = data["select_regulation_mode"] == "cooling"
self._cooling_enabled = mode == "cooling"

def _get_gateway_mode(
self, appliance: etree, entity_id: str, data: GwEntityData
Expand All @@ -724,12 +745,12 @@ def _get_gateway_mode(

Adam: collect the gateway mode.
"""
if not (self.smile(ADAM) and entity_id == self.gateway_id):
return

locator = "./actuator_functionalities/gateway_mode_control_functionality"
if (search := appliance.find(locator)) is not None:
data["select_gateway_mode"] = search.find("mode").text
if (
mode := self._get_actuator_mode(
appliance, entity_id, "gateway_mode_control_functionality"
)
) is not None:
data["select_gateway_mode"] = mode
self._count += 1

def _get_gateway_outdoor_temp(self, entity_id: str, data: GwEntityData) -> None:
Expand Down
Loading