Skip to content

minmcs — minimalistic mission control system

minmcs is a web-browser mission control system: operators monitor telemetry (TM) and uplink telecommands (TC) from a dashboard in their browser, backed by a Python API that decodes packets against a spacecraft model and stores them. It runs from containers with minimal configuration.

minmcs dashboard: live telemetry and uplinking TC_PING and TC_Set_Mode (DHS to NOMINAL) commands

The operator’s browser talks to the API directly over REST/WS on :9300 — the data_proxy bridge is not in that path. Its job is separate: it relays TM/TC between the ground link’s TCP socket and the API’s HTTP endpoints. 21001 is the ground-link port the repo’s example config uses by default; the code itself falls back to 9310/9311 when nothing is configured — see Configuration.

Getting started

See Quickstart for the first steps — copying .env.example, placing the XTCE database, and bringing up the stack (with Docker, or running the pieces locally).

minscs is a simulator that speaks the same ground-link wire format and pairs well with minmcs in place of (or alongside) the local bin/egse_link.py stub.

Repository layout

  • minmcs-lib/ — the Python/FastAPI core. It builds a Spacecraft model from an XTCE mission database, decodes TM into parameters, builds and tracks TC, and exposes all of that over a REST API plus a /ws WebSocket. The API itself never opens a socket to the ground — that’s the job of the ground-link bridge, bin/data_proxy.py.
  • minmcs-ui/ — a Vue 3 + Pinia + vue-router operator dashboard, built on a Bootstrap admin template and adapted for MCS use. Its domain components live in minmcs-ui/src/components/minmcs/; they talk to the API over REST and refresh reactively on the /ws broadcast.
  • containers/ + docker-compose.yamlthe full stack: Postgres/TimescaleDB, InfluxDB, the API, and the UI behind nginx, one container each.

Backend flow: packet in → parameters out

  1. api.py builds one global MinMCS for the mission named by MINMCS_MISSION — see The API service.
  2. Mission holds the Spacecraft model and the SQL engine. The live mission builds that model at load time from an XTCE file.
  3. Telemetry ingest parses each packet with minspp, identifies which container it belongs to by walking the XTCE containers’ restriction rules, and decodes it bit-level into stored parameters.
  4. Telecommand uplink looks up the command, packs its opcode and arguments, and derives the packet header straight from its XTCE container. The built packet is stored with sent=False; the ground-link bridge is what actually puts it on the wire.

minspp (PyPI minspp, github.com/nunorc/minspp) owns the CCSDS/PUS-C wire format underneath all of this: framing, the TM/TC secondary headers, and everything that’s filled in on the ground (sequence count, packet length, the CRC-16 PEC).

Read next

Last updated on