Skip to content

Make MO_CONFIG_MAX_VALSTRSIZE override-able via -D#450

Open
RAR wants to merge 1 commit intomatth-x:mainfrom
RAR:configurable-valstrsize-pr
Open

Make MO_CONFIG_MAX_VALSTRSIZE override-able via -D#450
RAR wants to merge 1 commit intomatth-x:mainfrom
RAR:configurable-valstrsize-pr

Conversation

@RAR
Copy link
Copy Markdown

@RAR RAR commented Apr 26, 2026

Summary

Wraps the existing MO_CONFIG_MAX_VALSTRSIZE #define in an #ifndef guard so it can be overridden via a build flag (-DMO_CONFIG_MAX_VALSTRSIZE=256) without patching the header. The default stays 128. Same shape as the surrounding MO_CONFIG_EXT_PREFIX and MO_CONFIG_TYPECHECK guards.

+#ifndef MO_CONFIG_MAX_VALSTRSIZE
 #define MO_CONFIG_MAX_VALSTRSIZE 128
+#endif

Motivation

The OCPP 1.6 MeterValuesSampledData advertised list overflows the 128-byte ceiling once the optional measurands are bound. A typical configuration that includes the four mandatory measurands plus Temperature, SoC, Frequency, and Power.Factor:

Energy.Active.Import.Register,Power.Active.Import,Voltage,Current.Import,Current.Offered,Power.Offered,Temperature,SoC,Frequency,Power.Factor

…is 138 chars. Configuration::setString in ConfigurationKeyValue.cpp:203 rejects writes longer than MO_CONFIG_MAX_VALSTRSIZE and silently returns false, so the CSMS-side default permanently overrides the value the CP advertised. Without source-level access this manifests as the CSMS's shorter list winning, with no log message hinting that a write was rejected.

I hit this on a CP that mirrors HA-side measurands (vehicle SoC, grid frequency, PF) into OCPP MeterValues — the rejection meant evcc never saw the extra rows even though the CP was sampling them every 30 s.

Why I think the default was 128

I assume this ceiling was sized for the original target (ESP8266, ~80 KB RAM) where every declared Configuration<const char*> carries an inline value buffer, so cumulative cost across ~30–50 standard config keys mattered. For the typical CP that publishes 4–5 measurands, 128 chars is comfortable. Modern targets (ESP32, BK7231N, etc.) and CPs that surface optional measurands hit the wall.

Why a guard, not a bump

Bumping the default would change static RAM cost for every existing user. Adding the #ifndef guard is non-invasive: existing builds compile identically. Consumers who need more pay only for what they ask for via -D.

Verification

Built and flashed against a BK7231N (LibreTiny bk72xx) CP with -DMO_CONFIG_MAX_VALSTRSIZE=256. The 138-char advertised list now survives setString (verified by reading back MeterValuesSampledData over GetConfiguration and seeing all 10 entries) and the CSMS subsequently honors it on the next ChangeConfiguration round-trip.

Test plan

  • Default-value build: header expands identically (no -D set → existing 128 kept)
  • Override build: -DMO_CONFIG_MAX_VALSTRSIZE=256 raises the ceiling and setString accepts a 138-char MeterValuesSampledData
  • Compiles clean on arduino-pico Arduino core (BK7231N via LibreTiny)

🤖 Generated with Claude Code

Wrap the existing 128-byte default in #ifndef so consumers can raise the
ceiling via a build flag (`-DMO_CONFIG_MAX_VALSTRSIZE=256` etc.) without
patching the header. Default is unchanged. Same shape as the surrounding
MO_CONFIG_EXT_PREFIX / MO_CONFIG_TYPECHECK guards.

Motivation: the OCPP 1.6 MeterValuesSampledData advertised list overflows
128 chars once the optional measurands (Temperature, SoC, Frequency,
Power.Factor) are bound — Configuration::setString silently rejects the
write and the CSMS-side default permanently overrides ours.
RAR added a commit to RAR/esphome-ocpp-server that referenced this pull request Apr 26, 2026
Switches the fork pin from the single-patch valstrsize SHA (5ac8e0e) to
a branch (ocpp-server) that combines:
  - MO_CONFIG_MAX_VALSTRSIZE override (PR matth-x/MicroOcpp#450)
  - Time.cpp Clock::now() delta cap from PR matth-x/MicroOcpp#447

The Time.cpp guard is defence-in-depth against the 32-bit tick-counter
overflow that produces ~12 h timestamp jumps in OCPP messages. The
upstream PR has both an espidf-only fix (Platform.cpp) and a
platform-agnostic guard (Time.cpp); we cherry-pick only the latter
since we're on MO_PLATFORM_ARDUINO and millis() wraps at ~49.7 days.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant