Skip to content

fix(drivers): bundle sungrow 1.6.1, an outage keeps the release - #1912

Merged
frahlg merged 4 commits into
masterfrom
fix/bundle-sungrow-1.6.1
Oct 28, 2026
Merged

frahlg merged 4 commits into
masterfrom
fix/bundle-sungrow-1.6.1

Conversation

@frahlg

@frahlg frahlg commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Paired with srcfl/device-drivers#202 (the DCO-signed copy of #201), merged as 46b28a1 on main. The pin points at that commit.

Problem

FTW's nightly random site rig ran on master 83c2b24 on 27 October 2026, with 10 seeds. Each time it took the Sungrow offline and brought it back, the bundled sungrow 1.6.0 driver made two mistakes:

  • Release skipped (driver half of triage item C1). Every write failed while the inverter was offline. The driver counted three of those failures as the inverter refusing the EMS block. After that, driver_default_mode returned true without writing anything. The inverter kept its last forced command (EMS 170/187) after it came back. the EMS control block rejected 3 writes in a row appears in 9 of 10 ftw.log files.

    Seed Window (elapsed s) Command
    207533 654–888 187 / 2668 W
    207535 579–812 170 / 2632 W (charge)
    207537 213–510 187 / 3854 W
    207538 1034–1209 187 / 4674 W

    In 207534 the battery discharged 5000 W, from 5.6 % to 5.0 %, while FTW was not dispatching it.

  • Registers dropped (triage item D1). The driver also counted failed reads during the outage as missing registers, and stopped reading them for the rest of the session:

    Seeds Registers dropped
    8 of 10 12999
    207534, 207535, 207536, 207539 13000
    207534, 207539 PV (5016, and 5010 in 207539)

    13000 tells FTW which way the battery is flowing. Without it, FTW read a discharge as a charge: 105 samples in 207539 (655–1010 s) and 13 in 207534 (968–980 s).

Change

  • drivers/BUNDLED_SOURCE.json: the pin moves from 5798498 to cc16f0e. This brings in sungrow 1.6.1, and no other bundled driver changes: scripts/check-driver-versions.sh origin/master passes for all 44 bundled drivers.
  • go/internal/drivers/sungrow_driver_test.go: new test TestSungrowOutageKeepsTheReleaseAndTheBatterySign. It runs the bundled driver in FTW's Lua host. While the inverter is "offline", reads fail with the dial error the rig logged (dial tcp …: connection refused) and writes fail with ErrModbusBackoff. The test checks three things:
    • the release reports failure while nothing reaches the inverter;
    • once the inverter is back, the release writes EMS mode 0;
    • the battery then reads −900 W, so its sign is right.
  • .changeset/bundle-sungrow-outage.md: patch.

This PR does not include the Core half of C1. Core still keeps the driver excluded for driverRefusalRetryInterval (5 min) and does not resend the default when the inverter returns. Two Core timers decide when the release is tried after the return, and neither restarts when the device answers again:

  • the Modbus reconnect backoff (reconnectBackoffMax, 60 s; 45.85 s seen in 207539);
  • the default-recovery retry (defaultRetryMax, 30 s).

So with this PR alone the forced state ends within about a minute of the return, not at once. The follow-up: retry the default on the first fresh poll of a driver with a recovery pending. That fix belongs in a separate PR.

Tests

No real hardware run.

Site rig (review run on 3af19bb, seeds 207533–207539)

  • treating it as absent: 0 times in all seven seeds (before: 1–7 per seed).
  • 207539: battery-sign mismatches against the plant fall from 48 to 0 (45 with 1.6.0 on the same commit). "Home use measured while every device reads" now passes.
  • Forced EMS state after each return: 23, 20, 23/17.9, 31.2/23.3, 19.6/51.0 and 3.3/216.7/69.3 s (before: 160–495 s, or it never ended). In 207533 the driver logged the device answers again at 18:19:40 and the release landed at 18:19:55, on the next recovery tick. The 216.7 s case is in 207539: the reconnect backoff was 45.85 s, and the next default attempt came after the second outage had begun. These delays are the Core timers named above, not the driver.
  • Other failures in each seed are the known Core items (R2–R5, C5, C6), except 207538 below.

207538 goes from pass on 1.6.0 to fail on 1.6.1, and the cause is Core. Same-commit A/B with drivers/sungrow.lua swapped to 1.6.0: "Charge now charges when there is room" passes on 1.6.0 (idle with room 16 s) and fails on 1.6.1 (128 s). Under 1.6.0 the stuck forced discharge (−1846 W) supplied power for Charge now. Under 1.6.1 the battery goes back to self-consumption (about −462 W), and Core holds Charge now at 1380 W / 2 A with reason fuse_limit, below the charger's 4140 W minimum. All phases read 1.5–2.6 A on a 20 A fuse, and phase currents at 375 s are nearly the same in both runs. Both runs exclude the driver from dispatch at 90 s and let it back in at 391 s, so the exclusion is not the difference. The driver now does what it should; the fuse hold on Charge now is a separate Core issue.

Risk

🤖 Generated with Claude Code

Move the pin to srcfl/device-drivers cc16f0e (srcfl/device-drivers#201,
not merged yet). After an outage, sungrow 1.6.0 reported the release as
held without writing it and dropped 13000, which signs the battery. The
random site rig on 83c2b24 saw the forced command outlive the outage in
8 of 10 seeds.

TestSungrowOutageKeepsTheReleaseAndTheBatterySign feeds the driver the
dial and backoff errors FTW's Modbus client returns while the inverter is
offline. It fails on 1.6.0 and passes on 1.6.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rig shows the forced state still running 3 to 69 s after the
inverter returns, because two Core timers (Modbus reconnect backoff and
the default-recovery retry) set when the release is tried. Say what the
driver change delivers, not that the forced state stops at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@frahlg
frahlg marked this pull request as ready for review October 28, 2026 10:30
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-28T10:31:36.544354Z 8f24a93 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@frahlg
frahlg merged commit c352465 into master Oct 28, 2026
22 checks passed
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