Repository: evcc-io/evcc
Pull request #2168 (2021-12-31 09:56:14)

Update pvtimer handling
Replace https://github.com/evcc-io/evcc/pull/2118

@rivengh mein push ging in neuen Branch- warum auch immer :/


Patch:
diff --git a/core/loadpoint.go b/core/loadpoint.go
index e7de7d08..82980077 100644
--- a/core/loadpoint.go
+++ b/core/loadpoint.go
@@ -347,6 +347,9 @@ func (lp *LoadPoint) evChargeStopHandler() {
 
 	// soc update reset
 	lp.socUpdated = time.Time{}
+
+	// reset pv enable/disable timer
+	lp.resetPVTimerIfRunning()
 }
 
 // evVehicleConnectHandler sends external start event
@@ -879,6 +882,22 @@ func (lp *LoadPoint) elapsePVTimer() {
 	lp.publishTimer(pvTimer, 0, timerInactive)
 }
 
+// resetPVTimerIfRunning resets the pv enable/disable timer to disabled state
+func (lp *LoadPoint) resetPVTimerIfRunning(typ ...string) {
+	if lp.pvTimer.IsZero() {
+		return
+	}
+
+	msg := "pv timer reset"
+	if len(typ) == 1 {
+		msg = fmt.Sprintf("pv %s timer reset", typ)
+	}
+	lp.log.DEBUG.Printf(msg)
+
+	lp.pvTimer = time.Time{}
+	lp.publishTimer(pvTimer, 0, timerInactive)
+}
+
 // scalePhasesIfAvailable scales if api.ChargePhases is available
 func (lp *LoadPoint) scalePhasesIfAvailable(phases int) error {
 	err := lp.scalePhases(phases)
@@ -1043,7 +1062,7 @@ func (lp *LoadPoint) publishTimer(name string, delay time.Duration, action strin
 	if action == timerInactive {
 		lp.log.DEBUG.Printf("%s action: %s", name, action)
 	} else {
-		lp.log.DEBUG.Printf("%s action: %s in %v", name, action, remaining)
+		lp.log.DEBUG.Printf("%s action: %s in %v", name, action, remaining.Round(time.Second))
 	}
 }
 
@@ -1099,10 +1118,7 @@ func (lp *LoadPoint) pvMaxCurrent(mode api.ChargeMode, sitePower float64, batter
 			}
 		} else {
 			// reset timer
-			lp.log.DEBUG.Printf("pv disable timer reset: %v", lp.Disable.Delay)
-			lp.pvTimer = lp.clock.Now()
-
-			lp.publishTimer(pvTimer, 0, timerInactive)
+			lp.resetPVTimerIfRunning("disable")
 		}
 
 		// lp.log.DEBUG.Println("pv disable timer: keep enabled")
@@ -1134,10 +1150,7 @@ func (lp *LoadPoint) pvMaxCurrent(mode api.ChargeMode, sitePower float64, batter
 			}
 		} else {
 			// reset timer
-			lp.log.DEBUG.Printf("pv enable timer reset: %v", lp.Enable.Delay)
-			lp.pvTimer = lp.clock.Now()
-
-			lp.publishTimer(pvTimer, 0, timerInactive)
+			lp.resetPVTimerIfRunning("enable")
 		}
 
 		// lp.log.DEBUG.Println("pv enable timer: keep disabled")
@@ -1145,12 +1158,7 @@ func (lp *LoadPoint) pvMaxCurrent(mode api.ChargeMode, sitePower float64, batter
 	}
 
 	// reset timer to disabled state
-	if !lp.pvTimer.IsZero() {
-		lp.log.DEBUG.Printf("pv timer reset")
-		lp.pvTimer = time.Time{}
-
-		lp.publishTimer(pvTimer, 0, timerInactive)
-	}
+	lp.resetPVTimerIfRunning()
 
 	// cap at maximum current
 	targetCurrent = math.Min(targetCurrent, maxCurrent)


Test patch:
diff --git a/core/loadpoint_test.go b/core/loadpoint_test.go
index bc088a89..d64e9198 100644
--- a/core/loadpoint_test.go
+++ b/core/loadpoint_test.go
@@ -262,8 +262,8 @@ func TestPVHysteresis(t *testing.T) {
 			{-500, 1, 0},
 			{-499, dt - 1, 0}, // should reset timer
 			{-500, dt + 1, 0}, // new begin of timer
-			{-500, 2*dt - 2, 0},
-			{-500, 2*dt - 1, minA},
+			{-500, 2 * dt, 0},
+			{-500, 2*dt + 1, minA},
 		}},
 		// reset enable timer when threshold not met while timer active and threshold not configured
 		{false, 0, 0, []se{
@@ -271,16 +271,16 @@ func TestPVHysteresis(t *testing.T) {
 			{-6 * 100 * 10, dt + 1, 0},
 			{-6 * 100 * 10, dt + 2, 0},
 			{-6 * 100 * 10, 2 * dt, 0},
-			{-6 * 100 * 10, 2*dt + 2, minA},
+			{-6 * 100 * 10, 2*dt + 1, minA},
 		}},
 		// reset disable timer when threshold not met while timer active
 		{true, 0, 500, []se{
 			{500, 0, minA},
 			{500, 1, minA},
-			{499, dt - 1, minA},   // reset timer
-			{500, dt + 1, minA},   // within reset timer duration
-			{500, 2*dt - 2, minA}, // still within reset timer duration
-			{500, 2*dt - 1, 0},    // reset timer elapsed
+			{499, dt - 1, minA}, // reset timer
+			{500, dt + 1, minA}, // within reset timer duration
+			{500, 2 * dt, minA}, // still within reset timer duration
+			{500, 2*dt + 1, 0},  // reset timer elapsed
 		}},
 	}