Metrics: distinguish missing meter energy from zero reading (#30297)
This commit is contained in:
parent
545d239495
commit
e3a79f4618
3 changed files with 28 additions and 39 deletions
61
core/site.go
61
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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue