From 23b6dfb882991f970727fea80317abdff06bc1d2 Mon Sep 17 00:00:00 2001 From: nename0 <26363498+nename0@users.noreply.github.com> Date: Sun, 19 Feb 2023 18:11:00 +0100 Subject: [PATCH] Update soc once when charging has stopped (#6267) --- core/loadpoint.go | 46 +++++++++++++++++++++++++++++------------- core/loadpoint_test.go | 5 ++++- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/core/loadpoint.go b/core/loadpoint.go index 5eed52e4b..93fe25ab8 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -119,15 +119,16 @@ type Loadpoint struct { MaxCurrent float64 // Max allowed current. Physically ensured by the charger GuardDuration time.Duration // charger enable/disable minimum holding time - enabled bool // Charger enabled state - phases int // Charger enabled phases, guarded by mutex - measuredPhases int // Charger physically measured phases - chargeCurrent float64 // Charger current limit - guardUpdated time.Time // Charger enabled/disabled timestamp - socUpdated time.Time // Soc updated timestamp (poll: connected) - vehicleDetect time.Time // Vehicle connected timestamp - vehicleDetectTicker *clock.Ticker - vehicleIdentifier string + enabled bool // Charger enabled state + phases int // Charger enabled phases, guarded by mutex + measuredPhases int // Charger physically measured phases + chargeCurrent float64 // Charger current limit + guardUpdated time.Time // Charger enabled/disabled timestamp + socUpdated time.Time // Soc updated timestamp (poll: connected) + didChargeOnLastSocUpdate bool // There was a charge process when Soc was updated last + vehicleDetect time.Time // Vehicle connected timestamp + vehicleDetectTicker *clock.Ticker + vehicleIdentifier string charger api.Charger chargeTimer api.ChargeTimer @@ -1304,17 +1305,34 @@ func (lp *Loadpoint) publishChargeProgress() { // socPollAllowed validates charging state against polling mode func (lp *Loadpoint) socPollAllowed() bool { + // always update soc when charging + if lp.charging() { + lp.didChargeOnLastSocUpdate = true + return true + } + + // update if connected and soc unknown + if lp.connected() && lp.socUpdated.IsZero() { + return true + } + remaining := lp.Soc.Poll.Interval - lp.clock.Since(lp.socUpdated) honourUpdateInterval := lp.Soc.Poll.Mode == pollAlways || - lp.Soc.Poll.Mode == pollConnected && lp.connected() || - lp.Soc.Poll.Mode == pollCharging && lp.connected() && (lp.vehicleSoc < float64(lp.Soc.target)) + lp.connected() && (lp.Soc.Poll.Mode == pollConnected || + // for mode charging allow one last soc update if did charge previously to not rely on soc estimator too much + lp.Soc.Poll.Mode == pollCharging && lp.didChargeOnLastSocUpdate) - if honourUpdateInterval && remaining > 0 { - lp.log.DEBUG.Printf("next soc poll remaining time: %v", remaining.Truncate(time.Second)) + if honourUpdateInterval { + if remaining > 0 { + lp.log.DEBUG.Printf("next soc poll remaining time: %v", remaining.Truncate(time.Second)) + } else { + lp.didChargeOnLastSocUpdate = false + return true + } } - return lp.charging() || honourUpdateInterval && (remaining <= 0) || lp.connected() && lp.socUpdated.IsZero() + return false } // checks if the connected charger can provide Soc to the connected vehicle diff --git a/core/loadpoint_test.go b/core/loadpoint_test.go index f8c15d3e0..1345f718b 100644 --- a/core/loadpoint_test.go +++ b/core/loadpoint_test.go @@ -680,7 +680,10 @@ func TestSocPoll(t *testing.T) { {pollCharging, api.StatusC, -1, true}, {pollCharging, api.StatusC, 0, true}, {pollCharging, api.StatusC, tNoRefresh, true}, // cached by vehicle - {pollCharging, api.StatusC, tRefresh, true}, + {pollCharging, api.StatusC, tRefresh, true}, // will set lp.didChargeOnLastSocUpdate + {pollCharging, api.StatusB, 0, false}, // last update must wait for interval + {pollCharging, api.StatusB, tRefresh, true}, // update once if connected and was charging + {pollCharging, api.StatusB, tRefresh, false}, // but only once // pollConnected {pollConnected, api.StatusA, -1, false},