1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
<div align="center">
<img src="https://github.com/home-assistant/brands/blob/master/core_brands/ubiquiti/icon.png?raw=true" alt="Ubiquiti airOS Logo" width="150" />
<h1>python-airos</h1>
<p>An asynchronous Python module to interact with Ubiquiti airOS devices, emulating a web browser client.</p>
</div>
<div align="center">
</div>
[](https://github.com/python-airos)
[](https://coderabbit.ai)
[](https://github.com/compatech/python-airos/issues/8)
[](https://pypi.python.org/pypi/airos/)
[](https://github.com/compatech/python-airos/actions)
[](https://github.com/compatech/python-airos/actions)
[](https://www.codefactor.io/repository/github/plugwise/python-airos)
[](https://codecov.io/gh/compatech/python-airos)
[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)
[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)
[](https://sonarcloud.io/summary/new_code?id=CoMPaTech_python-airos)
# Overview
`python-airos` or [`airos`](https://pypi.org/projects/airos) from pypi is an asynchronous Python library designed to programmatically interact with Ubiquiti airOS devices. It mimics a web browser client to fetch device status, configuration, and perform actions like kicking connected stations.
This library is a key component for a potential future core integration with [Home Assistant](https://www.home-assistant.io), with the initial pull request for core integration targeted for the 2025.8 release.
More details on the integration can be found on the [Ubiquiti UISP airOS](https://www.home-assistant.io/integrations/airos/) page. To add airOS directly feel free to use the button below:
[](https://my.home-assistant.io/redirect/_change/?redirect=config_flow_start%2F%3Fdomain%3Dairos)
## Features
- Asynchronous Operations: Built with `asyncio` and `aiohttp` for non-blocking I/O, which is perfect for integrations and background tasks.
- Client Emulation: Authenticates and interacts with airOS devices by emulating a client browser, ensuring a high degree of compatibility.
- Data Retrieval: Fetches comprehensive device status information, including:
- Wireless mode and signal strength.
- Connected stations and their statistics.
- System information and uptime.
- Device Control: Provides methods to perform actions, such as reconnecting/kicking a connected wireless station and rebooting the device itself.
- Discovery of airOS devices on your local network (by listening to announcements these devices broadcast).
## Installation
You can install python-airos from PyPI using pip:
```Bash
pip install airos
```
## Usage
Here is a more detailed example of how to use the library to connect, fetch status, and perform an action on an airOS device.
```Python
import aiohttp
import asyncio
from airos.airos6 import AirOS6, AirOS6Data
from airos.airos8 import AirOS8, AirOS8Data
from airos.helpers import DetectDeviceData, async_get_firmware_data
async def main():
"""Main function to demonstrate library usage."""
# Create an aiohttp session with SSL verification disabled.
# Be cautious with this setting; it's useful for self-signed certificates
# but not recommended for production environments without proper validation.
session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))
# Connection data
conn_data = {
"host": "192.168.1.2",
"username": "ubnt",
"password": "password",
"session": session
}
device_data: DetectDeviceData = await async_get_firmware_data(**conn_data)
airos_class: type[AirOS8 | AirOS6] = AirOS8
AirOSDataDetect = AirOS8Data | AirOS6Data
if device_data["fw_major"] == 6:
airos_class = AirOS6
# Initialize the AirOS device object.
airos_device = airos_class(**conn_data)
try:
# Step 1: Login to the device.
login_result = await airos_device.login()
print(f"Login successful: {login_result}")
# Step 2: Fetch the device status.
status_data = await airos_device.status()
print("\n--- Device Status ---")
print(f"Device Name: {status_data.host.hostname}")
print(f"Wireless Mode: {status_data.wireless.mode}")
print(f"Firmware Version: {status_data.host.fwversion}")
# Fetch and display connected stations if available
if status_data.wireless.sta:
print("\n--- Connected Stations ---")
for station in status_data.wireless.sta:
print(f" - MAC: {station.mac}")
print(f" Signal: {station.signal} dBm")
print(f" Uptime: {station.uptime} seconds")
# Step 3: Perform an action, e.g., kick a station.
# Replace '01:23:45:67:89:AB' with the MAC address of a station to kick.
# kick_result = await device.stakick("01:23:45:67:89:AB")
# print(f"\nKick station result: {kick_result}")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Ensure the aiohttp session is closed properly.
await session.close()
if __name__ == "__main__":
asyncio.run(main())
```
## Supported API classes and calls
Note: For firmware 6 we only support the login and status calls currently.
### Classes
- `airos.data` (directly) as well as `airos.airos8` (indirectly) provides `AirOSData`, a [mashumaro](https://pypi.org/project/mashumaro/) based dataclass
- `airos.discovery` provides `AirOSDiscoveryProtocol` for the actual discovery, we recommend to use the `async_discover_devices` function for consumption as described below
### Calls
- `airos.airos8`: initializes with `host: str, username: str, password: str, session: aiohttp.ClientSession`
- `login()`: Authenticates with the device.
- `status()`: Fetches a comprehensive dictionary of the device's status and statistics.
- `warnings()`: Retrieves warning status dict.
- `stakick(mac_address: str)`: Disconnects a specific station by its MAC address.
- `reboot()`: Reboots the device.
- `provmode(active: bool = False)`: Enables or disables the provisioning mode.
- `update_check(force: bool = False)`: Checks if new firmware has been discovered (or force to force check).
- `download()`: Starts downloading (not installing) new firmware.
- `progress()`: Fetches the firmware download (not install!) progress.
- `install()`: Installs the new firmware.
- `airos.discovery`
- `async_discover_devices(timeout: int)` mainly for consumption by HA's `config_flow` returning a dict mapping mac-addresses to discovered info.
#### Information
##### Update
Will return either ```{"update": False}``` or the full information regarding the available update:
```json
{"checksum": "b1bea879a9f518f714ce638172e3a860", "version": "v8.7.19", "security": "", "date": "250811", "url": "https://dl.ubnt.com/firmwares/XC-fw/v8.7.19/WA.v8.7.19.48279.250811.0636.bin", "update": True, "changelog": "https://dl.ubnt.com/firmwares/XC-fw/v8.7.19/changelog.txt"}
```
##### Progress
If no progress to report ```{"progress": -1}``` otherwise a positive value between 0 and 100.
##### Install
Only a positive outcome is expected from the user experience; the call should return:
```json
{
"ok": true,
"code": 0
}
```
#### Warnings
Will respond with something like:
```json
{
"isDefaultPasswd": false,
"customScripts": false,
"isWatchdogReset": 0,
"label": 0,
"chAvailable": false,
"emergReasonCode": -1,
"firmware": {
"isThirdParty": false,
"version": "",
"uploaded": false
}
}
```
## Contributing
We welcome contributions as well as additional codeowners to python-airos.
|