Install
openclaw skills install @psyb0t/planesnitchSelf-hosted aircraft monitor — watches one or more named locations for interesting aircraft (military/gov/police via plane-alert-db CSVs, emergency squawks 7500/7600/7700, custom ICAO hex/type lists, low-flyers by altitude, or literally everything) using free online ADS-B APIs (adsb.lol, adsb.fi, airplanes.live, adsb.one) or your own ultrafeeder — no SDR, no antenna, no hardware. Fires alerts to Telegram (with doc8643 aircraft-type photos) and/or webhooks (JSON array + base64 image), per-alert cooldowns, config-file driven (config.yaml), runs in Docker. Use when the user wants to monitor/alert on aircraft near a location, get pinged when a military/government/police plane flies overhead, watch for emergency squawks, or build their own plane-spotting radar without buying hardware.
openclaw skills install @psyb0t/planesnitchWatches your configured locations and snitches the second something worth caring about flies within radius — military jets, government spooks, cops, emergency squawks, sketchy low-flyers, or whatever hex/type list you feed it. Pulls live ADS-B data from free public APIs (or your own ultrafeeder if you run one) — no SDR, no antenna, no hardware, just a config file. Alerts go to Telegram and/or a webhook.
For the full config schema, env vars, Docker run/compose, and Telegram bot setup, see references/setup.md.
planesnitch sends data outbound on every poll cycle — know what you're pointing it at:
adsb.lol, adsb.fi, airplanes.live, adsb.one). If that's a concern, run your own ultrafeeder and point sources at it instead of the public endpoints.telegram notification target sends the matched aircraft's coordinates (lat/lon), squawk, registration, and (if attach_image is left at its default true) a doc8643 image to api.telegram.org. Every alert fired through a webhook notification target POSTs the same data — plus image_base64 when attach_image is on — to whatever url you set. In both cases the location's identity and the aircraft's tracked position leave your host to that third party on every match. Point notify: only at Telegram bots/chats and webhook urls you run or explicitly trust; treat the notification target list as part of your threat model, not just the ADS-B sources.config.yaml holds a live Telegram bot token and/or webhook URL + auth headers in plaintext. Treat it like a secret — don't commit it, don't paste it into chat, mount it read-only (:ro).notify: at Telegram chats and webhook endpoints you control. A webhook is an arbitrary outbound POST — vet the URL before adding it.:8080) — planesnitch doesn't listen for anything else. It's a poll-and-push loop, not a server other things talk to.ultrafeeder/dump1090 separately and point a ultrafeeder source at it if you want that.poll_interval, default 15s), not a live stream.Everything lives in one config.yaml. Five sections: locations, sources, watchlists, alerts, notifications.
display_units — how altitude/distance/speed render in alerts and webhook payloads. aviation (ft/nm/kts, default), metric (m/km/km·h), imperial (ft/mi/mph).
locations — named points with lat, lon, radius, optional name (falls back to the key). Distance/altitude values accept unit suffixes (km, mi, nm, ft, m) — radius: 150km, radius: 50nm both work. Plain numbers default to km (distance) / ft (altitude).
sources — where the ADS-B data comes from. Public APIs (adsb_lol, adsb_fi, airplanes_live, adsb_one — no config needed) or your own ultrafeeder (needs a url). Multiple sources fetch in parallel and dedupe by ICAO hex, keeping whichever entry has the most fields. adsb_fi/airplanes_live/adsb_one return enriched data (name, operator, year); adsb_lol/ultrafeeder are raw-fields-only.
watchlists — what to look for. Six types: all (everything in radius), squawk (transponder codes), icao (specific hex addresses), icao_type (ICAO type designators like C17/B738), icao_csv (hex list from a CSV file in csv/ — see plane-alert-db), proximity (altitude-filtered — the "low flyer" watch). All types still respect the location's radius regardless of type.
alerts — wires watchlists to notification targets. Optional locations filter (omit = all locations checked). cooldown (durations: 5m, 1h30m, 90s, or plain seconds) stops the same aircraft from re-triggering the alert for a while.
notifications — telegram (bot_token + chat_id) or webhook (url + optional headers). Both support attach_image: false to skip the doc8643 aircraft-type photo (default true) — Telegram gets it as a photo attachment, webhooks get it as image_base64 in the JSON payload. Every alert sends location coordinates and aircraft tracking data off-host — telegram targets to api.telegram.org, webhook targets to whatever url you set (see Security & safety above). Only add notification targets pointing at Telegram bots/chats and webhook endpoints you control or trust.
poll_interval: 1m
display_units: aviation
locations:
home:
name: "Home"
lat: 38.8719
lon: -77.0563
radius: 150km
sources:
- type: adsb_lol
- type: adsb_fi
- type: airplanes_live
- type: adsb_one
watchlists:
emergencies:
type: squawk
values: ["7500", "7600", "7700", "7400", "7777"]
military:
type: icao_csv
source: plane-alert-mil.csv
government:
type: icao_csv
source: plane-alert-gov.csv
low_flyers:
type: proximity
min_altitude: 0ft
max_altitude: 3000ft
alerts:
- name: "Emergency Alert"
watchlists: [emergencies]
cooldown: 1m
notify: [tg_main, my_webhook]
- name: "Military Spotter"
watchlists: [military, government]
cooldown: 5m
notify: [tg_main]
notifications:
tg_main:
type: telegram
bot_token: "123456:ABC-DEF"
chat_id: "-100123456789"
my_webhook:
type: webhook
url: "https://example.com/hook"
headers:
Authorization: "Bearer xxx"
CSV watchlists (icao_csv type) need the matching file under csv/ — military/government/police/civilian/PIA/everything lists are pulled from plane-alert-db, 15,000+ aircraft catalogued by the plane-spotting community. See references/setup.md for the download commands and the full CSV list.
# grab the example config and edit it — locations, sources, watchlists, alerts, notifications
curl -sL \
https://raw.githubusercontent.com/psyb0t/docker-planesnitch/main/config.yaml.example \
-o config.yaml
# minimal run — no CSV watchlists, no persistent image cache
docker run \
-v ./config.yaml:/app/config.yaml:ro \
psyb0t/planesnitch
# with CSV watchlists (military/gov/police lists) + persistent image cache
docker run \
-v ./config.yaml:/app/config.yaml:ro \
-v ./csv:/csv:ro \
-v ./images:/images \
psyb0t/planesnitch
A health endpoint runs on :8080; the image ships a built-in Docker healthcheck against it.
Full config field reference, env var table, Docker compose, and Telegram bot-token setup: references/setup.md.