From d0d6ac981071df19b1c117233f03cd37a8aa817b Mon Sep 17 00:00:00 2001 From: mfuchs1984 <57141790+mfuchs1984@users.noreply.github.com> Date: Thu, 8 May 2025 16:23:25 +0200 Subject: [PATCH] Vestel: decorate RFID support (#21124) --- charger/vestel.go | 13 +++-- charger/vestel_decorators.go | 61 ++++++++++++++++++++++-- templates/definition/charger/vestel.yaml | 5 +- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/charger/vestel.go b/charger/vestel.go index 865e8001d..33a66cd7f 100644 --- a/charger/vestel.go +++ b/charger/vestel.go @@ -67,7 +67,7 @@ func init() { registry.AddCtx("vestel", NewVestelFromConfig) } -//go:generate go tool decorate -f decorateVestel -b *Vestel -r api.Charger -t "api.PhaseSwitcher,Phases1p3p,func(int) error" -t "api.PhaseGetter,GetPhases,func() (int, error)" +//go:generate go tool decorate -f decorateVestel -b *Vestel -r api.Charger -t "api.PhaseSwitcher,Phases1p3p,func(int) error" -t "api.PhaseGetter,GetPhases,func() (int, error)" -t "api.Identifier,Identify,func() (string, error)" // NewVestelFromConfig creates a Vestel charger from generic config func NewVestelFromConfig(ctx context.Context, other map[string]interface{}) (api.Charger, error) { @@ -111,6 +111,11 @@ func NewVestel(ctx context.Context, uri string, id uint8) (api.Charger, error) { phasesG = wb.getPhases } + var identify func() (string, error) + if _, err := wb.identify(); err == nil { + identify = wb.identify + } + // get failsafe timeout from charger b, err := wb.conn.ReadHoldingRegisters(vestelRegFailsafeTimeout, 1) if err != nil { @@ -125,7 +130,7 @@ func NewVestel(ctx context.Context, uri string, id uint8) (api.Charger, error) { } go wb.heartbeat(ctx, timeout) - return decorateVestel(wb, phasesS, phasesG), err + return decorateVestel(wb, phasesS, phasesG, identify), err } func (wb *Vestel) heartbeat(ctx context.Context, timeout time.Duration) { @@ -298,10 +303,8 @@ func (wb *Vestel) getPhases() (int, error) { return 1 + int(binary.BigEndian.Uint16(b))<<1, nil } -var _ api.Identifier = (*Vestel)(nil) - // Identify implements the api.Identifier interface -func (wb *Vestel) Identify() (string, error) { +func (wb *Vestel) identify() (string, error) { b, err := wb.conn.ReadInputRegisters(vestelRegRFID, 15) if err != nil { return "", err diff --git a/charger/vestel_decorators.go b/charger/vestel_decorators.go index da5e62ba3..1d0e012e1 100644 --- a/charger/vestel_decorators.go +++ b/charger/vestel_decorators.go @@ -6,12 +6,12 @@ import ( "github.com/evcc-io/evcc/api" ) -func decorateVestel(base *Vestel, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger { +func decorateVestel(base *Vestel, phaseSwitcher func(int) error, phaseGetter func() (int, error), identifier func() (string, error)) api.Charger { switch { - case phaseSwitcher == nil: + case identifier == nil && phaseSwitcher == nil: return base - case phaseGetter == nil && phaseSwitcher != nil: + case identifier == nil && phaseGetter == nil && phaseSwitcher != nil: return &struct { *Vestel api.PhaseSwitcher @@ -22,7 +22,7 @@ func decorateVestel(base *Vestel, phaseSwitcher func(int) error, phaseGetter fun }, } - case phaseGetter != nil && phaseSwitcher != nil: + case identifier == nil && phaseGetter != nil && phaseSwitcher != nil: return &struct { *Vestel api.PhaseGetter @@ -36,11 +36,64 @@ func decorateVestel(base *Vestel, phaseSwitcher func(int) error, phaseGetter fun phaseSwitcher: phaseSwitcher, }, } + + case identifier != nil && phaseSwitcher == nil: + return &struct { + *Vestel + api.Identifier + }{ + Vestel: base, + Identifier: &decorateVestelIdentifierImpl{ + identifier: identifier, + }, + } + + case identifier != nil && phaseGetter == nil && phaseSwitcher != nil: + return &struct { + *Vestel + api.Identifier + api.PhaseSwitcher + }{ + Vestel: base, + Identifier: &decorateVestelIdentifierImpl{ + identifier: identifier, + }, + PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{ + phaseSwitcher: phaseSwitcher, + }, + } + + case identifier != nil && phaseGetter != nil && phaseSwitcher != nil: + return &struct { + *Vestel + api.Identifier + api.PhaseGetter + api.PhaseSwitcher + }{ + Vestel: base, + Identifier: &decorateVestelIdentifierImpl{ + identifier: identifier, + }, + PhaseGetter: &decorateVestelPhaseGetterImpl{ + phaseGetter: phaseGetter, + }, + PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{ + phaseSwitcher: phaseSwitcher, + }, + } } return nil } +type decorateVestelIdentifierImpl struct { + identifier func() (string, error) +} + +func (impl *decorateVestelIdentifierImpl) Identify() (string, error) { + return impl.identifier() +} + type decorateVestelPhaseGetterImpl struct { phaseGetter func() (int, error) } diff --git a/templates/definition/charger/vestel.yaml b/templates/definition/charger/vestel.yaml index 78d8e46fc..a4b3fab43 100644 --- a/templates/definition/charger/vestel.yaml +++ b/templates/definition/charger/vestel.yaml @@ -13,8 +13,11 @@ products: - brand: E.ON Drive description: generic: vBox -capabilities: ["1p3p"] +capabilities: ["rfid", "1p3p"] requirements: + description: + de: 1P3P und RFID erfordern Firmware 3.187.0 oder neuer. + en: 1P3P and RFID require at least firmware version 3.187.0. evcc: ["sponsorship"] params: - name: modbus