An application to control satellite ground station hardware.
It consists of a scheduling system and a series of utilities to control the hardware.
sat-o-mat server- Runs a web UI with an API to manage the ground station's schedule
- Spawns a runner process that watches and executes the schedule entries.
- If configured, spawns a SatNOGS client that periodically polls for observations on the SatNOGS network and submits schedule requests to the API.
- Utilities usually invoked by schedule scripts:
sat-o-mat tracker- Calculates the trajectory of an object relative to the ground station.
- Publishes realtime information about the relative range, speed, angles, etc. to a VITA-49 stream as context packets.
sat-o-mat rigctl- Controls a Hamlib compatible rotator or radio transceiver by translating VITA-49 packets to
rigctlcommands. - Publishes actual rotator position as context packets.
- Controls a Hamlib compatible rotator or radio transceiver by translating VITA-49 packets to
sat-o-mat recoder- Captures all VITA-49 packets into SigMF files for analysis and debugging$
The sat-o-mat server maintains a schedule of tasks, which can be in the following categories:
- Active: confirmed tasks that will be executed at the programmed time.
- Completed: tasks that have finished executing.
- Pending: tasks which have been submitted but require manual approval before transitioning to the Active state.
Tasks are YAML files with the following structure:
variables:
start: 2026-01-12T10:00:00Z
end: 2026-01-12T10:10:00Z
tle: ${sat-o-mat fetch-tle ISS}
steps:
# Tracker setup
- sat-o-mat tracker < $TLE
# Before pass script
- python -c "hello world from pre_script"
# Start GNURadio flowgraph
- python /home/jdiez/flowgraph.py
- docker run asasdfasfd
# Post pass script
- time: $end - 10 seconds
cmd: echo "Pass about to end!"$
cleanup:
- echo "hello from cleanup"There is a variables block, a steps block and a cleanup block.
The variables block consists of any number of user-defined variables, with start and end (timestamps formatted as RFC3559) being used by the scheduling system to determine when the execution should start and when it should end.
Both start and end are optional.
If start is not given, the task will be executed immediately.
The end is not given, the task will finish executing when the last step is executed.
However, in the majority of cases, you want to create schedule entries with both a start and an end time.
Variables may also be evaluated at schedule execution time by wrapping a shell command in ${...}.
The steps block is a list of commands to execute during the scheduled time.
All commands in this list are spawned as subprocesses and continue executing in the background.
The commands are spawned in the order given in the list, and the execution only stops if a command in the list has the time or wait properties (see below).
Each command can be defined as
- commandline_here args1 args2 $variable ...or:
- time: <RFC3559 formatted timestamp>
cmd: commandline_here args1 args2 $variable ...
wait: false | true
on_fail: abort | continue | retry(n)- When
timeis set, the schedule execution waits until the given time before spawning the command.timecan be given as an absolute timestamp or relative to another, for example$end - 10 secondsorT+10 seconds(equivalent to$start + 10 seconds). - When
waitis set, the schedule execution waits until this command has finished executing. - When
on_failisabort(default), the schedule execution will stop if the command exits with an exit code other than 0.
The cleanup block is like steps, but always gets executed at the end of a task.
The commands in steps and cleanup are executed with the current working directory (CWD) set to a new directory that can be used to store artifacts generated by the task's execution.