A portable C++17 core for devices and controllers on the Electrification Bus (eBus), which builds on the Homie 5 MQTT convention. The core holds the Homie device model (Device, Node, Property, the $state and $description lifecycle), /set dispatch, the controller, id and payload validation, and the mDNS discovery contract (TXT records, broker discovery). It depends on the C and C++ standard libraries and ArduinoJson, with no Arduino, ESP-IDF or FreeRTOS header, and a port supplies the MQTT client, the console and the clock.
.ebus-spec.json records the specification commit, framework.md version, and framework features this SDK implements.
| Target | Where | MQTT client |
|---|---|---|
| ESP32 (Arduino framework, PlatformIO) | esp32-sdk | arduino-mqtt |
| POSIX (Linux, macOS) | ports/posix/ in this repository |
Eclipse Paho MQTT C |
Version 0.4.0, alpha. Known limits:
- The POSIX demo build has no TLS; it connects to plain-TCP brokers only.
- After a broker loses its retained messages, esp32-sdk's reconnect does not restore
$description; it does not yet callDevice::forgetDescriptionHash()(After a reconnect). - The driver contract (
NodeEntity,NodeProperty) is still in esp32-sdk (why). - The code-first API has rough edges found while writing the POSIX demo: registering a settable property needs a live connection, the controller has no change callback, and float values are always formatted with
%f. - esp32-sdk is not public yet; links to it will resolve once it is.
You need CMake 3.18 or later, a C++17 compiler (GCC or Clang), and, for the end-to-end tests, mosquitto (Homebrew: brew install mosquitto; Debian/Ubuntu: apt-get install mosquitto).
cmake -S ports/posix -B ports/posix/build
cmake --build ports/posix/build -j
ctest --test-dir ports/posix/build --output-on-failureThen run the demo device and controller against a broker:
ports/posix/build/ebus-posix-device --host <broker> --device-id posix-demo
ports/posix/build/ebus-posix-controller --host <broker>
ports/posix/build/ebus-posix-controller --host <broker> --set posix-demo/switch/on=true --duration-s 5The device publishes ebus/5/posix-demo with a settable switch/on and a simulated sensor/temperature, plus a child device. The POSIX port README has every option and how the port meets the core's contract.
cmake -S . -B build
cmake --build build -j
ctest --test-dir build --output-on-failureAs the top-level project this builds the libraries below, compiles each public header on its own, and runs the Unity suites in test/. ArduinoJson 7.4.3 and Unity 2.6.1 are fetched and checked against their SHA-256. A parent CMake project uses add_subdirectory(<path>/cpp-sdk) and links ebus_core; the tests are then off.
| Target | Contents | Depends on | Docs |
|---|---|---|---|
ebus_mqtt |
The MQTT transport interface (MqttTransport), the publishes held while the link is down (PublishHold), the reconnect order (mqtt_after_connect()) |
nothing | doc/mqtt.md |
ebus_discovery |
The mDNS contract: each advertised service's TXT record (txt_build_ebus() and the rest), the interface a port's mDNS stack implements (MdnsBackend), broker service types and broker discovery over that interface |
nothing | doc/discovery.md |
ebus_homie |
The Homie model (Device, Node, Property, $state and $description), /set dispatch, the controller, id and payload validation, the HomieTransport adapter, the log and clock hooks |
ebus_mqtt, ArduinoJson |
doc/core.md |
ebus_core |
Umbrella: links the three, and puts include/, the pre-split header paths (<homie/Device.h>), on the include path |
ebus_mqtt, ebus_discovery, ebus_homie |
doc/core.md |
ebus_mqtt and ebus_discovery each build with only their own include directory (mqtt/include, discovery/include), and ebus_homie with its own and ebus_mqtt's, so a project can take one with add_subdirectory(<path>/cpp-sdk/mqtt), add_subdirectory(<path>/cpp-sdk/discovery) or add_subdirectory(<path>/cpp-sdk/homie).
A port binds four things, all documented in doc/core.md ("What a port implements"):
| Piece | Header | What the port does |
|---|---|---|
| MQTT transport | ebus/homie/homie_transport.h |
Subclasses HomieTransport, which is ebus_mqtt's MqttTransport plus a Homie adapter: publish(), subscribe() and queue_publish() with a completion callback (doc/mqtt.md) |
| Clock | ebus/homie/homie_clock.h |
homie_clock_bind(now_ms, sleep_ms) |
| Console | ebus/homie/homie_log.h |
homie_log_bind(vprintf_sink); optional, stdout otherwise |
| Settable table | ebus/homie/homie_settable.h |
Supplies storage to settable_table_bind(), routes each claimed /set message to settable_dispatch() on its own task, and subscribes every settable topic after each connect |
The POSIX port is the reference: ports/posix/src/posix_port.cpp binds the clock, console and settable table, and ports/posix/src/paho_transport.cpp is the transport. A port should also follow the rules for publishes made while the broker link is down and the reconnect order, both from ebus-mqtt-client; ebus_mqtt provides them as PublishHold and mqtt_after_connect(), which the POSIX port uses.
library.json makes this repository one PlatformIO library named ebus_core that compiles mqtt/src/, discovery/src/ and homie/src/, puts include/, mqtt/include/, discovery/include/ and homie/include/ on the include path, and depends on ArduinoJson 7.4.3. Add it with a git URL:
lib_deps =
https://github.com/electrification-bus/cpp-sdk.git#<tag>
build_flags =
-std=gnu++17
-DUSE_EBUS_TOPIC
build_unflags =
-std=gnu++11The core needs C++17; build_unflags drops the gnu++11 default of arduino-esp32. It is compiled without the project's build_src_flags, so a macro it reads (USE_EBUS_TOPIC, MAX_DATA_LEN, CONTROLLER_INBOX_BYTES) goes in build_flags. esp32-sdk carries the same code in lib/ebus_core/ until it moves to this dependency.
MIT License - Copyright (c) 2026 Clark Communications Corporation. Fetched dependencies and their licenses: THIRD_PARTY_LICENSES.md.
Split out of esp32-sdk, with its history. Developed by:
- Lead developer: Doug Mendonça (@nesl-admin), New Energy Solutions Lab, doug@newenergysolutionslab.com. Primary author of the firmware this code was split from, and a significant contributor to the eBus protocol and ecosystem more broadly.
- Project owner: Donald Clark Jackson (@dcj), Clark Communications Corporation, dcj@clark-communications.com. Project direction and documentation.