From 7a95266a6b125cb5e4424177d897e84ac9147e3d Mon Sep 17 00:00:00 2001 From: andig Date: Mon, 20 Jul 2026 10:11:25 +0200 Subject: [PATCH] Revert "Modbus: handle NaN values" (#31968) --- plugin/modbus.go | 8 +------- util/modbus/functions.go | 7 +++---- util/modbus/register.go | 3 +-- util/modbus/register_test.go | 17 ++++------------- 4 files changed, 9 insertions(+), 26 deletions(-) diff --git a/plugin/modbus.go b/plugin/modbus.go index bfc78e616..9eae8a9e4 100644 --- a/plugin/modbus.go +++ b/plugin/modbus.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/modbus" gridx "github.com/grid-x/modbus" @@ -157,12 +156,7 @@ func (m *Modbus) FloatGetter() (func() (f float64, err error), error) { return 0, fmt.Errorf("read failed: %w", err) } - // a "*nan" sentinel decodes to NaN - the device reports no valid value - if res := m.scale * decode(bytes); !math.IsNaN(res) { - return res, nil - } - - return 0, api.ErrNotAvailable + return m.scale * decode(bytes), nil }, nil } diff --git a/util/modbus/functions.go b/util/modbus/functions.go index faea9066e..867ad8746 100644 --- a/util/modbus/functions.go +++ b/util/modbus/functions.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "errors" "fmt" - "math" "slices" "strconv" "strings" @@ -82,7 +81,7 @@ func decodeNaN16(f func(b []byte) float64, nan ...uint16) func(b []byte) float64 return func(b []byte) float64 { u := binary.BigEndian.Uint16(b) if slices.Contains(nan, u) { - return math.NaN() + return 0 } return f(b) } @@ -92,7 +91,7 @@ func decodeNaN32(f func(b []byte) float64, nan ...uint32) func(b []byte) float64 return func(b []byte) float64 { u := binary.BigEndian.Uint32(b) if slices.Contains(nan, u) { - return math.NaN() + return 0 } return f(b) } @@ -102,7 +101,7 @@ func decodeNaN64(f func(b []byte) float64, nan ...uint64) func(b []byte) float64 return func(b []byte) float64 { u := binary.BigEndian.Uint64(b) if slices.Contains(nan, u) { - return math.NaN() + return 0 } return f(b) } diff --git a/util/modbus/register.go b/util/modbus/register.go index 4120b1209..676fc2f82 100644 --- a/util/modbus/register.go +++ b/util/modbus/register.go @@ -249,8 +249,7 @@ func (r Register) Operation() (RegisterOperation, error) { func asFloat64[T constraints.Signed | constraints.Unsigned | constraints.Float](f func([]byte) T) func([]byte) float64 { return func(v []byte) float64 { res := float64(f(v)) - // keep NaN so callers can map it to "not available"; sanitize Inf to 0 - if math.IsInf(res, 0) { + if math.IsNaN(res) || math.IsInf(res, 0) { res = 0 } return res diff --git a/util/modbus/register_test.go b/util/modbus/register_test.go index ba1a030f4..a30740fba 100644 --- a/util/modbus/register_test.go +++ b/util/modbus/register_test.go @@ -71,13 +71,10 @@ func TestDecoding(t *testing.T) { out float64 }{ {Register{Decode: "float32"}, []byte{0x4b, 0x3c, 0x61, 0x4e}, 12345678}, - {Register{Decode: "float32"}, []byte{0xff, 0xff, 0xff, 0x7f}, math.NaN()}, // IEEE NaN preserved + {Register{Decode: "float32"}, []byte{0xff, 0xff, 0xff, 0x7f}, 0}, // NaN {Register{Decode: "float32s"}, []byte{0x61, 0x4e, 0x4b, 0x3c}, 12345678}, - {Register{Decode: "float32s"}, []byte{0xff, 0x7f, 0xff, 0xff}, math.NaN()}, // IEEE NaN swapped preserved - {Register{Decode: "float32nans"}, []byte{0xff, 0xff, 0xff, 0x7f}, math.NaN()}, - {Register{Decode: "uint16nan"}, []byte{0xff, 0xff}, math.NaN()}, - {Register{Decode: "uint32nan"}, []byte{0xff, 0xff, 0xff, 0xff}, math.NaN()}, - {Register{Decode: "uint64nan"}, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, math.NaN()}, + {Register{Decode: "float32s"}, []byte{0xff, 0x7f, 0xff, 0xff}, 0}, // NaN swapped + {Register{Decode: "float32nans"}, []byte{0xff, 0xff, 0xff, 0x7f}, 0}, // NaN {Register{Decode: "uint64"}, []byte{0x00, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01}, 0x0004000300020001}, {Register{Decode: "uint64s"}, []byte{0x00, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01}, 0x0001000200030004}, } @@ -85,12 +82,6 @@ func TestDecoding(t *testing.T) { for _, tc := range tc { fun, err := tc.r.DecodeFunc() require.NoError(t, err, tc) - - out := fun(tc.in) - if math.IsNaN(tc.out) { - require.True(t, math.IsNaN(out), tc) - continue - } - require.Equal(t, tc.out, out, tc) + require.Equal(t, tc.out, fun(tc.in), tc) } }