Curtailment devices: new device class for feed-in limitation (BC) (#32416)
This commit is contained in:
parent
7c0ddf1828
commit
8661c66fc7
40 changed files with 819 additions and 149 deletions
|
|
@ -7,11 +7,11 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const _ClassName = "configfilemeterchargervehicletariffcircuitsitemqttdatabasemodbusproxyeebusjavascriptgohemsshminfluxmessengersponsorshiploadpoint"
|
||||
const _ClassName = "configfilemeterchargervehicletariffcircuitsitemqttdatabasemodbusproxyeebusjavascriptgohemsshminfluxmessengersponsorshiploadpointcurtailer"
|
||||
|
||||
var _ClassIndex = [...]uint8{0, 10, 15, 22, 29, 35, 42, 46, 50, 58, 69, 74, 84, 86, 90, 93, 99, 108, 119, 128}
|
||||
var _ClassIndex = [...]uint8{0, 10, 15, 22, 29, 35, 42, 46, 50, 58, 69, 74, 84, 86, 90, 93, 99, 108, 119, 128, 137}
|
||||
|
||||
const _ClassLowerName = "configfilemeterchargervehicletariffcircuitsitemqttdatabasemodbusproxyeebusjavascriptgohemsshminfluxmessengersponsorshiploadpoint"
|
||||
const _ClassLowerName = "configfilemeterchargervehicletariffcircuitsitemqttdatabasemodbusproxyeebusjavascriptgohemsshminfluxmessengersponsorshiploadpointcurtailer"
|
||||
|
||||
func (i Class) String() string {
|
||||
i -= 1
|
||||
|
|
@ -44,9 +44,10 @@ func _ClassNoOp() {
|
|||
_ = x[ClassMessenger-(17)]
|
||||
_ = x[ClassSponsorship-(18)]
|
||||
_ = x[ClassLoadpoint-(19)]
|
||||
_ = x[ClassCurtailer-(20)]
|
||||
}
|
||||
|
||||
var _ClassValues = []Class{ClassConfigFile, ClassMeter, ClassCharger, ClassVehicle, ClassTariff, ClassCircuit, ClassSite, ClassMqtt, ClassDatabase, ClassModbusProxy, ClassEEBus, ClassJavascript, ClassGo, ClassHEMS, ClassSHM, ClassInflux, ClassMessenger, ClassSponsorship, ClassLoadpoint}
|
||||
var _ClassValues = []Class{ClassConfigFile, ClassMeter, ClassCharger, ClassVehicle, ClassTariff, ClassCircuit, ClassSite, ClassMqtt, ClassDatabase, ClassModbusProxy, ClassEEBus, ClassJavascript, ClassGo, ClassHEMS, ClassSHM, ClassInflux, ClassMessenger, ClassSponsorship, ClassLoadpoint, ClassCurtailer}
|
||||
|
||||
var _ClassNameToValueMap = map[string]Class{
|
||||
_ClassName[0:10]: ClassConfigFile,
|
||||
|
|
@ -87,6 +88,8 @@ var _ClassNameToValueMap = map[string]Class{
|
|||
_ClassLowerName[108:119]: ClassSponsorship,
|
||||
_ClassName[119:128]: ClassLoadpoint,
|
||||
_ClassLowerName[119:128]: ClassLoadpoint,
|
||||
_ClassName[128:137]: ClassCurtailer,
|
||||
_ClassLowerName[128:137]: ClassCurtailer,
|
||||
}
|
||||
|
||||
var _ClassNames = []string{
|
||||
|
|
@ -109,6 +112,7 @@ var _ClassNames = []string{
|
|||
_ClassName[99:108],
|
||||
_ClassName[108:119],
|
||||
_ClassName[119:128],
|
||||
_ClassName[128:137],
|
||||
}
|
||||
|
||||
// ClassString retrieves an enum value from the enum constants string name.
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ func runConfigDelete(cmd *cobra.Command, args []string) {
|
|||
deleteDevice[api.Tariff](c)
|
||||
case templates.Circuit:
|
||||
deleteDevice[api.Circuit](c)
|
||||
case templates.Curtailer:
|
||||
deleteDevice[api.Curtailer](c)
|
||||
case templates.Hems:
|
||||
deleteDevice[hems.API](c)
|
||||
case templates.Loadpoint:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ const (
|
|||
ClassMessenger
|
||||
ClassSponsorship
|
||||
ClassLoadpoint
|
||||
ClassCurtailer
|
||||
)
|
||||
|
||||
// FatalError is an error that can be marshaled
|
||||
|
|
|
|||
12
cmd/refs.go
12
cmd/refs.go
|
|
@ -15,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
var references struct {
|
||||
meter, charger, vehicle, circuit, tariff []string
|
||||
meter, charger, vehicle, circuit, tariff, curtailer []string
|
||||
}
|
||||
|
||||
func collectRefs(conf globalconfig.All) error {
|
||||
|
|
@ -56,8 +56,9 @@ func collectRefs(conf globalconfig.All) error {
|
|||
|
||||
func collectSiteRefs(conf globalconfig.All) error {
|
||||
var refs struct {
|
||||
Meters core.MetersConfig `mapstructure:"meters"` // Meter references
|
||||
Other map[string]any `mapstructure:",remain"`
|
||||
Meters core.MetersConfig `mapstructure:"meters"` // Meter references
|
||||
Curtailers []string `mapstructure:"curtailers"` // Curtailment device references
|
||||
Other map[string]any `mapstructure:",remain"`
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(conf.Site, &refs); err != nil {
|
||||
|
|
@ -70,6 +71,7 @@ func collectSiteRefs(conf globalconfig.All) error {
|
|||
references.meter = append(references.meter, refs.Meters.ExtMetersRef...)
|
||||
references.meter = append(references.meter, refs.Meters.AuxMetersRef...)
|
||||
references.meter = append(references.meter, refs.Meters.ConsumerMetersRef...)
|
||||
references.curtailer = append(references.curtailer, refs.Curtailers...)
|
||||
|
||||
// append devices from settings
|
||||
if v, err := settings.String(keys.GridMeter); err == nil && v != "" {
|
||||
|
|
@ -82,6 +84,10 @@ func collectSiteRefs(conf globalconfig.All) error {
|
|||
}
|
||||
}
|
||||
|
||||
if v, err := settings.String(keys.Curtailers); err == nil && v != "" {
|
||||
references.curtailer = append(references.curtailer, strings.Split(v, ",")...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
49
cmd/setup.go
49
cmd/setup.go
|
|
@ -25,6 +25,7 @@ import (
|
|||
"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/curtailer"
|
||||
"github.com/evcc-io/evcc/hems"
|
||||
hemsapi "github.com/evcc-io/evcc/hems/hems"
|
||||
"github.com/evcc-io/evcc/hems/shm"
|
||||
|
|
@ -400,6 +401,50 @@ func configureMeters(static []config.Named, names ...string) error {
|
|||
return eg.Wait()
|
||||
}
|
||||
|
||||
func configureCurtailers(static []config.Named, names ...string) error {
|
||||
var eg errgroup.Group
|
||||
|
||||
for i, cc := range static {
|
||||
if cc.Name == "" {
|
||||
return fmt.Errorf("cannot create curtailer %d: missing name", i+1)
|
||||
}
|
||||
|
||||
// configure all, if no name refs are given
|
||||
if len(names) > 0 && !slices.Contains(names, cc.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := nameValid(cc.Name); err != nil {
|
||||
log.WARN.Printf("create curtailer %d: %v", i+1, err)
|
||||
}
|
||||
|
||||
eg.Go(func() error {
|
||||
return staticInstance("curtailer", cc, curtailer.NewFromConfig, config.Curtailers())
|
||||
})
|
||||
}
|
||||
|
||||
// append devices from database
|
||||
configurable, err := config.ConfigurationsByClass(templates.Curtailer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, conf := range configurable {
|
||||
eg.Go(func() error {
|
||||
cc := conf.Named()
|
||||
|
||||
// always skip unreferenced db devices
|
||||
if !slices.Contains(names, cc.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return configurableInstance("curtailer", &conf, curtailer.NewFromConfig, config.Curtailers())
|
||||
})
|
||||
}
|
||||
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
func configureChargers(static []config.Named, names ...string) error {
|
||||
var eg errgroup.Group
|
||||
|
||||
|
|
@ -1287,6 +1332,10 @@ func configureDevices(conf globalconfig.All) error {
|
|||
errs = append(errs, &ClassError{ClassCircuit, err})
|
||||
}
|
||||
|
||||
if err := configureCurtailers(conf.Curtailers, references.curtailer...); err != nil {
|
||||
errs = append(errs, &ClassError{ClassCurtailer, err})
|
||||
}
|
||||
|
||||
return joinErrors(errs...)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue