What's Changed
- test(cmd): expand runner and schedule validation test coverage by @atbore-phx-coding in #169
- feat(cmd,power,mqtt): add scheduler_mode selector (crontab | windows | auto) with crontab deprecation (#147) by @atbore-phx-coding in #170
- feat(ha,mqtt,cmd): convert HA add-on config to YAML with nested MQTT config by @atbore-phx-coding in #173
- docs: restructure documentation into MkDocs site on GitHub Pages by @atbore-phx-coding in #174
- Fix installation doc by @atbore-phx-coding in #175
- feat(doc,ha): tuning main topics by @atbore-phx-coding in #176
- feat(power,cmd): add weekday filtering to charge windows by @atbore-phx-coding in #178
- fix(cmd): keep runner alive in windows mode without MQTT by @atbore-phx-coding in #179
- Feat/dep updates by @atbore-phx-coding in #184
- fix(log): suppress error stack traces unless DEBUG=true by @mhornsby in #185
- docs(ha): fill in missing v2.1.0 changelog entries and add doc links by @atbore-phx-coding in #186
- Release/v2.1.0 by @atbore-phx in #136
New Contributors
Full Changelog: v2.0.2...v2.1.0
What's New in v2.1.0
Multi-window charging schedule
New windows configuration option replaces the single start_hr/end_hr/max_charge triple with an ordered list of charge windows, each with its own max_charge and optional forecast_horizon/consumption_horizon overrides. Key highlights:
- Define multiple charge windows per day (e.g. night 02:00–06:00 and midday 12:00–15:00) with independent power limits and horizons.
- Cross-midnight windows supported (e.g. 22:00–04:00).
- Overlap detection rejects misconfigured windows at startup.
- Legacy
start_hr/end_hr/max_chargekeys remain fully supported — they are synthesized into a single window whenwindowsis absent. - MQTT state payload and Home Assistant discovery now expose the active window name, max charge, and forecast horizon as diagnostic sensors.
- New
forecast_horizonandconsumption_horizonoptions replace the hardcoded noon-threshold forecast selection with explicit, named modes:forecast_horizon:default(current behavior),next_solar_day,remaining_today,today,tomorrow,offconsumption_horizon:full_day(current behavior),remaining_today
Existing installations keep current behavior under forecast_horizon=default and consumption_horizon=full_day.
See: Configuration → Multi-window · Forecast horizon modes · Consumption horizon modes
Weekday filtering on charge windows
Each window in the windows: list now accepts an optional weekdays field
for day-of-week filtering:
weekdays: "mon-fri" # Monday through Friday
weekdays: "mon,fri" # Monday and Friday only
weekdays: "mon-fri,sun" # weekdays plus SundayA cross-midnight window uses the start-day model: start: "22:00", end: "04:00", weekdays: "fri" is active Friday night/Saturday morning but not
Saturday night. Two windows with the same clock range but different weekday
sets (e.g., mon-fri vs sat,sun) validate without overlap errors.
See the Weekday Filtering guide
for the full format reference, start-day model explanation, and worked
configuration examples.
Scheduler mode selector
New scheduler_mode option (crontab | windows) replaces the legacy crontab field. The crontab key remains functional but is deprecated and will be removed in v3.0.0. A one-shot warning is logged when mode: crontab is configured.
scheduler_mode: crontab— legacy cron-driven scheduling. Ifwindowsis empty, the legacy single window (start_hr,end_hr,max_charge) is used. Ifwindowsis non-empty, the windows list drives charge decisions but ticks are still driven by the cron schedule.scheduler_mode: windows— the new internal ticker drives charge cycles, thecrontabfield is ignored, and awindowslist must be provided.
Windows mode adds per-window scheduling controls:
tick_minutes— per-window tick interval override (default 60 min).defaults(true/false) — enable per-window Fronius defaults reset at window end.before_end_defaults_minutes— how many minutes before the window end to fire the reset (default 5, minimum 0 for exact end).
The windows-mode ticker fires an immediate tick on startup (no idle gap if sbam starts mid-window) and uses exact boundary timers for window transitions. ValidateWindows rejects configurations where one window's end equals another's start to eliminate ambiguity at transitions.
See: Configuration → Scheduling
HA add-on YAML config
The Home Assistant add-on configuration is now defined in YAML format (config.yaml) with nested MQTT configuration, matching the standalone config.yaml structure. All options are documented in the sbam documentation site.
See: Configuration · Installation
Crontab default validation fix
The Home Assistant add-on configuration schema now accepts 0 0 0 0 0 as a valid crontab value, allowing users to disable scheduled execution through the HA UI. Previously the regex validation rejected this value even though the Go application has always treated it as the disabled sentinel.
See: Configuration → Scheduling
Inverter status check before Modbus defaults write
On classifier error (DecisionSkip) the system now reads the StorCtl_Mod register (40349) before writing Fronius defaults. If the inverter is already in normal operating mode (value 0), the write is skipped, avoiding an unnecessary Modbus cycle. A read failure falls through to the existing defaults write so safety is preserved.
See: Configuration → Operational
Runner lifecycle fix for windows mode without MQTT
Fixed an issue where the runner would shut down immediately when scheduler_mode=windows was configured without MQTT enabled. The runner is now correctly kept alive by its internal ticker in windows mode regardless of MQTT state. Only crontab mode without MQTT triggers an immediate shutdown (no internal driver to keep the process alive).
See: Configuration → Scheduling
Error stack trace suppression
Error log output is now cleaner by default: stack traces are suppressed unless DEBUG=true is set in the environment. When DEBUG=true, full stack traces are included as before. Contributed by @mhornsby in #185.
See: CLI → Debug Logs