Stellar ControlMission control · by Stellar Systems v0.1.0

SDKs and Integration

NATS Contract Reference

Subjects, headers, streams and messages of the contract between the MCS and its components.

The contract between the MCS and its external components is JSON over NATS. This page is its reference: the subjects, the headers, the JetStream streams and the messages. The Rust SDK (stellar-sdk, types in stellar-contract) and the Python SDK implement it; a component in any other language sends the same messages. The JSON Schema of each message is printed by stellar schema.

Tokens#

Every variable part of a subject is a token: ASCII letters, digits, - and _, not empty, not _ alone. A single-instance component uses _ as its instance token (stellar.param.psu-lab-2.psu._.voltage). Times are RFC 3339, UTC (in the time scale of the chain, time.scale). Identifiers of telecommands and runs are ULIDs.

Subjects#

Control plane#

SubjectDirectionPayload
stellar.ctl.registerinstance → reconciler (request)Registration; reply RegistrationReply
stellar.ctl.hb.<kind>.<instance>instance → reconcilerHeartbeat, every period
stellar.ctl.rpc.<kind>.<instance>.<verb>anyone → instance (request)JSON in and out; {"error": "…"} on failure

Common verbs: status (reply Status), credentials ({"jwt": "…"}), bindings (Bindings), reregister (the instance sends its registration again). Every driver answers encode (EncodeRequest → EncodeReply: {"tc", "context"} → {"frame": "<hex>"}) and decode (DecodeRequest → DecodeReply: {"frame": "<hex>", "context"} → {"samples"}), which encode or decode without sending or publishing anything (see Checking a driver on a running MCS). Drivers of CFDP platforms answer cfdp (CfdpRequest → CfdpStatus); the simulated gateway answers faults, fault, files, generate, rewrite, corrupt and stream_gap.

Telecommands#

SubjectDirectionPayload
stellar.tc.submit.<target>API → executora direct telecommand, resolved
stellar.tc.encode.<codec>.<target>executor → driverSemanticTc; durable consumer encode_<codec>_<target>
stellar.tc.wrap.<transport>.<target>driver → transportunit to frame; durable consumer wrap_<transport>_<target>
stellar.tc.uplink.<gateway>.<target>driver or transport → gatewayopaque frame; durable consumer uplink_<gateway>_<target>
stellar.tc.evt.<target>.<tc_id>executor, driver, gateway → MCSTcEvent

Telemetry, files and streams#

SubjectDirectionPayload
stellar.tm.raw.<gateway>.<target>gateway → MCSopaque frame
stellar.tm.unit.<transport>.<target>transport → driverunit received
stellar.tm.decoded.<target>driver, transport (link measures), transfer manager (stream measures) → compute stagelist of RawSample
stellar.param.<target>.<component>.<instance>.<measure>compute stage → MCSSample
stellar.file.chunk.<target>.<file_id>driver → transfer managerchunk of an on-board file, raw bytes
stellar.file.decode.<target>transfer manager → drivers (request, queue group decode.<target>)FileDecode; reply FileDecodeReply
stellar.stream.<target>.<stream_id>gateway → MCSsegment of a continuous stream, raw bytes
stellar.metrics.<gateway>.<target>gateway → MCSThroughputReport, every metrics_period (core NATS)
stellar.metrics.connector.<name>reconciler → anyoneConnectorLag, every 15 s

Runs, alarms and simulation#

SubjectDirectionPayload
stellar.run.submitAPI, scheduler, alarm service → executorRunSubmission (run, ir, by, and reaction for the reaction of an alarm, which takes the leases of its targets from any ordinary run)
stellar.run.evt.<run_id>executor → anyoneRunEvent
stellar.run.approval.<run_id>API → executorRunAnswer
stellar.run.control.<run_id>API, alarm service → executor (request)RunControl (suspend, resume, abort)
stellar.alarm.evt.<target>.<component>.<instance>.<alarm>alarm service → anyoneAlarmEvent
stellar.alarm.control.<target>API → alarm service (request)AlarmCommand
stellar.sim.evt.<target>simulated gateway → anyone{fault, active, at}

Headers#

HeaderOnContent
Nats-Msg-IdJetStream messagesDe-duplication id: <tc_id> (submission), <tc_id>-encode, <tc_id>-wrap, <tc_id>-uplink (-uplink-<i> for fragments), <tc_id>-<STATE> (events), <run_id>-<n> (run log), <key>-<seq> (alarm transitions)
Stellar-Configmost messagesConfiguration revision that produced the message
Stellar-Emitted-Atmessages of the coreEmission time
Stellar-Correlationtelecommands, frames, unitsTelecommand id; absent on a frame of no telecommand (CFDP PDU, COP-1 retransmission)
Stellar-Deadlinetelecommands, frames, unitsLatest uplink time: received later, refused
Stellar-Fragmentframes<i>/<n>, from 1: one frame among several of a telecommand
Stellar-Directiveunits on wrapA COP-1 directive of the link component (unlock, set_vr), arguments as JSON payload
Stellar-Ground-Timeraw telemetry, units, decoded values, stream segmentsGround reception time
Stellar-Deliveryraw telemetry, units, decoded valuesdeferred for data replayed from on-board storage
Stellar-Linkdecoded values, units, chunksLink of the frame
Stellar-Driverdecoded values<software>@<version> of the driver that decoded them
Stellar-Environmentdecoded values, unitsEnvironment whose link parameters were used
Stellar-File-Generation, Stellar-File-Offsetfile chunksGeneration of the file, offset in bytes
Stellar-Stream-Seqstream segmentsSegment number from 1, consecutive while nothing is lost
Stellar-Usersubmitted telecommandsIdentity of the operator, traced in PENDING
Stellar-For-Runtelecommands of the transfer managerThe run that started the transfer, whose lease the telecommand may use

Streams#

StreamSubjectsRetention
TC_COMMANDSstellar.tc.submit.>, stellar.tc.encode.>, stellar.tc.wrap.>, stellar.tc.uplink.>7 days
TC_EVENTSstellar.tc.evt.>30 days
TM_RAWstellar.tm.raw.>30 days
TM_DECODEDstellar.tm.decoded.>1 day (values decode again from TM_RAW)
PARAMSstellar.param.>30 days
RUNSstellar.run.submit, stellar.run.evt.>, stellar.run.approval.>365 days
ALARMSstellar.alarm.evt.>90 days
FILE_CHUNKSstellar.file.chunk.>7 days
STREAMSstellar.stream.>archive.streams.max_age and max_bytes (30 days, 2 TB)

Components also use a few buckets and object stores: stellar_instances (registrations and heartbeats, TTL of three periods), stellar_cop1 (FOP state of each link, key <target>.<link>), stellar_files (chunks and assembled files, read by drivers and files connectors) and stellar_uploads (contents to upload, read by CFDP drivers). See NATS and JetStream.

Messages#

Registration#

FieldTypeMeaning
kindtokendriver, transport, gateway, connector, or a component of the MCS
instancetokenUnique per kind
software{name, version}Software and semantic version
heartbeat_period_msintegerBetween 100 ms and 60 s
public_keystringnkey user public key (U…)
driverdrivers onlycodec, catalogue (name@requirement), telecommands, measures (component.name), optional output and params_schema
transporttransports onlyinput, output, optional params_schema
gatewaygateways onlytags, optional uplink and downlink: {link_type, rate_bps}

The reconciler rejects, with the reason: names that are not tokens, a key that is not an nkey user key, a version that is not semantic, a heartbeat period out of bounds, a missing or superfluous section for the kind, a catalogue that is not name@requirement, coverage entries that are not component.name, an output, input or link type that is not a token, a params_schema that is not the schema of an object. A new registration of an instance replaces the previous one.

RegistrationReply: {"status": "accepted"}, {"status": "accepted", "jwt": "…"} or {"status": "rejected", "reason": "…"}.

Heartbeat and Status#

  • Heartbeat: health (healthy or degraded), reason when degraded, link_available for gateways, sent_at.
  • Status (reply of the status verb): kind, instance, software, heartbeat (as last sent), started_at, bound (whether the instance holds a JWT issued by the reconciler).

Bindings#

links: for each link served, target, link, config (revision to stamp as Stellar-Config), codec, encode, uplink, driver, gateway, and when given params and environments (overrides by environment, key by key). A link with a transport adds transport, wrap and units. When the topology declares modes, a link also carries mode (the current mode of its target), parameters (the parameters of the target in that mode, by parameter: tcu.anode_voltage, tcu[TCU2].anode_voltage) and parameter_environments (the same, overrides applied, for each environment that overrides some). The reconciler delivers the bindings again at each change of mode. An instance no longer bound receives an empty list. components maps the components the driver knows under another name, name in the target → name in the driver's catalogue, for a driver of a package the platform imports renamed: the SDKs translate SemanticTc.component and RawSample.component with it.

A LinkContext (what a driver, transport or gateway knows of a link) is target, link, environment, params resolved for that environment, mode and parameters (from parameter_environments of the environment when present, else parameters). See Modes and Parameters.

SemanticTc#

id (ULID), target, optional link, component, optional instance (the file id for files), telecommand, args (defaults applied, numbers in the unit of the argument, enum values as strings, booleans, bytes in hexadecimal), optional environment.

TcEvent#

tc, state (PENDING, REJECTED, ENCODED, ENCODE_FAILED, SENT, SEND_FAILED, VERIFIED, VERIFY_FAILED, VERIFY_TIMEOUT, COMPLETE, or ECHO, which is not a state), at, optional detail (reason of a failure), conforming for ECHO, and on PENDING the telecommand ({component, instance, telecommand}). See Telecommand Lifecycle.

EventPublished by
PENDING, REJECTED, VERIFIED, VERIFY_FAILED, VERIFY_TIMEOUT, COMPLETEexecutor
ENCODED, ENCODE_FAILED, ECHOdriver
SENT, SEND_FAILEDgateway (or transport, for a unit it cannot frame)
ENCODE_FAILED, SEND_FAILED, VERIFY_TIMEOUT after executor.ack_timeoutexecutor

RawSample and Sample#

  • RawSample: component, optional instance, measure, value (number, boolean, enum value, hexadecimal bytes) before calibration, optional onboard_time.
  • Sample: value (physical; null when a temporal derived measure becomes unknown), optional raw, time (on-board time when known, else ground reception), ground_time, link, delivery (realtime or deferred).

Files#

  • FileChunk (SDK side): file_id, generation, offset, data.
  • FileDecode: file_id, generation, file_type, object (name in stellar_files). FileDecodeReply: {"outcome": "decoded", "samples": n}, {"outcome": "not_decodable"} or {"outcome": "failed", "error": "…"}.
  • CfdpRequest: target, file_id, generation, direction (download, upload), file_type, size, source (SHA-256 of an upload in stellar_uploads). CfdpStatus: {"state": "running", "progress": n}, {"state": "completed"} or {"state": "failed", "error": "…"}.
  • Transfer: target, file_id, generation, direction, file_type, size, checksum, state (REQUESTED, PARTIAL, COMPLETE, VERIFIED, PROCESSED, CORRUPTED, SUPERSEDED), received (ranges [start, end)), priority, by, created_at, updated_at, reason, source.

ThroughputReport and ConnectorLag#

  • ThroughputReport: uplink_bps, downlink_bps (mean over the window), uplink_bytes, downlink_bytes (since the gateway started), window_ms.
  • ConnectorLag: connector, kind, stream, consumer, pending, unacked, oldest_unread, lag_seconds, retention_seconds, fill, active, at_risk, reason, at.

Runs#

  • RunEvent: run, seq, at, and an event with its fields: started, procedure_started, procedure_finished, step_started, telecommand_sent, telecommand_finished, checked, asked, answered, answer_refused, taken_over, suspended, continued, decision_required, step_finished, finished. See Evidence and Reports.
  • RunAnswer: path, accepted, value, by, roles, token.
  • RunControl: {"action": "suspend", "by"}, {"action": "resume", "by", "choice"}, {"action": "abort", "by"}.

Alarms#

  • AlarmEvent: target, component, instance, alarm, previous, state (NORMAL, ACTIVE_UNACK, ACTIVE_ACK, CLEARED_UNACK), severity (warning, critical), value, at, seq, cause (condition, acknowledged, shelved, unshelved), by, shelved_until.
  • AlarmRecord: the current state in stellar_alarms: state, previous, severity, active_since, changed_at, value, seq, cause, by, shelved_until.
  • AlarmCommand: alarm ({component, instance, alarm}), action ({"action": "acknowledge"}, {"action": "shelve", "for": "30 min"}, {"action": "unshelve"}), by.

Passes and schedules#

Pass, Schedule and ScheduleRule are also bodies of the HTTP API: see the API reference and Writing a Pass Feeder.

JSON Schemas#

stellar schema <kind> prints the JSON Schema of a message, for editors, tests and components in other languages:

KindMessage
registration, registration-replyRegistration and its reply
heartbeat, statusHeartbeat, reply to status
bindingsLinks bound to an instance
semantic-tc, tc-eventTelecommand to encode, telecommand transition
raw-sample, sampleRaw value of a driver, measure sample
throughputThroughput report of a gateway
run-eventEvent of a run
encode-request, encode-reply, decode-request, decode-replyThe verbs encode and decode of a driver
alarm-event, alarm-record, alarm-commandAlarm transition, current state, command
pass, schedule, schedule-rulePass, schedule, recurring rule
transferFile transfer

The same command prints the schemas of the configuration files (catalogue, library, topology, simulation).

Shell
stellar schema registration > registration.schema.json

Stellar Control · v0.1.0

↑↓ to moveEnter to open