Add trip mode: self-learning EV charging scheduler
User enters car SOC + departure deadline; EMS computes when to start charging and activates the wallbox at the right time (grid import OK for trip mode). Charging rate is learned from completed PM sessions, improving over time. Car profiles (Mini Cooper SE 50 kWh, BMW ix2 63 kWh) are config-driven and selectable per trip. - internal/trip/trip.go: Goal/Session types, Manager with per-cycle Tick() that accumulates energy, detects session completion, learns avg charge rate from JSONL session log - internal/config: CarProfile + Cars map, TripGoalFile, SessionLogFile - internal/status: trip card (active goal) + trip form (set new goal), CarOption list, formatDay/formatDur helpers - main.go: tripMgr lifecycle, /trip + /trip/cancel HTTP handlers, runCycle integration (ShouldStartNow → ApplyOverride, auto-clear) - configs/ems-config.yaml: cars section, trip_goal_file, session_log_file Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,17 +10,24 @@ import (
|
||||
|
||||
// Config is the top-level EMS configuration.
|
||||
type Config struct {
|
||||
Prometheus PrometheusConfig `yaml:"prometheus"`
|
||||
Shelly ShellyConfig `yaml:"shelly"`
|
||||
Viessmann ViessmannConfig `yaml:"viessmann"`
|
||||
SOC SOCThresholds `yaml:"soc_thresholds"`
|
||||
Hysteresis HysteresisConfig `yaml:"hysteresis"`
|
||||
Thresholds PowerThresholds `yaml:"thresholds"`
|
||||
Consumers ConsumersConfig `yaml:"consumers"`
|
||||
Strategic StrategicConfig `yaml:"strategic"`
|
||||
Season SeasonConfig `yaml:"season"`
|
||||
Forecast ForecastConfig `yaml:"forecast"`
|
||||
EMS EMSConfig `yaml:"ems"`
|
||||
Prometheus PrometheusConfig `yaml:"prometheus"`
|
||||
Shelly ShellyConfig `yaml:"shelly"`
|
||||
Viessmann ViessmannConfig `yaml:"viessmann"`
|
||||
SOC SOCThresholds `yaml:"soc_thresholds"`
|
||||
Hysteresis HysteresisConfig `yaml:"hysteresis"`
|
||||
Thresholds PowerThresholds `yaml:"thresholds"`
|
||||
Consumers ConsumersConfig `yaml:"consumers"`
|
||||
Strategic StrategicConfig `yaml:"strategic"`
|
||||
Season SeasonConfig `yaml:"season"`
|
||||
Forecast ForecastConfig `yaml:"forecast"`
|
||||
Cars map[string]CarProfile `yaml:"cars"`
|
||||
EMS EMSConfig `yaml:"ems"`
|
||||
}
|
||||
|
||||
// CarProfile holds the display name and battery capacity of a known vehicle.
|
||||
type CarProfile struct {
|
||||
Name string `yaml:"name"`
|
||||
BatteryKWh float64 `yaml:"battery_kwh"`
|
||||
}
|
||||
|
||||
// PrometheusConfig holds Prometheus connection settings.
|
||||
@@ -160,6 +167,8 @@ type EMSConfig struct {
|
||||
OverrideTimeout string `yaml:"override_timeout"`
|
||||
OverrideMaxImportW float64 `yaml:"override_max_import_w"` // cancel override if grid import exceeds this (0 = disabled)
|
||||
MonitorOnlyFile string `yaml:"monitor_only_file"` // flag file path: presence = monitor-only mode active
|
||||
TripGoalFile string `yaml:"trip_goal_file"` // persisted active trip goal
|
||||
SessionLogFile string `yaml:"session_log_file"` // JSONL log of completed charge sessions
|
||||
}
|
||||
|
||||
func (e *EMSConfig) PollIntervalParsed() time.Duration {
|
||||
|
||||
Reference in New Issue
Block a user