Add configurable override duration and hard-stop thresholds

Override duration (web UI):
- Dropdown on Ein button: 30min / 1h / 2h / 4h
- Engine notified immediately via ApplyOverride() — no waiting for
  next SyncHardwareState cycle
- Aus button always uses 1h lockout (keeps consumer off for 1h)

Hard-stop thresholds that cancel active overrides:
- SOC emergency brake: now also clears ManualOverride flag so EMS
  resumes full control after the safety shutdown
- override_max_import_w (default 800W): if grid import exceeds this
  while an override is active, override is cancelled immediately
  (no hysteresis delay — protection is instant)

Config: ems.override_max_import_w (0 = disabled)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 10:43:49 +02:00
parent 4530b672d2
commit 7a971c4c41
5 changed files with 117 additions and 16 deletions

View File

@@ -151,12 +151,13 @@ func (f *ForecastConfig) FetchIntervalParsed() time.Duration {
// EMSConfig holds operational settings for the EMS daemon.
type EMSConfig struct {
PollInterval string `yaml:"poll_interval"`
ListenAddr string `yaml:"listen_addr"`
LogLevel string `yaml:"log_level"`
StateFile string `yaml:"state_file"`
RecoveryTimeout string `yaml:"recovery_timeout"`
OverrideTimeout string `yaml:"override_timeout"`
PollInterval string `yaml:"poll_interval"`
ListenAddr string `yaml:"listen_addr"`
LogLevel string `yaml:"log_level"`
StateFile string `yaml:"state_file"`
RecoveryTimeout string `yaml:"recovery_timeout"`
OverrideTimeout string `yaml:"override_timeout"`
OverrideMaxImportW float64 `yaml:"override_max_import_w"` // cancel override if grid import exceeds this (0 = disabled)
}
func (e *EMSConfig) PollIntervalParsed() time.Duration {