@@ -534,58 +534,18 @@ def _get_measurement_data(self, dev_id: str) -> DeviceZoneData:
534534 if appliance .find ("type" ).text in ACTUATOR_CLASSES :
535535 self ._get_actuator_functionalities (appliance , device , data )
536536
537- if dev_id == self .gateway_id and self .smile (ADAM ):
538- self ._get_regulation_mode (appliance , data )
539- self ._get_gateway_mode (appliance , data )
540-
541- # Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS - under Home
542- # The outdoor_temperature present in APPLIANCES is a local sensor connected to the active device
543- if self ._is_thermostat and dev_id == self .gateway_id :
544- outdoor_temperature = self ._object_value (
545- self ._home_location , "outdoor_temperature"
546- )
547- if outdoor_temperature is not None :
548- data .update ({"sensors" : {"outdoor_temperature" : outdoor_temperature }})
549- self ._count += 1
537+ self ._get_regulation_mode (appliance , dev_id , data )
538+ self ._get_gateway_mode (appliance , dev_id , data )
539+ self ._get_gateway_outdoor_temp (dev_id , data )
550540
551541 if "c_heating_state" in data :
552542 self ._process_c_heating_state (data )
553543 # Remove c_heating_state after processing
554544 data .pop ("c_heating_state" )
555545 self ._count -= 1
556546
557- if self ._is_thermostat and self .smile (ANNA ) and dev_id == self ._heater_id :
558- # Anna+Elga: base cooling_state on the elga-status-code
559- if "elga_status_code" in data :
560- if data ["thermostat_supports_cooling" ]:
561- # Techneco Elga has cooling-capability
562- self ._cooling_present = True
563- data ["model" ] = "Generic heater/cooler"
564- self ._cooling_enabled = data ["elga_status_code" ] in (8 , 9 )
565- data ["binary_sensors" ]["cooling_state" ] = self ._cooling_active = (
566- data ["elga_status_code" ] == 8
567- )
568- # Elga has no cooling-switch
569- if "cooling_ena_switch" in data ["switches" ]:
570- data ["switches" ].pop ("cooling_ena_switch" )
571- self ._count -= 1
572-
573- data .pop ("elga_status_code" , None )
574- self ._count -= 1
575-
576- # Loria/Thermastage: cooling-related is based on cooling_state
577- # and modulation_level
578- elif self ._cooling_present and "cooling_state" in data ["binary_sensors" ]:
579- self ._cooling_enabled = data ["binary_sensors" ]["cooling_state" ]
580- self ._cooling_active = data ["sensors" ]["modulation_level" ] == 100
581- # For Loria the above does not work (pw-beta issue #301)
582- if "cooling_ena_switch" in data ["switches" ]:
583- self ._cooling_enabled = data ["switches" ]["cooling_ena_switch" ]
584- self ._cooling_active = data ["binary_sensors" ]["cooling_state" ]
585-
586- self ._cleanup_data (data )
587-
588- return data
547+ if self ._is_thermostat and self .smile (ANNA ):
548+ self ._update_anna_cooling (dev_id , data )
589549
590550 def _power_data_from_location (self , loc_id : str ) -> DeviceZoneData :
591551 """Helper-function for smile.py: _get_device_zone_data().
@@ -731,27 +691,50 @@ def _get_actuator_functionalities(
731691 act_item = cast (ActuatorType , item )
732692 data [act_item ] = temp_dict
733693
734- def _get_regulation_mode (self , appliance : etree , data : DeviceZoneData ) -> None :
694+ def _get_regulation_mode (
695+ self , appliance : etree , dev_id : str , data : DeviceZoneData
696+ ) -> None :
735697 """Helper-function for _get_measurement_data().
736698
737- Collect the gateway regulation_mode.
699+ Adam: collect the gateway regulation_mode.
738700 """
701+ if not (self .smile (ADAM ) and dev_id == self .gateway_id ):
702+ return
703+
739704 locator = "./actuator_functionalities/regulation_mode_control_functionality"
740705 if (search := appliance .find (locator )) is not None :
741706 data ["select_regulation_mode" ] = search .find ("mode" ).text
742707 self ._count += 1
743708 self ._cooling_enabled = data ["select_regulation_mode" ] == "cooling"
744709
745- def _get_gateway_mode (self , appliance : etree , data : DeviceZoneData ) -> None :
710+ def _get_gateway_mode (
711+ self , appliance : etree , dev_id : str , data : DeviceZoneData
712+ ) -> None :
746713 """Helper-function for _get_measurement_data().
747714
748- Collect the gateway mode.
715+ Adam: collect the gateway mode.
749716 """
717+ if not (self .smile (ADAM ) and dev_id == self .gateway_id ):
718+ return
719+
750720 locator = "./actuator_functionalities/gateway_mode_control_functionality"
751721 if (search := appliance .find (locator )) is not None :
752722 data ["select_gateway_mode" ] = search .find ("mode" ).text
753723 self ._count += 1
754724
725+ def _get_gateway_outdoor_temp (self , dev_id : str , data : DeviceZoneData ) -> None :
726+ """Adam & Anna: the Smile outdoor_temperature is present in DOMAIN_OBJECTS and LOCATIONS.
727+
728+ Available under the Home location.
729+ """
730+ if self ._is_thermostat and dev_id == self .gateway_id :
731+ outdoor_temperature = self ._object_value (
732+ self ._home_location , "outdoor_temperature"
733+ )
734+ if outdoor_temperature is not None :
735+ data .update ({"sensors" : {"outdoor_temperature" : outdoor_temperature }})
736+ self ._count += 1
737+
755738 def _object_value (self , obj_id : str , measurement : str ) -> float | int | None :
756739 """Helper-function for smile.py: _get_device_zone_data() and _device_data_anna().
757740
@@ -770,29 +753,70 @@ def _process_c_heating_state(self, data: DeviceZoneData) -> None:
770753
771754 Process the central_heating_state value.
772755 """
756+ # Adam or Anna + OnOff device
773757 if self ._on_off_device :
774- # Anna + OnOff heater: use central_heating_state to show heating_state
775- # Solution for Core issue #81839
776- if self .smile (ANNA ):
777- data ["binary_sensors" ]["heating_state" ] = data ["c_heating_state" ]
778-
779- # Adam + OnOff cooling: use central_heating_state to show heating/cooling_state
780- if self .smile (ADAM ):
781- if "heating_state" not in data ["binary_sensors" ]:
782- self ._count += 1
783- data ["binary_sensors" ]["heating_state" ] = False
784- if "cooling_state" not in data ["binary_sensors" ]:
785- self ._count += 1
786- data ["binary_sensors" ]["cooling_state" ] = False
787- if self ._cooling_enabled :
788- data ["binary_sensors" ]["cooling_state" ] = data ["c_heating_state" ]
789- else :
790- data ["binary_sensors" ]["heating_state" ] = data ["c_heating_state" ]
758+ self ._process_on_off_device_c_heating_state (data )
791759
792760 # Anna + Elga: use central_heating_state to show heating_state
793761 if self ._elga :
794762 data ["binary_sensors" ]["heating_state" ] = data ["c_heating_state" ]
795763
764+ def _process_on_off_device_c_heating_state (self , data : DeviceZoneData ) -> None :
765+ """Adam or Anna + OnOff device - use central_heating_state to show heating/cooling_state.
766+
767+ Solution for Core issue #81839.
768+ """
769+ if self .smile (ANNA ):
770+ data ["binary_sensors" ]["heating_state" ] = data ["c_heating_state" ]
771+
772+ if self .smile (ADAM ):
773+ if "heating_state" not in data ["binary_sensors" ]:
774+ self ._count += 1
775+ data ["binary_sensors" ]["heating_state" ] = False
776+ if "cooling_state" not in data ["binary_sensors" ]:
777+ self ._count += 1
778+ data ["binary_sensors" ]["cooling_state" ] = False
779+ if self ._cooling_enabled :
780+ data ["binary_sensors" ]["cooling_state" ] = data ["c_heating_state" ]
781+ else :
782+ data ["binary_sensors" ]["heating_state" ] = data ["c_heating_state" ]
783+
784+ def _update_anna_cooling (self , dev_id : str , data : DeviceZoneData ) -> None :
785+ """Update the Anna heater_central device for cooling.
786+
787+ Support added for Techneco Elga and Thercon Loria/Thermastage.
788+ """
789+ if dev_id == self ._heater_id :
790+ # Anna+Elga: base cooling_state on the elga-status-code
791+ if "elga_status_code" in data :
792+ if data ["thermostat_supports_cooling" ]:
793+ # Techneco Elga has cooling-capability
794+ self ._cooling_present = True
795+ data ["model" ] = "Generic heater/cooler"
796+ self ._cooling_enabled = data ["elga_status_code" ] in (8 , 9 )
797+ data ["binary_sensors" ]["cooling_state" ] = self ._cooling_active = (
798+ data ["elga_status_code" ] == 8
799+ )
800+ # Elga has no cooling-switch
801+ if "cooling_ena_switch" in data ["switches" ]:
802+ data ["switches" ].pop ("cooling_ena_switch" )
803+ self ._count -= 1
804+
805+ data .pop ("elga_status_code" , None )
806+ self ._count -= 1
807+
808+ # Loria/Thermastage: cooling-related is based on cooling_state
809+ # and modulation_level
810+ elif self ._cooling_present and "cooling_state" in data ["binary_sensors" ]:
811+ self ._cooling_enabled = data ["binary_sensors" ]["cooling_state" ]
812+ self ._cooling_active = data ["sensors" ]["modulation_level" ] == 100
813+ # For Loria the above does not work (pw-beta issue #301)
814+ if "cooling_ena_switch" in data ["switches" ]:
815+ self ._cooling_enabled = data ["switches" ]["cooling_ena_switch" ]
816+ self ._cooling_active = data ["binary_sensors" ]["cooling_state" ]
817+
818+ self ._cleanup_data (data )
819+
796820 def _cleanup_data (self , data : DeviceZoneData ) -> None :
797821 """Helper-function for _get_measurement_data().
798822
0 commit comments