Add ambient temperature gate to heating period detection
Adds heating_min_ambient_c (default 15°C) to season config. When outdoor temperature is at or above this threshold, SG-Ready is suppressed even if the calendar month is within the heating season. Prevents unnecessary heat pump boost activation on warm spring/autumn days. Logic: heating active = in_heating_month AND ambient < threshold Zero value (unset) disables the temperature gate (calendar-only, old behaviour). New test: TestHeatingPeriodAmbientSuppression covers warm-day suppression, cold-day pass-through, and summer month independence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -208,6 +208,7 @@ func TestShutdownReverseOrder(t *testing.T) {
|
||||
|
||||
func TestHeatingPeriodDetection(t *testing.T) {
|
||||
eng := NewEngine(testConfig(), testLogger())
|
||||
cold := 5.0 // well below any threshold — pure calendar test
|
||||
|
||||
tests := []struct {
|
||||
month time.Month
|
||||
@@ -230,13 +231,36 @@ func TestHeatingPeriodDetection(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.month.String(), func(t *testing.T) {
|
||||
date := time.Date(2025, tt.month, 15, 12, 0, 0, 0, time.UTC)
|
||||
if got := eng.isHeatingPeriod(date); got != tt.expected {
|
||||
if got := eng.isHeatingPeriod(date, cold); got != tt.expected {
|
||||
t.Errorf("month %s: got %v, want %v", tt.month, got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeatingPeriodAmbientSuppression(t *testing.T) {
|
||||
cfg := testConfig()
|
||||
cfg.Season.HeatingMinAmbientC = 15.0
|
||||
eng := NewEngine(cfg, testLogger())
|
||||
|
||||
// Winter month, but warm day — should be suppressed
|
||||
warmWinterDay := time.Date(2025, time.January, 15, 12, 0, 0, 0, time.UTC)
|
||||
if eng.isHeatingPeriod(warmWinterDay, 18.0) {
|
||||
t.Error("expected heating period suppressed when ambient (18°C) >= threshold (15°C)")
|
||||
}
|
||||
|
||||
// Winter month, cold day — should be active
|
||||
if !eng.isHeatingPeriod(warmWinterDay, 8.0) {
|
||||
t.Error("expected heating period active when ambient (8°C) < threshold (15°C)")
|
||||
}
|
||||
|
||||
// Summer month, cold day — still not heating (month gate takes precedence)
|
||||
summerDay := time.Date(2025, time.July, 15, 12, 0, 0, 0, time.UTC)
|
||||
if eng.isHeatingPeriod(summerDay, 5.0) {
|
||||
t.Error("expected heating period inactive in summer regardless of temperature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWallboxMutualExclusion(t *testing.T) {
|
||||
cfg := testConfig()
|
||||
cfg.Hysteresis.ExportOnDuration = "0s"
|
||||
|
||||
Reference in New Issue
Block a user