From cb93b9b2f16a1929c664e2ff70d835025c6450cf Mon Sep 17 00:00:00 2001 From: andig Date: Mon, 10 May 2021 22:33:49 +0200 Subject: [PATCH] Allow vehicles to request soc update (#981) --- api/error.go | 3 +++ core/loadpoint.go | 19 +++++++++---------- core/loadpoint_test.go | 8 +++++++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/api/error.go b/api/error.go index 39a3bf7e5..77b674311 100644 --- a/api/error.go +++ b/api/error.go @@ -5,6 +5,9 @@ import "errors" // ErrNotAvailable indicates that a feature is not available var ErrNotAvailable = errors.New("not available") +// ErrMustRetry indicates that a rate-limited operation should be retried +var ErrMustRetry = errors.New("must retry") + // ErrTimeout is the error returned when a timeout happened. // Modeled after context.DeadlineError var ErrTimeout error = errTimeoutError{} diff --git a/core/loadpoint.go b/core/loadpoint.go index 5a109b205..a37c9a9d0 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -868,12 +868,7 @@ func (lp *LoadPoint) socPollAllowed() bool { lp.log.DEBUG.Printf("next soc poll remaining time: %v", remaining.Truncate(time.Second)) } - res := lp.charging() || honourUpdateInterval && (remaining <= 0) || lp.connected() && lp.socUpdated.IsZero() - if res { - lp.socUpdated = lp.clock.Now() - } - - return res + return lp.charging() || honourUpdateInterval && (remaining <= 0) || lp.connected() && lp.socUpdated.IsZero() } // publish state of charge, remaining charge duration and range @@ -883,6 +878,8 @@ func (lp *LoadPoint) publishSoCAndRange() { } if lp.socPollAllowed() { + lp.socUpdated = lp.clock.Now() + f, err := lp.socEstimator.SoC(lp.chargedEnergy) if err == nil { lp.socCharge = math.Trunc(f) @@ -898,10 +895,12 @@ func (lp *LoadPoint) publishSoCAndRange() { chargeRemainingEnergy := 1e3 * lp.socEstimator.RemainingChargeEnergy(lp.SoC.Target) lp.publish("chargeRemainingEnergy", chargeRemainingEnergy) } else { - // we need a value- so retry on error - lp.socUpdated = lp.clock.Now() - - lp.log.ERROR.Printf("vehicle: %v", err) + if errors.Is(err, api.ErrMustRetry) { + lp.socUpdated = time.Time{} + lp.log.DEBUG.Printf("vehicle: waiting for update") + } else { + lp.log.ERROR.Printf("vehicle: %v", err) + } } // range diff --git a/core/loadpoint_test.go b/core/loadpoint_test.go index 1883e55e7..1e27aa6fa 100644 --- a/core/loadpoint_test.go +++ b/core/loadpoint_test.go @@ -699,7 +699,13 @@ func TestSoCPoll(t *testing.T) { lp.SoC.Poll.Mode = tc.mode lp.status = tc.status - if res := lp.socPollAllowed(); tc.res != res { + res := lp.socPollAllowed() + if res { + // mimic update outside of socPollAllowed + lp.socUpdated = clock.Now() + } + + if tc.res != res { t.Errorf("expected %v, got %v", tc.res, res) } }