- Python 90.2%
- Makefile 6.5%
- Dockerfile 3.3%
| .claude | ||
| .forgejo/workflows | ||
| grafana | ||
| wan_monitor | ||
| .gitignore | ||
| CLAUDE.md | ||
| Dockerfile | ||
| Makefile | ||
| poetry.lock | ||
| project_vars.mk | ||
| pyproject.toml | ||
| README.md | ||
wan-monitor
Monitor WAN IP changes on an Orange Livebox gateway and get notified via Telegram, email, or any Apprise-supported service.
Queries the Livebox sysbus API directly (no authentication required) to detect changes in both IPv4 address and IPv6 delegated prefix.
Includes a Prometheus exporter (default :9100) exposing WAN status and, when gateway authentication is configured, DSL line stats, interface traffic, and device info.
Configuration
Configuration is loaded from environment variables or JSON files (in order):
~/.config/wan-monitor.json/etc/wan-monitor/wan-monitor.json
Example
{
"alias": "Home Livebox",
"gateway": {
"url": "http://192.168.1.1",
"password": "my-livebox-password"
},
"notificationurls": [
"tgram://BOT_TOKEN/CHAT_ID",
"mailto://user:pass@smtp.example.com"
],
"loop": {
"interval": 300
},
"prometheus": {
"port": 9100,
"namespace": ""
},
"logging": {
"level": "INFO"
}
}
Parameters
| Parameter | Default | Description |
|---|---|---|
alias |
(required) | Location name shown in notifications |
gateway.url |
http://192.168.1.1 |
Livebox gateway URL |
gateway.password |
(empty) | Livebox admin password; enables authenticated metrics when set |
notificationurls |
(required) | List of Apprise notification URLs |
loop.interval |
300 |
Polling interval in seconds |
prometheus.port |
9100 |
Prometheus metrics HTTP port |
prometheus.namespace |
(empty) | Prefix for all metric names |
prometheus.url |
(empty) | Prometheus base URL; seeds WAN state on startup to avoid false change notifications after restarts |
prometheus.filters |
(empty) | PromQL label matchers for seeding (e.g. job="wan-monitor") |
api.port |
8000 |
HTTP API port |
logging.level |
WARNING |
Log level (DEBUG, INFO, WARNING, ERROR, FATAL) |
Apprise URL examples
- Telegram:
tgram://BOT_TOKEN/CHAT_ID - Email (SMTP):
mailto://user:pass@smtp.example.com - Gotify:
gotify://hostname/token - ntfy:
ntfy://topic
See the full list at https://github.com/caronc/apprise/wiki
Prometheus Metrics
Always available (no authentication)
| Metric | Type | Labels | Description |
|---|---|---|---|
wan_link_up |
Gauge | — | 1 if WAN link is up, 0 otherwise |
wan_info |
Info | ipv4, ipv6_address, ipv6_prefix, link_type |
WAN connection information |
With authentication (gateway.password set)
DSL stats (NeMo/Intf/dsl0:getDSLStats):
| Metric | Type | Labels | Description |
|---|---|---|---|
dsl_sync_rate_kbps |
Gauge | direction |
DSL sync rate in kbps |
dsl_snr_db |
Gauge | direction |
Signal-to-noise ratio in dB |
dsl_attenuation_db |
Gauge | direction |
Line attenuation in dB |
dsl_errors_total |
Gauge | type |
Error counters — crc: frames with checksum mismatch (data corruption), fec: errors corrected by forward error correction (noisy line), hec: corrupted ATM cell headers, errored_seconds: one-second intervals containing at least one error |
Interface traffic (NeMo/Intf/<iface>:getStats):
| Metric | Type | Labels | Description |
|---|---|---|---|
interface_bytes_total |
Gauge | interface, direction |
Bytes transferred (tx/rx) |
interface_packets_total |
Gauge | interface, direction |
Packets transferred (tx/rx) |
interface_errors_total |
Gauge | interface |
Error count |
interface_discards_total |
Gauge | interface |
Packets dropped by the interface (buffer overflows, QoS policies, rate limiting) |
Interfaces monitored: data, eth0, wl0.
Device info (DeviceInfo:get, Hosts:getDevices):
| Metric | Type | Labels | Description |
|---|---|---|---|
device_uptime_seconds |
Gauge | — | Device uptime in seconds |
device_info |
Info | model, firmware, serial |
Device information |
connected_devices |
Gauge | — | Number of active connected devices |
Usage
Local
pip install wan-monitor
python -m wan_monitor
Docker
docker run -v ~/.config/:/etc/wan-monitor/:ro \
-p 8000:8000 -p 9100:9100 \
wan-monitor:latest
HTTP API
The API server (default :8000) exposes management endpoints. Prometheus metrics are served separately on :9100.
| Endpoint | Port | Method | Description |
|---|---|---|---|
/metrics |
9100 | GET | Prometheus metrics |
/test-notification |
8000 | POST | Send a test notification to all configured URLs |
# Test notification setup
curl -X POST http://localhost:8000/test-notification
How it works
- Starts a Prometheus HTTP server on the configured port
- Queries the Livebox sysbus API at
POST <gateway>/sysbus/NMC:getWANStatus - Extracts
IPAddress(IPv4) andIPv6DelegatedPrefixfrom the response - Updates Prometheus metrics with current WAN status
- If authenticated, collects DSL stats, interface traffic, and device info
- Compares WAN IPs against previously stored state
- On change, sends a notification with old and new values
- Saves new state and sleeps until next check
Build
make build
Release
Bump the version, commit, and tag in one step:
make release
git push && git push --tags
Docker tags
| Trigger | Tags |
|---|---|
Push to main |
:latest |
Semver tag (e.g. 1.2.3) |
:v1, :v1.2, :v1.2.3 |
| Other tag | :{tag} |
CI/CD
The Forgejo Actions workflow (.forgejo/workflows/docker.yaml) runs linting and pushes Docker images on every push to main or any tag.
Repository configuration
| Name | Type | Description |
|---|---|---|
DOCKER_REGISTRY |
Variable | Registry URL (e.g. registry.example.com/user) |
DOCKER_USERNAME |
Secret | Registry username |
DOCKER_PASSWORD |
Secret | Registry password/token |