Skip to content

fix: apply external_solar_mode to Growatt TOU hardware paths - #3

Merged
jdungen merged 1 commit into
mainfrom
claude/ac-coupled-growatt-tou-fix
Jul 14, 2026
Merged

fix: apply external_solar_mode to Growatt TOU hardware paths#3
jdungen merged 1 commit into
mainfrom
claude/ac-coupled-growatt-tou-fix

Conversation

@jdungen

@jdungen jdungen commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Why

Follow-up to #1. With external_solar_mode enabled, SOLAR_STORAGE periods still showed Load First and no grid charge in the schedule overview, and the battery never charged during the solar window (AC-coupled, no DC input on the battery inverter).

The #1 override covered the base-class rate/mode mapping (inverter_controller.py) and the solax_modbus controller, but not the two paths that build the TOU segments actually written to Growatt hardware:

  • GrowattMinController._group_periods_by_mode() read INTENT_TO_MODE directly, so SOLAR_STORAGE stayed load_first. Load-first groups are skipped when converting to TOU intervals, so no battery-first segment was ever programmed.
  • GrowattSphController excludes SOLAR_STORAGE from CHARGE_INTENTS on the assumption that an SPH charges from its own MPPT — which never happens without DC solar input.

What

  • MIN grouping now goes through _effective_mode_for_intent(), so SOLAR_STORAGE groups become battery_first TOU segments when the flag is on. This also covers SolaxModbusGrowattController, which inherits the grouping.
  • SPH uses a new _effective_charge_intents() that adds SOLAR_STORAGE as an AC charge period when the flag is on.
  • 7 new unit tests covering both paths (flag on/off, TOU interval creation, SPH charge blocks).

Verification

1179 fast backend tests pass locally; black + ruff clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JD7RhRSGxkW8zZirZQFRFC


Generated by Claude Code

The external_solar_mode override (#1) covered the base-class rate/mode
mapping and the solax_modbus controller, but not the two paths that
build the TOU segments actually written to Growatt hardware:

- GrowattMinController._group_periods_by_mode() read INTENT_TO_MODE
  directly, so SOLAR_STORAGE stayed load_first. Load-first groups are
  skipped when converting to TOU intervals, so no battery-first segment
  was ever programmed and an AC-coupled battery sat idle through the
  whole solar window.
- GrowattSphController excludes SOLAR_STORAGE from CHARGE_INTENTS on
  the assumption that an SPH charges from its own MPPT. With no DC
  solar input that never happens; SOLAR_STORAGE must produce an AC
  charge period.

Both paths now honor the override: MIN grouping goes through
_effective_mode_for_intent, and SPH uses _effective_charge_intents()
which adds SOLAR_STORAGE when external_solar_mode is enabled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JD7RhRSGxkW8zZirZQFRFC
@jdungen
jdungen merged commit 702e65a into main Jul 14, 2026
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.

2 participants