Skip to content

Commit

Permalink
Warp: validate charger phases (#13230)
Browse files Browse the repository at this point in the history
  • Loading branch information
poohnet authored Mar 31, 2024
1 parent 1d4a161 commit 412ec23
Show file tree
Hide file tree
Showing 5 changed files with 1,603 additions and 67 deletions.
4 changes: 4 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ type PhaseSwitcher interface {
Phases1p3p(phases int) error
}

type PhaseGetter interface {
GetPhases() (int, error)
}

// Diagnosis is a helper interface that allows to dump diagnostic data to console
type Diagnosis interface {
Diagnose()
Expand Down
4 changes: 4 additions & 0 deletions charger/warp/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,7 @@ type EmState struct {
RelayState bool `json:"relay_state"`
ErrorFlags int `json:"error_flags"`
}

type EmLowLevelState struct {
Is3phase bool `json:"is_3phase"`
}
39 changes: 37 additions & 2 deletions charger/warp2.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Warp2 struct {
chargeG func() (string, error)
userconfigG func() (string, error)
emStateG func() (string, error)
emLowLevelG func() (string, error)
maxcurrentS func(int64) error
phasesS func(int64) error
current int64
Expand All @@ -36,7 +37,7 @@ func init() {
registry.Add("warp-fw2", NewWarp2FromConfig) // deprecated
}

//go:generate go run ../cmd/tools/decorate.go -f decorateWarp2 -b *Warp2 -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.PhaseVoltages,Voltages,func() (float64, float64, float64, error)" -t "api.Identifier,Identify,func() (string, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) error"
//go:generate go run ../cmd/tools/decorate.go -f decorateWarp2 -b *Warp2 -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.PhaseVoltages,Voltages,func() (float64, float64, float64, error)" -t "api.Identifier,Identify,func() (string, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) error" -t "api.PhaseGetter,GetPhases,func() (int, error)"

// NewWarpFromConfig creates a new configurable charger
func NewWarp2FromConfig(other map[string]interface{}) (api.Charger, error) {
Expand Down Expand Up @@ -77,13 +78,15 @@ func NewWarp2FromConfig(other map[string]interface{}) (api.Charger, error) {
}

var phases func(int) error
var getPhases func() (int, error)
if cc.EnergyManager != "" {
if res, err := wb.emState(); err == nil && res.ExternalControl != 1 {
phases = wb.phases1p3p
getPhases = wb.getPhases
}
}

return decorateWarp2(wb, currentPower, totalEnergy, currents, voltages, identity, phases), err
return decorateWarp2(wb, currentPower, totalEnergy, currents, voltages, identity, phases, getPhases), err
}

// NewWarp2 creates a new configurable charger
Expand Down Expand Up @@ -149,6 +152,7 @@ func NewWarp2(mqttconf mqtt.Config, topic, emTopic string, timeout time.Duration
if err != nil {
return nil, err
}

wb.phasesS, err = provider.NewMqtt(log, client,
fmt.Sprintf("%s/power_manager/external_control_update", emTopic), 0).
WithPayload(`{ "phases_wanted": ${phases} }`).
Expand All @@ -157,6 +161,11 @@ func NewWarp2(mqttconf mqtt.Config, topic, emTopic string, timeout time.Duration
return nil, err
}

wb.emLowLevelG, err = to.StringGetter(mq("%s/power_manager/low_level_state", emTopic))
if err != nil {
return nil, err
}

return wb, nil
}

Expand Down Expand Up @@ -328,6 +337,18 @@ func (wb *Warp2) emState() (warp.EmState, error) {
return res, err
}

func (wb *Warp2) emLowLevelState() (warp.EmLowLevelState, error) {
var res warp.EmLowLevelState

s, err := wb.emLowLevelG()
if err == nil {
err = json.Unmarshal([]byte(s), &res)
}

return res, err
}

// phases1p3p implements the api.PhaseSwitcher interface
func (wb *Warp2) phases1p3p(phases int) error {
res, err := wb.emState()
if err != nil {
Expand All @@ -340,3 +361,17 @@ func (wb *Warp2) phases1p3p(phases int) error {

return wb.phasesS(int64(phases))
}

// getPhases implements the api.PhaseGetter interface
func (wb *Warp2) getPhases() (int, error) {
res, err := wb.emLowLevelState()
if err != nil {
return 0, err
}

if res.Is3phase {
return 3, nil
}

return 1, nil
}
Loading

0 comments on commit 412ec23

Please sign in to comment.