AirOS 6 Wireless Deserialization#
The Wireless6 dataclass in airos/data.py models the wireless status payload for AirOS v6 devices. Unlike the v8 Wireless model, AirOS v6 API responses return raw strings for opmode, antenna, txrate, and rxrate rather than structured/typed fields. A __pre_deserialize__ hook normalizes these into virtual fields β ieeemode, antenna_gain, and polling β so that callers get a unified interface across firmware generations .
Pre-Deserialization Field Mappings#
All transformation logic lives in Wireless6.__pre_deserialize__:
| Raw field | Virtual field | Logic |
|---|---|---|
opmode | ieeemode: IeeeMode | Upper-cased, then validated against IeeeMode enum |
antenna | antenna_gain: int | None | Regex extracts dBi integer (e.g. "400 - 25 dBi" β 25) |
rxrate / txrate | polling: Polling6 | Mbps strings β integer kbps; rxrate β dl_capacity, txrate β ul_capacity |
frequency | frequency: int | Strips " MHz" suffix when present |
The same hook also calls _check_and_log_unknown_enum_value on mode (β Wireless6Mode) and security (β Security) before processing ieeemode .
IeeeMode Enum#
IeeeMode is the shared enum for both v6 and v8 devices. Current members:
| Enum member | String value | Device context |
|---|---|---|
AUTO | "AUTO" | Generic |
_11ACVHT80 | "11ACVHT80" | NanoStation (v8) |
_11ACVHT60 | "11ACVHT60" | β |
_11ACVHT50 | "11ACVHT50" | β |
_11ACVHT40 | "11ACVHT40" | β |
_11ACVHT20 | "11ACVHT20" | LiteBeam 5AC |
_11NAHT40MINUS | "11NAHT40MINUS" | v6 XM |
_11NAHT40PLUS | "11NAHT40PLUS" | v6 XW |
_11NAHT20 | "11NAHT20" | PowerBeam M5 400 / v6 XW 20 MHz |
_11NGHT20 | "11NGHT20" | v6 XM 900 MHz / NanoStation loco M900 |
A trailing comment # More to be added when known signals this list is explicitly incomplete .
Unknown Enum Guard & Failure Mode#
_check_and_log_unknown_enum_value is the central defensive guard. When a string value is not a valid member of the target enum, it:
- Deletes the key from the raw dict
- Logs a
WARNINGwith the unknown value and a link to the GitHub issues page
This prevents mashumaro from raising on unknown enum strings, but has a cascading consequence: if the deleted key is a required field (e.g. ieeemode: IeeeMode, which has no default), mashumaro raises MissingField, which propagates as InvalidFieldValue on the parent AirOS6Data.wireless .
The PowerBeam M5 400 running firmware v6.3.24 triggered exactly this: opmode = "11NAHT20" was unknown at the time, causing the integration to fail entirely on status polling .
Adding Support for a New Device#
When a device reports an unrecognized opmode string:
- Note the unknown value from the
WARNINGlog line. - Add a new member to
IeeeModefollowing the existing convention (prefix numeric strings with_, e.g._11NAHT20 = "11NAHT20"). - If the device model name needs a SKU mapping, add it to
MANUAL_MODELSinairos/model_map.py. - Reference PRs: #205 β NanoStation loco M900 /
11NGHT20and #45 β LiteBeam 5AC /11ACVHT20+11ACVHT40.
Key Source References#
| File | Relevance |
|---|---|
airos/data.py β IeeeMode | Enum of all recognized opmode strings |
airos/data.py β Wireless6 | Dataclass with all v6 wireless fields |
airos/data.py β __pre_deserialize__ | All field transformation logic |
airos/data.py β _check_and_log_unknown_enum_value | Unknown enum guard |
| Issue #260 | PowerBeam M5 400 11NAHT20 failure case |