diff --git a/charger/vestel.go b/charger/vestel.go index e38824efe..f3599db9a 100644 --- a/charger/vestel.go +++ b/charger/vestel.go @@ -34,6 +34,8 @@ const ( vestelRegBrand = 190 // 10 vestelRegModel = 210 // 5 vestelRegFirmware = 230 // 50 + vestelRegNumberPhases = 404 + vestelRegPhasesSwitch = 405 vestelRegChargeStatus = 1001 vestelRegCableStatus = 1004 vestelRegChargeTime = 1508 @@ -64,6 +66,8 @@ 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)" + // NewVestelFromConfig creates a Vestel charger from generic config func NewVestelFromConfig(ctx context.Context, other map[string]interface{}) (api.Charger, error) { cc := modbus.TcpSettings{ @@ -78,7 +82,7 @@ func NewVestelFromConfig(ctx context.Context, other map[string]interface{}) (api } // NewVestel creates a Vestel charger -func NewVestel(ctx context.Context, uri string, id uint8) (*Vestel, error) { +func NewVestel(ctx context.Context, uri string, id uint8) (api.Charger, error) { conn, err := modbus.NewConnection(uri, "", "", 0, modbus.Tcp, id) if err != nil { return nil, err @@ -97,6 +101,15 @@ func NewVestel(ctx context.Context, uri string, id uint8) (*Vestel, error) { current: 6, } + var ( + phasesS func(int) error + phasesG func() (int, error) + ) + if b, err := wb.conn.ReadHoldingRegisters(vestelRegNumberPhases, 1); err == nil && binary.BigEndian.Uint16(b) == 3 { + phasesS = wb.phases1p3p + phasesG = wb.getPhases + } + // get failsafe timeout from charger b, err := wb.conn.ReadHoldingRegisters(vestelRegFailsafeTimeout, 1) if err != nil { @@ -111,7 +124,7 @@ func NewVestel(ctx context.Context, uri string, id uint8) (*Vestel, error) { } go wb.heartbeat(ctx, timeout) - return wb, nil + return decorateVestel(wb, phasesS, phasesG), err } func (wb *Vestel) heartbeat(ctx context.Context, timeout time.Duration) { @@ -269,6 +282,21 @@ func (wb *Vestel) Voltages() (float64, float64, float64, error) { return wb.getPhaseValues(vestelRegVoltages, 1) } +// phases1p3p implements the api.PhaseSwitcher interface +func (wb *Vestel) phases1p3p(phases int) error { + _, err := wb.conn.WriteSingleRegister(vestelRegNumberPhases, uint16(phases)) + return err +} + +// getPhases implements the api.PhaseGetter interface +func (wb *Vestel) getPhases() (int, error) { + b, err := wb.conn.ReadHoldingRegisters(vestelRegPhasesSwitch, 1) + if err != nil { + return 0, err + } + return int(binary.BigEndian.Uint16(b)), nil +} + var _ api.Diagnosis = (*Vestel)(nil) // Diagnose implements the api.Diagnosis interface diff --git a/charger/vestel_decorators.go b/charger/vestel_decorators.go new file mode 100644 index 000000000..da5e62ba3 --- /dev/null +++ b/charger/vestel_decorators.go @@ -0,0 +1,58 @@ +package charger + +// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT. + +import ( + "github.com/evcc-io/evcc/api" +) + +func decorateVestel(base *Vestel, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger { + switch { + case phaseSwitcher == nil: + return base + + case phaseGetter == nil && phaseSwitcher != nil: + return &struct { + *Vestel + api.PhaseSwitcher + }{ + Vestel: base, + PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{ + phaseSwitcher: phaseSwitcher, + }, + } + + case phaseGetter != nil && phaseSwitcher != nil: + return &struct { + *Vestel + api.PhaseGetter + api.PhaseSwitcher + }{ + Vestel: base, + PhaseGetter: &decorateVestelPhaseGetterImpl{ + phaseGetter: phaseGetter, + }, + PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{ + phaseSwitcher: phaseSwitcher, + }, + } + } + + return nil +} + +type decorateVestelPhaseGetterImpl struct { + phaseGetter func() (int, error) +} + +func (impl *decorateVestelPhaseGetterImpl) GetPhases() (int, error) { + return impl.phaseGetter() +} + +type decorateVestelPhaseSwitcherImpl struct { + phaseSwitcher func(int) error +} + +func (impl *decorateVestelPhaseSwitcherImpl) Phases1p3p(p0 int) error { + return impl.phaseSwitcher(p0) +} diff --git a/templates/definition/charger/vestel.yaml b/templates/definition/charger/vestel.yaml index 5cc326be6..668b9d0e7 100644 --- a/templates/definition/charger/vestel.yaml +++ b/templates/definition/charger/vestel.yaml @@ -10,6 +10,7 @@ products: - brand: E.ON Drive description: generic: vBox +capabilities: ["1p3p"] requirements: evcc: ["sponsorship"] params: