A single-purpose status board for the stuff you self-host. Add checks for Jellyfin, Seafile, Paperless-ngx, prosody, the Flint 2's admin page — anything reachable over HTTP(S) or TCP — and get a glanceable list of what's up, response latency, and rolling uptime. When something that was up goes down, you get a notification.
Built the way the rest of the land.rob.* fleet is built: GTK4 +
libadwaita + PyGObject, meson, GSettings, SQLite, libsecret, Flatpak.
Adaptive out of the box — the whole UI is one boxed list with a bottom-
sheet edit dialog, so it's equally at home on a desktop and on Phosh.
- HTTP(S) — GET the URL, compare the status code (configurable, so a
401from a deliberately locked-down admin panel can count as "up"). Optional per-service auth header (Authorization: Bearer …,X-Api-Key: …, etc.) stored in the keyring via libsecret, and an "ignore TLS errors" toggle for self-signed homelab certs. - TCP — plain
connect()to host:port. Good for XMPP (5222), SSH (22), SMTP, or anything that isn't HTTP.
No ICMP ping on purpose: raw sockets aren't available in the Flatpak sandbox, and "the port I actually use answers" is a better liveness signal than "the kernel answers" anyway.
- Auto-refresh every 2 minutes by default (
refresh-intervalGSettings key, floor of 30 s;notify-on-downto toggle notifications). - Last 200 results per service are kept in
~/.local/share/pulse/pulse.dband drive the uptime percentage. - Checks run on a small thread pool; the UI never blocks.
Local dev run (needs python3-gi, GTK4, libadwaita, libsecret):
glib-compile-schemas data/ --targetdir=data/
GSETTINGS_SCHEMA_DIR=data/ python3 -m src.mainFlatpak:
flatpak-builder --user --install --force-clean build land.rob.Pulse.json
flatpak run land.rob.PulseFor the phone, the usual aarch64 dance applies:
flatpak-builder --arch=aarch64 --repo=repo --force-clean build land.rob.Pulse.json├── land.rob.Pulse.json Flatpak manifest (GNOME 48 runtime)
├── meson.build
├── data/
│ ├── land.rob.Pulse.desktop.in
│ ├── land.rob.Pulse.metainfo.xml.in
│ └── land.rob.Pulse.gschema.xml
└── src/
├── main.py Adw.Application, actions
├── window.py service list, refresh loop, notifications
├── edit_dialog.py add/edit bottom sheet
├── monitor.py threaded HTTP/TCP probes
├── store.py SQLite (services + pruned result history)
└── secrets.py libsecret wrapper for auth headers
- App icon (SVG, symbolic variant)
- Per-service check intervals
- A tiny sparkline of recent latency in an expanded row
- Background checking via
xdg-desktop-portalBackground portal — or, on postmarketOS, a bgmgrd-friendly mode