@@ -158,38 +158,67 @@ def _derived_data_helper(
158158 "mode" : DerivedWirelessMode .PTP ,
159159 "sku" : sku ,
160160 }
161+
161162 # WIRELESS
162163 derived = derived_wireless_data_func (derived , response )
163164
164- # INTERFACES
165- addresses = {}
166- interface_order = ["br0" , "eth0" , "ath0" ]
167-
165+ # Interfaces / MAC (for unique id)
168166 interfaces = response .get ("interfaces" , [])
169-
170167 # No interfaces, no mac, no usability
171168 if not interfaces :
172169 _LOGGER .error ("Failed to determine interfaces from AirOS data" )
173170 raise AirOSKeyDataMissingError from None
174171
175- for interface in interfaces :
176- if interface ["enabled" ]: # Only consider if enabled
177- addresses [interface ["ifname" ]] = interface ["hwaddr" ]
172+ derived ["mac" ] = AirOS .get_mac (interfaces )["mac" ]
173+ derived ["mac_interface" ] = AirOS .get_mac (interfaces )["mac_interface" ]
178174
179- # Fallback take fist alternate interface found
180- derived ["mac" ] = interfaces [0 ]["hwaddr" ]
181- derived ["mac_interface" ] = interfaces [0 ]["ifname" ]
182-
183- for interface in interface_order :
184- if interface in addresses :
185- derived ["mac" ] = addresses [interface ]
186- derived ["mac_interface" ] = interface
187- break
175+ # Firmware Major Version
176+ fwversion = (response .get ("host" ) or {}).get ("fwversion" , "invalid" )
177+ derived ["fw_major" ] = AirOS .get_fw_major (fwversion )
188178
189179 response ["derived" ] = derived
190180
191181 return response
192182
183+ @staticmethod
184+ def get_fw_major (fwversion : str ) -> int :
185+ """Extract major firmware version from fwversion string."""
186+ try :
187+ return int (fwversion .lstrip ("v" ).split ("." , 1 )[0 ])
188+ except (ValueError , AttributeError ) as err :
189+ _LOGGER .error ("Invalid firmware version '%s'" , fwversion )
190+ raise AirOSKeyDataMissingError ("invalid fwversion" ) from err
191+
192+ @staticmethod
193+ def get_mac (interfaces : list [dict [str , Any ]]) -> dict [str , str ]:
194+ """Extract MAC address from interfaces."""
195+ result : dict [str , str ] = {"mac" : "" , "mac_interface" : "" }
196+
197+ if not interfaces :
198+ return result
199+
200+ addresses : dict [str , str ] = {}
201+ interface_order = ["br0" , "eth0" , "ath0" ]
202+
203+ for interface in interfaces :
204+ if (
205+ interface .get ("enabled" )
206+ and interface .get ("hwaddr" )
207+ and interface .get ("ifname" )
208+ ):
209+ addresses [interface ["ifname" ]] = interface ["hwaddr" ]
210+
211+ for preferred in interface_order :
212+ if preferred in addresses :
213+ result ["mac" ] = addresses [preferred ]
214+ result ["mac_interface" ] = preferred
215+ break
216+ else :
217+ result ["mac" ] = interfaces [0 ].get ("hwaddr" , "" )
218+ result ["mac_interface" ] = interfaces [0 ].get ("ifname" , "" )
219+
220+ return result
221+
193222 @classmethod
194223 def derived_data (cls , response : dict [str , Any ]) -> dict [str , Any ]:
195224 """Add derived data to the device response (instance method for polymorphism)."""
@@ -354,12 +383,15 @@ async def login(self) -> None:
354383 else :
355384 return
356385
357- async def status (self ) -> AirOSDataModel :
386+ async def status (self , underived : bool = False ) -> AirOSDataModel | dict [ str , Any ] :
358387 """Retrieve status from the device."""
359388 response = await self ._request_json (
360389 "GET" , self ._status_cgi_url , authenticated = True
361390 )
362391
392+ if underived :
393+ return response
394+
363395 try :
364396 adjusted_json = self .derived_data (response )
365397 return self .data_model .from_dict (adjusted_json )
0 commit comments