Skip to content

Repository files navigation

morfBeacon

Read in another language: English (this document) · Français.

Version C++ Qt Build License

Shared C++ library for LAN supervision of desktop applications.

morfBeacon lets an application (ComponentHub, SiteWatch, GatewayLab, and future tools) announce its presence on the local network and expose its metrics to a supervisor (morfDashboard), in a few lines of code.

Principle: push presence / pull detail

Two distinct needs, two mechanisms:

Need Mechanism Who talks Frequency
"Is the app alive?" UDP broadcast heartbeat the app emits every 15 s
"What is its detailed state?" HTTP /status server the supervisor asks on demand

The supervisor scans nothing: it listens passively. No IP to know, no configuration, automatic discovery. An app that stops emitting for ~1 minute is considered offline. Detailed metrics never travel in the heartbeat: they stay behind /status, queried only when needed.

Proven on a heterogeneous fleet (23 July 2026). Distributed discovery works across Windows, Linux, Raspberry Pi and ESP32 simultaneously, with no manual configuration: morfMonitor instances discover one another, and services published by the Raspberry Pi appear automatically on Windows and the other way round. No IP address is written anywhere. The independent implementations of the protocol - this Qt library, the Arduino emitter, morfSync in native C++ and morfDashboard in Python - interoperate on the same network, which is what the checker below exists to keep true.

The morfbeacon/1 protocol

UDP heartbeat (compact JSON, broadcast on port 45454):

{
  "proto": "morfbeacon/1",
  "app": "ComponentHub",
  "host": "fredpc",
  "version": "1.6.0",
  "state": "ok",
  "status_port": 8787,
  "instance": "ComponentHub@fredpc",
  "uptime_s": 3600,
  "ts": 1752400000
}

HTTP GET /status (on status_port):

{
  "app": "ComponentHub",
  "host": "fredpc",
  "version": "1.6.0",
  "state": "ok",
  "uptime_s": 3600,
  "metrics": { "components": 812, "projects": 14, "last_backup_age_s": 7200 },
  "ts": 1752400000
}

GET /healthz returns {"status":"ok"} (a lightweight liveness probe). The full protocol is specified in docs/fr/PROTOCOL.md (FR).

Declaring a web interface

An application that serves a web interface declares it by setting one field:

cfg.webUiPath        = "/";                       // the whole declaration
cfg.webUiLabel       = "Analyses météo";          // optional, defaults to appName
cfg.webUiDescription = "Tendances et corrélations."; // optional
// cfg.webUiPort     = 8080;                      // optional, defaults to statusPort

The capability web_ui is then added automatically to the heartbeat, and the detail appears in /status:

"capabilities": ["web_ui"],
"web_ui": { "path": "/", "label": "Analyses météo", "port": 8799 }

A consumer discovers the service, sees the capability, fetches /status once to learn how to open it, and offers a link - without knowing the application. Adding a new service to the ecosystem therefore requires no change to any consumer.

The capability is derived from webUiPath, never declared separately: the detail and the capability that makes it discoverable cannot drift apart.

Integration in 5 lines

#include <morfbeacon/PresenceService.h>
#include <morfbeacon/IMetricsProvider.h>

morfbeacon::PresenceConfig cfg;
cfg.appName = "ComponentHub";
cfg.version = APP_VERSION;

morfbeacon::FunctionMetricsProvider provider([this] {
    QJsonObject m;
    m["components"] = m_inventory->count();
    return m;
});

auto* presence = new morfbeacon::PresenceService(cfg, &provider, this);
presence->start();

Detailed guide (CMake + where to wire the code in ComponentHub / SiteWatch): docs/fr/INTEGRATION.md (FR).

Building

Same commands as ComponentHub / SiteWatch:

# Windows (MSYS2 / MinGW)
cmake --preset mingw
cmake --build --preset mingw

# Linux / Raspberry Pi
cmake --preset linux          # or linux-arm64
cmake --build --preset linux

In a standalone build, the morfbeacon_demo example is compiled (build-*/examples/minimal/).

Try it without hardware

In two terminals:

# 1. the "fake app" (emits the heartbeat + exposes /status)
./build-mingw/examples/minimal/morfbeacon_demo

# 2. the "fake dashboard" (listens + polls), no dependency
python tools/fake_dashboard.py --poll --every 10

The tester shows discovery, offline transitions and metrics. It reproduces exactly what morfDashboard does.

Checking the protocol

The protocol now has five implementations, forced by platform and language boundaries: two emitters (Qt, ESP32) and three listeners (Qt, ESP32, Python). None can be shared with the others, so what is common is a format - and a format without verification drifts in silence. A renamed field, an integer sent as a string, a misspelt capability, and a consumer stops seeing a service with nothing to report it.

tools/check-protocol.py is the executable reference for that format. Run on the local network, it validates the real datagrams of every implementation at once:

python tools/check-protocol.py              # listen 20 s, validate everything
python tools/check-protocol.py --seconds 60
python tools/check-protocol.py --no-pull    # skip the /status requests
python tools/check-protocol.py --file capture.json

It changes nothing and emits nothing: it listens, reports, explains. Exit status is non-zero on any violation, so it can gate a release.

Its most valuable check is not on either document but between them: a service announcing the web_ui capability must serve a web_ui block in /status. Declaring one without the other produces an interface nobody can open - a defect that occurred twice in the ecosystem, both times in a service that reimplements its own /status and forgot the block.

Standard library only, like fake_dashboard.py.

Dependencies

Qt 6 (Core + Network only - no Widgets, usable in a headless service). C++17, CMake ≥ 3.21.

Documentation

The in-depth guides are in French under docs/fr/; an English index is at docs/en/.

Document Contents
docs/fr/PROTOCOL.md (FR) The morfbeacon/1 wire protocol (heartbeat, /status, ports)
docs/fr/ARCHITECTURE.md (FR) The classes (Heartbeat, StatusServer, providers, PresenceService)
docs/fr/INTEGRATION.md (FR) Integrating morfBeacon into an application
CHANGELOG.md Version history
ROADMAP.md Planned work
CONTRIBUTING.md Contribution guide

License

Distributed under the GPL-3.0-only license. © 2026 morfredus.

About

Shared C++ library for LAN presence and supervision. An application announces itself by UDP heartbeat and exposes its metrics over HTTP - push presence, pull detail. No IP to configure, no scanning: discovery is automatic.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages