3636
3737import aiohttp
3838from defusedxml import ElementTree as etree
39+ from munch import Munch
3940from packaging .version import Version , parse
4041
4142
@@ -72,16 +73,17 @@ def __init__(
7273 self ._smile_api : SmileAPI | SmileLegacyAPI
7374 self ._stretch_v2 = False
7475 self ._target_smile : str = NONE
75- self .smile_hostname : str = NONE
76- self .smile_hw_version : str | None = None
77- self .smile_legacy = False
78- self .smile_mac_address : str | None = None
79- self .smile_model : str = NONE
80- self .smile_model_id : str | None = None
81- self .smile_name : str = NONE
82- self .smile_type : str = NONE
83- self .smile_version : Version = Version ("0.0.0" )
84- self .smile_zigbee_mac_address : str | None = None
76+ self .smile : Munch = Munch ()
77+ self .smile .hostname : str = NONE
78+ self .smile .hw_version : str | None = None
79+ self .smile .legacy = False
80+ self .smile .mac_address : str | None = None
81+ self .smile .model : str = NONE
82+ self .smile .model_id : str | None = None
83+ self .smile .name : str = NONE
84+ self .smile .type : str = NONE
85+ self .smile .version : Version = Version ("0.0.0" )
86+ self .smile .zigbee_mac_address : str | None = None
8587
8688 @property
8789 def cooling_present (self ) -> bool :
@@ -109,7 +111,7 @@ def reboot(self) -> bool:
109111
110112 All non-legacy devices support gateway-rebooting.
111113 """
112- return not self .smile_legacy
114+ return not self .smile . legacy
113115
114116 async def connect (self ) -> Version :
115117 """Connect to the Plugwise Gateway and determine its name, type, version, and other data."""
@@ -158,16 +160,9 @@ async def connect(self) -> Version:
158160 self ._opentherm_device ,
159161 self ._request ,
160162 self ._schedule_old_states ,
161- self .smile_hostname ,
162- self .smile_hw_version ,
163- self .smile_mac_address ,
164- self .smile_model ,
165- self .smile_model_id ,
166- self .smile_name ,
167- self .smile_type ,
168- self .smile_version ,
163+ self .smile ,
169164 )
170- if not self .smile_legacy
165+ if not self .smile . legacy
171166 else SmileLegacyAPI (
172167 self ._is_thermostat ,
173168 self ._loc_data ,
@@ -176,21 +171,14 @@ async def connect(self) -> Version:
176171 self ._request ,
177172 self ._stretch_v2 ,
178173 self ._target_smile ,
179- self .smile_hostname ,
180- self .smile_hw_version ,
181- self .smile_mac_address ,
182- self .smile_model ,
183- self .smile_name ,
184- self .smile_type ,
185- self .smile_version ,
186- self .smile_zigbee_mac_address ,
174+ self .smile ,
187175 )
188176 )
189177
190178 # Update all endpoints on first connect
191179 await self ._smile_api .full_xml_update ()
192180
193- return self .smile_version
181+ return self .smile . version
194182
195183 async def _smile_detect (
196184 self , result : etree .Element , dsmrmain : etree .Element
@@ -203,23 +191,23 @@ async def _smile_detect(
203191 if (gateway := result .find ("./gateway" )) is not None :
204192 if (v_model := gateway .find ("vendor_model" )) is not None :
205193 model = v_model .text
206- self .smile_version = parse (gateway .find ("firmware_version" ).text )
207- self .smile_hw_version = gateway .find ("hardware_version" ).text
208- self .smile_hostname = gateway .find ("hostname" ).text
209- self .smile_mac_address = gateway .find ("mac_address" ).text
210- self .smile_model_id = gateway .find ("vendor_model" ).text
194+ self .smile . version = parse (gateway .find ("firmware_version" ).text )
195+ self .smile . hw_version = gateway .find ("hardware_version" ).text
196+ self .smile . hostname = gateway .find ("hostname" ).text
197+ self .smile . mac_address = gateway .find ("mac_address" ).text
198+ self .smile . _model_id = gateway .find ("vendor_model" ).text
211199 else :
212200 model = await self ._smile_detect_legacy (result , dsmrmain , model )
213201
214- if model == "Unknown" or self .smile_version is None : # pragma: no cover
202+ if model == "Unknown" or self .smile . version is None : # pragma: no cover
215203 # Corner case check
216204 LOGGER .error (
217205 "Unable to find model or version information, please create"
218206 " an issue on http://github.com/plugwise/python-plugwise"
219207 )
220208 raise UnsupportedDeviceError
221209
222- version_major = str (self .smile_version .major )
210+ version_major = str (self .smile . version .major )
223211 self ._target_smile = f"{ model } _v{ version_major } "
224212 LOGGER .debug ("Plugwise identified as %s" , self ._target_smile )
225213 if self ._target_smile not in SMILES :
@@ -230,7 +218,7 @@ async def _smile_detect(
230218 )
231219 raise UnsupportedDeviceError
232220
233- if not self .smile_legacy :
221+ if not self .smile . legacy :
234222 self ._timeout = DEFAULT_TIMEOUT
235223
236224 if self ._target_smile in ("smile_open_therm_v2" , "smile_thermo_v3" ):
@@ -240,14 +228,14 @@ async def _smile_detect(
240228 ) # pragma: no cover
241229 raise UnsupportedDeviceError # pragma: no cover
242230
243- self .smile_model = "Gateway"
244- self .smile_name = SMILES [self ._target_smile ].smile_name
245- self .smile_type = SMILES [self ._target_smile ].smile_type
231+ self .smile . model = "Gateway"
232+ self .smile . name = SMILES [self ._target_smile ].smile_name
233+ self .smile . type = SMILES [self ._target_smile ].smile_type
246234
247- if self .smile_type == "stretch" :
235+ if self .smile . type == "stretch" :
248236 self ._stretch_v2 = int (version_major ) == 2
249237
250- if self .smile_type == "thermostat" :
238+ if self .smile . type == "thermostat" :
251239 self ._is_thermostat = True
252240 # For Adam, Anna, determine the system capabilities:
253241 # Find the connected heating/cooling device (heater_central),
@@ -275,36 +263,36 @@ async def _smile_detect_legacy(
275263 return_model = model
276264 # Stretch: find the MAC of the zigbee master_controller (= Stick)
277265 if (network := result .find ("./module/protocols/master_controller" )) is not None :
278- self .smile_zigbee_mac_address = network .find ("mac_address" ).text
266+ self .smile . zigbee_mac_address = network .find ("mac_address" ).text
279267 # Find the active MAC in case there is an orphaned Stick
280268 if zb_networks := result .findall ("./network" ):
281269 for zb_network in zb_networks :
282270 if zb_network .find ("./nodes/network_router" ) is not None :
283271 network = zb_network .find ("./master_controller" )
284- self .smile_zigbee_mac_address = network .find ("mac_address" ).text
272+ self .smile . zigbee_mac_address = network .find ("mac_address" ).text
285273
286274 # Legacy Anna or Stretch:
287275 if (
288276 result .find ('./appliance[type="thermostat"]' ) is not None
289277 or network is not None
290278 ):
291279 system = await self ._request (SYSTEM )
292- self .smile_version = parse (system .find ("./gateway/firmware" ).text )
280+ self .smile . version = parse (system .find ("./gateway/firmware" ).text )
293281 return_model = str (system .find ("./gateway/product" ).text )
294- self .smile_hostname = system .find ("./gateway/hostname" ).text
282+ self .smile . hostname = system .find ("./gateway/hostname" ).text
295283 # If wlan0 contains data it's active, eth0 should be checked last as is preferred
296284 for network in ("wlan0" , "eth0" ):
297285 locator = f"./{ network } /mac"
298286 if (net_locator := system .find (locator )) is not None :
299- self .smile_mac_address = net_locator .text
287+ self .smile . mac_address = net_locator .text
300288
301289 # P1 legacy:
302290 elif dsmrmain is not None :
303291 status = await self ._request (STATUS )
304- self .smile_version = parse (status .find ("./system/version" ).text )
292+ self .smile . version = parse (status .find ("./system/version" ).text )
305293 return_model = str (status .find ("./system/product" ).text )
306- self .smile_hostname = status .find ("./network/hostname" ).text
307- self .smile_mac_address = status .find ("./network/mac_address" ).text
294+ self .smile . hostname = status .find ("./network/hostname" ).text
295+ self .smile . mac_address = status .find ("./network/mac_address" ).text
308296 else : # pragma: no cover
309297 # No cornercase, just end of the line
310298 LOGGER .error (
@@ -313,7 +301,7 @@ async def _smile_detect_legacy(
313301 )
314302 raise ResponseError
315303
316- self .smile_legacy = True
304+ self .smile . legacy = True
317305 return return_model
318306
319307 async def async_update (self ) -> dict [str , GwEntityData ]:
0 commit comments