From 4ed241e9f0fd72489ddbb5b568b76b1b82474e7a Mon Sep 17 00:00:00 2001 From: premultiply <4681172+premultiply@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:00:36 +0000 Subject: [PATCH] sungrow-charger: add more diagnostics --- charger/sungrow.go | 70 ++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/charger/sungrow.go b/charger/sungrow.go index 6e959493c7..61e43dd13f 100644 --- a/charger/sungrow.go +++ b/charger/sungrow.go @@ -35,20 +35,24 @@ type Sungrow struct { } const ( - // holding - sgRegEnable = 21210 // uint16 - sgRegMaxCurrent = 21202 // uint16 0.01A - sgRegPhases = 21203 // uint16 - sgRegWorkingMode = 21262 // uint16 [Network=0, Plug&Play=2, EMS=6] - - // input - sgRegPhasesPower = 21224 // uint16 + // input (read only) + sgRegPhase = 21224 // uint16 [1: Single-phase, 3: Three-phase] + sgRegWorkMode = 21262 // uint16 [0: Network, 2: Plug&Play, 6: EMS] + sgRegRemCtrlStatus = 21267 // uint16 sgRegPhasesState = 21269 // uint16 sgRegTotalEnergy = 21299 // uint32s 1Wh sgRegActivePower = 21307 // uint32s 1W sgRegChargedEnergy = 21309 // uint32s 1Wh - sgRegStartMode = 21313 // uint16 [EMS=1, Swiping=2] + sgRegStartMode = 21313 // uint16 [1: Started by EMS, 2: Started by swiping card] + sgRegPowerRequest = 21314 // uint16 [0: Enable, 1: Close] + sgRegPowerFlag = 21315 // uint16 [0: Charging or power regulation is not allowed; 1: Charging or power regulation is allowed] sgRegState = 21316 // uint16 + + // holding + sgRegSetOutI = 21202 // uint16 0.01A + sgRegPhaseSwitch = 21203 // uint16 + sgRegUnavailable = 21210 // uint16 + sgRegRemoteControl = 21211 // uint16 ) var ( @@ -140,7 +144,7 @@ func (wb *Sungrow) Status() (api.ChargeStatus, error) { // Enabled implements the api.Charger interface func (wb *Sungrow) Enabled() (bool, error) { - b, err := wb.conn.ReadHoldingRegisters(sgRegEnable, 1) + b, err := wb.conn.ReadInputRegisters(sgRegRemCtrlStatus, 1) if err != nil { return false, err } @@ -151,11 +155,11 @@ func (wb *Sungrow) Enabled() (bool, error) { // Enable implements the api.Charger interface func (wb *Sungrow) Enable(enable bool) error { var u uint16 - if enable { + if !enable { u = 1 } - _, err := wb.conn.WriteSingleRegister(sgRegEnable, u) + _, err := wb.conn.WriteSingleRegister(sgRegRemoteControl, u) return err } @@ -173,7 +177,7 @@ func (wb *Sungrow) MaxCurrentMillis(current float64) error { return fmt.Errorf("invalid current %.1f", current) } - _, err := wb.conn.WriteSingleRegister(sgRegMaxCurrent, uint16(current*10)) + _, err := wb.conn.WriteSingleRegister(sgRegSetOutI, uint16(current*10)) return err } @@ -182,7 +186,7 @@ var _ api.Meter = (*Sungrow)(nil) // CurrentPower implements the api.Meter interface func (wb *Sungrow) CurrentPower() (float64, error) { - b, err := wb.conn.ReadHoldingRegisters(sgRegActivePower, 2) + b, err := wb.conn.ReadInputRegisters(sgRegActivePower, 2) if err != nil { return 0, err } @@ -208,7 +212,7 @@ var _ api.ChargeRater = (*Sungrow)(nil) // ChargedEnergy implements the api.MeterEnergy interface func (wb *Sungrow) ChargedEnergy() (float64, error) { - b, err := wb.conn.ReadHoldingRegisters(sgRegChargedEnergy, 2) + b, err := wb.conn.ReadInputRegisters(sgRegChargedEnergy, 2) if err != nil { return 0, err } @@ -220,7 +224,7 @@ var _ api.MeterEnergy = (*Sungrow)(nil) // TotalEnergy implements the api.MeterEnergy interface func (wb *Sungrow) TotalEnergy() (float64, error) { - b, err := wb.conn.ReadHoldingRegisters(sgRegTotalEnergy, 2) + b, err := wb.conn.ReadInputRegisters(sgRegTotalEnergy, 2) if err != nil { return 0, err } @@ -238,7 +242,7 @@ func (wb *Sungrow) Phases1p3p(phases int) error { u = 1 } - _, err := wb.conn.WriteSingleRegister(sgRegPhases, u) + _, err := wb.conn.WriteSingleRegister(sgRegPhaseSwitch, u) return err } @@ -247,20 +251,23 @@ var _ api.Diagnosis = (*Sungrow)(nil) // Diagnose implements the api.Diagnosis interface func (wb *Sungrow) Diagnose() { - if b, err := wb.conn.ReadHoldingRegisters(sgRegMaxCurrent, 1); err == nil { - fmt.Printf("\tMaxCurrent:\t%d\n", binary.BigEndian.Uint16(b)) + if b, err := wb.conn.ReadHoldingRegisters(sgRegSetOutI, 1); err == nil { + fmt.Printf("\tSetOutI:\t%d\n", binary.BigEndian.Uint16(b)) } - if b, err := wb.conn.ReadHoldingRegisters(sgRegPhases, 1); err == nil { - fmt.Printf("\tPhases:\t%d\n", binary.BigEndian.Uint16(b)) + if b, err := wb.conn.ReadHoldingRegisters(sgRegPhaseSwitch, 1); err == nil { + fmt.Printf("\tPhaseSwitch:\t%d\n", binary.BigEndian.Uint16(b)) } - if b, err := wb.conn.ReadHoldingRegisters(sgRegEnable, 1); err == nil { - fmt.Printf("\tEnable:\t%d\n", binary.BigEndian.Uint16(b)) + if b, err := wb.conn.ReadHoldingRegisters(sgRegUnavailable, 1); err == nil { + fmt.Printf("\tUnavailable:\t%d\n", binary.BigEndian.Uint16(b)) } - if b, err := wb.conn.ReadHoldingRegisters(sgRegWorkingMode, 1); err == nil { - fmt.Printf("\tWorkingMode:\t%d\n", binary.BigEndian.Uint16(b)) + if b, err := wb.conn.ReadHoldingRegisters(sgRegRemoteControl, 1); err == nil { + fmt.Printf("\tRemoteControl:\t%d\n", binary.BigEndian.Uint16(b)) } - if b, err := wb.conn.ReadInputRegisters(sgRegPhasesPower, 1); err == nil { - fmt.Printf("\tPhasesPower:\t%d\n", binary.BigEndian.Uint16(b)) + if b, err := wb.conn.ReadInputRegisters(sgRegWorkMode, 1); err == nil { + fmt.Printf("\tWorkMode:\t%d\n", binary.BigEndian.Uint16(b)) + } + if b, err := wb.conn.ReadInputRegisters(sgRegPhase, 1); err == nil { + fmt.Printf("\tPhase:\t%d\n", binary.BigEndian.Uint16(b)) } if b, err := wb.conn.ReadInputRegisters(sgRegPhasesState, 1); err == nil { fmt.Printf("\tPhasesState:\t%d\n", binary.BigEndian.Uint16(b)) @@ -271,4 +278,13 @@ func (wb *Sungrow) Diagnose() { if b, err := wb.conn.ReadInputRegisters(sgRegState, 1); err == nil { fmt.Printf("\tState:\t%d\n", binary.BigEndian.Uint16(b)) } + if b, err := wb.conn.ReadInputRegisters(sgRegRemCtrlStatus, 1); err == nil { + fmt.Printf("\tRemCtrlStatus:\t%d\n", binary.BigEndian.Uint16(b)) + } + if b, err := wb.conn.ReadInputRegisters(sgRegPowerRequest, 1); err == nil { + fmt.Printf("\tPowerRequest:\t%d\n", binary.BigEndian.Uint16(b)) + } + if b, err := wb.conn.ReadInputRegisters(sgRegPowerFlag, 1); err == nil { + fmt.Printf("\tPowerFlag:\t%d\n", binary.BigEndian.Uint16(b)) + } }