Hardybarth Salia: add phase switching (#16683)
This commit is contained in:
parent
730ad8f3af
commit
96e6c97256
3 changed files with 275 additions and 18 deletions
|
|
@ -4,6 +4,7 @@ const (
|
|||
HeartBeat = "salia/heartbeat"
|
||||
ChargeMode = "salia/chargemode"
|
||||
PauseCharging = "salia/pausecharging"
|
||||
SetPhase = "salia/phase_switching/setphase"
|
||||
GridCurrentLimit = "grid_current_limit"
|
||||
)
|
||||
|
||||
|
|
@ -33,8 +34,13 @@ type Port struct {
|
|||
}
|
||||
}
|
||||
Salia struct {
|
||||
ChargeMode string
|
||||
PauseCharging int `json:"pausecharging,string"`
|
||||
ChargeMode string
|
||||
PauseCharging int `json:"pausecharging,string"`
|
||||
PhaseSwitching struct {
|
||||
Actual int `json:",string"`
|
||||
Status string
|
||||
SetPhase string `json:"setphase,omitempty"`
|
||||
} `json:"phase_switching"`
|
||||
}
|
||||
Metering struct {
|
||||
Meter struct {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func init() {
|
|||
registry.Add("hardybarth-salia", NewSaliaFromConfig)
|
||||
}
|
||||
|
||||
//go:generate go run ../cmd/tools/decorate.go -f decorateSalia -b *Salia -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)"
|
||||
//go:generate go run ../cmd/tools/decorate.go -f decorateSalia -b *Salia -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) error" -t "api.PhaseGetter,GetPhases,func() (int, error)"
|
||||
|
||||
// NewSaliaFromConfig creates a Salia cPH2 charger from generic config
|
||||
func NewSaliaFromConfig(other map[string]interface{}) (api.Charger, error) {
|
||||
|
|
@ -118,17 +118,34 @@ func NewSalia(uri string, cache time.Duration) (api.Charger, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
go wb.heartbeat()
|
||||
|
||||
wb.pause(false)
|
||||
|
||||
if res.Secc.Port0.Metering.Meter.Available > 0 {
|
||||
return decorateSalia(wb, wb.currentPower, wb.totalEnergy, wb.currents), nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return wb, err
|
||||
go wb.heartbeat()
|
||||
|
||||
wb.pause(false)
|
||||
|
||||
var (
|
||||
currentPower func() (float64, error)
|
||||
totalEnergy func() (float64, error)
|
||||
currents func() (float64, float64, float64, error)
|
||||
phasesG func() (int, error)
|
||||
phasesS func(int) error
|
||||
)
|
||||
|
||||
if res.Secc.Port0.Metering.Meter.Available > 0 {
|
||||
currentPower = wb.currentPower
|
||||
totalEnergy = wb.totalEnergy
|
||||
currents = wb.currents
|
||||
}
|
||||
|
||||
if res.Secc.Port0.Salia.PhaseSwitching.Actual > 0 {
|
||||
phasesG = wb.getPhases
|
||||
phasesS = wb.phases1p3p
|
||||
}
|
||||
|
||||
return decorateSalia(wb, currentPower, totalEnergy, currents, phasesS, phasesG), nil
|
||||
}
|
||||
|
||||
func (wb *Salia) heartbeat() {
|
||||
|
|
@ -250,6 +267,30 @@ func (wb *Salia) currents() (float64, float64, float64, error) {
|
|||
// return "", api.ErrNotAvailable
|
||||
// }
|
||||
|
||||
func (wb *Salia) getPhases() (int, error) {
|
||||
res, err := wb.apiG.Get()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if res.Secc.Port0.Salia.PhaseSwitching.Actual == 0 {
|
||||
return 0, api.ErrNotAvailable
|
||||
}
|
||||
|
||||
return res.Secc.Port0.Salia.PhaseSwitching.Actual, nil
|
||||
}
|
||||
|
||||
func (wb *Salia) phases1p3p(phases int) error {
|
||||
p, err := wb.getPhases()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p == phases {
|
||||
return nil
|
||||
}
|
||||
return wb.post(salia.SetPhase, "toggle")
|
||||
}
|
||||
|
||||
var _ api.Diagnosis = (*Salia)(nil)
|
||||
|
||||
// Diagnose implements the api.Diagnosis interface
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import (
|
|||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
func decorateSalia(base *Salia, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error)) api.Charger {
|
||||
func decorateSalia(base *Salia, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
|
||||
switch {
|
||||
case meter == nil:
|
||||
case meter == nil && phaseSwitcher == nil:
|
||||
return base
|
||||
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents == nil:
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseSwitcher == nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
|
|
@ -22,7 +22,7 @@ func decorateSalia(base *Salia, meter func() (float64, error), meterEnergy func(
|
|||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents == nil:
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseSwitcher == nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
|
|
@ -37,7 +37,7 @@ func decorateSalia(base *Salia, meter func() (float64, error), meterEnergy func(
|
|||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents != nil:
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseSwitcher == nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
|
|
@ -52,7 +52,7 @@ func decorateSalia(base *Salia, meter func() (float64, error), meterEnergy func(
|
|||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents != nil:
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseSwitcher == nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
|
|
@ -70,6 +70,200 @@ func decorateSalia(base *Salia, meter func() (float64, error), meterEnergy func(
|
|||
phaseCurrents: phaseCurrents,
|
||||
},
|
||||
}
|
||||
|
||||
case meter == nil && phaseGetter == nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseGetter == nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseGetter == nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateSaliaMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseGetter == nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.PhaseCurrents
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
|
||||
phaseCurrents: phaseCurrents,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseGetter == nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.PhaseCurrents
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateSaliaMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
|
||||
phaseCurrents: phaseCurrents,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter == nil && phaseGetter != nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.PhaseGetter
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
PhaseGetter: &decorateSaliaPhaseGetterImpl{
|
||||
phaseGetter: phaseGetter,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseGetter != nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.PhaseGetter
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
PhaseGetter: &decorateSaliaPhaseGetterImpl{
|
||||
phaseGetter: phaseGetter,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseGetter != nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.PhaseGetter
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateSaliaMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
PhaseGetter: &decorateSaliaPhaseGetterImpl{
|
||||
phaseGetter: phaseGetter,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseGetter != nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.PhaseCurrents
|
||||
api.PhaseGetter
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
|
||||
phaseCurrents: phaseCurrents,
|
||||
},
|
||||
PhaseGetter: &decorateSaliaPhaseGetterImpl{
|
||||
phaseGetter: phaseGetter,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
|
||||
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseGetter != nil && phaseSwitcher != nil:
|
||||
return &struct {
|
||||
*Salia
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.PhaseCurrents
|
||||
api.PhaseGetter
|
||||
api.PhaseSwitcher
|
||||
}{
|
||||
Salia: base,
|
||||
Meter: &decorateSaliaMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateSaliaMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
|
||||
phaseCurrents: phaseCurrents,
|
||||
},
|
||||
PhaseGetter: &decorateSaliaPhaseGetterImpl{
|
||||
phaseGetter: phaseGetter,
|
||||
},
|
||||
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
|
||||
phaseSwitcher: phaseSwitcher,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -98,3 +292,19 @@ type decorateSaliaPhaseCurrentsImpl struct {
|
|||
func (impl *decorateSaliaPhaseCurrentsImpl) Currents() (float64, float64, float64, error) {
|
||||
return impl.phaseCurrents()
|
||||
}
|
||||
|
||||
type decorateSaliaPhaseGetterImpl struct {
|
||||
phaseGetter func() (int, error)
|
||||
}
|
||||
|
||||
func (impl *decorateSaliaPhaseGetterImpl) GetPhases() (int, error) {
|
||||
return impl.phaseGetter()
|
||||
}
|
||||
|
||||
type decorateSaliaPhaseSwitcherImpl struct {
|
||||
phaseSwitcher func(int) error
|
||||
}
|
||||
|
||||
func (impl *decorateSaliaPhaseSwitcherImpl) Phases1p3p(p0 int) error {
|
||||
return impl.phaseSwitcher(p0)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue