Metrics: store entity title on lazy-create (#30196)
This commit is contained in:
parent
0fa8b97daf
commit
a8361b575b
21 changed files with 209 additions and 142 deletions
|
|
@ -78,19 +78,19 @@ type batteryTotals struct {
|
|||
discharge float64
|
||||
}
|
||||
|
||||
// metricsBatteryTotals sums charge and discharge energy per battery entity.
|
||||
// metricsBatteryTotals sums charge and discharge energy per battery title.
|
||||
func metricsBatteryTotals(series []metrics.Series) map[string]batteryTotals {
|
||||
res := make(map[string]batteryTotals)
|
||||
for _, s := range series {
|
||||
if s.Group != metrics.Battery {
|
||||
continue
|
||||
}
|
||||
t := res[s.Name]
|
||||
t := res[s.Title]
|
||||
for _, slot := range s.Data {
|
||||
t.charge += slot.Energy
|
||||
t.discharge += slot.ReturnEnergy
|
||||
}
|
||||
res[s.Name] = t
|
||||
res[s.Title] = t
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ func metricsWriteBatteryTable(w io.Writer, selected []metrics.EntityInfo, totals
|
|||
fmt.Fprintln(tw, "name\ttitle\tcharge\tdischarge\tefficiency")
|
||||
|
||||
for _, e := range selected {
|
||||
t := totals[e.Name]
|
||||
t := totals[title(e.Group, e.Name)]
|
||||
|
||||
efficiency := ""
|
||||
if t.charge > 0 {
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ import (
|
|||
|
||||
func TestMetricsBatteryTotals(t *testing.T) {
|
||||
series := []metrics.Series{
|
||||
{Group: metrics.Battery, Name: "bat", Data: []metrics.Slot{
|
||||
{Group: metrics.Battery, Title: "bat", Data: []metrics.Slot{
|
||||
{Energy: 1.0, ReturnEnergy: 0.4},
|
||||
{Energy: 2.0, ReturnEnergy: 1.6},
|
||||
}},
|
||||
// non-battery series must be ignored
|
||||
{Group: metrics.Grid, Name: "grid", Data: []metrics.Slot{
|
||||
{Group: metrics.Grid, Title: "grid", Data: []metrics.Slot{
|
||||
{Energy: 5.0, ReturnEnergy: 3.0},
|
||||
}},
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ func TestMetricsWriteBatteryTable(t *testing.T) {
|
|||
{Group: metrics.Battery, Name: "bat2"},
|
||||
}
|
||||
totals := map[string]batteryTotals{
|
||||
"bat1": {charge: 10.0, discharge: 9.0},
|
||||
"Home": {charge: 10.0, discharge: 9.0},
|
||||
// bat2 deliberately absent: no data in the timeframe
|
||||
}
|
||||
title := func(group, name string) string {
|
||||
|
|
|
|||
|
|
@ -72,13 +72,19 @@ func runMetricsData(cmd *cobra.Command, args []string) {
|
|||
|
||||
byEntity := make(map[string]metrics.Series, len(series))
|
||||
for _, s := range series {
|
||||
byEntity[s.Group+"/"+s.Name] = s
|
||||
byEntity[s.Group+"/"+s.Title] = s
|
||||
}
|
||||
|
||||
if asCSV, _ := cmd.Flags().GetBool("csv"); asCSV {
|
||||
var out metrics.SeriesCSV
|
||||
seen := make(map[string]bool, len(selected))
|
||||
for _, e := range selected {
|
||||
if s, ok := byEntity[e.Group+"/"+e.Name]; ok {
|
||||
key := e.Group + "/" + title(e.Group, e.Name)
|
||||
if seen[key] {
|
||||
continue
|
||||
}
|
||||
seen[key] = true
|
||||
if s, ok := byEntity[key]; ok {
|
||||
out = append(out, s)
|
||||
}
|
||||
}
|
||||
|
|
@ -236,7 +242,7 @@ func metricsWriteTable(w io.Writer, selected []metrics.EntityInfo, byEntity map[
|
|||
}
|
||||
|
||||
for _, spec := range specs {
|
||||
s, ok := byEntity[spec.entity.Group+"/"+spec.entity.Name]
|
||||
s, ok := byEntity[spec.entity.Group+"/"+title(spec.entity.Group, spec.entity.Name)]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,10 +93,10 @@ func TestMetricsWriteTable(t *testing.T) {
|
|||
{Group: metrics.Grid, Name: "grid"},
|
||||
}
|
||||
byEntity := map[string]metrics.Series{
|
||||
metrics.Loadpoint + "/lp-1": {Group: metrics.Loadpoint, Name: "lp-1", Data: []metrics.Slot{
|
||||
metrics.Loadpoint + "/Carport": {Group: metrics.Loadpoint, Title: "Carport", Data: []metrics.Slot{
|
||||
{Start: h0, Energy: 1.84},
|
||||
}},
|
||||
metrics.Grid + "/grid": {Group: metrics.Grid, Name: "grid", Data: []metrics.Slot{
|
||||
metrics.Grid + "/grid": {Group: metrics.Grid, Title: "grid", Data: []metrics.Slot{
|
||||
{Start: h0, Energy: 0.412},
|
||||
{Start: h1, Energy: 0.38, ReturnEnergy: 0.05},
|
||||
}},
|
||||
|
|
@ -105,6 +105,9 @@ func TestMetricsWriteTable(t *testing.T) {
|
|||
if group == metrics.Loadpoint {
|
||||
return "Carport"
|
||||
}
|
||||
if group == metrics.Grid {
|
||||
return "grid"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,18 +11,18 @@ import (
|
|||
|
||||
func TestMetricsForecastTotals(t *testing.T) {
|
||||
series := []metrics.Series{
|
||||
{Group: metrics.Forecast, Name: "forecast", Data: []metrics.Slot{
|
||||
{Group: metrics.Forecast, Title: "forecast", Data: []metrics.Slot{
|
||||
{Energy: 10.0}, {Energy: 5.0},
|
||||
}},
|
||||
// actual PV production is summed across all pv entities
|
||||
{Group: metrics.PV, Name: "pv1", Data: []metrics.Slot{
|
||||
{Group: metrics.PV, Title: "pv1", Data: []metrics.Slot{
|
||||
{Energy: 4.0}, {Energy: 3.0},
|
||||
}},
|
||||
{Group: metrics.PV, Name: "pv2", Data: []metrics.Slot{
|
||||
{Group: metrics.PV, Title: "pv2", Data: []metrics.Slot{
|
||||
{Energy: 2.0},
|
||||
}},
|
||||
// other groups are ignored
|
||||
{Group: metrics.Grid, Name: "grid", Data: []metrics.Slot{
|
||||
{Group: metrics.Grid, Title: "grid", Data: []metrics.Slot{
|
||||
{Energy: 99.0},
|
||||
}},
|
||||
}
|
||||
|
|
|
|||
16
cmd/setup.go
16
cmd/setup.go
|
|
@ -1305,12 +1305,24 @@ func configureSite(conf map[string]any, loadpoints []*core.Loadpoint, tariffs *t
|
|||
func newLoadpoint(idx int, name string, other map[string]any, settingsFn func(*util.Logger) coresettings.Settings) (*core.Loadpoint, error) {
|
||||
log := util.NewLoggerWithLoadpoint("lp-"+strconv.Itoa(idx), idx)
|
||||
|
||||
collector, err := metrics.NewCollector(metrics.Loadpoint, name)
|
||||
collector, err := metrics.NewCollector(metrics.Loadpoint, name, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return core.NewLoadpointFromConfig(log, settingsFn(log), collector, other)
|
||||
lp, err := core.NewLoadpointFromConfig(log, settingsFn(log), collector, other)
|
||||
if err != nil {
|
||||
return lp, err
|
||||
}
|
||||
|
||||
// lazily update entity title
|
||||
if title := lp.GetTitle(); title != "" {
|
||||
if err := collector.UpdateTitle(title); err != nil {
|
||||
return lp, err
|
||||
}
|
||||
}
|
||||
|
||||
return lp, nil
|
||||
}
|
||||
|
||||
func configureLoadpoints(conf globalconfig.All) error {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue