Browser-based satellite tracking, radio control, SDR control, and rotator control for Raspberry Pi.
Pi-Sat is a local web control surface for satellite operations. It combines pass prediction, live tracking, Doppler-aware RX/TX tuning, SDR coordination, and rotator control into one Pi-hosted interface designed for actual operating use rather than just passive monitoring.
The Raspberry Pi owns the backend, device control, and tracking logic. The browser is the operator console.
Setup and operating guidance is available in the Pi-Sat Controller Wiki. Hardware support depends on the selected Hamlib backend and device. Report compatibility problems or hardware-specific behavior in GitHub Issues.
- Live pass tracking with map and pass arc display
- Doppler-aware RX/TX tuning
- SDR, radio, and rotator control
- Native IC-9700 CI-V control and bidirectional audio over LAN connectivity
- Multi-source TLE and CelesTrak GP/OMM JSON loading, including six-digit NORAD IDs
- Satellite profile management
- Monitor page with backend event logging
- Optional live Robot24/36/72, Martin M1/M2, and PD120/180 SSTV decoding from the existing native IC-9700 SUB/RX audio stream using SSTVFlow
- Optional APRS decoding from a selectable side of the native IC-9700 RX audio stream, plus manual APRS transmit of a beacon, status line, or message
- Optional FT4 / FT8 module using stock WSJT-X on the same host, with native SUB receive audio, Pi-Sat-controlled transmit, automatic QSO sequencing, an audio passband display, and ADIF contact export
- Systemd-based Pi service install and update flow
In Settings, Orbital Data Source URLs accepts named TLE or CelesTrak JSON
links, one per line. The format is detected automatically, and saving a changed
link refreshes the orbital data. For amateur satellites, the JSON source is
https://celestrak.org/NORAD/elements/gp.php?GROUP=amateur&FORMAT=JSON.
TLE and JSON sources can be combined; the newest epoch for each NORAD ID is kept.
- Raspberry Pi OS or another Debian-based Linux environment
- Raspberry Pi 3B or newer
- Python 3.11 or newer with
venvsupport (python3-venv) git- 64-bit Raspberry Pi OS (AArch64)
- Dire Wolf for the optional APRS receiver and
gen_packetstransmit modulator (installed by the installer, or built from source) - Hamlib utilities through
libhamlib-utilsrigctlrigctldrotctlrotctld
Hamlib 4.6 or newer can reduce radio read traffic by publishing generic asynchronous state updates. This optimization is optional: Pi-Sat detects the installed version and selected backend at runtime and retains normal polling when it is unavailable. Raspberry Pi OS Trixie's Hamlib 4.6.2 package is supported. See Radio State Updates for configuration and troubleshooting.
Run this on the Pi as the normal user:
curl -fsSL https://raw.githubusercontent.com/W9KSB/Pi-Sat/main/install/install_pi.sh | sh- clones or updates the repo into
~/pi-sat - creates
pi-sat-controller.conffrom the example template if needed - creates
update_pi.shfromupdater.templateif needed - creates an isolated
.venvand installs Python dependencies fromrequirements.txt - grants the service user serial-device access for local USB/serial radios and rotators
- installs the bundled SSTVFlow Python decoder from
vendor/sstvflow - installs Dire Wolf for the optional APRS receiver
- asks whether to install WSJT-X and audio dependencies for FT4/FT8 (default: No)
- installs the
pi-satsystemd service - starts the service
After install, open https://<PI-IP>/ in a browser on your local network.
Pi-Sat defaults to HTTPS on port 443.
On first start it generates a self-signed certificate if none exists, then reuses
it on subsequent starts. Browser certificate acceptance/trust and microphone
permission are still required. See
HTTPS setup for certificates,
custom ports, and the explicit HTTP option for reverse proxies.
Open https://<PI-IP>/dashboard for Pi-Sat: Station Monitor, a read-only
display suited to a full-screen TV. It uses the checked satellites from the Home
page and cycles their world-map positions one at a time every five seconds. It
also shows continuously scrolling passes for the next 24 hours, live SSTV or the last
saved image, and radio/tracking/rotator status. The refresh interval defaults to
three minutes and can be adjusted in the top-right corner; SSTV updates live.
Select satellites and operate the devices and decoder from the main interface.
sudo systemctl status pi-sat
sudo systemctl restart pi-sat
journalctl -u pi-sat -fFrom the Pi-Sat installation directory, run as the normal Pi user:
sh install/install_pi.sh --uninstallThis stops and disables Pi-Sat and removes its installed systemd unit and managed Python override. The installation folder, configuration, station data, and shared packages remain. See Installation for details.
See the Pi-Sat Controller Wiki for manual installation, update, and customization guidance.
The installer creates an ignored local update_pi.sh from the tracked
updater.template. Newer updater versions refresh that local copy after a
repository update and re-enter the update automatically. On a Pi whose local
updater predates this refresh behavior, run the old updater once, then run:
cd ~/pi-sat
cp updater.template update_pi.sh
chmod +x update_pi.sh
./update_pi.shPi-Sat installs Python packages into .venv. The updater prepares and verifies
that environment before changing the service. A standard run-server service
that still uses system Python is migrated automatically without uninstalling
Debian packages. Existing virtual-environment services are retained. A
customized system-Python execution command requires a manual interpreter
change.
- Hamlib for radio and rotator control interfaces
- Skyfield for orbital calculations and pass prediction
- Dire Wolf by John Langner (WB2OSZ) for APRS and AX.25 decoding
SSTVFlow and APRS receiver notices are preserved in THIRD_PARTY_LICENSES.md.
- CelesTrak for TLE data used by the application
Pi-Sat depends on these projects and data sources for core functionality. We thank their maintainers for the outstanding work they have done in this space.
Let's address the elephant in well.... every room nowadays. This project utilizes AI, Codex in particular with a few other models. I'm not hiding it, I'm embracing it. I've been working with python for the last 12-15 years or so, but recognized the possibilities of what this project could be with some AI assistance. I don't hide that it has been a very helpful tool and helped me put together some pretty cool things. That being said, I always believe in transparency and why I felt the need to at least add this statement.
