Satellite#
Data#
Data are sent via the CDTP protocol, where data are send in data records, consisting of blocks containing binary data. It is up to the implementation to decide how to organize the data. Additionally, each record can contain metadata in form of tags (key-value pairs) in the record header.
Transmitting Data#
The TransmitterSatellite
class can be used to send data during
a run over the network. It sends the Begin-of-Run (BOR) message in the starting
state and the End-of-Run (EOR) message in
the stopping
state. This is achieved in the BaseSatellite
by
dynamically casting it to a TransmitterSatellite
.
Warning
Sending data is not thread safe. If multiple threads need to access the sender, it needs to be protected with a mutex.
Receiving Data#
The ReceiverSatellite
class can be used to receive data during
a run over the network. Similar to the TransmitterSatellite
mentioned above, executing transmitter transitions in addition to user transitions is achieve in the
BaseSatellite
by dynamically casting it to a
ReceiverSatellite
.
constellation::satellite
Namespace#
-
using constellation::satellite::Generator = std::shared_ptr<Satellite>(std::string_view, std::string_view)#
-
class BaseSatellite#
Subclassed by constellation::satellite::Satellite
Public Functions
-
virtual ~BaseSatellite() = default#
Destruct base satellite.
Warning
BaseSatellite::join()
has to be called before destruction
-
inline std::string_view getSatelliteType() const#
Return the satellite type.
-
inline std::string_view getSatelliteName() const#
Return the satellite name.
-
std::string getCanonicalName() const#
Return the canonical name of the satellite.
The canonical name is satellite_type.satellite_name
-
inline bool supportsReconfigure() const#
Returns if online configuration is supported.
-
inline std::string_view getStatus() const#
Return the current status of the satellite.
-
inline std::string_view getRunIdentifier() const#
Return the current or last used run identifier.
-
inline networking::Port getCommandPort() const#
Return the ephemeral port number to which the CSCP socket is bound to.
-
inline networking::Port getHeartbeatPort() const#
Return the ephemeral port number to which the CHP socket is bound to.
-
inline FSM &getFSM()#
Return the FSM of the satellite.
Warning
Use carefully, the FSM gives direct access to low level functionality of the framework.
-
void join()#
Join CSCP processing thread.
Join the CSCP processing thread, which happens when the satellite is shut down or terminated.
-
void terminate()#
Terminate the satellite.
-
inline bool terminated() const#
Check if the satellite has been terminated.
- Returns:
True if the satellite has been terminated
Protected Functions
-
BaseSatellite(std::string_view type, std::string_view name)#
-
inline bool is_run_degraded() const#
Helper to check whether the current or past run has been marked as degraded.
- Returns:
True if the run has been marked as degraded, false otherwise
Protected Attributes
-
log::Logger logger_#
-
virtual ~BaseSatellite() = default#
-
class CommandRegistry#
- #include <constellation/satellite/CommandRegistry.hpp>
Registry for user commands.
Class to allow registration and execution of arbitrary commands based on their name. The commands can require any number of arguments that can be converted from std::string. Return values are also possible as long as a conversion to std::string is possible.
Public Functions
-
template<typename C>
void add(std::string_view name, std::string description, std::set<protocol::CSCP::State> allowed_states, C function)# Register a command with arbitrary arguments.
- Parameters:
name – Name of the command
description – Description of the command
allowed_states – Set of states in which this command can be called
function – Function to add
-
config::Value call(protocol::CSCP::State state, const std::string &name, const config::List &args)#
Calls a registered function with its arguments This method calls a registered function and returns the output of the function, or an empty string.
- Parameters:
state – Current state of the finite state machine when this call was made
name – Name of the command to be called
args – List of arguments
- Throws:
UnknownUserCommand – if no command is not registered under this name
InvalidUserCommand – if the command is registered but cannot be called in the current state
MissingUserCommandArguments – if the number of arguments does not match
std::invalid_argument – if an argument or the return value could not be decoded or encoded to std::string
- Returns:
Return value of the called function
-
std::map<std::string, std::string> describeCommands() const#
Generate map of commands with comprehensive description.
The description consists of the user-provided command description from registering the command. In addition, this description is appended with a statement on how many arguments the command requires and a list of states in which the command can be called.
- Returns:
Map with command names and descriptions
-
template<typename C>
-
class CommunicationError : public constellation::satellite::SatelliteError#
- #include <constellation/satellite/exceptions.hpp>
Satellite Error for device communication.
An error occurred in the user code implementation of a satellite when attempting to communicate with hardware
Public Functions
-
inline explicit CommunicationError(const std::string &reason)#
-
inline explicit CommunicationError(const std::string &reason)#
-
class FSM#
Public Types
-
using Transition = protocol::CSCP::Transition#
-
using TransitionCommand = protocol::CSCP::TransitionCommand#
-
using TransitionPayload = std::variant<std::monostate, config::Configuration, std::string>#
Payload of a transition function: variant with configuration or run identifier
-
using TransitionFunction = State (FSM::*)(TransitionPayload)#
Function pointer for a transition function: takes the variant mentioned above, returns new State
-
using TransitionMap = std::map<Transition, TransitionFunction>#
Maps the allowed transitions of a state to a transition function
-
using StateTransitionMap = std::map<State, TransitionMap>#
Maps state to transition maps for that state
Public Functions
-
inline FSM(BaseSatellite *satellite)#
Construct the final state machine of a satellite.
- Parameters:
satellite – Satellite class with functions of transitional states
-
~FSM()#
-
inline std::chrono::system_clock::time_point getLastChanged() const#
Return the timestamp of the last state change.
-
bool isAllowed(Transition transition) const#
Check if a FSM transition is allowed in current state.
- Parameters:
transition – Transition to check if allowed
- Returns:
True if transition is possible
-
void react(Transition transition, TransitionPayload payload = {})#
Perform a FSM transition.
- Parameters:
transition – Transition to perform
payload – Payload for the transition function
- Throws:
FSMError – if the transition is not a valid transition in the current state
-
bool reactIfAllowed(Transition transition, TransitionPayload payload = {})#
Perform a FSM transition if allowed, otherwise do nothing.
- Parameters:
transition – Transition to perform if allowed
payload – Payload for the transition function
- Returns:
True if the transition was initiated
-
std::pair<message::CSCP1Message::Type, std::string> reactCommand(TransitionCommand transition_command, const message::PayloadBuffer &payload)#
Perform a FSM transition via a CSCP message.
- Parameters:
transition_command – Transition command from CSCP
payload – Payload frame from CSCP
- Returns:
Tuple containing the CSCP message type and a description
-
void requestInterrupt(std::string_view reason)#
Try to perform an interrupt as soon as possible.
This function waits for the next steady state and performs an interrupt if in ORBIT or RUN state, otherwise nothing is done. It guarantees that the FSM is in a state where the satellite can be safely shut down.
Warning
This function is not thread safe, meaning that no other react command should be called during execution.
- Parameters:
reason – Reason for the requested interrupt
-
void requestFailure(std::string_view reason)#
Try to perform a failure as soon as possible.
This function waits for the next steady state and performs a failure if not in ERROR, otherwise nothing is done.
Warning
This function is not thread safe, meaning that no other react command should be called during execution.
- Parameters:
reason – Reason for the requested failure
-
void registerStateCallback(const std::string &identifier, std::function<void(State, std::string_view)> callback)#
Registering a callback to be executed when a new state was entered.
This function adds a new state update callback. Registered callbacks are used to distribute the state of the FSM whenever it was changed.
Warning
State callbacks block the execution of further transitions, callbacks that take a long time should offload the work to a new thread.
- Parameters:
identifier – Identifier string for this callback
callback – Callback taking the new state as argument
-
void unregisterStateCallback(const std::string &identifier)#
Unregistering a state callback.
This function removed the state update callback with the given identifier
- Parameters:
identifier – Identifier string for this callback
-
void registerRemoteCallback(std::function<std::optional<State>(std::string_view)> callback)#
Registering a callback which allows to fetch the state of a remote satellite.
This function registers a remote state callback which allows the FSM to query the last known state of a remote satellite, e.g. for conditional transitions
- Parameters:
callback – Callback taking the name of the remote satellite as argument and returning an optional with its state, if known, or a
std::nullopt
if not known
-
using Transition = protocol::CSCP::Transition#
-
class FSMError : public constellation::utils::RuntimeError#
- #include <constellation/satellite/exceptions.hpp>
Finite State Machine Error.
An error occurred in a request to the finite state machine
Subclassed by constellation::satellite::InvalidFSMTransition
Protected Functions
-
FSMError() = default#
-
FSMError() = default#
-
class InvalidCDTPMessageType : public constellation::satellite::SatelliteError#
- #include <constellation/satellite/exceptions.hpp>
Error when a received CDTP message does not have the correct type.
Public Functions
-
inline explicit InvalidCDTPMessageType(message::CDTP2Message::Type type, std::string_view reason)#
-
inline explicit InvalidCDTPMessageType(message::CDTP2Message::Type type, std::string_view reason)#
-
class InvalidFSMTransition : public constellation::satellite::FSMError#
- #include <constellation/satellite/exceptions.hpp>
Invalid transition requested.
A transition of the finite state machine was requested which is not allowed from the current state
Public Functions
-
inline explicit InvalidFSMTransition(protocol::CSCP::Transition transition, protocol::CSCP::State state)#
-
inline explicit InvalidFSMTransition(protocol::CSCP::Transition transition, protocol::CSCP::State state)#
-
class InvalidUserCommand : public constellation::satellite::UserCommandError#
- #include <constellation/satellite/exceptions.hpp>
Invalid user command.
The user command is not valid in the current state of the finite state machine
-
class InvalidUserCommandArguments : public constellation::satellite::UserCommandError#
- #include <constellation/satellite/exceptions.hpp>
Invalid arguments for user command.
Public Functions
-
inline explicit InvalidUserCommandArguments(std::string_view argtype, std::string_view valuetype)#
-
inline explicit InvalidUserCommandArguments(std::string_view argtype, std::string_view valuetype)#
-
class InvalidUserCommandResult : public constellation::satellite::UserCommandError#
- #include <constellation/satellite/exceptions.hpp>
Invalid return type from user command.
Public Functions
-
inline explicit InvalidUserCommandResult(std::string_view argtype)#
-
inline explicit InvalidUserCommandResult(std::string_view argtype)#
-
class MissingUserCommandArguments : public constellation::satellite::UserCommandError#
- #include <constellation/satellite/exceptions.hpp>
Missing arguments for user command.
Public Functions
-
inline explicit MissingUserCommandArguments(const std::string &command, std::size_t args_expected, std::size_t args_given)#
-
inline explicit MissingUserCommandArguments(const std::string &command, std::size_t args_expected, std::size_t args_given)#
-
class ReceiverSatellite : public constellation::satellite::Satellite, private constellation::pools::BasePool<message::CDTP2Message, protocol::CHIRP::DATA, zmq::socket_type::pull>#
- #include <constellation/satellite/ReceiverSatellite.hpp>
Satellite class with additional functions to receive data.
Subclassed by DevNullReceiverSatellite, EudaqNativeWriterSatellite
Public Functions
-
void running(const std::stop_token &stop_token) final#
Run function.
Note
For data receiving satellites, this function must not be implemented. Instead
receive_bor()
,receive_data()
andreceive_eor()
have to be implemented.- Parameters:
stop_token – Token which tracks if running should be stopped or aborted
Protected Functions
-
ReceiverSatellite(std::string_view type, std::string_view name)#
Construct a data receiving satellite.
- Parameters:
type – Satellite type
name – Name of this satellite instance
-
void validate_output_directory(const std::filesystem::path &path)#
Validate the output directory.
This method checks if the directory exists and is a directory, creates all parent directories if necessary, and registers a disk space metric for the path.
- Parameters:
path – Prospective output directory
-
std::filesystem::path validate_output_file(const std::filesystem::path &path, const std::string &file_name, const std::string &ext = "")#
Create the final output file path from output directory, file name and extension and validates access.
- Parameters:
path – Output directory the file will be located in
file_name – Name of the file
ext – File extension of the file, will be only set if not empty
- Returns:
Validated canonical path to the output file
-
std::ofstream create_output_file(const std::filesystem::path &path, const std::string &file_name, const std::string &ext = "", bool binary = true)#
Create the final output file from output directory, file name and extension.
- Parameters:
path – Output directory the file will be located in
file_name – Name of the file
ext – File extension of the file, will be only set if not empty
binary – Boolean flag whether the file should be opened in binary mode or not
- Returns:
Output file stream to the target file
-
virtual void receive_bor(std::string_view sender, const config::Dictionary &user_tags, const config::Configuration &config) = 0#
Receive and handle Begin-of-Run (BOR) message.
- Parameters:
sender – Canonical name of the sending satellite
user_tags – Dictionary with the user tags of the sending satellite
config – Configuration of the sending satellite
-
virtual void receive_data(std::string_view sender, const message::CDTP2Message::DataRecord &data_record) = 0#
Receive and handle data record.
- Parameters:
sender – Canonical name of the sending satellite
data_record – Data record containing the user tags and payload
-
virtual void receive_eor(std::string_view sender, const config::Dictionary &user_tags, const config::Dictionary &run_metadata) = 0#
Receive and handle End-of-Run (EOR) message.
- Parameters:
sender – Canonical name of the sending satellite
user_tags – Dictionary with the user tags of the sending satellite
run_metadata – Dictionary with run meta data of the sending satellite
-
inline std::size_t get_bytes_received() const#
Get amount of payload data received from all transmitters in the current run.
- Returns:
Amount of data in bytes
-
virtual bool should_connect(const chirp::DiscoveredService &service) final#
Checks whether or not to connect to a discovered service.
- Returns:
True if service should be connected to, false otherwise
-
void running(const std::stop_token &stop_token) final#
-
class Satellite : public constellation::satellite::BaseSatellite#
- #include <constellation/satellite/Satellite.hpp>
Satellite class with transitional user functions.
Subclassed by DummySatelliteNR< constellation::satellite::Satellite >, DummySatelliteNR< SatelliteT >, FlightRecorderSatellite, MattermostSatellite, SputnikSatellite, constellation::satellite::ReceiverSatellite, constellation::satellite::TransmitterSatellite
Public Functions
-
virtual ~Satellite() = default#
-
void initializing(config::Configuration &config) override#
Initialize satellite.
In this function a satellite can for example check the configuration or establish connection to a device.
Note
A satellite can be re-initialized from INIT, i.e. this function can be called twice in a row. Any actions required to be undone before another initialization should be done in
launching()
instead.- Parameters:
config – Configuration of the satellite
-
void launching() override#
Launch satellite.
In this function the configuration should be applied and the satellite prepared for data taking, for example by ramping up the high voltage of a device.
-
void landing() override#
Land satellite.
In this function should actions performed in the
launching()
function should be undone, for example by ramping down the high voltage of a device.
-
void reconfiguring(const config::Configuration &partial_config) override#
Reconfigure satellite.
In this function a partial configuration should be applied to the already launched satellite. This function should throw if a configuration parameter is changed that is not supported in online reconfiguration.
Note
By default, the satellite does not support online reconfiguration. Support for online reconfiguration can be enabled with
support_reconfigure()
.- Parameters:
partial_config – Changes to the configuration of the satellite
-
void starting(std::string_view run_identifier) override#
Start satellite.
In this function the data acquisition of the satellite should be started, for example by opening the output file.
Note
This function should not take a long time to execute. Slow actions such as applying a configuration should be performed in the
launching()
function.- Parameters:
run_identifier – Run identifier for the upcoming run
-
void stopping() override#
Stop satellite.
In this function the data acquisition of the satellite should be stopped, for example by closing the output file.
-
void running(const std::stop_token &stop_token) override#
Run function.
In this function the data acquisition of the satellite should be continuously executed.
- Parameters:
stop_token – Token which tracks if running should be stopped or aborted
-
void interrupting(protocol::CSCP::State previous_state, std::string_view reason) override#
Interrupt function.
In this function a response for the transition from ORBIT or RUN to the SAFE state can be implemented. This includes for example closing open files or turning off the high voltage. By default, this function calls
stopping()
(if in RUN state) and thenlanding()
.- Parameters:
previous_state – State in which the satellite was being interrupted
reason – Reason for the interrupt
-
void failure(protocol::CSCP::State previous_state, std::string_view reason) override#
Failure function.
In this function a response to uncaught errors can be implemented. It is executed after entering the ERROR state.
- Parameters:
previous_state – State in which the satellite was before experiencing a failure
reason – Reason for the failure
Protected Functions
-
Satellite(std::string_view type, std::string_view name)#
Construct a satellite.
- Parameters:
type – Satellite type
name – Name of this satellite instance
-
inline void support_reconfigure(bool enable = true)#
Enable or disable support for reconfigure transition.
Required to enable the
reconfiguring()
function (disabled by default).- Parameters:
enable – If online reconfiguration support should be enabled
-
inline void submit_status(std::string status)#
Submit a new status message.
This status message will be transmitted to the FSM at the end of the current transition
- Parameters:
status – Status message
-
template<typename C>
void register_timed_metric(std::string name, std::string unit, metrics::MetricType type, std::string description, std::chrono::steady_clock::duration interval, std::set<protocol::CSCP::State> allowed_states, C value_callback)# Register a metric which will be emitted in regular intervals, evaluated from the provided function.
- Parameters:
name – Name of the metric
unit – Unit of the metric as human readable string
type – Type of the metric
description – Description of the metric
interval – Interval in which to send the metric
allowed_states – Set of states in which the callback is allowed
value_callback – Callback to determine the current value of the metric
-
template<typename T, typename R, typename ...Args>
void register_command(std::string_view name, std::string description, std::set<protocol::CSCP::State> allowed_states, R (T::* func)(Args...), T *t)# Register a new user command.
- Parameters:
name – Name of the command
description – Comprehensive description of the command
allowed_states – Set of states in which this command can be called
func – Pointer to the member function to be called
t – Pointer to the object of the member function
-
template<typename C>
void register_command(std::string_view name, std::string description, std::set<protocol::CSCP::State> allowed_states, C function)# Register a new user command from a function or lambda.
- Parameters:
name – Name of the command
description – Comprehensive description of the command
allowed_states – Set of states in which this command can be called
function – Function to be registered
Protected Static Functions
-
static void register_metric(std::string name, std::string unit, metrics::MetricType type, std::string description)#
Register a metric which can be emitted manually.
- Parameters:
name – Unique topic of the metric
unit – Unit of the provided value
type – Type of the metric
description – Description of the metric
-
template<typename C>
static void register_timed_metric(std::string name, std::string unit, metrics::MetricType type, std::string description, std::chrono::steady_clock::duration interval, C value_callback)# Register a metric which will be emitted in regular intervals, evaluated from the provided function.
- Parameters:
name – Name of the metric
unit – Unit of the metric as human readable string
type – Type of the metric
description – Description of the metric
interval – Interval in which to send the metric
value_callback – Callback to determine the current value of the metric
-
virtual ~Satellite() = default#
-
class SatelliteError : public constellation::utils::RuntimeError#
- #include <constellation/satellite/exceptions.hpp>
Generic Satellite Error.
An unspecified error occurred in the user code implementation of a satellite
Subclassed by constellation::satellite::CommunicationError, constellation::satellite::InvalidCDTPMessageType
Public Functions
-
inline explicit SatelliteError(const std::string &reason)#
Protected Functions
-
SatelliteError() = default#
-
inline explicit SatelliteError(const std::string &reason)#
-
class TransmitterSatellite : public constellation::satellite::Satellite#
- #include <constellation/satellite/TransmitterSatellite.hpp>
Satellite class with additional functions to transmit data.
Subclassed by RandomTransmitterSatellite
Public Functions
-
message::CDTP2Message::DataRecord newDataRecord(std::size_t blocks = 1)#
Create new data record.
Note
This function increases the CDTP sequence number.
Note
To send the data record, use
sendDataRecord()
.- Parameters:
blocks – Number of data record blocks to reserve
-
inline void sendDataRecord(message::CDTP2Message::DataRecord &&data_record)#
Queue data record for sending created with
newDataRecord()
Note
This call might block if current data rate limited
- Parameters:
data_record – Data record to send
-
inline bool canSendRecord() const#
Check if a data record can be send immediately.
Note
If this functions returns false, the available data rate of the data transmission connection is too low for the rate at which the satellite is sending data.
- Returns:
True if a data record send immediately, false otherwise
-
inline void markRunTainted()#
Mark this run data as tainted.
This will set the condition tag in the run metadata to
TAINTED
instead ofGOOD
to mark that there might be an issue with the data recorded during this run.
-
template<typename T>
inline void setBORTag(std::string_view key, const T &value)# Set tag for the BOR message metadata send at the begin of the run.
-
message::CDTP2Message::DataRecord newDataRecord(std::size_t blocks = 1)#
-
class UnknownUserCommand : public constellation::satellite::UserCommandError#
- #include <constellation/satellite/exceptions.hpp>
Invalid user command.
The user command is not registered
Public Functions
-
inline explicit UnknownUserCommand(const std::string &command)#
-
inline explicit UnknownUserCommand(const std::string &command)#
-
class UserCommandError : public constellation::utils::RuntimeError#
- #include <constellation/satellite/exceptions.hpp>
Error thrown for all user command errors
Subclassed by constellation::satellite::InvalidUserCommand, constellation::satellite::InvalidUserCommandArguments, constellation::satellite::InvalidUserCommandResult, constellation::satellite::MissingUserCommandArguments, constellation::satellite::UnknownUserCommand
Protected Functions
-
UserCommandError() = default#
-
UserCommandError() = default#