Skip to content

fix: MENU_MODE uses setMode() for consistent slave mode sync#121

Merged
basmeerman merged 1 commit intomasterfrom
fix/menu-mode-setmode-consistency
Mar 27, 2026
Merged

fix: MENU_MODE uses setMode() for consistent slave mode sync#121
basmeerman merged 1 commit intomasterfrom
fix/menu-mode-setmode-consistency

Conversation

@basmeerman
Copy link
Copy Markdown
Owner

Summary

  • Fix: Replace SETITEM(MENU_MODE, Mode) with explicit setMode(val) call in setItemValue(), matching the existing STATUS_MODE handler
  • Root cause: When master broadcasts system config via BroadcastSettings() (Modbus register 0x0200), slaves received Mode as a raw assignment (Mode = val) without the side effects that setMode() provides
  • Tests: 8 new tests in test_mode_sync.c verifying phase switching, error clearing, and mode-dependent regulation

The bug

Two code paths deliver Mode to slaves:

Path Register Handler Side effects
processAllNodeStates 0x0003 (STATUS_MODE) setMode(val) Full
BroadcastSettings 0x0200 (MENU_MODE) Mode = valsetMode(val) None → Full

If BroadcastSettings arrives before/instead of the per-node write, the slave gets the mode without phase switching checks, error clearing, or timer resets.

Safety-relevant: with EnableC2=SOLAR_OFF, switching to Solar mode must open the C2 contactor. Without setMode(), the contactor stays closed — wrong phase configuration.

Side effect analysis

Every setMode() side effect was analyzed for slave safety (LoadBl >= 2):

Side effect Slave-relevant? Risk
Phase switching (SOLAR_OFF) Yes — safety-critical Contactor must open
Phase switching (AUTO 1P→3P) Yes — safety-critical CP disconnect needed
Clear LESS_6A for Smart mode Yes Prevents stale errors
Clear SolarStopTimer for Smart Yes Prevents stale timer
Clear ChargeDelay Yes Prevents stale delay
Reset OverrideCurrent for Solar Yes Consistency
NodeNewMode flag Harmless Not consumed on slaves
request_write_settings Appropriate Persists to NVS
MainsMeter check (line 608) Skipped Guard: LoadBl < 2
Double-call prevention if (Mode != val) guard No redundant execution

Test plan

  • 8 new tests in test_mode_sync.c — all pass
  • Full native test suite (49 suites) — all pass
  • Address + UB sanitizers — clean
  • cppcheck static analysis — clean
  • ESP32 firmware build — success
  • CH32 firmware build — success

Fixes #120

🤖 Generated with Claude Code

When the master broadcasts system configuration via BroadcastSettings()
(Modbus register 0x0200), the slave previously received Mode through
SETITEM(MENU_MODE, Mode) — a raw assignment that skipped all setMode()
side effects. This could leave slaves with stale error flags, wrong
phase switching state, or active SolarStopTimer after a mode change.

Safety-relevant: if a slave is charging on 3 phases and mode switches
to Solar with EnableC2=SOLAR_OFF, the C2 contactor must open. Without
setMode(), the contactor stays closed — wrong phase configuration.

Fix: replace SETITEM(MENU_MODE, Mode) with an explicit handler that
calls setMode(val), guarded by `if (Mode != val)` to prevent redundant
calls. This mirrors the existing STATUS_MODE handler at line 2737.

Side effect analysis — setMode() on a slave (LoadBl >= 2):
- Phase switching checks: NEEDED (safety-critical for SOLAR_OFF/AUTO)
- LESS_6A/SolarStopTimer clearing: NEEDED (prevents stale errors)
- ChargeDelay reset: NEEDED (prevents stale delays)
- OverrideCurrent reset for Solar: NEEDED (consistency)
- NodeNewMode flag: harmless (not consumed on slaves)
- request_write_settings: appropriate (persists to NVS)
- MainsMeter check at line 608: skipped on slaves (LoadBl >= 2)
- Double-call guard: if (Mode != val) prevents re-execution

Adds 8 tests in test_mode_sync.c verifying behavioral expectations.

Fixes #120

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@basmeerman basmeerman merged commit 7f7b735 into master Mar 27, 2026
13 checks passed
@basmeerman basmeerman deleted the fix/menu-mode-setmode-consistency branch March 27, 2026 10:00
basmeerman added a commit that referenced this pull request Mar 27, 2026
Test infrastructure grew from 47→50 suites and 1,046→1,096 tests after
merging multi-node solar fix (PR #119, +24 tests) and mode sync fix
(PR #121, +8 tests). Updated all documentation references:

- CLAUDE.md, README.md, CONTRIBUTING.md: test count references
- docs/quality.md: 4 occurrences of test metrics
- docs/upstream-differences.md: added both fixes as upstream divergences
- docs/manual-test-plan.md: test count reference
- test-specification.md: regenerated (70 features, 1,082 scenarios)

Co-Authored-By: Claude Opus 4.6 (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.

fix: MENU_MODE (BroadcastSettings) skips setMode() side effects on slaves

1 participant