evcc-io/hems/relay/relay.go
2025-09-03 08:25:31 +02:00

101 lines
1.9 KiB
Go

package relay
import (
"context"
"errors"
"time"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/core/circuit"
"github.com/evcc-io/evcc/core/site"
"github.com/evcc-io/evcc/hems/shared"
"github.com/evcc-io/evcc/plugin"
"github.com/evcc-io/evcc/util"
)
type Relay struct {
log *util.Logger
root api.Circuit
limit func() (bool, error)
maxPower float64
interval time.Duration
}
// New creates an Relay HEMS from generic config
func New(ctx context.Context, other map[string]interface{}, site site.API) (*Relay, error) {
cc := struct {
MaxPower float64
Limit plugin.Config
Interval time.Duration
}{
Interval: 10 * time.Second,
}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
// get root circuit
root := circuit.Root()
if root == nil {
return nil, errors.New("hems requires load management- please configure root circuit")
}
// register LPC circuit if not already registered
lpc, err := shared.GetOrCreateCircuit("lpc", "relay")
if err != nil {
return nil, err
}
// wrap old root with new pc parent
if err := root.Wrap(lpc); err != nil {
return nil, err
}
site.SetCircuit(lpc)
// limit getter
limitG, err := cc.Limit.BoolGetter(ctx)
if err != nil {
return nil, err
}
return NewRelay(lpc, limitG, cc.MaxPower, cc.Interval)
}
// NewRelay creates Relay HEMS
func NewRelay(root api.Circuit, limit func() (bool, error), maxPower float64, interval time.Duration) (*Relay, error) {
c := &Relay{
log: util.NewLogger("relay"),
root: root,
maxPower: maxPower,
limit: limit,
interval: interval,
}
return c, nil
}
func (c *Relay) Run() {
for range time.Tick(c.interval) {
if err := c.run(); err != nil {
c.log.ERROR.Println(err)
}
}
}
func (c *Relay) run() error {
limit, err := c.limit()
if err != nil {
return err
}
var power float64
if limit {
power = c.maxPower
}
c.root.SetMaxPower(power)
return nil
}