Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions cmd/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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}
}
Expand All @@ -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}
}
Expand Down
28 changes: 22 additions & 6 deletions core/loadpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -1730,8 +1736,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)
}
}

Expand Down
8 changes: 5 additions & 3 deletions core/metrics/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
17 changes: 3 additions & 14 deletions core/metrics/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,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
Expand Down
3 changes: 2 additions & 1 deletion server/http_config_loadpoint_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading