diff --git a/core/site.go b/core/site.go index 514e81dd8..81415192a 100644 --- a/core/site.go +++ b/core/site.go @@ -844,8 +844,9 @@ func (site *Site) updateGridMeter() error { } // grid energy (import); nil when the device has no MeterEnergy capability or the read fails + // ignore spurious zero readings (NaN-derived or nightly reset, #30950) if energyMeter, ok := api.Cap[api.MeterEnergy](site.gridMeter); ok { - if f, err := energyMeter.TotalEnergy(); err == nil { + if f, err := nonZeroEnergy(energyMeter.TotalEnergy()); err == nil { mm.Energy = &f } else if !errors.Is(err, api.ErrNotAvailable) { site.log.ERROR.Printf("grid energy: %v", err) @@ -853,8 +854,9 @@ func (site *Site) updateGridMeter() error { } // grid return energy (export); nil when the device has no MeterReturnEnergy capability or the read fails + // ignore spurious zero readings as above if returnEnergyMeter, ok := api.Cap[api.MeterReturnEnergy](site.gridMeter); ok { - if f, err := returnEnergyMeter.ReturnEnergy(); err == nil { + if f, err := nonZeroEnergy(returnEnergyMeter.ReturnEnergy()); err == nil { mm.ReturnEnergy = &f } else if !errors.Is(err, api.ErrNotAvailable) { site.log.ERROR.Printf("grid return energy: %v", err) diff --git a/templates/definition/meter/solaredge-hybrid.yaml b/templates/definition/meter/solaredge-hybrid.yaml index a60fb2364..40da8696f 100644 --- a/templates/definition/meter/solaredge-hybrid.yaml +++ b/templates/definition/meter/solaredge-hybrid.yaml @@ -130,7 +130,7 @@ render: | register: address: 0xE176 # Battery 1 Lifetime Export Energy Counter (discharged) type: holding - decode: uint64s + decode: uint64snan scale: 0.001 returnenergy: source: modbus @@ -138,7 +138,7 @@ render: | register: address: 0xE17A # Battery 1 Lifetime Import Energy Counter (charged) type: holding - decode: uint64s + decode: uint64snan scale: 0.001 batterymode: source: watchdog diff --git a/util/modbus/register.go b/util/modbus/register.go index f62c0f3a3..96e36f055 100644 --- a/util/modbus/register.go +++ b/util/modbus/register.go @@ -125,6 +125,8 @@ func (r Register) DecodeFunc() (func([]byte) float64, error) { return asFloat64(encoding.Uint64), nil case "uint64s": return asFloat64(uint64LswFirst), nil + case "uint64snan": + return decodeNaN64(asFloat64(uint64LswFirst), 1<<64-1), nil case "uint64nan": return decodeNaN64(asFloat64(encoding.Uint64), 1<<64-1), nil case "float64":