UplinkWatch

Guides

uplink-watchdog

ChirpStack has no alerting. The Things Stack Community Edition has none either. So when a sensor goes flat, floods, or fails to rejoin, nothing tells you — and the first person to notice is usually your client, asking why the graph has been empty for three weeks.

This is one Python file, no dependencies outside the standard library, that notices and tells you. MIT licensed. Take it, change it, ship it inside your own product if you like.

Download uplink_watchdog.py   v1.0.0 · ~14 kB · Python 3.8+ · MIT licence

Run it

curl -O https://watch.geosensor.tech/tools/uplink_watchdog.py
python3 uplink_watchdog.py --selftest     # prove it works, offline
python3 uplink_watchdog.py --ntfy my-secret-topic-name

Then point your network server's existing HTTP integration at http://your-host:8000/uplink:

ChirpStack        Applications ▸ your app ▸ Integrations ▸ HTTP
The Things Stack  Integrations ▸ Webhooks ▸ Add webhook ▸ Custom
Anything else     any JSON POST carrying a device EUI or id

There is nothing to configure per device. Devices appear the first time they send something.

Alert channels

# Phone push (install ntfy, subscribe to a topic only you know)
python3 uplink_watchdog.py --ntfy my-secret-topic-name

# Slack, Teams, or your own endpoint — receives {"title": ..., "text": ...}
python3 uplink_watchdog.py --webhook https://hooks.example.com/...

# Email
python3 uplink_watchdog.py --email-to ops@example.com \
    --smtp-host smtp.example.com --smtp-port 587 \
    --smtp-user alerts@example.com --smtp-pass "$SMTP_PASS"

Use as many at once as you like. Credentials can come from the environment (SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS) instead of the command line. Your ntfy topic is a password in all but name — anyone who guesses it reads your alerts, so make it unguessable.

When does it decide a device is silent?

By default it learns. Each device gets its own window of three times its observed average interval, with a floor of 30 minutes. A sensor reporting every 15 minutes is called silent after 45; one reporting daily is not called silent until three days have passed.

That needs no per-device configuration and tolerates one dropped uplink without crying wolf. If you would rather set one flat window for everything, use --silence 60. Each fault alerts once, and you get a second message when the device recovers, so you know a site visit worked without opening anything.

What it does not do

Honesty is cheaper than a support ticket. This script keeps state in a JSON file on one machine. It has no history, no dashboard, no per-user accounts, and — the part that matters — nothing watches the watchdog. If the box it runs on reboots, runs out of disk, or loses its network, it goes quiet in exactly the same way a dead sensor does, and you will not be told. A monitor that fails silently is worse than no monitor, because you trust it.

That is the honest argument for the hosted version: UplinkWatch runs off your infrastructure, so it is still watching when your infrastructure is the thing that broke. It also keeps history, handles gateways, and does not need you to remember it exists. Free for 5 devices.

Source

Public repository: github.com/geosensor-tech/uplink-watchdog. Issues and pull requests welcome. If the repo is ever unreachable, the download button above always serves the current file.

Or let us watch it for you

UplinkWatch is the same idea, hosted in Helsinki, so it keeps watching when your own machine is the thing that broke. Paste one URL into your network server. Free for 5 devices.

Start free What it does

Version 1.0.0. Last updated 2026-09-07.