6868from packaging import version
6969
7070
71+ def search_actuator_functionalities (appliance : etree , actuator : str ) -> etree | None :
72+ """Helper-function for finding the relevant actuator xml-structure."""
73+ locator = f"./actuator_functionalities/{ actuator } "
74+ if (search := appliance .find (locator )) is not None :
75+ return search
76+
77+ return None
78+
79+
7180class SmileComm :
7281 """The SmileComm class."""
7382
@@ -398,7 +407,9 @@ def _appliance_info_finder(self, appl: Munch, appliance: etree) -> Munch:
398407 self ._appl_heater_central_info (
399408 appl , appliance , False
400409 ) # False means non-legacy device
401- self ._appl_dhw_mode_info (appl , appliance )
410+ self ._dhw_allowed_modes = self ._get_appl_actuator_modes (
411+ appliance , "domestic_hot_water_mode_control_functionality"
412+ )
402413 # Skip orphaned heater_central (Core Issue #104433)
403414 if appl .entity_id != self ._heater_id :
404415 return Munch ()
@@ -441,7 +452,9 @@ def _appl_gateway_info(self, appl: Munch, appliance: etree) -> Munch:
441452 appl .zigbee_mac = found .find ("mac_address" ).text
442453
443454 # Also, collect regulation_modes and check for cooling, indicating cooling-mode is present
444- self ._appl_regulation_mode_info (appliance )
455+ self ._reg_allowed_modes = self ._get_appl_actuator_modes (
456+ appliance , "regulation_mode_control_functionality"
457+ )
445458
446459 # Finally, collect the gateway_modes
447460 self ._gw_allowed_modes = []
@@ -452,34 +465,24 @@ def _appl_gateway_info(self, appl: Munch, appliance: etree) -> Munch:
452465
453466 return appl
454467
455- def _appl_regulation_mode_info (self , appliance : etree ) -> None :
456- """Helper-function for _appliance_info_finder()."""
457- reg_mode_list : list [str ] = []
458- locator = "./actuator_functionalities/regulation_mode_control_functionality"
459- if (search := appliance .find (locator )) is not None :
460- if search .find ("allowed_modes" ) is not None :
461- for mode in search .find ("allowed_modes" ):
462- reg_mode_list .append (mode .text )
463- if mode .text == "cooling" :
464- self ._cooling_present = True
465- self ._reg_allowed_modes = reg_mode_list
466-
467- def _appl_dhw_mode_info (self , appl : Munch , appliance : etree ) -> Munch :
468- """Helper-function for _appliance_info_finder().
469-
470- Collect dhw control operation modes - Anna + Loria.
471- """
472- dhw_mode_list : list [str ] = []
473- locator = (
474- "./actuator_functionalities/domestic_hot_water_mode_control_functionality"
475- )
476- if (search := appliance .find (locator )) is not None :
477- if search .find ("allowed_modes" ) is not None :
478- for mode in search .find ("allowed_modes" ):
479- dhw_mode_list .append (mode .text )
480- self ._dhw_allowed_modes = dhw_mode_list
468+ def _get_appl_actuator_modes (
469+ self , appliance : etree , actuator_type : str
470+ ) -> list [str ]:
471+ """Get allowed modes for the given actuator type."""
472+ mode_list : list [str ] = []
473+ if (
474+ search := search_actuator_functionalities (appliance , actuator_type )
475+ ) is not None and (modes := search .find ("allowed_modes" )) is not None :
476+ for mode in modes :
477+ mode_list .append (mode .text )
478+ self ._check_cooling_mode (mode .text )
481479
482- return appl
480+ return mode_list
481+
482+ def _check_cooling_mode (self , mode : str ) -> None :
483+ """Check if cooling mode is present and update state."""
484+ if mode == "cooling" :
485+ self ._cooling_present = True
483486
484487 def _get_appliances_with_offset_functionality (self ) -> list [str ]:
485488 """Helper-function collecting all appliance that have offset_functionality."""
@@ -645,7 +648,10 @@ def _get_plugwise_notifications(self) -> None:
645648 def _get_actuator_functionalities (
646649 self , xml : etree , entity : GwEntityData , data : GwEntityData
647650 ) -> None :
648- """Helper-function for _get_measurement_data()."""
651+ """Get and process the actuator_functionalities details for an entity.
652+
653+ Add the resulting dict(s) to the entity's data.
654+ """
649655 for item in ACTIVE_ACTUATORS :
650656 # Skip max_dhw_temperature, not initially valid,
651657 # skip thermostat for all but zones with thermostats
@@ -701,21 +707,36 @@ def _get_actuator_functionalities(
701707 act_item = cast (ActuatorType , item )
702708 data [act_item ] = temp_dict
703709
710+ def _get_actuator_mode (
711+ self , appliance : etree , entity_id : str , key : str
712+ ) -> str | None :
713+ """Helper-function for _get_regulation_mode and _get_gateway_mode.
714+
715+ Collect the requested gateway mode.
716+ """
717+ if not (self .smile (ADAM ) and entity_id == self .gateway_id ):
718+ return None
719+
720+ if (search := search_actuator_functionalities (appliance , key )) is not None :
721+ return str (search .find ("mode" ).text )
722+
723+ return None
724+
704725 def _get_regulation_mode (
705726 self , appliance : etree , entity_id : str , data : GwEntityData
706727 ) -> None :
707728 """Helper-function for _get_measurement_data().
708729
709730 Adam: collect the gateway regulation_mode.
710731 """
711- if not ( self . smile ( ADAM ) and entity_id == self . gateway_id ):
712- return
713-
714- locator = "./actuator_functionalities/regulation_mode_control_functionality"
715- if ( search := appliance . find ( locator ) ) is not None :
716- data ["select_regulation_mode" ] = search . find ( " mode" ). text
732+ if (
733+ mode := self . _get_actuator_mode (
734+ appliance , entity_id , "regulation_mode_control_functionality"
735+ )
736+ ) is not None :
737+ data ["select_regulation_mode" ] = mode
717738 self ._count += 1
718- self ._cooling_enabled = data [ "select_regulation_mode" ] == "cooling"
739+ self ._cooling_enabled = mode == "cooling"
719740
720741 def _get_gateway_mode (
721742 self , appliance : etree , entity_id : str , data : GwEntityData
@@ -724,12 +745,12 @@ def _get_gateway_mode(
724745
725746 Adam: collect the gateway mode.
726747 """
727- if not ( self . smile ( ADAM ) and entity_id == self . gateway_id ):
728- return
729-
730- locator = "./actuator_functionalities/gateway_mode_control_functionality"
731- if ( search := appliance . find ( locator ) ) is not None :
732- data ["select_gateway_mode" ] = search . find ( " mode" ). text
748+ if (
749+ mode := self . _get_actuator_mode (
750+ appliance , entity_id , "gateway_mode_control_functionality"
751+ )
752+ ) is not None :
753+ data ["select_gateway_mode" ] = mode
733754 self ._count += 1
734755
735756 def _get_gateway_outdoor_temp (self , entity_id : str , data : GwEntityData ) -> None :
0 commit comments