diff --git a/.changeset/sungrow-zero-test-confirms-the-battery.md b/.changeset/sungrow-zero-test-confirms-the-battery.md new file mode 100644 index 00000000..3ac5c077 --- /dev/null +++ b/.changeset/sungrow-zero-test-confirms-the-battery.md @@ -0,0 +1,5 @@ +--- +"ftw": patch +--- + +The Sungrow zero-power test confirms the battery before commanding, matching the driver's refusal to write EMS registers a string inverter does not implement. diff --git a/go/internal/drivers/sungrow_driver_test.go b/go/internal/drivers/sungrow_driver_test.go index eb2271fc..fa4be710 100644 --- a/go/internal/drivers/sungrow_driver_test.go +++ b/go/internal/drivers/sungrow_driver_test.go @@ -56,12 +56,26 @@ func TestSungrowZeroBatteryCommandForcesIdle(t *testing.T) { env := NewHostEnv("sungrow", tel).WithModbus(modbus) env.BatteryCapacityWh = 9600 + // Answer register 4999 as an SH8.0RT so the driver classifies this as a + // hybrid. Sungrow ships two families behind one driver and an SG string + // inverter implements none of 13049-13051, so the driver refuses a battery + // setpoint until the model has named itself a hybrid or a battery register + // has answered. Without this the mock answers 0 everywhere, detection + // settles on "unknown", and the refusal is correct rather than a bug -- + // see srcfl/device-drivers#40 and #43. + modbus.regs[4999] = 0x0E0E + d, err := NewLuaDriver("../../../drivers/sungrow.lua", env) if err != nil { t.Fatalf("load: %v", err) } defer d.Cleanup() + if _, err := d.Poll(context.Background()); err != nil { + t.Fatalf("poll: %v", err) + } + modbus.resetWrites() + cmd, _ := json.Marshal(map[string]any{"action": "battery", "power_w": 0}) if err := d.Command(context.Background(), cmd); err != nil { t.Fatalf("command: %v", err)