Add SG-Ready startup grace period and daily PV yield tracking
SG-Ready startup grace period (sg_ready_startup_min: 10): Heat pump compressor takes ~9 minutes to start after receiving the SG-Ready signal. Previously, idle detection fired after only 3×2min=6min, turning off SG-Ready before the compressor had time to respond. The grace period suppresses idle detection for the configured duration after activation. 0 = disabled (tests and unconfigured deployments are unaffected). Daily PV yield (photovoltaic_production_cumulated_currentDay): Reads actual kWh produced today from Prometheus (Wh → kWh, ÷1000). Logged as pv_today_kwh each cycle. Shown on status page in two places: - PV card sub-line: "Heute: 31.9 kWh" - Forecast card alongside forecast: "Ist: 31.9 kWh" Immediately makes forecast vs reality visible (today: forecast 15.9, actual 31.9 kWh — explains why SOC bypass triggered). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -169,8 +169,20 @@ func (e *Engine) Decide(state collector.SystemState, now time.Time, wwBoostC, fo
|
||||
}
|
||||
|
||||
// --- Compressor idle: release SG-Ready early if heat pump stopped ---
|
||||
// A startup grace period is applied after activation: the heat pump compressor
|
||||
// takes several minutes to start after receiving the SG-Ready signal, so idle
|
||||
// detection is suppressed until the grace period has elapsed.
|
||||
if cs := e.consumers[ConsumerSGReady]; cs.Active {
|
||||
if state.CompressorPowerW < float64(e.cfg.Consumers.CompressorIdleW) {
|
||||
startupMin := e.cfg.Consumers.SGReadyStartupMin
|
||||
inGrace := startupMin > 0 && !cs.ActivatedAt.IsZero() && now.Sub(cs.ActivatedAt) < time.Duration(startupMin)*time.Minute
|
||||
|
||||
if inGrace {
|
||||
e.logger.Debug("SG-Ready: startup grace period, skipping idle check",
|
||||
"activated_at", cs.ActivatedAt.Format("15:04"),
|
||||
"grace_min", startupMin,
|
||||
"elapsed_min", int(now.Sub(cs.ActivatedAt).Minutes()),
|
||||
)
|
||||
} else if state.CompressorPowerW < float64(e.cfg.Consumers.CompressorIdleW) {
|
||||
cs.LowPowerCycles++
|
||||
e.logger.Debug("SG-Ready: compressor idle cycle",
|
||||
"compressor_w", state.CompressorPowerW,
|
||||
|
||||
Reference in New Issue
Block a user