Controller#

constellation::controller Namespace#

class ConfigFileNotFoundError : public constellation::controller::ControllerError#
#include <constellation/controller/exceptions.hpp>

Notifies of a missing configuration file.

Public Functions

inline explicit ConfigFileNotFoundError(const std::filesystem::path &file_name)#

Construct an error for a configuration that is not found.

Parameters:

file_name – Name of the configuration file

class ConfigFileParseError : public constellation::controller::ControllerError#
#include <constellation/controller/exceptions.hpp>

Error with parsing the file content to TOML.

Public Functions

inline explicit ConfigFileParseError(std::string_view error)#

Construct an error for a configuration file that cannot correctly be parsed as TOML.

Parameters:

error – Error message returned by the TOML parser

class ConfigFileTypeError : public constellation::controller::ControllerError#
#include <constellation/controller/exceptions.hpp>

Error with the type of a key in the configuration file.

Public Functions

inline explicit ConfigFileTypeError(std::string_view key, std::string_view error)#

Construct an error for a configuration key that has an invalid type.

Parameters:
  • key – The offending configuration key

  • error – Error message

class ConfigFileValidationError : public constellation::controller::ControllerError#
#include <constellation/controller/exceptions.hpp>

Error in configuration file validation.

Public Functions

inline explicit ConfigFileValidationError(std::string_view error)#

Construct an error for a configuration file validation failure.

Parameters:

error – Error message

class Controller#
#include <constellation/controller/Controller.hpp>

Controller base class which handles satellite connections, command distribution and heartbeat reception

Subclassed by DummyController, constellation::gui::QController

Public Types

using CommandPayload = std::variant<std::monostate, config::Dictionary, config::List, std::string>#

Payload of a command function: variant with (configuration) dictionary, (argument) list or (run id) string

Public Functions

Controller(std::string controller_name)#

Construct a controller base object.

Parameters:

controller_name – Name of the controller

virtual ~Controller() = default#

Destruct controller.

Warning

stop() has to be called before the pool can be safely destructed

void start()#
void stop()#

Destruct the controller base class object.

This deregisters the CHIRP service discovery callback and closes all open connections to satellites

message::CSCP1Message sendCommand(std::string_view satellite_name, message::CSCP1Message &cmd)#

Send a command to a single satellite.

This method allows to send an already prepared command message to a connected satellite, identified via its canonical name. Returns a message with verb ERROR if the satellite is not connected or the message is not a request. If the command was successfully transmitted to the satellite, the response message of the command is returned.

Parameters:
  • satellite_name – Canonical name of the target satellite

  • cmd – Command message

Returns:

CSCP response message

message::CSCP1Message sendCommand(std::string_view satellite_name, std::string verb, const CommandPayload &payload = {})#

Send a command to a single satellite.

This method allows to send a command to a connected satellite, identified via its canonical name. Returns a message with verb ERROR if the satellite is not connected. If the command was successfully transmitted to the satellite, the response message of the command is returned.

Parameters:
  • satellite_name – Canonical name of the target satellite

  • verb – Command

  • payload – Optional payload for this command message

Returns:

CSCP response message

std::map<std::string, message::CSCP1Message> sendCommands(message::CSCP1Message &cmd)#

Send a command to all connected satellites.

This method allows to send an already prepared command message to all connected satellites. The response from all satellites is returned as a map.

Parameters:

cmd – Command message

Returns:

Map of satellite canonical names and their CSCP response messages

std::map<std::string, message::CSCP1Message> sendCommands(std::string verb, const CommandPayload &payload = {})#

Send a command to all connected satellites.

This method allows to send command message to all connected satellites. The message is formed from the provided verb and optional payload. The payload is the same for all satellites. The response from all satellites is returned as a map.

Parameters:
  • verb – Command

  • payload – Optional payload for this command message

Returns:

Map of satellite canonical names and their CSCP response messages

std::map<std::string, message::CSCP1Message> sendCommands(const std::string &verb, const std::map<std::string, CommandPayload> &payloads, bool include_missing = true)#

Send a command to all connected satellites.

This method allows to send command message to all connected satellites. The message is formed individually for each satellite from the provided verb and the payload entry in the map for the given satellite. The response from all satellites is returned as a map.

Parameters:
  • verb – Command

  • payloads – Map of payloads for each target satellite.

  • include_missing – Also send the command to satellites not present in the payload map. If false, missing satellites are skipped, if true, they will receive an empty payload.

Returns:

Map of satellite canonical names and their CSCP response messages

bool isInState(protocol::CSCP::State state) const#

Helper to check if all connected satellites are in a given state.

Parameters:

state – State to be checked for

Returns:

True if all connected satellites are in the given state, false otherwise

bool hasAnyErrorState() const#

Helper to check if any of the connected satellites report an error or safe state.

Returns:

True if any satellite is in ERROR or SAFE state, false otherwise

bool isInGlobalState() const#

Helper to check if the constellation is in a coherent global state of if states are mixed.

Returns:

True if all connected satellites are in the same state, false if states are mixed

void awaitState(protocol::CSCP::State state, std::chrono::seconds timeout) const#

Helper to wait until all connected satellites are in a given state.

Parameters:
  • state – State to be checked for

  • timeout – Time to wait before an exception is thrown

Throws:

ControllerError – If the timeout is reached before the global state is reached

protocol::CSCP::State getLowestState() const#

Get lowest state of any satellite connected.

This returns the lowest state of any of the satellites. Here, “lowest” refers to the state code, i.e. the underlying value of the protocol::CSCP::State enum.

Returns:

Lowest state currently held

std::set<std::string> getConnections() const#

Get set of currently active connected satellites.

Returns:

Set of fully-qualified canonical names of currently connected satellites

bool hasConnection(std::string_view satellite_name) const#

Check if the controller has a connection to the satellite.

Parameters:

satellite_name – Canonical name of the satellite

Returns:

True if connection is established, false if the satellite is known

config::Dictionary getConnectionCommands(std::string_view satellite_name) const#

Get set of all available commands for the given satellite.

Parameters:

satellite_name – Canonical name of the satellite

Returns:

Dictionary of commands and their description that the satellite in question provides

inline std::size_t getConnectionCount() const#

Get total number of currently active connected satellites.

Returns:

Number of currently connected satellites

std::string getRunIdentifier()#

Return the current or last run identifier of the constellation.

This function will search through all connected satellites and returns the first valid run identifier found. The value will be empty if the satellites have just started or no satellite is connected.

Returns:

Run identifier

std::optional<std::chrono::system_clock::time_point> getRunStartTime()#

Return the starting time of the current or last run of the constellation.

This function will go through all connected satellites and returns the latest run starting time found. The optional will not hold a value if the satellites have just started or no satellite is connected.

Returns:

Optional with the run starting time

Protected Types

enum class UpdateType : std::uint8_t#

Update identifier

Values:

enumerator UPDATED#

Connection data has been updated

enumerator ADDED#

A connection has been added

enumerator REMOVED#

A connection has been removed

Protected Functions

virtual void reached_state(protocol::CSCP::State state, bool global)#

Method called whenever a new global or lowest state has been reached.

A global state is a situation when all connected satellites share a common state. The lowest state is often used to convey the state of a Constellation when its constituents are in different states, i.e. the Constellation is not in a global state. Whenever a new state of the Constellation is reached, e.g. by a state update of a satellite or the joining or departing of a satellite, this method is called. This can e.g. be used to emit signals for user interfaces or to trigger further actions.

Parameters:
  • state – The new global or lowest state of the constellation

  • global – Flag indicating whether the new state is global or lowest

virtual void leaving_state(protocol::CSCP::State state, bool global)#

Method called whenever a global or lowest state is left towards a new state.

Parameters:
  • state – The previous lowest state of the constellation

  • global – Flag indicating whether the previous state was global or lowest

virtual void propagate_update(UpdateType type, std::size_t position, std::size_t total)#

Method to propagate updates of connection data.

This virtual method can be overridden by derived controller classes in order to be informed about data updates of the attached connections such as state changes and additions or deletions of connections. The parameter position holds the position of the updated data row.

Parameters:
  • type – Type of the connection update performed

  • position – Index of the connection which has received an update

  • total – Total number of current connections

Protected Attributes

log::Logger logger_#

Logger to use

std::map<std::string, Connection, std::less<>> connections_#

Map of open connections

mutable std::mutex connection_mutex_#

Mutex for accessing the connection map

Note

: This is marked mutable since some derived controllers may need to lock this for read access to the connection list in functions marked as const.

struct Connection#
#include <constellation/controller/Controller.hpp>

Local representation of a remote connection and state.

Remote connection, comprising the socket and host ID and URI of a remote satellite as well as its last known state, the last command response and verb. Furthermore, the current heartbeat interval, heartbeat check time points and lives are kept.

Public Members

zmq::socket_t req#

Connection

message::MD5Hash host_id#
std::string uri#
protocol::CSCP::State state = {protocol::CSCP::State::NEW}#

State and last response

message::CSCP1Message::Type last_cmd_type = {}#
std::string last_message = {}#
config::Dictionary commands = {}#
protocol::CHP::Role role = {protocol::CHP::Role::DYNAMIC}#

Heartbeat status

std::chrono::milliseconds interval = {10000}#
std::chrono::system_clock::time_point last_heartbeat = {std::chrono::system_clock::now()}#
std::chrono::system_clock::time_point last_checked = {std::chrono::system_clock::now()}#
std::uint8_t lives = {protocol::CHP::Lives}#
class ControllerConfiguration#
#include <constellation/controller/ControllerConfiguration.hpp>

Configuration parser to read TOML files and emit dictionaries for individual satellites.

The configuration file holds a hierarchy of tables which contain the configuration keys for all satellites of the Constellation. The dictionaries for the individual satellites need to be assembled from keys specific to the respective satellite, keys valid for the relevant satellite type and keys intended for all satellites.

Public Functions

virtual ~ControllerConfiguration() = default#
ControllerConfiguration() = default#

Default constructor with empty configuration dictionaries.

ControllerConfiguration(std::string_view toml)#

Construct a controller configuration and parse dictionaries from a string.

Parameters:

toml – TOML data as string

Throws:
explicit ControllerConfiguration(const std::filesystem::path &path)#

Construct a controller configuration and parse dictionaries from a configuration file.

Parameters:

path – File path to the TOML configuration file

Throws:
bool hasSatelliteConfiguration(std::string_view canonical_name) const#

Check if a configuration exists for a given satellite.

This only checks the specific (named) satellite sections of the configuration file, not any type-bound or global configuration key-value-pairs.

Returns:

True if a configuration is available for the satellite with the given name, false otherwise

config::Dictionary getSatelliteConfiguration(std::string_view canonical_name) const#

Prepare and return configuration dictionary for a given satellite.

The cached dictionaries from parsed from the input TOML are searched for the given satellite, and keys from the type section matching this satellite as well as global keys to all satellites are added. Name and type are matched case-insensitively.

Returns:

Configuration dictionary, possibly empty if the satellite was not found in the cached configuration

void addSatelliteConfiguration(std::string_view canonical_name, config::Dictionary config)#
std::string getAsTOML() const#
void validate() const#

Validate the configuration.

Runs checks such as dependency graph validation on the set of satellite configurations

Throws:

ConfigFileValidationError – if a validation error is encountered

class ControllerError : public constellation::utils::RuntimeError#
#include <constellation/controller/exceptions.hpp>

Base class for all controller exceptions.

Subclassed by constellation::controller::ConfigFileNotFoundError, constellation::controller::ConfigFileParseError, constellation::controller::ConfigFileTypeError, constellation::controller::ConfigFileValidationError, constellation::controller::QueueError

Public Functions

inline explicit ControllerError(std::string what_arg)#

Protected Functions

ControllerError() = default#
class MeasurementCondition#
#include <constellation/controller/MeasurementCondition.hpp>

Base class for measurement conditions.

Subclassed by constellation::controller::MetricCondition, constellation::controller::TimerCondition

Public Functions

virtual void await(std::atomic_bool &running, Controller &controller, log::Logger &logger) const = 0#

Method waiting for the condition to become true, blocking call.

This is the purely virtual interface method to be implemented by condition classes

Parameters:
  • running – Reference to the running state of the measurement queue

  • controller – Reference to the controller used by the measurement queue

  • logger – Reference to the logger used by the measurement queue

virtual std::string str() const = 0#

Provide human-readable representation of the condition.

Returns:

Condition description

virtual ~MeasurementCondition() = default#

Protected Functions

MeasurementCondition() = default#
class MeasurementQueue#
#include <constellation/controller/MeasurementQueue.hpp>

Measurement queue class which allows to queue and fetch measurement configurations which can be used to reconfigure a constellation.

The measurement queue holds a reference to the currently used controller of the constellation and can take over when the global state is ORBIT, i.e. all satellites have been initialized and launched, It will only take care of reconfiguring, starting and stopping, and will leave the constellation in the ORBIT state when finishing.

Each measurement consists of a set parameters for any number of satellites. The original values of the measurement parameters are read from the satellites using the get_config command before each measurement and are cached in the queue. WHenever a parameter does not appear in the measurement anymore, it is reset to the original value the next time a reconfiguration is performed.

For example, a queue that first scans the parameter a with values from 1 - 2 and the parameter b from 5 - 7 will first read the parameter a from the satellite configuration, then set a = 1 and a = 2 in the subsequent measurement. The next measurement will set b = 5, but parameter a does not appear anymore and is reset to its original value read from the satellite.

Subclassed by DummyQueue

Public Types

enum class State : std::uint8_t#

Values:

enumerator IDLE#

Queue is idling (there are pending measurements but the queue is stopped)

enumerator FINISHED#

Queue is finished (there are no measurements in the queue and it is stopped)

enumerator RUNNING#

Queue is currently running.

enumerator FAILED#

Queue has experienced a failure and has stopped.

using Measurement = std::map<std::string, Controller::CommandPayload>#

Measurement is a map with satellite canonical names as keys and configuration dictionaries as values

Public Functions

MeasurementQueue(Controller &controller, std::chrono::seconds timeout = std::chrono::seconds(60))#

Construct a measurement queue.

Parameters:
  • controller – Reference to the controller object to be used

  • timeout – Transition timeout after which the queue will be interrupted if the target state was not reached

virtual ~MeasurementQueue()#

Destruct the measurement queue.

void setPrefix(std::string prefix)#

Set run identifier prefix.

Parameters:

prefix – Prefix for the run identifier

void setDefaultCondition(std::shared_ptr<MeasurementCondition> condition)#

Set default condition.

Parameters:

condition – Stopping condition for run stop in case no per-measurement condition is defined

void append(Measurement measurement, std::shared_ptr<MeasurementCondition> condition = nullptr)#

Append a new measurement.

Appends the measurement to the queue and updates the progress. The currently configured default condition is set for this measurement unless a measurement-specific condition is provided.

Parameters:
  • measurement – Measurement to be added to the queue

  • condition – Optional condition for this specific measurement. If not provided, the queue’s default condition is used.

void clear()#

Clear all measurements.

If the queue is not running, this will clear all measurements. If the queue is currently running, it will clear all but the current measurement

inline bool running() const#

Helper to check if the queue is running.

Returns:

True if running, false otherwise

inline std::size_t size() const#

Get number of remaining measurements.

Returns:

Remaining measurement queue length

double progress() const#

Current progress of the measurement queue.

Returns the fraction of measurements successfully performed over the total number of measurements. Since measurements are popped from the queue once they have been done, this uses the run sequence counter to account for the number of measurements already performed.

Returns:

Progress of the queue, value as 0 < progress < 1

void start()#

Start the measurement queue.

Note

Requires the constellation to be in global state ORBIT

void halt()#

Halt the measurement queue after the current measurement has concluded.

void interrupt()#

Interrupt the current measurement and halt the queue.

Protected Functions

virtual void queue_state_changed(State queue_state, std::string_view reason)#

Method called whenever a the queue state changed, e.g. it started or stopped processing measurements, or the queue failed.

Parameters:
  • queue_state – New state of the queue

  • reason – Reason for the state change, may be empty

virtual void measurement_concluded()#

Method called whenever a measurement was successfully concluded and has been removed from the queue.

virtual void progress_updated(std::size_t current, std::size_t total)#

Method called whenever the progress of the queue was updated.

Parameters:
  • current – Current number of measurements already successfully finished

  • total – Total number of measurements (finished and pending) of this queue

Protected Attributes

std::deque<std::pair<Measurement, std::shared_ptr<MeasurementCondition>>> measurements_#

Queue of measurements

mutable std::mutex measurement_mutex_#
std::shared_ptr<MeasurementCondition> default_condition_#
class MetricCondition : public constellation::controller::MeasurementCondition#
#include <constellation/controller/MeasurementCondition.hpp>

Class implementing a telemetry-based measurement condition.

Public Functions

MetricCondition(std::string remote, std::string metric, config::Value target, std::function<bool(const config::Value, const config::Value)> comparator = std::greater_equal<>(), std::string comp_name = ">=")#

Constructor for a metric-based measurement condition.

This condition will subscribe to the provided metric with the configured remote satellite and waits until the received value matches the target value and condition.

Parameters:
  • remote – Remote satellite to subscribe to

  • metric – Metric to subscribe to from remote satellite

  • target – Target value of the metric

  • comparator – Comparison function the received metric value and the target value should satisfy

  • comp_name – String representation of the comparator function, e.g. “>=”

virtual void await(std::atomic_bool &running, Controller &controller, log::Logger &logger) const override#

Method waiting for the condition to become true, blocking call.

This is the purely virtual interface method to be implemented by condition classes

Parameters:
  • running – Reference to the running state of the measurement queue

  • controller – Reference to the controller used by the measurement queue

  • logger – Reference to the logger used by the measurement queue

virtual std::string str() const override#

Provide human-readable representation of the condition.

Returns:

Condition description

class QueueError : public constellation::controller::ControllerError#
#include <constellation/controller/exceptions.hpp>

Error from a measurement queue.

Public Functions

inline explicit QueueError(std::string_view error)#

Construct an error for a measurement queue.

Parameters:

error – Error message from the queue

class TimerCondition : public constellation::controller::MeasurementCondition#
#include <constellation/controller/MeasurementCondition.hpp>

Class implementing a timer-based measurement condition.

Public Functions

inline TimerCondition(std::chrono::seconds duration)#

Constructor for a timer-based condition.

: This condition will wait until the configured duration has passed

Parameters:

duration – Duration of this measurement

virtual void await(std::atomic_bool &running, Controller &controller, log::Logger &logger) const override#

Method waiting for the condition to become true, blocking call.

This is the purely virtual interface method to be implemented by condition classes

Parameters:
  • running – Reference to the running state of the measurement queue

  • controller – Reference to the controller used by the measurement queue

  • logger – Reference to the logger used by the measurement queue

virtual std::string str() const override#

Provide human-readable representation of the condition.

Returns:

Condition description