Skip to content

Alarms and Health API

dtvsold checks the router every minute and keeps an alarm register in its database: one row per failing condition, identified by a stable key (for example bond0/eno2/link). An alarm is raised after 2 failing checks in a row (a critical service down and the DHCP service are raised at once) and cleared after 2 good checks. Every raise and clear is also recorded as a history event. Cleared alarms and events older than 90 days are deleted.

What is checked: everything GET /alerts reports (DHCP, VLANs, address pools, unknown clients, CGNAT, anti-spoofing, the OLT collector and fiber warnings, the licence) plus the router itself — bond members without link or outside the LACP aggregator, the uplink down or no default route, ports carrying addresses or VLANs without carrier, flapping links, failed or stopped router services and timers, disks filling up (warning at 90 %, critical at 95 %), CPU, memory, out-of-memory kills, temperatures, connection tracking and port errors.

Both endpoints are read-only and have no /api?action= form. The CLI equivalent is dtvsol alarms. Authentication and errors: see the API overview.

Field Meaning
area olt, onu, network, server or services (derived from source).
key Stable identifier of the condition.
source The check: e.g. link, uplink, bond, interface, nic, cpu, memory, temp, conntrack, disk, service, timer, dhcp, dhcp-pool, stranger, cgnat, spoof, olt, fiber, licence.
level critical, warning or info.
text Human-readable description.
detail Extra data of the check (object or null).
first_seen, last_seen YYYY-MM-DD HH:MM:SS.
cleared When it cleared, or null while active.
count Integer kept with the alarm row.

The active alarms, critical first, then the oldest. With all=1, the alarms cleared in the last 7 days follow the active ones. With history=N, the last N raises and clears instead (newest first).

Name In Type Notes
all query boolean 1 adds alarms cleared in the last 7 days.
history query integer Return the last N raise/clear events (1–1000; 50 when not a positive number). Takes precedence over all.
Terminal window
curl -s "http://ROUTER-IP:8880/alarms?all=1" -H "X-API-Key: YOUR_API_KEY"
{
"count": 1,
"generated": "2026-09-28 10:40:00",
"checked": {
"at": "2026-09-28 10:39:58",
"took_ms": 412,
"errors": [],
"health": {"cpu": {"…": "…"}, "memory": {"…": "…"}, "ports": ["…"]}
},
"alarms": [
{
"area": "network",
"key": "bond0/eno2/link",
"source": "link",
"level": "warning",
"text": "bond0: member eno2 has no link",
"detail": null,
"first_seen": "2026-09-28 09:12:00",
"last_seen": "2026-09-28 10:39:58",
"cleared": null,
"count": 1
}
]
}

count is the number of active alarms (cleared ones returned by all=1 are not counted). checked describes the last check run (null before the first one); checked.errors lists what it could not check.

History form:

Terminal window
curl -s "http://ROUTER-IP:8880/alarms?history=20" -H "X-API-Key: YOUR_API_KEY"
{
"count": 2,
"generated": "2026-09-28 10:40:00",
"events": [
{"area": "services", "at": "2026-09-28 10:05:00", "kind": "clear", "level": "warning",
"key": "dhcp-pool/vlan100", "source": "dhcp-pool", "text": "…"},
{"area": "services", "at": "2026-09-28 09:30:00", "kind": "raise", "level": "warning",
"key": "dhcp-pool/vlan100", "source": "dhcp-pool", "text": "…"}
]
}

Errors: 405 for any method other than GET; 500 with {"ok": false, "code": 500, "error": …} when the database cannot be read.

Each area’s current readings, shown beside that area’s alarms in the monitor’s Alarms tab. Everything is read from data the daemon already keeps; nothing here queries an OLT.

Name In Type Notes
area query string olt, onu, network, server or services. Omit for all areas.

What each area contains:

  • server — from the last alarm check: cpu, load, memory, temps, disks, conntrack, uptime_s, units (the router’s services), and measured (when).
  • network — ports (rates and errors from the last check), bonds (mode, members, link state, LACP aggregator membership, link failures), uplinks (up / carrier) and default_routes.
  • olt — per registered OLT: collector status (ok, at, age_s, took_ms, error), number of PON ports, ports in use, ports_dark (PON ports whose ONTs are all offline), boards, ONTs and ONTs online, errors.
  • onu — per OLT: total ONTs, counts by state, offline causes, received light in bands (good −8 to −25 dBm, weak −25 to −27 dBm, too_weak below −27 dBm, too_strong above −8 dBm) and the five weakest ONTs.
  • services — DHCP-served interfaces, number of legacy clients, services by state, CGNAT (enabled, iface, assigned, capacity, free) and anti-spoofing (enabled, mode, dropped IPv4/IPv6/ARP packets, last_hour).
Terminal window
curl -s "http://ROUTER-IP:8880/health?area=onu" -H "X-API-Key: YOUR_API_KEY"
{
"ok": true,
"generated": "2026-09-28 10:41:00",
"area": "onu",
"health": {
"olts": [
{
"olt": "olt-1",
"at": "2026-09-28 10:40:12",
"total": 412,
"states": {"online": 398, "offline": 14},
"offline_causes": {"power off": 9, "fiber cut": 5},
"light": {"good": 390, "weak": 6, "too_weak": 2, "too_strong": 0},
"weakest": [{"fsp": "0/1/3", "ont_id": 12, "rx_dbm": -28.4, "description": "…"}]
}
]
}
}

Without area the answer is {"ok": true, "generated": …, "areas": {"olt": …, "onu": …, "network": …, "server": …, "services": …}}.

Errors: 400 ("area is one of olt, onu, network, server, services") for an unknown area; 405 for any method other than GET.