Intelligent water boiler controller optimizing photovoltaic (PV) auto-consumption with multi-stage resistance heating and weather forecasts.
Domestic hot water boilers represent one of the largest single electrical energy consumers in a typical household. Traditionally, boilers heat water overnight during fixed off-peak hours using 100% grid electricity.
With solar photovoltaic (PV) systems, homeowners frequently export excess electricity to the grid at low feed-in tariffs. Commercial continuous-modulation controllers (such as the Fronius Ohmpilot) are expensive and lack predictive awareness of future weather.
Wattpilot provides a lightweight, cost-effective, DIY solution. Instead of continuously modulating power via expensive thyristor electronics, it discretely switches multiple heating elements (typically 3 electrical resistances, e.g. 3 × 1,333 W) based on:
- Real-Time Solar Surplus: Exported power measured directly from Fronius inverters.
- Predictive Weather Forecasts: Upcoming cloud cover retrieved from OpenWeatherMap.
- Scheduled Off-Peak Windows: User-defined off-peak heating periods with midnight wrap-around.
- Target Temperatures & Hysteresis: Independent temperature setpoints for solar, scheduled, and forced modes.
-
⚡ Multi-Stage Load Switching: Dynamically steps through 1 to
$N$ heating elements according to instantaneous solar export, maximizing self-consumption without expensive variable-power hardware. - ☀️ Real-Time Solar Surplus Tracking: Directly queries the Fronius Solar API to detect surplus generation and adjust active boiler loads on the fly.
- 🌤️ Predictive Weather Forecasting: Periodically queries OpenWeatherMap for upcoming cloud cover. During the scheduled window, real-time solar surplus takes precedence; otherwise, if clear weather is forecast, grid heating is suppressed to reserve boiler capacity for solar auto-consumption. If heavy cloudiness is predicted (exceeding a configurable threshold), backup grid heating engages to ensure the target temperature is reached.
- ⏱️ Flexible Off-Peak Schedule: Configurable schedule window with full support for midnight wrap-around (e.g. 23:00 to 02:00) and an interactive 24-hour visual timeline.
- 🌡️ Granular Temperature Setpoints: Set distinct boiler target temperatures for solar surplus, scheduled off-peak, and manual force heating (45.0 °C to 65.0 °C in 0.5 °C steps) with automatic temperature hysteresis.
- 📱 Modern Reactive Dashboard: Sleek web interface built with NiceGUI, featuring live temperature gauges, heating element indicators, one-click mode switching, and bilingual localization (English & French).
- 📊 PVOutput Telemetry: Built-in support to stream temperature and power telemetry to PVOutput.
- 🐳 Docker & Raspberry Pi Native: Runs in Docker with simulated devices for local testing or directly on Raspberry Pi hardware using GPIO and 1-Wire DS18B20 sensors.
Wattpilot is built using the Pykka actor model for concurrent, non-blocking hardware control:
WattPilot: Core actor governing the boiler state machine (idle,solar,schedule,force,halt).Fronius: Inverter interface polling grid export metrics.OpenWeatherMap: Weather client fetching forecast cloudiness percentages.Temperature: Polling actor for 1-Wire DS18B20 temperature sensors.PVOutput: Telemetry actor transmitting live status to PVOutput.FrontendApp&BackendService: Decoupled, reactive NiceGUI application interfacing via actor proxies.
- Python 3.15+
uvpackage manager- (Optional) Docker and Docker Compose
Clone the repository and install dependencies:
git clone https://github.com/lostcontrol/wattpilot.git
cd wattpilot
uv syncLaunch Wattpilot in simulated device mode:
uv run python wattpilot.py --fake-devicesOpen http://localhost:8080 in your browser.
docker compose up -dAccess the dashboard at http://localhost (port 80).
docker compose -f docker-compose.development.yml upAccess the development interface at http://localhost:8088.
docker compose -f docker-compose.rpi.yml up -dMaps /dev/gpiochip0 for native GPIO pin control via rpi-lgpio.
Wattpilot uses a 3-tier cascading INI configuration system where later files override earlier ones:
config.ini: Base defaults tracked in git.config.ini.local: Local site configuration, hardware pins, API keys, and inverter IP addresses (gitignored).config.ini.settings: Runtime UI settings persisted by the web interface (highest priority). The file path can be customized via theWATTPILOT_SETTINGSenvironment variable.
Create a config.ini.local file to specify your hardware and credentials:
[main]
hysteresis_to_grid = 500
hysteresis_from_grid = 0
fronius_host = 192.168.1.50
cloudiness_level = 75
[temperature]
address = 28-0416350909ff
[openweathermap]
lat = 46.2044
lon = 6.1432
key = YOUR_OPENWEATHERMAP_API_KEY
[pvoutput]
key = YOUR_PVOUTPUT_API_KEY
sid = YOUR_PVOUTPUT_SYSTEM_ID
field = v12
[load_1]
power = 1333
pin = 26
[load_2]
power = 1333
pin = 20
[load_3]
power = 1333
pin = 21The web interface is decoupled under the frontend/ directory and delivers an intuitive, mobile-optimized experience:
- Dashboard:
- Live system state badge (
En attente / Idle,Solaire / Solar,Programmé / Schedule,Forcer / Force). - Circular water temperature gauge with live readings.
- Multi-stage heating element status indicators.
- Upcoming weather forecast preview with cloud cover percentage and schedule decision badge.
- One-click trigger for the upcoming off-peak scheduled period.
- Fast mode switcher (Attente, Forcer, Arrêter).
- Live system state badge (
- Control Page:
- Adjust target temperatures for solar surplus, scheduled heating, and force mode (45.0 °C to 65.0 °C in 0.5 °C steps).
- Set off-peak schedule start and stop hours with immediate 24-hour visual period rendering.
- Settings are validated and written directly to the persistent settings file.
- Internationalization:
- Full English and French support (
frontend/locales/en.jsonandfrontend/locales/fr.json). - Automatic language detection with preference stored in client-side cookies (
wattpilot_lang).
- Full English and French support (
Execute the unit and integration test suite:
uv run pytest -v -s --cov=wattpilot --cov-report term test/Run all pre-commit hooks:
uv run pre-commit run --all-filesOr run tools individually:
uv run ruff check --fix .
uv run ruff format .
uv run ty checkThis project is licensed under the terms of the GNU General Public License v2 (GPL-2.0).
