- control.levelbased.shiftArmPercent (default 95): output % threshold that
arms the shift on the way up. Once armed, the up-curve % at the
filling→draining transition becomes the held value, kept until level
drops to shiftLevel; from there it ramps to 0 % at startLevel.
- shiftLevel description updated — it is no longer the arming trigger,
it's the level at which the held output begins ramping down.
- MeasurementContainer.js: prominent doc block on the class plus a
JSDoc on getFlattenedOutput documenting the `${type}.${variant}.
${position}.${childId}` flatten format and the implicit 'default'
childId convention. This was the #1 footgun for new dashboard
consumers — the comments now make the rule impossible to miss.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MeasurementContainer.isUnitCompatible now short-circuits to accept any unit
when the measurement type is not in the built-in measureMap. Known types
(pressure, flow, power, temperature, volume, length, mass, energy) still
validate strictly. This unblocks user-defined types in the measurement
node's new digital/MQTT mode — e.g. 'humidity' with unit '%', 'co2' with
'ppm' — without forcing those units into the convert-module unit system.
measurement.json schema: add 'mode.current' (analog | digital) and
'channels' (array) so the validator stops stripping them from the runtime
config. Ignored in analog mode.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace hardcoded position strings with POSITIONS.* constants
- Prefix unused variables with _ to resolve no-unused-vars warnings
- Fix no-prototype-builtins with Object.prototype.hasOwnProperty.call()
- Extract menuUtils.js (543 lines) into 6 focused modules under menu/
- menuUtils.js now 35 lines, delegates via prototype mixin pattern
- Add 158 unit tests for ConfigManager, MeasurementContainer, ValidationUtils
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>