Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to this project will be documented in this file.

## [0.2.8] - 2025-08-12

### Changed

- Improved exception handling
- GPS data optional (reported on NanoStation via HA Core Issue 150491)

## [0.2.7] - 2025-08-08

### Added

- Added support for 8.7.11 NanoStation not having 'age' in the 'remote'(s)
- Added debugging script for pinpointing issues in the dataclass

## [0.2.6] - 2025-08-06

### Added
Expand Down
39 changes: 20 additions & 19 deletions airos/airos8.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import asyncio
import json
import logging
from typing import Any
Expand Down Expand Up @@ -185,12 +186,12 @@ async def login(self) -> bool:
log = f"Login failed with status {response.status}. Full Response: {response.text}"
_LOGGER.error(log)
raise AirOSConnectionAuthenticationError from None
except (
aiohttp.ClientError,
aiohttp.client_exceptions.ConnectionTimeoutError,
) as err:
except (TimeoutError, aiohttp.client_exceptions.ClientError) as err:
_LOGGER.exception("Error during login")
raise AirOSDeviceConnectionError from err
except asyncio.CancelledError:
_LOGGER.info("Login task was cancelled")
raise

def derived_data(
self, response: dict[str, Any] | None = None
Expand Down Expand Up @@ -301,12 +302,12 @@ async def status(self) -> AirOSData:
response_text,
)
raise AirOSDeviceConnectionError
except (
aiohttp.ClientError,
aiohttp.client_exceptions.ConnectionTimeoutError,
) as err:
_LOGGER.error("Status API call failed: %s", err)
except (TimeoutError, aiohttp.client_exceptions.ClientError) as err:
_LOGGER.exception("Status API call failed: %s", err)
raise AirOSDeviceConnectionError from err
except asyncio.CancelledError:
_LOGGER.info("API status retrieval task was cancelled")
raise

async def stakick(self, mac_address: str = None) -> bool:
"""Reconnect client station."""
Expand Down Expand Up @@ -339,12 +340,12 @@ async def stakick(self, mac_address: str = None) -> bool:
log = f"Unable to restart connection response status {response.status} with {response_text}"
_LOGGER.error(log)
return False
except (
aiohttp.ClientError,
aiohttp.client_exceptions.ConnectionTimeoutError,
) as err:
_LOGGER.exception("Error during reconnect request call")
except (TimeoutError, aiohttp.client_exceptions.ClientError) as err:
_LOGGER.exception("Error during call to reconnect remote: %s", err)
raise AirOSDeviceConnectionError from err
except asyncio.CancelledError:
_LOGGER.info("Reconnect task was cancelled")
raise

async def provmode(self, active: bool = False) -> bool:
"""Set provisioning mode."""
Expand Down Expand Up @@ -378,9 +379,9 @@ async def provmode(self, active: bool = False) -> bool:
log = f"Unable to change provisioning mode response status {response.status} with {response_text}"
_LOGGER.error(log)
return False
except (
aiohttp.ClientError,
aiohttp.client_exceptions.ConnectionTimeoutError,
) as err:
_LOGGER.exception("Error during provisioning mode call")
except (TimeoutError, aiohttp.client_exceptions.ClientError) as err:
_LOGGER.exception("Error during call to change provisioning mode: %s", err)
raise AirOSDeviceConnectionError from err
except asyncio.CancelledError:
_LOGGER.info("Provisioning mode change task was cancelled")
raise
8 changes: 6 additions & 2 deletions airos/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,6 @@ class Remote(AirOSDataClass):
cable_loss: int
ethlist: list[EthList]
ipaddr: list[str]
gps: GPSData
oob: bool
unms: UnmsStatus
airview: int
Expand All @@ -357,6 +356,9 @@ class Remote(AirOSDataClass):
ip6addr: list[str] | None = None # For v4 only devices
height: int | None = None
age: int | None = None # At least not present on 8.7.11
gps: GPSData | None = (
None # Reported NanoStation 5AC 8.7.18 without GPS Core 150491
)

@classmethod
def __pre_deserialize__(cls, d: dict[str, Any]) -> dict[str, Any]:
Expand Down Expand Up @@ -556,5 +558,7 @@ class AirOS8Data(AirOSDataClass):
provmode: Any
ntpclient: Any
unms: UnmsStatus
gps: GPSMain
derived: Derived
gps: GPSData | None = (
None # Reported NanoStation 5AC 8.7.18 without GPS Core 150491
)
7 changes: 6 additions & 1 deletion fixtures/airos_liteapgps_ap_ptmp_40mhz.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
},
"genuine": "/images/genuine.png",
"gps": {
"alt": 252.5,
"dim": 3,
"dop": 1.52,
"fix": 1,
"lat": 52.379894,
"lon": 4.901608
"lon": 4.901608,
"sats": 8,
"time_synced": null
},
"host": {
"cpuload": 59.595959,
Expand Down
7 changes: 6 additions & 1 deletion fixtures/airos_loco5ac_ap-ptp.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
},
"genuine": "/images/genuine.png",
"gps": {
"alt": null,
"dim": null,
"dop": null,
"fix": 0,
"lat": 52.379894,
"lon": 4.901608
"lon": 4.901608,
"sats": null,
"time_synced": null
},
"host": {
"cpuload": 10.10101,
Expand Down
7 changes: 6 additions & 1 deletion fixtures/airos_loco5ac_sta-ptp.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
},
"genuine": "/images/genuine.png",
"gps": {
"alt": null,
"dim": null,
"dop": null,
"fix": 0,
"lat": 52.379894,
"lon": 4.901608
"lon": 4.901608,
"sats": null,
"time_synced": null
},
"host": {
"cpuload": 44.0,
Expand Down
7 changes: 6 additions & 1 deletion fixtures/airos_nanobeam5ac_sta_ptmp_40mhz.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
},
"genuine": "/images/genuine.png",
"gps": {
"alt": null,
"dim": null,
"dop": null,
"fix": 0,
"lat": 52.379894,
"lon": 4.901608
"lon": 4.901608,
"sats": null,
"time_synced": null
},
"host": {
"cpuload": 32.673267,
Expand Down
Loading