Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to `cpp-sdk` are recorded here. Format follows [Keep a Chang

## [Unreleased]

### Fixed

- `Property::setValue(float)` published `nan`, `inf` or `-inf`, which the float payload grammar does not allow. `homie_format_float()` and `homie_format_double()` now return `false` with an empty string for a NaN or infinity, and `setValue()` logs and keeps the previous value. ([#27](https://github.com/electrification-bus/cpp-sdk/issues/27))

### Added

- `test_homie_float_vectors`: the 434 float32 vectors shared with python-sdk and rust-sdk.

## [0.7.0] - 2026-10-10

### Changed
Expand Down
8 changes: 4 additions & 4 deletions homie/include/ebus/homie/homie_datatype.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ bool homie_validate_number(double value, const char* format, double* coerced);
// Format a float payload: the shortest decimal that reads back as the same float, laid
// out like Python's repr() without the exponent '+' (fixed notation with at least one
// fraction digit for exponents -4..15, else d.ddde-XX), so "21.4", "40.0", "1e-05",
// "1e16". This is python-sdk's float text. Writes NUL-terminated text to out (n >= 32);
// a non-finite value is written as "nan", "inf" or "-inf", which is not a valid payload.
void homie_format_float(float value, char* out, size_t n);
// "1e16". This is python-sdk's float text. Writes NUL-terminated text to out (n >= 32)
// and returns true. A NaN or infinity has no float payload: returns false, out is "".
bool homie_format_float(float value, char* out, size_t n);

// The same for a double: the shortest decimal that reads back as the same double.
void homie_format_double(double value, char* out, size_t n);
bool homie_format_double(double value, char* out, size_t n);
8 changes: 7 additions & 1 deletion homie/src/Property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,14 @@ void Property::setValue(int64_t value) {
_has_value = true;
}
void Property::setValue(float value) {
char text[32];
if (!homie_format_float(value, text, sizeof(text))) {
homie_logf("Property: '%s' - %f is not a float payload; keeping the previous value\n",
_id, (double)value);
return;
}
_floatValue = value;
homie_format_float(value, _value, sizeof(_value));
snprintf(_value, sizeof(_value), "%s", text);
_has_value = true;
}
void Property::setValue(const char* value) {
Expand Down
15 changes: 8 additions & 7 deletions homie/src/homie_datatype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,10 @@ bool homie_validate_duration(const char* payload) {
// Shortest round trip: the fewest significant digits whose text reads back as `value`,
// through strtof() for a float (nine digits always suffice) or strtod() for a double
// (seventeen).
static void format_shortest(double value, bool is_float, char* out, size_t n) {
static bool format_shortest(double value, bool is_float, char* out, size_t n) {
if (!isfinite(value)) {
snprintf(out, n, "%g", value);
return;
if (n > 0) out[0] = '\0';
return false;
}
char sci[32];
const int max_prec = is_float ? 8 : 16;
Expand Down Expand Up @@ -346,12 +346,13 @@ static void format_shortest(double value, bool is_float, char* out, size_t n) {
snprintf(buf + len, sizeof(buf) - len, "e%s%02d", exp10 < 0 ? "-" : "", abs(exp10));
}
snprintf(out, n, "%s", buf);
return true;
}

void homie_format_float(float value, char* out, size_t n) {
format_shortest(value, true, out, n);
bool homie_format_float(float value, char* out, size_t n) {
return format_shortest(value, true, out, n);
}

void homie_format_double(double value, char* out, size_t n) {
format_shortest(value, false, out, n);
bool homie_format_double(double value, char* out, size_t n) {
return format_shortest(value, false, out, n);
}
Loading
Loading