Loadpoints: track metrics (#29143)
Co-authored-by: Michael Geers <michael@geers.tv>
This commit is contained in:
parent
1fbe26a6ca
commit
1ac513c913
5 changed files with 53 additions and 36 deletions
33
cmd/setup.go
33
cmd/setup.go
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/evcc-io/evcc/core/circuit"
|
||||
"github.com/evcc-io/evcc/core/keys"
|
||||
"github.com/evcc-io/evcc/core/loadpoint"
|
||||
"github.com/evcc-io/evcc/core/metrics"
|
||||
coresettings "github.com/evcc-io/evcc/core/settings"
|
||||
"github.com/evcc-io/evcc/hems"
|
||||
hemsapi "github.com/evcc-io/evcc/hems/hems"
|
||||
|
|
@ -1301,14 +1302,25 @@ func configureSite(conf map[string]any, loadpoints []*core.Loadpoint, tariffs *t
|
|||
return site, nil
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return core.NewLoadpointFromConfig(log, settingsFn(log), collector, other)
|
||||
}
|
||||
|
||||
func configureLoadpoints(conf globalconfig.All) error {
|
||||
for id, cc := range conf.Loadpoints {
|
||||
cc.Name = "lp-" + strconv.Itoa(id+1)
|
||||
idx := id + 1
|
||||
cc.Name = "lp-" + strconv.Itoa(idx)
|
||||
|
||||
log := util.NewLoggerWithLoadpoint(cc.Name, id+1)
|
||||
settings := coresettings.NewDatabaseSettingsAdapter(fmt.Sprintf("lp%d.", id+1))
|
||||
|
||||
instance, err := core.NewLoadpointFromConfig(log, settings, cc.Other)
|
||||
instance, err := newLoadpoint(idx, cc.Name, cc.Other, func(*util.Logger) coresettings.Settings {
|
||||
return coresettings.NewDatabaseSettingsAdapter(fmt.Sprintf("lp%d.", idx))
|
||||
})
|
||||
if err != nil {
|
||||
return &DeviceError{cc.Name, err}
|
||||
}
|
||||
|
|
@ -1326,19 +1338,16 @@ func configureLoadpoints(conf globalconfig.All) error {
|
|||
|
||||
for _, conf := range configurable {
|
||||
cc := conf.Named()
|
||||
|
||||
id := len(config.Loadpoints().Devices())
|
||||
name := "lp-" + strconv.Itoa(id+1)
|
||||
log := util.NewLoggerWithLoadpoint(name, id+1)
|
||||
|
||||
settings := coresettings.NewConfigSettingsAdapter(log, &conf)
|
||||
idx := len(config.Loadpoints().Devices()) + 1
|
||||
|
||||
dynamic, static, err := loadpoint.SplitConfig(cc.Other)
|
||||
if err != nil {
|
||||
return &DeviceError{cc.Name, err}
|
||||
}
|
||||
|
||||
instance, err := core.NewLoadpointFromConfig(log, settings, static)
|
||||
instance, err := newLoadpoint(idx, cc.Name, static, func(log *util.Logger) coresettings.Settings {
|
||||
return coresettings.NewConfigSettingsAdapter(log, &conf)
|
||||
})
|
||||
if err != nil {
|
||||
err = &DeviceError{cc.Name, err}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/evcc-io/evcc/core/coordinator"
|
||||
"github.com/evcc-io/evcc/core/keys"
|
||||
"github.com/evcc-io/evcc/core/loadpoint"
|
||||
"github.com/evcc-io/evcc/core/metrics"
|
||||
"github.com/evcc-io/evcc/core/planner"
|
||||
"github.com/evcc-io/evcc/core/session"
|
||||
"github.com/evcc-io/evcc/core/settings"
|
||||
|
|
@ -137,10 +138,11 @@ type Loadpoint struct {
|
|||
chargeRater api.ChargeRater
|
||||
chargedAtStartup float64 // session energy at startup
|
||||
|
||||
circuit api.Circuit // Circuit
|
||||
chargeMeter api.Meter // Charger usage meter
|
||||
vehicle api.Vehicle // Currently active vehicle
|
||||
defaultVehicle api.Vehicle // Default vehicle (disables detection)
|
||||
circuit api.Circuit // Circuit
|
||||
chargeMeter api.Meter // Charger usage meter
|
||||
chargeEnergy *metrics.Collector // Charger usage collector
|
||||
vehicle api.Vehicle // Currently active vehicle
|
||||
defaultVehicle api.Vehicle // Default vehicle (disables detection)
|
||||
coordinator coordinator.API
|
||||
socEstimator *soc.Estimator
|
||||
|
||||
|
|
@ -183,7 +185,7 @@ type Loadpoint struct {
|
|||
}
|
||||
|
||||
// NewLoadpointFromConfig creates a new loadpoint
|
||||
func NewLoadpointFromConfig(log *util.Logger, settings settings.Settings, other map[string]any) (*Loadpoint, error) {
|
||||
func NewLoadpointFromConfig(log *util.Logger, settings settings.Settings, collector *metrics.Collector, other map[string]any) (*Loadpoint, error) {
|
||||
lp := NewLoadpoint(log, settings)
|
||||
if err := util.DecodeOther(other, lp); err != nil {
|
||||
return lp, err
|
||||
|
|
@ -266,6 +268,10 @@ func NewLoadpointFromConfig(log *util.Logger, settings settings.Settings, other
|
|||
}
|
||||
|
||||
lp.configureChargerType(lp.charger)
|
||||
// add collector
|
||||
if lp.chargeMeter != nil {
|
||||
lp.chargeEnergy = collector
|
||||
}
|
||||
|
||||
// phase switching defaults based on charger capabilities
|
||||
if !lp.hasPhaseSwitching() {
|
||||
|
|
@ -1733,8 +1739,18 @@ func (lp *Loadpoint) publishChargeProgress() {
|
|||
// TODO deprecated: use sessionEnergy instead
|
||||
lp.publish(keys.ChargedEnergy, lp.GetChargedEnergy())
|
||||
lp.publish(keys.ChargeDuration, lp.chargeDuration)
|
||||
|
||||
// update energy, prefer totals
|
||||
var importTotal *float64
|
||||
if api.HasCap[api.MeterEnergy](lp.chargeMeter) {
|
||||
lp.publish(keys.ChargeTotalImport, lp.chargeMeterTotal())
|
||||
if f := lp.chargeMeterTotal(); f > 0 {
|
||||
lp.publish(keys.ChargeTotalImport, f)
|
||||
importTotal = &f
|
||||
}
|
||||
}
|
||||
|
||||
if lp.chargeEnergy != nil {
|
||||
lp.chargeEnergy.AddEnergy(importTotal, nil, lp.chargePower)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ import (
|
|||
|
||||
const (
|
||||
// groups
|
||||
Grid = "grid"
|
||||
PV = "pv"
|
||||
Home = "home" // meter and group (virtual measurement)
|
||||
Battery = "battery"
|
||||
Grid = "grid"
|
||||
PV = "pv"
|
||||
Home = "home" // meter and group (virtual measurement)
|
||||
Loadpoint = "loadpoint"
|
||||
)
|
||||
|
||||
type Collector struct {
|
||||
|
|
|
|||
|
|
@ -36,24 +36,13 @@ func SetupSchema() error {
|
|||
m := db.Instance.Migrator()
|
||||
|
||||
// entites: create entity first to make sure foreign keys for existing data work
|
||||
hasTable := m.HasTable(new(entity))
|
||||
if err := db.Instance.AutoMigrate(new(entity)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// entites: add entity id 1
|
||||
if hasTable {
|
||||
var res entity
|
||||
if err := db.Instance.Where(&entity{Id: 1, Name: Home}).FirstOrCreate(&res).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if res.Group == "" {
|
||||
res.Group = Home
|
||||
if err := db.Instance.Save(&res).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// ensure home entity exists (reserves id=1 for legacy meter FK references)
|
||||
if _, err := createEntity(Home, Home); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// drop obsolete indexes
|
||||
|
|
|
|||
|
|
@ -165,7 +165,8 @@ func newLoadpointHandler() http.HandlerFunc {
|
|||
}
|
||||
|
||||
settings := coresettings.NewConfigSettingsAdapter(log, &conf)
|
||||
instance, err := core.NewLoadpointFromConfig(log, settings, static)
|
||||
|
||||
instance, err := core.NewLoadpointFromConfig(log, settings, nil, static)
|
||||
if err != nil {
|
||||
conf.Delete()
|
||||
jsonError(w, http.StatusBadRequest, err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue