Constellation Preview Release 0.7#

We are happy to announce the release of Constellation version 0.7, named Reticulum. This is a major step towards 1.0, including nested configurations and a GUI for telemetry.

Breaking Changes for Operators#

Programs using previous versions of Constellation are not compatible with this version due to the breaking changes in the network discovery and configuration of satellites.

Configuration Files#

Existing configuration files require slight adjustment to work with version 0.7 and onwards. The three major breaking changes for existing configuration files are the removal of the satellites base node, the new _default section for global/type defaults and the introduction of sections for framework parameters.

Previously:

_role = "TRANSIENT"

[Sputnik]
_role = "NONE"

[Sputnik.One]
_role = "ESSENTIAL"

After 0.7:

[_default]
_autonomy.role = "TRANSIENT"

[Sputnik._default]
_autonomy.role = "NONE"

[Spuntik.One]
_autonomy.role = "ESSENTIAL"

These changes allow for the introduction of nested configuration sections, see new features for details.

Breaking Changes for Application Developers#

Programs written for previous versions of Constellation are not compatible with this version due to the breaking changes in the telemetry registration and configuration of satellites.

Using Defaults in Configuration (Python)#

As part of the introduction of nested configuration sections, the setdefault method has been replaced by a get method, which supports providing a default value as well as checking the return type.

Previously:

voltage = config.setdefault("voltage", 5.0)

After 0.7:

voltage = config.get("voltage", 5.0)

Removal of the Metric Type#

The metric type has been removed since it is not being used in both our current monitoring solutions. Satellites need to be adjusted by removing the corresponding flag from the metric definition.

Previously:

register_metric("NAME", "unit", MetricsValue::LAST_VALUE, "description");
@schedule_metric("A", MetricsType.LAST_VALUE, 10)

After 0.7:

register_metric("NAME", "unit", "description");
@schedule_metric("A", 10)

New Features for Operators#

TelemetryConsole#

Previously setting up Grafana and InfluxDB was required to monitor the telemetry data of satellites in a Constellation. In this release, a new user interface called TelemetryConsole has been added, which allows to quickly take a glanze at telemetry data without any setup. Note that unlike InfluxDB, TelemetryConsole has no persistency, meaning that the telemetry data is lost when the GUI is closed.

Screenshot of telemetry monitoring with TelemetryConsole

Configuration Sections#

Previously satellite configurations had to be flat, meaning no nested structures where allowed. In this release support for nested structures, called configuration sections, has been added.

A typical example where sections come in handy are satellites controlling instruments with multiple channels, such as power supply outputs. Here, sections can be used to describe and configure each channel individually:

[MyPSU.Bias]

port = "/dev/ttyUSB0"

[MyPSU.Bias.channels]

channel_0.enabled = true
channel_0.name = "5V Logic"
channel_0.voltage = 5

channel_1.enabled = true
channel_1.name = "3.3V Logic"
channel_1.voltage = 3.3

More details can be found in the corresponding Configuration Files chapter in the operator guide.

YAML Configuration Files#

Support for YAML as an alternative format for configuration files has been added. In the example above, the corresponding YAML configuration would look like this:

MyPSU:
  Bias:
    port: /dev/ttyUSB0
    channels:
      channel_0:
        enabled: true
        name: 5V Logic
        voltage: 5.0
      channel_1:
        enabled: true
        name: 3.3V Logic
        voltage: 3.3

New Features for Application Developers#

Overhauled Configuration Classes#

With the introducation of configuration sections, the configuration classes in C++ and Python have been overhauled allowing for more flexibility.

The previously mentioned example with two fixed channels can be implemented in C++ or Python as demonstrated in the following. The parameters not nested in a section are read directly from the Configuration objects, while the individual channel configurations are retrieved via the getSection()/get_section() methods:

// Get port for connection
const auto port = config.get<std::string>("port");

// Get configuration section for channels
auto& channels_section = config.getSection("channels");

// Read channel 0 & 1 as nested configuration sections
for(auto n : {0, 1}) {

  // Get section for channel n
  auto& channel_section = config.getSection("channel_" + to_string(n));

  // Note that channel_section has the same methods available as config

  // Get if channel is enabled, its assigned name and the set voltage
  const auto enabled = channel_section.get<bool>("enabled");
  const auto name = channel_section.get<std::string>("name");
  const auto voltage = channel_section.get<double>("voltage");
}
# Get port for connection
port = config.get("port", return_type=str)

# Get configuration section for channels
channels_section = config.get_section("channels")

# Read channel 0 & 1 as nested sections
for n in [0, 1]:

    # Get section for channel n
    channel_section = config.get_section(f"channel_{n}");

    # Note that channel_section has the same methods available as config

    # Get if channel is enabled, its assigned name and the set voltage
    enabled  = channel_section.get("enabled", return_type=bool)
    name = channel_section.get("name", return_type=str)
    voltage = channel_section.get_num("voltage")

More details can be found in the corresponding Configuration Sections chapter in the application developer guide.

Detailed Changelog#

The following changes related to protocols are included in this release:

  • MR!988: CMDP: drop metric type

  • MR!992: CHIRP: use lower-case canonical and group names for hashing

The following changes related to satellites are included in this release:

  • MR!967: EudaqNativeWriter: allow to set device number

  • MR!970: CaenHV: move to own repository

  • MR!974: Influx: use batching instead of synchronous mode

  • MR!1004: Influx: allow writing strings to InfluxDB

The following changes related to graphical user interfaces are included in this release:

  • MR!829: Introduction of TelemetryConsole for telemetry monitoring

  • MR!957: Prevent color being drawn outside combo box

  • MR!987: MissionControl: improve handling of run identifiers

The following improvements to the framework are included in this release:

  • MR!528/MR!955: Check for DATA services at launching

  • MR!896: [C++] Allow fetching config values as optionals

  • MR!906: Add support YAML configuration files

  • MR!907: Drop satellites node from configuration files

  • MR!942: [Python] Fix potential hangs on connection loss

  • MR!952: Calculate heartbeat intervals from monotonic clock

  • MR!955: [Python] Fix not sending heartbeats on timezone change

  • MR!954: [C++] Fix chrono compilation on MacOS

  • MR!986: [C++] Update LLVM toolchain to LLVM 21

  • MR!951/MR!973: Introduce nested configuration sections

  • MR!977/MR!1006: Read config variables from environment

  • MR!1004: [C++] Emit run ID as metric in starting

The following miscellaneous changes are included in this release:

  • MR!934: Add support for Python 3.14

  • MR!946: Replace flake8 with ruff

  • MR!949: Add markdownlint to CI

  • MR!956: Improved MacOS installation documentation

  • MR!961: Add MADMAX satellites to satellite library

  • MR!965: Refresh documentation with various improvements

  • MR!969: Replace mypy with basedpyright

Notes#

The software is publicly available under the EUPL-1.2 from the DESY GitLab repository. In addition, the Python version is available on PyPI and the C++ version is available on Flathub for Linux.

It should be noted that this is a preview release and some interfaces and protocols might change until the first official major release.