From fac81285da16c242b0ee78c2ccd27cdb9b9cdc75 Mon Sep 17 00:00:00 2001 From: Josh Deprez Date: Mon, 11 Jan 2021 10:21:53 +1100 Subject: [PATCH] add sanity check on uint values --- main.go | 5 ++++- modbus.go | 31 ++++++++++++++++++++++--------- sungrow_map.go | 9 +++++---- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/main.go b/main.go index acc61f2..c10c108 100644 --- a/main.go +++ b/main.go @@ -106,7 +106,10 @@ func readRegs(client modbus.Client, start, qty uint16) { if addr <= start || addr > start+qty { continue } - val := reg.read(data[(addr-start-1)*2:]) + val, err := reg.read(data[(addr-start-1)*2:]) + if err != nil { + log.Fatalf("Couldn't parse input register data: %v", err) + } //fmt.Printf("%s: %v %s\n", reg.name, val, reg.unit) registerGauges[addr].Set(val) } diff --git a/modbus.go b/modbus.go index f5e2d71..cae503c 100644 --- a/modbus.go +++ b/modbus.go @@ -1,23 +1,36 @@ package main -import "encoding/binary" +import ( + "encoding/binary" + "fmt" +) // Helpers for converting straight from modbus data to floats. -func u16(data []byte) float64 { - return float64(binary.BigEndian.Uint16(data)) +func u16(data []byte) (float64, error) { + n := binary.BigEndian.Uint16(data) + if n == 0xFFFF { + // probably a misread + return 0, fmt.Errorf("likely misread: u16 read %v", n) + } + return float64(n), nil } -func s16(data []byte) float64 { - return float64(int16(binary.BigEndian.Uint16(data))) +func s16(data []byte) (float64, error) { + return float64(int16(binary.BigEndian.Uint16(data))), nil } -func u32(data []byte) float64 { +func u32(data []byte) (float64, error) { // Little-endian big-endian :# - return float64(uint32(binary.BigEndian.Uint16(data)) + uint32(binary.BigEndian.Uint16(data[2:]))<<16) + n := uint32(binary.BigEndian.Uint16(data)) + uint32(binary.BigEndian.Uint16(data[2:]))<<16 + if n == 0xFFFFFFFF { + // probably a misread + return 0, fmt.Errorf("likely misread: u32 read %v", n) + } + return float64(n), nil } -func s32(data []byte) float64 { +func s32(data []byte) (float64, error) { // Little-endian big-endian :# - return float64(int32(binary.BigEndian.Uint16(data)) + int32(binary.BigEndian.Uint16(data[2:]))<<16) + return float64(int32(binary.BigEndian.Uint16(data)) + int32(binary.BigEndian.Uint16(data[2:]))<<16), nil } diff --git a/sungrow_map.go b/sungrow_map.go index fb72216..cd460be 100644 --- a/sungrow_map.go +++ b/sungrow_map.go @@ -2,13 +2,14 @@ package main type register struct { name string - conv func([]byte) float64 + conv func([]byte) (float64, error) mult float64 unit string } -func (r *register) read(data []byte) float64 { - return r.conv(data) * r.mult +func (r *register) read(data []byte) (float64, error) { + n, err := r.conv(data) + return n * r.mult, err } var sungrowInputRegs = map[uint16]*register{ @@ -32,7 +33,7 @@ var sungrowInputRegs = map[uint16]*register{ //5023: {"phase_b_current", u16, 0.1, "A"}, //5024: {"phase_c_current", u16, 0.1, "A"}, 5031: {"output_real_power", u32, 1, "VA"}, - 5033: {"output_reactive_power", s32, 1, "VA"}, + 5033: {"output_reactive_power", s32, 1, "VAr"}, 5035: {"power_factor", s16, 0.001, ""}, 5036: {"frequency", u16, 0.1, "Hz"}, 5049: {"nominal_reactive_power", s16, 0.1, "kVA"},