All notable changes to cpp-sdk are recorded here. Format follows Keep a Changelog; the project uses Semantic Versioning.
0.7.1 - 2026-10-10
Property::setValue(float)publishednan,infor-inf, which the float payload grammar does not allow.homie_format_float()andhomie_format_double()now returnfalsewith an empty string for a NaN or infinity, andsetValue()logs and keeps the previous value. (#27)
test_homie_float_vectors: the 434 float32 vectors shared with python-sdk and rust-sdk.
0.7.0 - 2026-10-10
Property::setValue(float)publishes the shortest decimal that reads back as the same float, laid out like python-sdk's float text:21.4,40.0,1e-05,1e16instead of21.400000. The formatters arehomie_format_float()andhomie_format_double()inebus/homie/homie_datatype.h. (#23)
0.6.0 - 2026-10-10
- Breaking:
EbusLink::setup(EbusLink::CONTROLLER)needsebus_link_enable_controller()to have been called; without it the link logs and is disabled. Controller mode moves tolink/src/link_controller.cpp, which only that call reaches, so a device that usesEbusLinkno longer links the controller and its discovery table. On an ESP32-POE-ISO-16MB device with three device-mode links that saves 2,544 bytes of static RAM and 3,664 bytes of flash. (#20)
0.5.0 - 2026-10-10
ebus_link, a CMake target overebus_homie(link/, doc/link.md):EbusLinkcopies up to three property values, local or remote, into a settable property, with a format, rounding, change detection, retry backoff, and the last good value kept on a retraction. In a device (EbusLink::DEVICE) it reads the rootDevice's properties, watches remote ones through the settable table and sets a local target withdeliver_local_set(); in a controller (EbusLink::CONTROLLER) it reads the discovery cache, binds*in the device or node part once discovery has settled, refuses an ambiguous match, and commands the target only while it isready. The logic comes from esp32-sdk'slogic/link, by Doug Mendonça.ebus_corelinks it, PlatformIO buildslink/src/, and a CI step compiles it with only its own andebus_homie's include directories.- Unity suites
test_link_coreandtest_link_engine, which linkebus_link. --link SOURCES=>TARGET(with--link-format,--link-decimals,--link-interval-ms) forebus-posix-deviceandebus-posix-controller, and the end-to-end testse2e_linkande2e_link_device.
0.4.1 - 2026-10-10
Property::has_value(), and for the controller's copy of a remote propertyProperty::store_received()andProperty::forget_value()(doc/core.md).controller_device_count()andcontroller_device_at(), which return a pointer into the controller's device table, so a caller need not copy everyControllerDevicewithcontroller_list_device_info().
- A zero-length payload on a property topic (the retained value removed) set the controller's copy to false, 0 or 0.000000 by datatype. It now clears
has_value()and leavesvalue()at the last payload. - The controller's
value()of a received property is the payload as published. It was reformatted by datatype, so a float21.37read back as21.370001.
0.4.0 - 2026-10-09
ebus_homie, a CMake target (homie/, doc/core.md): the Homie model,/setdispatch, the controller, id and payload validation, the JSON helpers,HomieTransport, and the log and clock hooks. It depends onebus_mqttand ArduinoJson, not onebus_discovery. A CI step compiles it with only its own,ebus_mqtt's and ArduinoJson's include directories. (#3)
- The Homie headers move to
<ebus/homie/...>, andutil/jsonUtils.hto<ebus/homie/jsonUtils.h>;<homie/...>and<util/jsonUtils.h>forward to them.include/homie/homie_limits.halso repeats the four base limits esp32-sdk's generator reads from it. ebus_coreis an INTERFACE target that linksebus_mqtt,ebus_discoveryandebus_homie. The Homie suites linkebus_homiealone. PlatformIO still builds one library.
0.3.0 - 2026-10-09
ebus_discovery, a CMake target with no dependency (discovery/, doc/discovery.md):txt_build_ebus(),txt_build_device_info(),txt_build_http()andtxt_build_log(), which build each advertised service's TXT record from oneEbusIdentityinto a fixed-sizeTxtRecord, with the keys and order of framework.md, ebus-service-discovery and esp32-sdk;MdnsBackend, the advertise, browse and resolve interface a port implements over its mDNS stack;broker_browse()andbroker_reresolve(), esp32-sdk's broker selection over that interface;broker_service_type().ebus_corelinks it. PlatformIO still builds one library.- Unity suites
test_discovery_txtandtest_discovery_backend, which linkebus_discoveryalone, and a CI step that compilesebus_discoverywith only its own include directory. Device::forgetDescriptionHash(): the nextpublish()of that device sends$descriptioneven if it is unchanged. A port calls it on every device before a recovery republish (doc/core.md); the no-op skip innotifyStructuralChange()stays. (#9)
broker_discovery.handmdns_strings.hmove toebus_discoveryas<ebus/discovery/broker_discovery.h>and<ebus/discovery/mdns_strings.h>;<platform/broker_discovery.h>and<platform/mdns_strings.h>forward to them. Their suite is nowtest_discovery_broker.mdns_strings.hadds the full service types (MDNS_TYPE_*),broker_ca,hw_version,broker-hostand each auth method value.
- The POSIX demo device republishes the whole tree,
$descriptionincluded, on every reconnect (waspublishStateTree()), so a broker restarted without persistence describes it again. Thereconnectend-to-end test checks that the root and child$descriptionare retained after the restart. doc/mqtt.mdlisted esp32-sdk'sMqttClientTransportas overriding the Propertyqueue_publish(); it overrides the generic one.
0.2.0 - 2026-10-09
ebus_mqtt, a CMake target with no dependency (mqtt/, doc/mqtt.md):MqttTransport, the transport interface, whosequeue_publish()takes a QoS and a completion callback (mqtt_publish_done_fnand avoid*context);PublishHold, the disconnected-link rules, moved from the POSIX port; andmqtt_after_connect(), which runs the reconnect order (flush, re-subscribe, notify).ebus_corelinks it. PlatformIO still builds one library.- Unity suites
test_mqtt_publish_holdandtest_mqtt_reconnect, which linkebus_mqttalone, and a CI step that compilesebus_mqttwith only its own include directory.
HomieTransportderives fromMqttTransport. Itsqueue_publish(..., Property* source)is no longer pure: it forwards to the generic overload with a callback that callsProperty::queued_publish_done(). A port that overrides it, as esp32-sdk's does, builds unchanged; a new port overrides the generic overload instead.PublishHoldsizes areEBUS_MQTT_HOLD_ENTRIES,EBUS_MQTT_HOLD_TOPIC_MAXandEBUS_MQTT_HOLD_PAYLOAD_MAX(wereEBUS_POSIX_HOLD_ENTRIESandEBUS_POSIX_HOLD_PAYLOAD_MAX). It no longer logs;hold()returnsEVICTED_OLDESTorDROPPED_TOO_LARGEand the port logs. Its header is<ebus/mqtt/publish_hold.h>.- The POSIX port's
PahoTransportoverrides the genericqueue_publish()and runs its connect throughmqtt_after_connect().
0.1.0 - 2026-10-08
- The portable core, split out of esp32-sdk's
lib/ebus_core/with its history: the Homie 5 Device, Node and Property model,/setdispatch and the settable table, the controller, id and payload validation, broker-discovery parsing, and theHomieTransport, log and clock interfaces a port implements. - The POSIX port (
ports/posix/): aHomieTransportover Eclipse Paho MQTT C, a demo device and controller, and end-to-end tests against mosquitto. - The core's Unity suites, built and run with CMake and CTest.
library.json, so a PlatformIO project can add the core with alib_depsgit URL.