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.