diff --git a/api/api.go b/api/api.go index 887508562..f27eb7783 100644 --- a/api/api.go +++ b/api/api.go @@ -185,6 +185,12 @@ type SocLimiter interface { GetLimitSoc() (int64, error) } +// Dimmer provides §14a dimming +type Dimmer interface { + Dimmed() (bool, error) + Dim(bool) error +} + // ChargeController allows to start/stop the charging session on the vehicle side type ChargeController interface { ChargeEnable(bool) error diff --git a/charger/sgready-boost.go b/charger/sgready-boost.go index fb3477938..f7844de51 100644 --- a/charger/sgready-boost.go +++ b/charger/sgready-boost.go @@ -53,7 +53,7 @@ func NewSgReadyBoostFromConfig(ctx context.Context, other map[string]interface{} func NewSgReadyBoost(ctx context.Context, embed *embed, charger api.Charger) (*SgReady, error) { modeS := func(mode int64) error { switch mode { - case Dimm: + case Dim: return api.ErrNotAvailable case Normal: return charger.Enable(false) diff --git a/charger/sgready.go b/charger/sgready.go index bf34821f6..7c7c53f2d 100644 --- a/charger/sgready.go +++ b/charger/sgready.go @@ -47,7 +47,7 @@ func init() { const ( _ int64 = iota - Dimm // 1 + Dim // 1 Normal // 2 Boost // 3 ) @@ -134,8 +134,8 @@ func (wb *SgReady) Status() (api.ChargeStatus, error) { return api.StatusNone, err } - if mode == Dimm { - return api.StatusNone, errors.New("dimm mode") + if mode == Dim { + return api.StatusNone, errors.New("dim mode") } status := map[int64]api.ChargeStatus{Boost: api.StatusC, Normal: api.StatusB} @@ -161,6 +161,30 @@ func (wb *SgReady) Enable(enable bool) error { return wb.setMaxPower(wb.power) } +var _ api.Dimmer = (*SgReady)(nil) + +// Dimmed implements the api.Dimmer interface +func (wb *SgReady) Dimmed() (bool, error) { + mode, err := wb.getMode() + return mode == Dim, err +} + +// Dimm implements the api.Dimmer interface +func (wb *SgReady) Dim(dim bool) error { + mode := Normal + if dim { + mode = Dim + } + + if err := wb.modeS(mode); err != nil { + return err + } + + wb.mode = Dim + + return nil +} + // MaxCurrent implements the api.Charger interface func (wb *SgReady) MaxCurrent(current int64) error { return wb.MaxCurrentMillis(float64(current)) diff --git a/core/keys/loadpoint.go b/core/keys/loadpoint.go index ac72074f1..7542b3924 100644 --- a/core/keys/loadpoint.go +++ b/core/keys/loadpoint.go @@ -36,6 +36,7 @@ const ( Enabled = "enabled" // loadpoint enabled Connected = "connected" // connected Charging = "charging" // charging + Dimmed = "dimmed" // dimmed pseudo-status // loadpoint setpoint OfferedCurrent = "offeredCurrent" // offered current diff --git a/core/loadpoint.go b/core/loadpoint.go index 650087ec6..05c5b5e20 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -1847,6 +1847,31 @@ func (lp *Loadpoint) Update(sitePower, batteryBoostPower float64, consumption, f lp.publishChargeProgress() lp.PublishEffectiveValues() + // §14a + if dimmer, ok := lp.charger.(api.Dimmer); ok { + dimmed, err := dimmer.Dimmed() + if err != nil { + lp.log.ERROR.Printf("dimmed: %v", err) + return + } + + dim := lp.circuit != nil && lp.circuit.Dimmed() + + if dim != dimmed { + if err := dimmer.Dim(dim); err != nil { + lp.log.ERROR.Printf("dim: %v", err) + return + } + + lp.publish(keys.Dimmed, dim) + lp.log.INFO.Printf("§14a dim: %t", dim) + } + + if dim { + return + } + } + // read and publish status welcomeCharge, err := lp.updateChargerStatus() if err != nil {