@@ -310,14 +310,12 @@ class SmileHelper:
310310
311311 def __init__ (self ) -> None :
312312 """Set the constructor for this class."""
313- self ._adam_cooling_enabled = False
314- self ._allowed_modes : list [str ] = []
315- self ._anna_cooling_present = False
316313 self ._appliances : etree
317314 self ._appl_data : dict [str , ApplianceData ] = {}
318315 self ._cooling_activation_outdoor_temp : float
319316 self ._cooling_deactivation_threshold : float
320317 self ._cooling_present = False
318+ self ._dhw_allowed_modes : list [str ] = []
321319 self ._domain_objects : etree
322320 self ._heater_id : str | None = None
323321 self ._home_location : str
@@ -331,6 +329,7 @@ def __init__(self) -> None:
331329 self ._on_off_device = False
332330 self ._opentherm_device = False
333331 self ._outdoor_temp : float
332+ self ._reg_allowed_modes : list [str ] = []
334333 self ._schedule_old_states : dict [str , dict [str , str ]] = {}
335334 self ._sched_setpoints : list [float ] | None = None
336335 self ._smile_legacy = False
@@ -340,21 +339,19 @@ def __init__(self) -> None:
340339 self ._system : etree
341340 self ._thermo_locs : dict [str , ThermoLoc ] = {}
342341 ###################################################################
343- # '_elga_cooling_enabled' refers to the state of the Elga heatpump
342+ # '_cooling_enabled' can refer to the state of the Elga heatpump
344343 # connected to an Anna. For Elga, 'elga_status_code' in [8, 9]
345344 # means cooling mode is available, next to heating mode.
346345 # 'elga_status_code' = 8 means cooling is active, 9 means idle.
347346 #
348- # '_lortherm_cooling_enabled' refers to the state of the Loria or
347+ # '_cooling_enabled' cam refer to the state of the Loria or
349348 # Thermastage heatpump connected to an Anna. For these,
350- # 'cooling_state ' = on means set to cooling mode, instead of to
349+ # 'cooling_enabled ' = on means set to cooling mode, instead of to
351350 # heating mode.
352- # 'modulation_level ' = 100 means cooling is active, 0.0 means idle .
351+ # 'cooling_state ' = on means cooling is active.
353352 ###################################################################
354- self ._elga_cooling_active = False
355- self ._elga_cooling_enabled = False
356- self ._lortherm_cooling_active = False
357- self ._lortherm_cooling_enabled = False
353+ self ._cooling_active = False
354+ self ._cooling_enabled = False
358355
359356 self .gateway_id : str | None = None
360357 self .gw_data : GatewayData = {}
@@ -528,15 +525,15 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
528525 ):
529526 appl .zigbee_mac = found .find ("mac_address" ).text
530527
531- # Adam: check for active heating/cooling operation-mode
532- mode_list : list [str ] = []
528+ # Adam: check for active heating/cooling operation-mode and collect modes
529+ reg_mode_list : list [str ] = []
533530 locator = "./actuator_functionalities/regulation_mode_control_functionality"
534531 if (search := appliance .find (locator )) is not None :
535- self ._adam_cooling_enabled = search .find ("mode" ).text == "cooling"
532+ self ._cooling_enabled = search .find ("mode" ).text == "cooling"
536533 if search .find ("allowed_modes" ) is not None :
537534 for mode in search .find ("allowed_modes" ):
538- mode_list .append (mode .text )
539- self ._allowed_modes = mode_list
535+ reg_mode_list .append (mode .text )
536+ self ._reg_allowed_modes = reg_mode_list
540537
541538 return appl
542539
@@ -584,6 +581,16 @@ def _appliance_info_finder(self, appliance: etree, appl: Munch) -> Munch:
584581 if self ._cooling_present
585582 else "Generic heater"
586583 )
584+
585+ # Anna + Loria: collect dhw control operation modes
586+ dhw_mode_list : list [str ] = []
587+ locator = "./actuator_functionalities/domestic_hot_water_mode_control_functionality"
588+ if (search := appliance .find (locator )) is not None :
589+ if search .find ("allowed_modes" ) is not None :
590+ for mode in search .find ("allowed_modes" ):
591+ dhw_mode_list .append (mode .text )
592+ self ._dhw_allowed_modes = dhw_mode_list
593+
587594 return appl
588595
589596 # Collect info from Stretches
@@ -863,7 +870,7 @@ def _appliance_measurements(
863870
864871 data [measurement ] = appl_p_loc .text # type: ignore [literal-required]
865872 # measurements with states "on" or "off" that need to be passed directly
866- if measurement not in ["regulation_mode" ]:
873+ if measurement not in ["dhw_mode" , " regulation_mode" ]:
867874 data [measurement ] = format_measure (appl_p_loc .text , getattr (attrs , ATTR_UNIT_OF_MEASUREMENT )) # type: ignore [literal-required]
868875
869876 # Anna: save cooling-related measurements for later use
@@ -937,7 +944,7 @@ def _get_appliance_data(self, d_id: str) -> DeviceData:
937944 if "c_heating_state" in data :
938945 # Anna + Elga and Adam + OnOff heater/cooler don't use intended_cental_heating_state
939946 # to show the generic heating state
940- if (self ._anna_cooling_present and "heating_state" in data ) or (
947+ if (self ._cooling_present and "heating_state" in data ) or (
941948 self .smile_name == "Adam" and self ._on_off_device
942949 ):
943950 if data .get ("c_heating_state" ) and not data .get ("heating_state" ):
@@ -950,24 +957,25 @@ def _get_appliance_data(self, d_id: str) -> DeviceData:
950957 data .pop ("heating_state" , None )
951958
952959 if d_id == self ._heater_id :
953- if self ._adam_cooling_enabled :
954- data ["adam_cooling_enabled" ] = self ._adam_cooling_enabled
960+ # Adam
961+ if self ._cooling_enabled :
962+ data ["cooling_enabled" ] = self ._cooling_enabled
955963 if self .smile_name == "Smile Anna" :
956- # Use elga_status_code or cooling_state to set the relevant * _cooling_enabled to True
957- if not self ._anna_cooling_present :
964+ # Use elga_status_code or cooling_enabled to set _cooling_enabled to True
965+ if not self ._cooling_present :
958966 pass
959967
960968 # Elga:
961969 if "elga_status_code" in data :
962- self ._elga_cooling_enabled = data ["elga_status_code" ] in [8 , 9 ]
963- data ["elga_cooling_enabled " ] = self ._elga_cooling_enabled
964- self ._elga_cooling_active = data ["elga_status_code" ] == 8
970+ self ._cooling_enabled = data ["elga_status_code" ] in [8 , 9 ]
971+ data ["cooling_enabled " ] = self ._cooling_enabled
972+ self ._cooling_active = data ["elga_status_code" ] == 8
965973 data .pop ("elga_status_code" , None )
966974 # Loria/Thermastate: look at cooling_state, not at cooling_enabled, not available on R32!
967- elif "cooling_state " in data :
968- self ._lortherm_cooling_enabled = data ["cooling_state " ]
969- data ["lortherm_cooling_enabled " ] = self ._lortherm_cooling_enabled
970- self ._lortherm_cooling_active = data ["modulation_level" ] == 100
975+ elif "cooling_ena_switch " in data :
976+ self ._cooling_enabled = data ["cooling_ena_switch " ]
977+ data ["cooling_enabled " ] = self ._cooling_enabled
978+ self ._cooling_active = data ["cooling_state" ]
971979
972980 # Don't show cooling_state when no cooling present
973981 if not self ._cooling_present and "cooling_state" in data :
@@ -1243,7 +1251,7 @@ def _schedules(
12431251 name = self ._domain_objects .find (f'./rule[@id="{ rule_id } "]/name' ).text
12441252 schedule : dict [str , list [float ]] = {}
12451253 # Only process the active schedule in detail for Anna with cooling
1246- if self ._anna_cooling_present and loc_id != NONE :
1254+ if self ._cooling_present and loc_id != NONE :
12471255 locator = f'./rule[@id="{ rule_id } "]/directives'
12481256 directives = self ._domain_objects .find (locator )
12491257 for directive in directives :
@@ -1269,7 +1277,7 @@ def _schedules(
12691277 if schedules :
12701278 available .remove (NONE )
12711279 last_used = self ._last_used_schedule (location , schedules )
1272- if self ._anna_cooling_present and last_used in schedules :
1280+ if self ._cooling_present and last_used in schedules :
12731281 schedule_temperatures = schedules_temps (schedules , last_used )
12741282
12751283 return available , selected , schedule_temperatures , last_used
@@ -1367,7 +1375,9 @@ def _update_device_with_dicts(
13671375
13681376 # Add plugwise notification binary_sensor to the relevant gateway
13691377 if d_id == self .gateway_id :
1370- if self ._is_thermostat :
1378+ if self ._is_thermostat or (
1379+ not self ._smile_legacy and self .smile_type == "power"
1380+ ):
13711381 bs_dict ["plugwise_notification" ] = False
13721382
13731383 device_out .update (data )
0 commit comments