# Skylark feeder toolkit Free tools for receiver owners. Read a local decoder, pair a station, diagnose uploads and contribute direct ADS-B observations alongside your other feeds. ## Licence and scope The MIT licence in LICENSE applies to `skylark_feed.py`, `install.sh`, `skylark-feeder.service`, `verify.py` and this README in the downloadable toolkit. In the source repository these are `feeder/skylark_feed.py`, `public/feed/install.sh`, `infra/skylark-feeder.service`, `feeder/verify.py` and `feeder/README.md`. It does not license the rest of the Skylark application. Aircraft data has separate permissions; optionally published archive data uses ODbL 1.0. Public source files: https://skylark.watch/feed/source/README.md Download the complete source toolkit from https://skylark.watch/feed/. It includes offline checks; after extracting, run `python3 verify.py`. These synthetic checks verify software behavior and do not establish radio or hardware compatibility. ## Try it before creating an account Download and inspect the source toolkit. On your receiver, read one snapshot without installing a service or sending anything to Skylark: ```sh python3 skylark_feed.py --check # Or choose your decoder explicitly: python3 skylark_feed.py --check --source /run/readsb/aircraft.json python3 skylark_feed.py --check --source http://127.0.0.1:8080/data/aircraft.json ``` No credentials are needed. The result reports the number of eligible direct positions and `transmitted: false`. A fresh empty sky passes with zero; an unlabelled decoder or stale snapshot fails. Local HTTP reads bypass environment proxies and refuse redirects. Files and the local decoder are only read; this step does not upload or change your setup. ## Install alongside existing feeds Needs Linux with systemd and Python 3.9+. Inspect install.sh before running it. On an existing receiver: ```sh curl -fsSL https://skylark.watch/feed/install.sh | sudo bash sudo skylark-feeder doctor ``` Create your station at https://skylark.watch/network, then claim the receiver's pairing code at https://skylark.watch/pair. Keep the station recovery key private. Upload credentials cannot manage the station. The client reads supported readsb/dump1090-fa aircraft.json files or loopback HTTP copies. It never opens the SDR, changes another feeder, installs a decoder or requests inbound network access. PiAware, ultrafeeder and ADSB.im paths are detected, but real hardware compatibility is still being verified. Decoder labels alone do not attest radio origin. Do not forward an aggregate or a remote receiver's stream. Only use equipment you operate and have permission to share from. ## Inspect or reuse the client The forwarder uses only the Python standard library. A local check uploads nothing: ```sh python3 skylark_feed.py --detect python3 skylark_feed.py --check --source /run/readsb/aircraft.json python3 skylark_feed.py --config /path/to/private-config.json --doctor ``` The private configuration contains your feed key and endpoint. Store it with mode 600. Do not include it in a repository, support report or source bundle. `--help` lists pairing and source selection options. A local decoder check, HTTPS acknowledgement and first accepted position are distinct stages; none establishes independent hardware acceptance. ## Prove each step 1. **Local snapshot:** `--check` confirms that the decoder file is fresh and labelled. It uploads nothing. 2. **Skylark receipt:** after pairing and installation, `sudo skylark-feeder doctor` must report a recent upload. A valid empty snapshot proves receipt but not reception. 3. **Accepted observation:** open https://skylark.watch/station.html and check for a first accepted position. Publication approval is a separate stage. You can keep every other feeder running throughout. To leave, run `sudo skylark-feeder uninstall`; it removes this toolkit and its local key. Your station account remains on Skylark. ## What leaves the receiver Every ten seconds, at most 500 direct `adsb_icao` positions under 45 seconds old are sent over HTTPS. The allowlisted fields are aircraft address, callsign, position, barometric/geometric altitude, speed, track, vertical rates and observation-age/type metadata. MLAT, TIS-B and database enrichment are excluded. No audio, decoder CPU statistics, remote commands or radio access is included. Use the private station workspace for scope/map, measured coverage, ten-minute observed replay, a change journal and diagnostic export. Publication requires operator approval; historical open-data publication requires separate opt-in. Exact station coordinates stay private. ## Manage and remove ```sh sudo skylark-feeder status sudo skylark-feeder logs sudo skylark-feeder upgrade sudo skylark-feeder uninstall ``` Uninstall removes the local forwarder, service, private configuration and service user. Your station account remains on Skylark. Pause and publication choices live in your station workspace. Read the contributor terms at https://skylark.watch/network-terms before enrolling. The download manifest records hashes and sizes. A checksum supplied by the same host provides integrity, not an independent signature. The source bundle name includes its content hash; compare the entire SHA-256 in the manifest before extraction. ## Receiver Lab: useful before you join Unzip the source toolkit, then run: ```sh python3 skylark_feed.py --lab --source /run/readsb/aircraft.json ``` Open `http://127.0.0.1:8765`. No account, feed key, installation or Python packages are needed. The Lab never enrolls or uploads. It reads the decoder file or a loopback HTTP URL, alongside your existing feeder services. Add `--latitude 53.4 --longitude -6.2` with **your antenna's coordinates** for true bearing, great-circle surface distance and observed reach by altitude. These example coordinates are not a default receiver location. Without a location, the aircraft list, freshness, signal and history still work. The installed helper also supports `sudo skylark-feeder lab`. For a receiver on another machine, use an SSH tunnel: ```sh ssh -L 8765:127.0.0.1:8765 user@receiver ``` Keep the Lab running on the receiver and open localhost on your laptop. The server binds only to loopback and rejects foreign Host/Origin requests. Direct observations, MLAT and TIS-B are distinguished. RSSI is the decoder's reported dBFS, not calibrated antenna power. Charts do not establish RF origin, missed-aircraft probability or the cause of weak reception. Empty coverage cells mean no observation. Altitude is barometric or geometric, never AGL. One worker reads every two seconds, regardless of visitor count. History holds 300 samples (ten minutes); displayed contacts are capped at 500; measurements include all valid direct positions in the bounded decoder snapshot; session identities at 50,000. Each directional altitude cell keeps 512 recent distinct position ranges for percentiles, plus session counts and maxima. Truncation is labelled. Stale or unavailable output clears current contacts while retaining labelled session history. Restarting clears all measurements. No measurement files are written unless you explicitly export. Exports include precise antenna and aircraft positions: inspect them before sharing. `receiver_lab.py` and `lab/` are also covered by the bundled MIT licence.