From 8ed21de3dfabc41e04a6783a029840d3a34eb6a4 Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 30 Dec 2023 13:50:12 +0100 Subject: [PATCH] chore: refactor reading phase values (#11347) --- charger/hesotec.go | 21 ++++++++------------- charger/phoenix-charx.go | 19 +++++++------------ meter/tasmota/connection.go | 32 +++++++++++++++----------------- meter/tasmota/types.go | 2 +- 4 files changed, 31 insertions(+), 43 deletions(-) diff --git a/charger/hesotec.go b/charger/hesotec.go index 1b5910874..00a36cef7 100644 --- a/charger/hesotec.go +++ b/charger/hesotec.go @@ -180,31 +180,26 @@ var _ api.PhaseCurrents = (*Hesotec)(nil) // Currents implements the api.PhaseCurrents interface func (wb *Hesotec) Currents() (float64, float64, float64, error) { - b, err := wb.conn.ReadHoldingRegisters(hesotecRegCurrents, 6) - if err != nil { - return 0, 0, 0, err - } - - var res [3]float64 - for i := range res { - res[i] = float64(binary.BigEndian.Uint32(b[4*i:])) / 1e3 - } - - return res[0], res[1], res[2], nil + return wb.getPhaseValues(hesotecRegCurrents, 2, 1e3) } var _ api.PhaseVoltages = (*Hesotec)(nil) // Voltages implements the api.PhaseVoltages interface func (wb *Hesotec) Voltages() (float64, float64, float64, error) { - b, err := wb.conn.ReadHoldingRegisters(hesotecRegVoltages, 3) + return wb.getPhaseValues(hesotecRegVoltages, 1, 1) +} + +// getPhaseValues returns 3 sequential phase values +func (wb *Hesotec) getPhaseValues(reg, width uint16, divider float64) (float64, float64, float64, error) { + b, err := wb.conn.ReadHoldingRegisters(reg, 3*width) if err != nil { return 0, 0, 0, err } var res [3]float64 for i := range res { - res[i] = float64(binary.BigEndian.Uint16(b[2*i:])) + res[i] = float64(binary.BigEndian.Uint32(b[2*int(width)*i:])) / divider } return res[0], res[1], res[2], nil diff --git a/charger/phoenix-charx.go b/charger/phoenix-charx.go index 2ae37c032..7b3357cbb 100644 --- a/charger/phoenix-charx.go +++ b/charger/phoenix-charx.go @@ -212,22 +212,17 @@ func (wb *PhoenixCharx) totalEnergy() (float64, error) { // currents implements the api.PhaseCurrents interface func (wb *PhoenixCharx) currents() (float64, float64, float64, error) { - b, err := wb.conn.ReadHoldingRegisters(wb.register(charxRegCurrents), 3*2) - if err != nil { - return 0, 0, 0, err - } - - var res [3]float64 - for i := range res { - res[i] = float64(encoding.Int32(b[4*i:])) / 1e3 - } - - return res[0], res[1], res[2], nil + return wb.getPhaseValues(charxRegCurrents) } // voltages implements the api.PhaseVoltages interface func (wb *PhoenixCharx) voltages() (float64, float64, float64, error) { - b, err := wb.conn.ReadHoldingRegisters(wb.register(charxRegVoltages), 3*2) + return wb.getPhaseValues(charxRegVoltages) +} + +// getPhaseValues returns 3 sequential phase values +func (wb *PhoenixCharx) getPhaseValues(reg uint16) (float64, float64, float64, error) { + b, err := wb.conn.ReadHoldingRegisters(wb.register(reg), 6) if err != nil { return 0, 0, 0, err } diff --git a/meter/tasmota/connection.go b/meter/tasmota/connection.go index 438e5626c..818831bfc 100644 --- a/meter/tasmota/connection.go +++ b/meter/tasmota/connection.go @@ -220,38 +220,36 @@ func (c *Connection) TotalEnergy() (float64, error) { // Currents implements the api.PhaseCurrents interface func (c *Connection) Currents() (float64, float64, float64, error) { - s, err := c.statusSnsG.Get() - if err != nil { - return 0, 0, 0, err - } - - var res [3]float64 - for i, c := range c.channels { - res[i], err = s.StatusSNS.Energy.Current.Channel(c) - if err != nil { - return 0, 0, 0, err - } - } - - return res[0], res[1], res[2], err + return c.getPhaseValues(func(s StatusSNSResponse) Channels { + return s.StatusSNS.Energy.Current + }) } // Voltages implements the api.PhaseVoltages interface func (c *Connection) Voltages() (float64, float64, float64, error) { + return c.getPhaseValues(func(s StatusSNSResponse) Channels { + return s.StatusSNS.Energy.Voltage + }) +} + +// getPhaseValues returns 3 sequential phase values +func (c *Connection) getPhaseValues(fun func(StatusSNSResponse) Channels) (float64, float64, float64, error) { s, err := c.statusSnsG.Get() if err != nil { return 0, 0, 0, err } + all := fun(s) + var res [3]float64 - for i, c := range c.channels { - res[i], err = s.StatusSNS.Energy.Voltage.Channel(c) + for i := range res { + res[i], err = all.Channel(c.channels[i]) if err != nil { return 0, 0, 0, err } } - return res[0], res[1], res[2], err + return res[0], res[1], res[2], nil } // SmlPower provides the sml sensor power diff --git a/meter/tasmota/types.go b/meter/tasmota/types.go index 4435ee827..e8cba524e 100644 --- a/meter/tasmota/types.go +++ b/meter/tasmota/types.go @@ -92,7 +92,7 @@ type StatusSNSResponse struct { } } -// Channels is a Tasmota specifc helper type to handle meter value lists and single meter values +// Channels is a Tasmota specific helper type to handle meter value lists and single meter values type Channels []float64 func (ch *Channels) Channel(channel int) (float64, error) {