module

Kozai::CLI

The command line.

Three subcommands, because a station daemon is mostly used two ways: run it and leave it, or ask it one question from a shell script.

kozai serve                      # the daemon, API and web interface
kozai passes                     # print upcoming passes and exit
kozai position --sat 25544       # print where something is now

Constants

FAILURE = 1

Exit status when the command could not be carried out.

LARGE_CATALOGUE = 500

Catalogue size above which a pass search stops being instant.

NOTE: not a limit, and deliberately not. Measured on an eight-core laptop, a day of passes takes 0.30 s across 97 satellites and 34 s across the 16093 in CelesTrak's active group — linear, on one core, and recomputed on every /api/passes. Nothing about that is broken; it is simply not what this is for, and a station that points [tle] urls at a full catalogue deserves to be told before it decides the interface has hung.

The cure is [prediction] satellites, which cuts the work rather than the output. Five hundred is where a search first takes about a second.

SCHEDULE_INTERVAL = 5.minutes

Re-reads element sources on the cache expiry schedule. How often the plan is rebuilt.

A pass search over a watchlist is milliseconds, so this could be far more frequent; it is not, because a plan that changes under the operator every few seconds is harder to trust than one that changes on a known cadence.

Class methods

build_config(path : String | Nil, overrides : Hash(String, String)) : Tuple(Config, Settings::Store, Config)

Loads configuration from every source, in order of increasing authority.

NOTE: file, then environment, then command line flags, then the settings page. The environment beats the file because that is what makes a container image configurable without one; the page beats everything because it is the only source an operator holding a phone can reach.

Returns three things: the configuration in force, the settings store — the only thing that knows which environment variables it covered, because it notes them as it overwrites them — and the configuration as it stood before the store was applied, which is what a cleared setting falls back to.

Source
build_transponders(config : Config) : Transponders::Table

The transponder table: compiled-in entries with any configured file laid over them.

Source
build_transponders_or_warn(config : Config, error : IO) : Transponders::Table

:ditto:, but never fatal.

NOTE: used at startup, where the transponder path may have come from the settings page — and the settings page is the only way its operator can correct it. A daemon that refuses to start over a file it was told about through a web form takes away the form. So it says what is wrong, falls back to the compiled-in table, and stays reachable.

Source
default_config_path

Where the configuration lives if nothing says otherwise.

Source
run(arguments : Array(String), output : IO = STDOUT, error : IO = STDERR) : Int32

Runs the command line and returns a process exit status.

Source
serve(config : Config, settings : Settings::Store, base : Config, output : IO, error : IO) : Int32

Runs the daemon.

Source