-
Notifications
You must be signed in to change notification settings - Fork 2
developer reference
This document serves as a guide for anyone looking to contribute to, modify, or extend the glinet-router integration.
The integration is cleanly separated into two distinct layers:
-
The API Layer (
api/): A standalone, framework-agnostic asynchronous HTTP client built usingaiohttpfor communicating with the GL.iNet JSON-RPC (/rpc) interface. -
The Integration Layer (
entities/,hub.py,services.py): The Home Assistant-specific implementation that translates router data into sensors, trackers, and switches.
The API client is highly modular.
Instead of a single monolithic client class, the API is broken down into specific feature modules. Each module extends BaseModule and implements the RPC methods relevant to its domain. Current modules include: system, wifi, clients, modem, mcu, wg_client, wg_server, ovpn_client, ovpn_server, tailscale, repeater, fan, firewall, led, macclone, diag, adguard, parental_control, and black_white_list.
When adding a new router endpoint, you should:
- Create a new module file in
api/modules/. - Inherit from
BaseModuleand implement your API calls. - Attach the module to the main
GLinetApiClientclass inapi/client.pyas an instance attribute so it can be accessed likeclient.my_feature.get_status().
The integration uses two layers of data models:
-
api/models.py: Strongly-typeddataclassmodels for raw API response fields. These are returned directly from API module calls. -
models.py(integration layer): Higher-level dataclasses used by the hub and entities, e.g.,ClientDeviceInfo,RepeaterStatus,WireGuardClient,ParentalGroup. These aggregate, transform, or combine data from one or more API responses.
The GLinetHub is the heart of the integration. It inherits from DataUpdateCoordinator and manages:
- Session state: Handing token expiration and renewal.
- Polling Loop: Executing API requests sequentially every scan interval (user-configurable, default 30s) to prevent overwhelming the router's lighttpd server.
- Caching: Storing the latest fetched values from the API models so Home Assistant entities can read them instantly without making network calls.
For more details on the Hub's functions and data fetching logic, see the Runtime State & Poller Reference.
The integration implements the Home Assistant diagnostics platform. This allows users to download a sanitized JSON snapshot of the router's state for debugging.
When adding new data points to the hub, ensure they are also captured in async_get_config_entry_diagnostics and properly redacted if they contain PII (SSIDs, MACs, IPs, etc.).
Entities are split by Home Assistant domain (e.g., sensor.py, switch.py, button.py).
All entities inherit from CoordinatorEntity[GLinetHub]. Entities should never make direct network calls in their property methods. Instead, they should return values directly from the cached GLinetHub state. Network calls (like toggling a switch) must be performed via the hub's methods.
To add a new sensor for an existing API endpoint:
-
API Models: Update
api/models.pyif the new field isn't captured in the raw API dataclass. -
Hub Models: Update
models.pyif the new field needs a higher-level model or transformation. -
Hub: Update
hub.pyto fetch, store, and expose the new data point. -
Entities: Add your sensor to
entities/sensor.py. -
Diagnostics: Update
diagnostics.pyto include the new data point in the export. -
Tests: Update your mock tests in
tests/to ensure the new sensor state works correctly.
The project relies on standard Python development tools:
-
Testing:
pytestandpytest-asyncio. Tests mock all network interactions to ensure the API and hub function correctly without a live router. -
Linting: We strictly enforce linting and formatting via
ruff.
Run the following commands before submitting any pull requests:
python -m pytest -q
python -m ruff check custom_components tests --fix
python -m ruff format custom_components testsDo not add massive third-party library dependencies unless absolutely necessary. Home Assistant integrations should remain lightweight. The core integration relies only on aiohttp (which is native to HA).
The repository uses a two-branch model: main is the release branch
and development is the integration branch. All day-to-day pull
requests target development. Releases are cut as a development
→ main PR by the maintainer(s).
A bot (pr-target-check.yml)
comments and applies the wrong-target label to any PR opened
against main that is not a development → main release. Outside
contributors fork the repository and submit from a fork — no one
outside the maintainer team has direct write access.
main is protected by a ruleset (1 approval, code-owner review,
CI must pass). development has no ruleset on purpose: maintainers
can push directly there, and Dependabot and bot updates don't need
to fight branch protection. See
.github/BRANCH_PROTECTION.md
for the full ruleset and rationale.
Solo-maintainer note: the
mainruleset leaves the "Require approval of the most recent reviewable push" rule off so the only maintainer can self-merge release PRs. Re-enable it when a second maintainer is added.
For the full contribution flow, see
CONTRIBUTING.md.
- Architecture — How the integration is structured and interacts with Home Assistant.
-
Runtime State & Poller (Hub) — Details on the
GLinetHubandDataUpdateCoordinator. - Router API Notes — Endpoints, authentication, and module inventory.
- Modem API Coverage — Details on the optional cellular modem API.
- CI and Release Workflows — How automated testing and releases work.
-
CONTRIBUTING.md— Full contributor guide.