Vestel: add phase switching (#18911)
This commit is contained in:
parent
bc219c8c3a
commit
3365c846a2
3 changed files with 89 additions and 2 deletions
|
|
@ -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
|
||||
|
|
|
|||
58
charger/vestel_decorators.go
Normal file
58
charger/vestel_decorators.go
Normal file
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ products:
|
|||
- brand: E.ON Drive
|
||||
description:
|
||||
generic: vBox
|
||||
capabilities: ["1p3p"]
|
||||
requirements:
|
||||
evcc: ["sponsorship"]
|
||||
params:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue