chore: add custom dimmer/curtailer (#29857)
This commit is contained in:
parent
ed828c5504
commit
8ce8d6d9f9
4 changed files with 117 additions and 5 deletions
86
meter/measurement/action.go
Normal file
86
meter/measurement/action.go
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
package measurement
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/evcc-io/evcc/api/implement"
|
||||
"github.com/evcc-io/evcc/plugin"
|
||||
)
|
||||
|
||||
type Dimmer struct {
|
||||
Dim *plugin.Config // optional
|
||||
Dimmed *plugin.Config // optional
|
||||
}
|
||||
|
||||
func (cc *Dimmer) Configure(ctx context.Context) (
|
||||
func(bool) error,
|
||||
func() (bool, error),
|
||||
error,
|
||||
) {
|
||||
dimS, err := cc.Dim.BoolSetter(ctx, "dim")
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("dim: %w", err)
|
||||
}
|
||||
|
||||
dimmedG, err := cc.Dimmed.BoolGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("dimmed: %w", err)
|
||||
}
|
||||
|
||||
if (dimS == nil) != (dimmedG == nil) {
|
||||
return nil, nil, errors.New("must have dim and dimmed or none of both")
|
||||
}
|
||||
|
||||
return dimS, dimmedG, nil
|
||||
}
|
||||
|
||||
func (cc *Dimmer) Implement(ctx context.Context, i implement.Caps) error {
|
||||
dimS, dimmedG, err := cc.Configure(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
implement.May(i, implement.Dimmer(dimS, dimmedG))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Curtailer struct {
|
||||
Curtail *plugin.Config // optional
|
||||
Curtailed *plugin.Config // optional
|
||||
}
|
||||
|
||||
func (cc *Curtailer) Configure(ctx context.Context) (
|
||||
func(bool) error,
|
||||
func() (bool, error),
|
||||
error,
|
||||
) {
|
||||
curtailS, err := cc.Curtail.BoolSetter(ctx, "curtail")
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("curtail: %w", err)
|
||||
}
|
||||
|
||||
curtailedG, err := cc.Curtailed.BoolGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("curtailed: %w", err)
|
||||
}
|
||||
|
||||
if (curtailS == nil) != (curtailedG == nil) {
|
||||
return nil, nil, errors.New("must have curtail and curtailed or none of both")
|
||||
}
|
||||
|
||||
return curtailS, curtailedG, nil
|
||||
}
|
||||
|
||||
func (cc *Curtailer) Implement(ctx context.Context, i implement.Caps) error {
|
||||
curtailS, curtailedG, err := cc.Configure(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
implement.May(i, implement.Curtailer(curtailS, curtailedG))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -18,8 +18,10 @@ func init() {
|
|||
// NewConfigurableFromConfig creates a new meter from config
|
||||
func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.Meter, error) {
|
||||
cc := struct {
|
||||
measurement.Energy `mapstructure:",squash"` // energy optional
|
||||
measurement.Phases `mapstructure:",squash"` // optional
|
||||
measurement.Energy `mapstructure:",squash"` // energy optional
|
||||
measurement.Phases `mapstructure:",squash"` // optional
|
||||
measurement.Dimmer `mapstructure:",squash"` // optional
|
||||
measurement.Curtailer `mapstructure:",squash"` // optional
|
||||
|
||||
// pv
|
||||
pvMaxACPower `mapstructure:",squash"`
|
||||
|
|
@ -95,6 +97,14 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.M
|
|||
implement.May(m, implement.PhasePowers(powersG))
|
||||
implement.May(m, implement.MaxACPowerGetter(cc.pvMaxACPower.Decorator()))
|
||||
|
||||
// dim/curtail
|
||||
if err := cc.Dimmer.Implement(ctx, m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cc.Curtailer.Implement(ctx, m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue