The single supported entry point is the strom command:

strom --config-dir ./config --horizon-hours 24 --log-level INFO

All three flags are optional. The defaults are:

Flag Default Meaning
--config-dir auto-detected Folder with your configuration files (see Configuration)
--horizon-hours 24 How many whole hours ahead to optimize (must be at least 1)
--log-level INFO Verbosity: DEBUG, INFO, WARNING or ERROR

You can also run python -m strom. The old python main.py still works as a backwards-compatible shim for existing cron jobs — it runs the exact same code path.

What one run does

  1. Validates the configuration (credentials, API keys, house parameters). Any problem stops the run immediately with a clear error.
  2. Discovers the smart plug at DEVICEIP. If the plug cannot be reached, nothing else happens — no data is fetched and nothing is actuated.
  3. Fetches weather and prices for the next --horizon-hours whole hours, aligned to hourly UTC timestamps. Gaps are never invented: if the weather forecast or published prices don’t cover the horizon, the run stops with a CoverageError.
  4. Optimizes the heating schedule for the whole horizon with convex optimization.
  5. Actuates the current hour as a duty cycle: the optimizer’s fractional output for this interval (say 0.4) becomes ON for 0.4 × interval and OFF for the rest. Tiny on-times are rounded up to a 60-second minimum pulse so the relay is not chattered.
  6. Watches for a stuck plug: an independent watchdog forces the plug OFF if it has been continuously ON for more than 3 hours, no matter what the optimizer or controller believes.
  7. Logs the plan (seconds ON / OFF) and the final plug state.

Exit codes

  • 0 — the run completed.
  • 1 — an expected operational failure: bad configuration, data provider outage, insufficient data coverage, solver failure or device trouble. The reason is logged; no traceback is printed.
  • Anything else — an unexpected bug. The traceback is printed so it can be reported.

Scheduling runs

Strom acts on the current hour, so it works best when run regularly. The recommended cadence is once an hour, e.g. from cron:

0 * * * * cd /path/to/Strom && ./venv/bin/strom

Troubleshooting

Configuration errors

Error messages name the fix: the missing key and its file, the unknown house_config.json keys with the list of supported keys, or the exact spot where JSON parsing failed. See Configuration.

API connection issues

Transient problems (timeouts, connection errors, rate limits, server errors) are retried up to 3 times with exponential backoff. Permanent failures (bad key, malformed response) fail immediately. If retries are exhausted:

  1. Verify your API keys are correct
  2. Check your internet connection
  3. Ensure you haven’t exceeded API rate limits

Missing price data (CoverageError)

ENTSO-E publishes day-ahead prices once per day. If prices for part of your horizon are not published yet, Strom refuses to optimize against invented numbers and exits. Re-run later, when the day-ahead publication is out.

Smart plug connection issues

  1. Verify the plug is powered and on the same network (ping 192.168.1.42 should respond)
  2. Verify DEVICEIP, EMAIL and PASSWORD in tapologin.env
  3. Set --log-level DEBUG for details

The watchdog fired

A log line Max-on watchdog fired ... forcing plug OFF means the plug was ON continuously for more than 3 hours. Check your heating schedule and the house parameters — a heater that needs to run that long in one go usually means the heater is undersized for the comfort bounds.