From 8be06fbb9d3431946c66529ddbb090ec46be3d44 Mon Sep 17 00:00:00 2001 From: andig Date: Fri, 16 Dec 2022 08:34:35 +0100 Subject: [PATCH] Target charge: don't allow timestamps in the past --- core/loadpoint/api.go | 2 +- core/loadpoint_api.go | 9 ++++++++- server/http_handler.go | 7 +++++-- server/http_handler_test.go | 3 ++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/core/loadpoint/api.go b/core/loadpoint/api.go index d2540a58d..d341af896 100644 --- a/core/loadpoint/api.go +++ b/core/loadpoint/api.go @@ -49,7 +49,7 @@ type API interface { SetPhases(int) error // SetTargetCharge sets the charge targetSoC - SetTargetCharge(time.Time, int) + SetTargetCharge(time.Time, int) error // RemoteControl sets remote status demand RemoteControl(string, RemoteDemand) diff --git a/core/loadpoint_api.go b/core/loadpoint_api.go index 29f2c855a..c710ada15 100644 --- a/core/loadpoint_api.go +++ b/core/loadpoint_api.go @@ -1,6 +1,7 @@ package core import ( + "errors" "fmt" "time" @@ -185,10 +186,14 @@ func (lp *LoadPoint) SetPhases(phases int) error { } // SetTargetCharge sets loadpoint charge targetSoC -func (lp *LoadPoint) SetTargetCharge(finishAt time.Time, soc int) { +func (lp *LoadPoint) SetTargetCharge(finishAt time.Time, soc int) error { lp.Lock() defer lp.Unlock() + if !finishAt.IsZero() && finishAt.Before(time.Now()) { + return errors.New("timestamp is in the past") + } + lp.log.DEBUG.Printf("set target charge: %d @ %v", soc, finishAt) // apply immediately @@ -201,6 +206,8 @@ func (lp *LoadPoint) SetTargetCharge(finishAt time.Time, soc int) { lp.requestUpdate() } } + + return nil } // RemoteControl sets remote status demand diff --git a/server/http_handler.go b/server/http_handler.go index 3bcbf6dff..5e67cde61 100644 --- a/server/http_handler.go +++ b/server/http_handler.go @@ -294,7 +294,10 @@ func targetChargeHandler(loadpoint targetCharger) http.HandlerFunc { return } - loadpoint.SetTargetCharge(timeV, socV) + if err := loadpoint.SetTargetCharge(timeV, socV); err != nil { + jsonError(w, http.StatusBadRequest, err) + return + } res := struct { SoC int `json:"soc"` @@ -371,5 +374,5 @@ func socketHandler(hub *SocketHub) http.HandlerFunc { // TargetCharger defines target charge related loadpoint operations type targetCharger interface { // SetTargetCharge sets the charge targetSoC - SetTargetCharge(time.Time, int) + SetTargetCharge(time.Time, int) error } diff --git a/server/http_handler_test.go b/server/http_handler_test.go index ac0a70d73..46d4e9294 100644 --- a/server/http_handler_test.go +++ b/server/http_handler_test.go @@ -15,9 +15,10 @@ type mockLoadpoint struct { TargetTime time.Time } -func (lp *mockLoadpoint) SetTargetCharge(time time.Time, soc int) { +func (lp *mockLoadpoint) SetTargetCharge(time time.Time, soc int) error { lp.SoC = soc lp.TargetTime = time + return nil } func TestTargetChargeHandler(t *testing.T) {