From 6fd6d7472ccb45fcbeb9f071c69854a88d08e534 Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 21 Aug 2021 14:25:31 +0200 Subject: [PATCH] Add plausi check for phase configuration --- core/helper.go | 2 +- core/loadpoint.go | 16 ++++++++++------ core/loadpoint_adapter.go | 2 +- core/loadpoint_test.go | 6 +++--- core/soc/adapter.go | 9 +++++++++ core/soc/timer.go | 8 -------- 6 files changed, 24 insertions(+), 19 deletions(-) create mode 100644 core/soc/adapter.go diff --git a/core/helper.go b/core/helper.go index 0efeb53d3..6ad10c4a9 100644 --- a/core/helper.go +++ b/core/helper.go @@ -16,7 +16,7 @@ var ( ) // powerToCurrent is a helper function to convert power to per-phase current -func powerToCurrent(power float64, phases int64) float64 { +func powerToCurrent(power float64, phases int) float64 { if Voltage == 0 { panic("Voltage is not set") } diff --git a/core/loadpoint.go b/core/loadpoint.go index 1c524f20f..d0ace0544 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -86,7 +86,7 @@ type LoadPoint struct { Mode api.ChargeMode `mapstructure:"mode"` // Charge mode, guarded by mutex Title string `mapstructure:"title"` // UI title - Phases int64 `mapstructure:"phases"` // Charger enabled phases + Phases int `mapstructure:"phases"` // Charger enabled phases ChargerRef string `mapstructure:"charger"` // Charger reference VehicleRef string `mapstructure:"vehicle"` // Vehicle reference VehiclesRef []string `mapstructure:"vehicles"` // Vehicles reference @@ -103,7 +103,7 @@ type LoadPoint struct { GuardDuration time.Duration // charger enable/disable minimum holding time enabled bool // Charger enabled state - activePhases int64 // Charger active phases as used by vehicle + activePhases int // Charger active phases as used by vehicle chargeCurrent float64 // Charger current limit guardUpdated time.Time // Charger enabled/disabled timestamp socUpdated time.Time // SoC updated timestamp (poll: connected) @@ -848,7 +848,7 @@ func (lp *LoadPoint) scalePhases(phases int) error { } lp.Lock() - if lp.Phases != int64(phases) { + if lp.Phases != phases { lp.Unlock() // disable charger - this will also stop the car charging using the api if available @@ -862,7 +862,7 @@ func (lp *LoadPoint) scalePhases(phases int) error { } lp.Lock() - lp.Phases = int64(phases) + lp.Phases = phases lp.publish("phases", lp.Phases) // disable phase timer @@ -883,6 +883,10 @@ func (lp *LoadPoint) pvScalePhases(availablePower, minCurrent, maxCurrent float6 phases := lp.GetPhases() targetCurrent := availablePower / Voltage / float64(lp.activePhases) + if phases < lp.activePhases { + lp.log.WARN.Printf("invalid status: %dp active @ %dp configured", lp.activePhases, phases) + } + lp.log.DEBUG.Printf("!!pvScalePhases available power %.0f for target current %.1f @ %dp/%dp", availablePower, targetCurrent, lp.activePhases, phases) if lp.phaseTimer.IsZero() { lp.log.DEBUG.Printf("!!pvScalePhases timer empty") @@ -1070,7 +1074,7 @@ func (lp *LoadPoint) updateChargeCurrents() { // guess active phases from power consumption // assumes that chargePower has been updated before if lp.charging() && lp.chargeCurrent > 0 { - phases := int64(math.Round(lp.chargePower / Voltage / lp.chargeCurrent)) + phases := int(math.Round(lp.chargePower / Voltage / lp.chargeCurrent)) if phases >= 1 && phases <= 3 { lp.activePhases = phases lp.log.DEBUG.Printf("detected phases: %dp (%.1fA @ %.0fW)", lp.activePhases, lp.chargeCurrent, lp.chargePower) @@ -1092,7 +1096,7 @@ func (lp *LoadPoint) updateChargeCurrents() { lp.publish("chargeCurrents", lp.chargeCurrents) if lp.charging() { - var phases int64 + var phases int for _, i := range lp.chargeCurrents { if i >= minActiveCurrent { phases++ diff --git a/core/loadpoint_adapter.go b/core/loadpoint_adapter.go index 3ea15f951..9f18e7653 100644 --- a/core/loadpoint_adapter.go +++ b/core/loadpoint_adapter.go @@ -18,7 +18,7 @@ func (a *adapter) SocEstimator() *soc.Estimator { return a.lp.socEstimator } -func (a *adapter) ActivePhases() int64 { +func (a *adapter) ActivePhases() int { return a.lp.activePhases } diff --git a/core/loadpoint_test.go b/core/loadpoint_test.go index a9712a5dc..8e245c7ea 100644 --- a/core/loadpoint_test.go +++ b/core/loadpoint_test.go @@ -897,8 +897,8 @@ func TestScalePhases(t *testing.T) { charger: charger, MinCurrent: minA, MaxCurrent: maxA, - Phases: int64(tc.phases), - activePhases: int64(tc.activePhases), + Phases: tc.phases, + activePhases: tc.activePhases, Enable: ThresholdConfig{ Delay: dt, }, @@ -918,7 +918,7 @@ func TestScalePhases(t *testing.T) { if res := lp.pvScalePhases(tc.availablePower, minA, maxA); tc.res != res { t.Errorf("expected %v, got %v", tc.res, res) } else { - if lp.Phases != int64(tc.toPhases) { + if lp.Phases != tc.toPhases { t.Errorf("expected %dp, got %dp", tc.toPhases, lp.Phases) } } diff --git a/core/soc/adapter.go b/core/soc/adapter.go new file mode 100644 index 000000000..58ec2fdf7 --- /dev/null +++ b/core/soc/adapter.go @@ -0,0 +1,9 @@ +package soc + +// Adapter provides the required methods for interacting with the loadpoint +type Adapter interface { + Publish(key string, val interface{}) + SocEstimator() *Estimator + ActivePhases() int + Voltage() float64 +} diff --git a/core/soc/timer.go b/core/soc/timer.go index 36afe5334..143cc3db8 100644 --- a/core/soc/timer.go +++ b/core/soc/timer.go @@ -11,14 +11,6 @@ const ( deviation = 30 * time.Minute ) -// Adapter provides the required methods for interacting with the loadpoint -type Adapter interface { - Publish(key string, val interface{}) - SocEstimator() *Estimator - ActivePhases() int64 - Voltage() float64 -} - // Timer is the target charging handler type Timer struct { Adapter