diff --git a/core/site.go b/core/site.go index 48a8dbbc7..63dc02bfe 100644 --- a/core/site.go +++ b/core/site.go @@ -496,10 +496,18 @@ func (site *Site) collectMeters(key string, meters []config.Device[api.Meter]) [ fun := func(i int, dev config.Device[api.Meter]) { meter := dev.Instance() + props := deviceProperties(dev) + mm[i] = types.Measurement{ + Name: dev.Config().Name, + Title: props.Title, + Icon: props.Icon, + } + // power var b bytes.Buffer power, err := backoff.RetryWithData(meter.CurrentPower, modbus.Backoff()) if err == nil { + mm[i].Power = power site.log.DEBUG.Printf("%s %d power: %.0fW", key, i+1, power) } else { if b.Len() > 0 { @@ -509,22 +517,13 @@ func (site *Site) collectMeters(key string, meters []config.Device[api.Meter]) [ } // energy (production) - var energy float64 if m, ok := api.Cap[api.MeterEnergy](meter); err == nil && ok { - energy, err = m.TotalEnergy() - if err != nil { + if f, err := m.TotalEnergy(); err == nil { + mm[i].Energy = &f + } else { site.log.ERROR.Printf("%s %d energy: %v", key, i+1, err) } } - - props := deviceProperties(dev) - mm[i] = types.Measurement{ - Name: dev.Config().Name, - Title: props.Title, - Icon: props.Icon, - Power: power, - Energy: energy, - } } var wg sync.WaitGroup @@ -570,7 +569,10 @@ func (site *Site) updatePvMeters() { return math.Abs(m.ExcessDCPower) }) totalEnergy := lo.SumBy(mm, func(m types.Measurement) float64 { - return m.Energy + if m.Energy == nil { + return 0 + } + return *m.Energy }) if len(site.pvMeters) > 1 { @@ -589,13 +591,7 @@ func (site *Site) updatePvMeters() { // persist per-meter PV energy slots (used for history and forecast scaling) for i, dev := range site.pvMeters { c := site.collectors[dev.Config().Name] - - var importEnergy *float64 - if mm[i].Energy > 0 { - importEnergy = &mm[i].Energy - } - - if err := c.AddEnergy(importEnergy, nil, mm[i].Power); err != nil { + if err := c.AddEnergy(mm[i].Energy, nil, mm[i].Power); err != nil { site.log.ERROR.Printf("persist pv %d energy: %v", i+1, err) } } @@ -652,7 +648,10 @@ func (site *Site) updateBatteryMeters() { return m.Power }) site.battery.Energy = lo.SumBy(mm, func(m types.Measurement) float64 { - return m.Energy + if m.Energy == nil { + return 0 + } + return *m.Energy }) if len(site.batteryMeters) > 1 { @@ -669,11 +668,7 @@ func (site *Site) updateBatteryMeters() { if !ok { continue } - var exportEnergy *float64 - if mm[i].Energy > 0 { - exportEnergy = &mm[i].Energy - } - if err := c.AddEnergy(nil, exportEnergy, -mm[i].Power); err != nil { + if err := c.AddEnergy(nil, mm[i].Energy, -mm[i].Power); err != nil { site.log.ERROR.Printf("persist battery %d energy: %v", i+1, err) } } @@ -708,11 +703,7 @@ func (site *Site) addMeterEnergy(meters []config.Device[api.Meter], mm []types.M if !ok { continue } - var importEnergy *float64 - if mm[i].Energy > 0 { - importEnergy = &mm[i].Energy - } - if err := c.AddEnergy(importEnergy, nil, mm[i].Power); err != nil { + if err := c.AddEnergy(mm[i].Energy, nil, mm[i].Power); err != nil { site.log.ERROR.Printf("persist meter %s energy: %v", ref, err) } } @@ -790,18 +781,16 @@ func (site *Site) updateGridMeter() error { } } - // grid energy (import) - var importEnergy *float64 + // grid energy (import); nil when the device has no MeterEnergy capability or the read fails if energyMeter, ok := api.Cap[api.MeterEnergy](site.gridMeter); ok { if f, err := energyMeter.TotalEnergy(); err == nil { - mm.Energy = f - importEnergy = &f + mm.Energy = &f } else { site.log.ERROR.Printf("grid energy: %v", err) } } - site.collectors[site.Meters.GridMeterRef].AddEnergy(importEnergy, nil, mm.Power) + site.collectors[site.Meters.GridMeterRef].AddEnergy(mm.Energy, nil, mm.Power) site.publish(keys.Grid, mm) diff --git a/core/types/types.go b/core/types/types.go index e4a808a67..fe3b3e724 100644 --- a/core/types/types.go +++ b/core/types/types.go @@ -12,8 +12,8 @@ type Measurement struct { Title string `json:"title,omitempty"` Icon string `json:"icon,omitempty"` Power float64 `json:"power"` - Energy float64 `json:"energy,omitempty"` - ReturnEnergy float64 `json:"returnEnergy,omitempty"` + Energy *float64 `json:"energy,omitempty"` + ReturnEnergy *float64 `json:"returnEnergy,omitempty"` Powers []float64 `json:"powers,omitempty"` Currents []float64 `json:"currents,omitempty"` ExcessDCPower float64 `json:"excessdcpower,omitempty"` diff --git a/server/mqtt_test.go b/server/mqtt_test.go index c262c5a21..e9def0cda 100644 --- a/server/mqtt_test.go +++ b/server/mqtt_test.go @@ -115,7 +115,7 @@ func (suite *mqttSuite) TestMeasurement() { suite.Equal(topics, suite.topics, "topics") suite.Equal([]string{"", "", "", "0", "", "", "", "", "", "", "", ""}, suite.payloads, "empty payloads") - suite.publish("test", false, types.Measurement{Energy: 1}) + suite.publish("test", false, types.Measurement{Energy: new(1.0)}) suite.Equal(topics, suite.topics, "topics") suite.Equal([]string{"", "", "", "0", "1", "", "", "", "", "", "", ""}, suite.payloads, "energy payloads")