155 lines
4.1 KiB
Go
155 lines
4.1 KiB
Go
package cmd
|
|
|
|
import (
|
|
"iter"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/evcc-io/evcc/api/globalconfig"
|
|
"github.com/evcc-io/evcc/core"
|
|
"github.com/evcc-io/evcc/core/keys"
|
|
"github.com/evcc-io/evcc/server/db/settings"
|
|
"github.com/evcc-io/evcc/util"
|
|
"github.com/evcc-io/evcc/util/config"
|
|
"github.com/evcc-io/evcc/util/templates"
|
|
)
|
|
|
|
var references struct {
|
|
meter, charger, vehicle, circuit, tariff []string
|
|
}
|
|
|
|
func collectRefs(conf globalconfig.All) error {
|
|
// site
|
|
if err := collectSiteRefs(conf); err != nil {
|
|
return err
|
|
}
|
|
|
|
// tariffs
|
|
if err := collectTariffRefs(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// circuits
|
|
if err := collectCircuitRefs(conf.Circuits); err != nil {
|
|
return err
|
|
}
|
|
|
|
// loadpoints
|
|
if err := collectLoadpointRefs(slices.Values(conf.Loadpoints)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// append devices from database
|
|
configurable, err := config.ConfigurationsByClass(templates.Loadpoint)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return collectLoadpointRefs(func(yield func(config.Named) bool) {
|
|
for _, cc := range configurable {
|
|
if !yield(cc.Named()) {
|
|
return
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func collectSiteRefs(conf globalconfig.All) error {
|
|
var refs struct {
|
|
Meters core.MetersConfig `mapstructure:"meters"` // Meter references
|
|
Other map[string]any `mapstructure:",remain"`
|
|
}
|
|
|
|
if err := util.DecodeOther(conf.Site, &refs); err != nil {
|
|
return err
|
|
}
|
|
|
|
references.meter = append(references.meter, refs.Meters.GridMeterRef)
|
|
references.meter = append(references.meter, refs.Meters.PVMetersRef...)
|
|
references.meter = append(references.meter, refs.Meters.BatteryMetersRef...)
|
|
references.meter = append(references.meter, refs.Meters.ExtMetersRef...)
|
|
references.meter = append(references.meter, refs.Meters.AuxMetersRef...)
|
|
references.meter = append(references.meter, refs.Meters.ConsumerMetersRef...)
|
|
|
|
// append devices from settings
|
|
if v, err := settings.String(keys.GridMeter); err == nil && v != "" {
|
|
references.meter = append(references.meter, v)
|
|
}
|
|
|
|
for _, key := range []string{keys.PvMeters, keys.BatteryMeters, keys.ExtMeters, keys.AuxMeters, keys.ConsumerMeters} {
|
|
if v, err := settings.String(key); err == nil && v != "" {
|
|
references.meter = append(references.meter, strings.Split(v, ",")...)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func collectTariffRefs() error {
|
|
// Load tariff device references from settings
|
|
if !settings.Exists(keys.TariffRefs) {
|
|
return nil
|
|
}
|
|
|
|
var refs globalconfig.TariffRefs
|
|
if err := settings.Json(keys.TariffRefs, &refs); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Collect all non-empty refs
|
|
if refs.Grid != "" {
|
|
references.tariff = append(references.tariff, refs.Grid)
|
|
}
|
|
if refs.FeedIn != "" {
|
|
references.tariff = append(references.tariff, refs.FeedIn)
|
|
}
|
|
if refs.Co2 != "" {
|
|
references.tariff = append(references.tariff, refs.Co2)
|
|
}
|
|
if refs.Planner != "" {
|
|
references.tariff = append(references.tariff, refs.Planner)
|
|
}
|
|
references.tariff = append(references.tariff, refs.Solar...)
|
|
|
|
return nil
|
|
}
|
|
|
|
func collectLoadpointRefs(named iter.Seq[config.Named]) error {
|
|
for cc := range named {
|
|
var refs struct {
|
|
CircuitRef string `mapstructure:"circuit"` // Circuit reference
|
|
ChargerRef string `mapstructure:"charger"` // Charger reference
|
|
VehicleRef string `mapstructure:"vehicle"` // Vehicle reference
|
|
MeterRef string `mapstructure:"meter"` // Charge meter reference
|
|
Other map[string]any `mapstructure:",remain"`
|
|
}
|
|
|
|
if err := util.DecodeOther(cc.Other, &refs); err != nil {
|
|
return err
|
|
}
|
|
|
|
references.meter = append(references.meter, refs.MeterRef)
|
|
references.charger = append(references.charger, refs.ChargerRef)
|
|
references.vehicle = append(references.vehicle, refs.VehicleRef)
|
|
references.circuit = append(references.circuit, refs.CircuitRef)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func collectCircuitRefs(circuits []config.Named) error {
|
|
for _, cc := range circuits {
|
|
var refs struct {
|
|
MeterRef string `mapstructure:"meter"` // Circuit meter reference
|
|
Other map[string]any `mapstructure:",remain"`
|
|
}
|
|
|
|
if err := util.DecodeOther(cc.Other, &refs); err != nil {
|
|
return err
|
|
}
|
|
|
|
references.meter = append(references.meter, refs.MeterRef)
|
|
}
|
|
|
|
return nil
|
|
}
|