From aaa89dfe1044fb422e0b875c4711a98d8c7f4b33 Mon Sep 17 00:00:00 2001 From: tajniak81 <13187254+tajniak81@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:01:29 +0200 Subject: [PATCH] Relays that run at 33 degrees, not 331 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two relay temperatures came back as 331 and 319 from a charger sitting idle with nothing plugged in. The spec's gain column says 1 for both, so we reported them as 331 °C and 319 °C — a reading that would have meant a fire rather than a wallbox at room temperature. The gain is 10. The same table hands the maximum current setting a unit of watts and the timeout a unit of amps, so its unit and gain columns are not load-bearing here; what settles the alignment is the LED brightness two registers earlier, which reads exactly 100 at gain 1, and the fact that the neighbouring registers all decode as tabulated. Read back from the charger afterwards: 33.1 °C and 31.9 °C. The field becomes a float, as the voltages and currents beside it already are. Co-Authored-By: Claude Opus 5 --- .../plugins/builtin/ankersolix/modbus.go | 20 ++++++++++++------- .../plugins/builtin/ankersolix/modbus_test.go | 13 ++++++------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/API Server/internal/plugins/builtin/ankersolix/modbus.go b/API Server/internal/plugins/builtin/ankersolix/modbus.go index 43baf35..cd1b728 100644 --- a/API Server/internal/plugins/builtin/ankersolix/modbus.go +++ b/API Server/internal/plugins/builtin/ankersolix/modbus.go @@ -65,8 +65,8 @@ const ( regSolarBalancing = 20090 regCPVoltage = 20091 regCPSignal = 20092 - regRelay1Temp = 20093 // INT16, degC - regRelay2Temp = 20094 // INT16, degC + regRelay1Temp = 20093 // INT16, decidegC — see decodeLive on the gain + regRelay2Temp = 20094 // INT16, decidegC regBoostMode = 20095 regLEDBrightness = 20096 // % regChargingStatus = 20097 // same 0-8 enum as the cloud's operating_state @@ -171,8 +171,8 @@ type ModbusSnapshot struct { CPSignal *int `json:"cpSignal,omitempty"` CPSignalDesc string `json:"cpSignalDesc,omitempty"` - Relay1TempC *int `json:"relay1TempC,omitempty"` - Relay2TempC *int `json:"relay2TempC,omitempty"` + Relay1TempC *float64 `json:"relay1TempC,omitempty"` + Relay2TempC *float64 `json:"relay2TempC,omitempty"` OcppStatus *int `json:"ocppStatus,omitempty"` OcppStatusDesc string `json:"ocppStatusDesc,omitempty"` @@ -271,13 +271,19 @@ func decodeLive(snap *ModbusSnapshot, regs []uint16) { b := v != 0 return &b } - degrees := func(addr int) *int { + // The spec's gain column says 1 for the two relay temperatures, but a charger + // idling with nothing plugged in reads 331 and 319 there, which is a gain of + // 10 and not a pair of relays at 331 °C. The same table gives the maximum + // current setting in watts and the timeout in amps, so its unit and gain + // columns are not load-bearing; the LED brightness two registers earlier + // reads exactly 100 at gain 1, which is what fixes the alignment. + degrees := func(addr int) *float64 { v, ok := at(addr) if !ok { return nil } - n := int(int16(v)) // signed: the relays can read below zero - return &n + c := float64(int16(v)) / 10 // signed: the relays can read below zero + return &c } snap.VoltageL1 = scaled(regVoltageL1N, 10) diff --git a/API Server/internal/plugins/builtin/ankersolix/modbus_test.go b/API Server/internal/plugins/builtin/ankersolix/modbus_test.go index 06cae86..1b863c6 100644 --- a/API Server/internal/plugins/builtin/ankersolix/modbus_test.go +++ b/API Server/internal/plugins/builtin/ankersolix/modbus_test.go @@ -106,18 +106,19 @@ func TestDecodeLiveNamesStates(t *testing.T) { func TestDecodeLiveReadsNegativeTemperatures(t *testing.T) { b := newLiveBlock() - below := int16(-7) + below := int16(-72) b.set(regRelay1Temp, uint16(below)) - b.set(regRelay2Temp, 41) + // 331 is what an idle charger actually reports: 33.1 °C, not 331 °C. + b.set(regRelay2Temp, 331) var snap ModbusSnapshot decodeLive(&snap, b) - if snap.Relay1TempC == nil || *snap.Relay1TempC != -7 { - t.Errorf("Relay1TempC = %v, want -7", snap.Relay1TempC) + if snap.Relay1TempC == nil || *snap.Relay1TempC != -7.2 { + t.Errorf("Relay1TempC = %v, want -7.2", snap.Relay1TempC) } - if snap.Relay2TempC == nil || *snap.Relay2TempC != 41 { - t.Errorf("Relay2TempC = %v, want 41", snap.Relay2TempC) + if snap.Relay2TempC == nil || *snap.Relay2TempC != 33.1 { + t.Errorf("Relay2TempC = %v, want 33.1", snap.Relay2TempC) } }