44"""
55from __future__ import annotations
66
7+ from plugwise .constants import ModelData
78from plugwise .util import check_heater_central , check_model
89
910from defusedxml import ElementTree as etree
@@ -16,6 +17,7 @@ class SmileCommon:
1617 def __init__ (self ) -> None :
1718 """Init."""
1819 self ._appliances : etree
20+ self ._cooling_present : bool
1921 self ._heater_id : str
2022 self ._on_off_device : bool
2123 self ._opentherm_device : bool
@@ -25,12 +27,11 @@ def smile(self, name: str) -> bool:
2527 """Helper-function checking the smile-name."""
2628 return self .smile_name == name
2729
28- def _appl_thermostat_info (self , xml : etree , appl : Munch ) -> Munch :
30+ def _appl_thermostat_info (self , xml_1 : etree , xml_2 : etree , appl : Munch ) -> Munch :
2931 """Helper-function for _appliance_info_finder()."""
30- # Collect thermostat device info
3132 locator = "./logs/point_log[type='thermostat']/thermostat"
3233 mod_type = "thermostat"
33- module_data = self ._get_module_data (xml , locator , mod_type )
34+ module_data = self ._get_module_data (xml_1 , xml_2 , locator , mod_type )
3435 appl .vendor_name = module_data ["vendor_name" ]
3536 appl .model = check_model (module_data ["vendor_model" ], appl .vendor_name )
3637 appl .hardware = module_data ["hardware_version" ]
@@ -39,13 +40,20 @@ def _appl_thermostat_info(self, xml: etree, appl: Munch) -> Munch:
3940
4041 return appl
4142
42- def _appl_heater_central_info (self , xml_1 : etree , xml_2 : etree , appl : Munch ) -> Munch :
43+ def _appl_heater_central_info (
44+ self ,
45+ xml_1 : etree ,
46+ xml_2 : etree ,
47+ xml_3 : etree ,
48+ appl : Munch
49+ ) -> Munch :
4350 """Helper-function for _appliance_info_finder()."""
4451 # Remove heater_central when no active device present
4552 if not self ._opentherm_device and not self ._on_off_device :
4653 return None
4754
4855 # Find the valid heater_central
56+ # xml_1 = self._appliances for legacy, self._domain_objects for actual
4957 self ._heater_id = check_heater_central (xml_1 )
5058
5159 # Info for On-Off device
@@ -57,16 +65,70 @@ def _appl_heater_central_info(self, xml_1: etree, xml_2: etree, appl: Munch) ->
5765
5866 # Info for OpenTherm device
5967 appl .name = "OpenTherm"
60- locator1 = "./logs/point_log[type='flame_state']/boiler_state"
61- locator2 = "./services/boiler_state"
68+ locator_1 = "./logs/point_log[type='flame_state']/boiler_state"
69+ locator_2 = "./services/boiler_state"
6270 mod_type = "boiler_state"
63- module_data = self ._get_module_data (xml_2 , locator1 , mod_type )
71+ # xml_2 = appliance
72+ # xml_3 = self._modules for legacy, self._domain_objects for actual
73+ module_data = self ._get_module_data (xml_2 , xml_3 , locator_1 , mod_type )
6474 if not module_data ["contents" ]:
65- module_data = self ._get_module_data (xml_2 , locator2 , mod_type )
75+ module_data = self ._get_module_data (xml_2 , xml_3 , locator_2 , mod_type )
6676 appl .vendor_name = module_data ["vendor_name" ]
6777 appl .hardware = module_data ["hardware_version" ]
6878 appl .model = module_data ["vendor_model" ]
6979 if appl .model is None :
70- appl .model = "Generic heater"
80+ appl .model = (
81+ "Generic heater/cooler"
82+ if self ._cooling_present
83+ else "Generic heater"
84+ )
7185
7286 return appl
87+
88+ def _get_module_data (
89+ self , xml_1 : etree , xml_2 : etree , locator : str , mod_type : str , legacy = False ,
90+ ) -> ModelData :
91+ """Helper-function for _energy_device_info_finder() and _appliance_info_finder().
92+
93+ Collect requested info from MODULES.
94+ """
95+ model_data : ModelData = {
96+ "contents" : False ,
97+ "firmware_version" : None ,
98+ "hardware_version" : None ,
99+ "reachable" : None ,
100+ "vendor_name" : None ,
101+ "vendor_model" : None ,
102+ "zigbee_mac_address" : None ,
103+ }
104+ # xml_1 = appliance
105+ if (appl_search := xml_1 .find (locator )) is not None :
106+ link_id = appl_search .attrib ["id" ]
107+ loc = f".//services/{ mod_type } [@id='{ link_id } ']...."
108+ if legacy :
109+ loc = f".//{ mod_type } [@id='{ link_id } ']...."
110+ # Not possible to walrus for some reason...
111+ # xml_2 = self._modules for legacy, self._domain_objects for actual
112+ module = xml_2 .find (loc )
113+ if module is not None : # pylint: disable=consider-using-assignment-expr
114+ model_data ["contents" ] = True
115+ if (vendor_name := module .find ("vendor_name" ).text ) is not None :
116+ model_data ["vendor_name" ] = vendor_name
117+ if "Plugwise" in vendor_name :
118+ model_data ["vendor_name" ] = vendor_name .split (" " , 1 )[0 ]
119+ model_data ["vendor_model" ] = module .find ("vendor_model" ).text
120+ model_data ["hardware_version" ] = module .find ("hardware_version" ).text
121+ model_data ["firmware_version" ] = module .find ("firmware_version" ).text
122+ if legacy :
123+ # Stretches
124+ if (router := module .find ("./protocols/network_router" )) is not None :
125+ model_data ["zigbee_mac_address" ] = router .find ("mac_address" ).text
126+ # Also look for the Circle+/Stealth M+
127+ if (coord := module .find ("./protocols/network_coordinator" )) is not None :
128+ model_data ["zigbee_mac_address" ] = coord .find ("mac_address" ).text
129+ # Adam
130+ elif (zb_node := module .find ("./protocols/zig_bee_node" )) is not None :
131+ model_data ["zigbee_mac_address" ] = zb_node .find ("mac_address" ).text
132+ model_data ["reachable" ] = zb_node .find ("reachable" ).text == "true"
133+
134+ return model_data
0 commit comments