Een zelfbouw energiemanagementsysteem voor een Raspberry Pi, dat warmtepomp-, laadpaal- en PV-sturing combineert met dynamische energieprijzen (day-ahead).
- Leest de slimme meter uit (DSMR/P1) en berekent netto verbruik/levering.
- Haalt dagelijks de day-ahead stroomprijzen op (via Enever.nl) en rangschikt de uren van goedkoop naar duur.
- Berekent op basis van een graaddagen-model hoeveel uur de warmtepomp nodig heeft, en bepaalt welke uren daarvoor het goedkoopst zijn.
- Stuurt warmtepomp-, laadpaal- en PV-omvormer-setpoints bij op basis van actuele PV-overschot en het prijsniveau van het huidige uur.
- Toont de energiestromen visueel in een webdashboard (Flask + SVG).
Dit is de kernlogica (prijsberekening, sturing, dataopslag) - niet de daadwerkelijke hardware-aansturing. Zie Scope hieronder.
De pijlen en waardes verversen elke 5 seconden, gebaseerd op energy.json.
Alle communicatie tussen de losse Python-processen loopt via drie gedeelde
JSON-bestanden (share/), met file-locking en atomic writes
(shared_store.py):
reader_data.json- geschreven door reader-scripts (metingen), gelezen doorE_manager.py.setpoints.json- geschreven doorE_manager.py(berekende setpoints), gelezen door actuator-scripts.energy.json- gevoed door meerdere processen, uitsluitend voor het webdashboard.
Zie DATA_CONTRACT.md voor het volledige overzicht:
welke key waar naartoe geschreven wordt, en door wie.
Deze repository bevat de kernlogica en is hardware-onafhankelijk:
| Onderdeel | Wat het doet |
|---|---|
E_manager.py |
Prijssturing, WP/LP/PV-setpoint-berekening, database-logging |
p1_reader.py |
DSMR/P1 slimme-meter-uitlezing |
Enever_tarieven.py |
Ophalen day-ahead prijzen |
energietarieven.py |
Prijsverwerking, graaddagen/WP-uren-berekening, weersverwachting |
webapp/ |
Flask-dashboard (energiestromen-visualisatie) |
simulate_readers.py |
Dummy-script om het systeem te testen zonder eigen hardware |
Niet meegenomen: de daadwerkelijke aansturing van warmtepomp, laadpaal
en PV-omvormer (WP_reader.py, LP_reader.py, PV_reader.py). Die zijn
specifiek voor mijn eigen apparaten (Vaillant-warmtepomp via EBUS, Alfen
Eve-laadpaal via een combinatie van Modbus TCP en OCPP, Fronius-omvormer
via Modbus/SunSpec) en horen niet in een generiek publiceerbaar project
thuis. DATA_CONTRACT.md beschrijft precies welke keys zo'n script zou
moeten lezen/schrijven om zelf een vergelijkbare integratie te bouwen.
- Python 3.11
- Packages:
python-dotenv,requests,APScheduler,Flask,Flask-Cors,pyserial python3-systemd(viaapt install python3-systemd, niet via pip - vereist libsystemd-dev)- Een Enever.nl API-token (day-ahead prijzen)
- Een weerlive.nl API-token (temperatuur/graaddagen-berekening)
git clone https://github.com/Pyroil/E_manager.git
cd E_manager
pip install python-dotenv requests apscheduler flask flask-cors pyserial --break-system-packages
sudo apt install python3-systemd
mkdir -p share logs
cp .env.example .env
# vul .env in met je eigen Enever_token en Weerlive_token
python3 -c "
import sqlite3
db = sqlite3.connect('E_manager.db')
with open('schema.sql') as f:
db.executescript(f.read())
db.commit()
"Pas config.py aan naar jouw situatie: P1_SERIAL_PORT (check met
ls /dev/serial/by-id/), WP_MAX_SETPOINT, LP_MIN_AMP, en de overige
drempelwaardes naar wat voor jouw installatie logisch is.
simulate_readers.py simuleert alle externe reader-scripts (warmtepomp,
laadpaal, PV-omvormer) met plausibele testwaarden, zodat je E_manager.py
en het dashboard kunt testen zonder de daadwerkelijke apparaten. p1_reader.py
kun je met of zonder echte P1-hardware laten meedraaien (zie de opmerking
hieronder over SIMULATE_P1_READER in simulate_readers.py).
1. Test eerst in de voorgrond, één proces per terminal (of tmux/screen- venster), zodat je meteen fouten ziet:
python3 simulate_readers.pypython3 p1_reader.pypython3 E_manager.pycd webapp && python3 app.pyDashboard bereikbaar op http://<ip>:5001/. De front-end (E_manager.js)
verwacht standaard de route /E_manager/ (zonder prefix) - draai je achter
een reverse proxy met een andere prefix, pas dan API_URL bovenin dat
bestand aan.
2. Als alles goed draait, naar de achtergrond:
nohup python3 simulate_readers.py > /tmp/simulate.log 2>&1 &
nohup python3 p1_reader.py > /tmp/p1.log 2>&1 &
nohup python3 E_manager.py > /tmp/emanager.log 2>&1 &
cd webapp && nohup python3 app.py > /tmp/webapp.log 2>&1 &3. Verificatie:
tail -f logs/system.log
cat share/reader_data.json
cat share/setpoints.json
cat share/energy.jsonZet simulate_readers.py uit (pkill -f simulate_readers.py) zodra je
eigen reader-scripts (of een echte p1_reader.py) draaien - anders
overschrijven ze elkaars data op dezelfde keys. Als je p1_reader.py wél
met echte hardware laat draaien naast simulate_readers.py, zet dan
SIMULATE_P1_READER = False bovenin simulate_readers.py, zodat de
simulatie niet de echte meterstand overschrijft.
Het dashboard toont naast de actuele stromen ook een uur- en 24-uurs-
overzicht (verbruik, levering, kosten). Deze cijfers komen uit
E_manager.py's store_hourly_snapshot(), die vergelijkt met eerder
opgeslagen meterstanden in HourlyMeter (de database). Dat betekent:
- De 1-uurs cijfers verschijnen pas nadat er minstens 1 uur aan
echte meterdata is opgebouwd (dus na het eerste volledige uur draaien
met een echte
p1_reader.py). - De 24-uurs cijfers verschijnen pas na een volledige dag.
- Met alleen
simulate_readers.py(zonder echte P1-hardware) verschijnen deze cijfers nooit, omdat de gesimuleerde data niet inHourlyMeterterechtkomt - dat vereist echte DSMR-telegrammen viap1_reader.py.
Tot die tijd toont het dashboard hier 0.00 (geen foutmelding of NaN) -
dat is verwacht gedrag, geen bug.
De hardware-integratiescripts (niet in deze repo, zie Scope) zijn gebouwd op:
- Laadpaal (Alfen Eve): leesstatus/instellingen via Modbus TCP met alfen_eve_modbus_tcp; het daadwerkelijke laadvermogen (amps) wordt ingesteld via een eigen lokale OCPP-server, gebouwd met de ocpp- library van Mobility House (OCPP 1.6) - dit vereist specifieke instellingen in de ACE-installer van de laadpaal om externe/smart- charging-sturing via OCPP mogelijk te maken.
- Warmtepomp (Vaillant, EBUS): ebusd-configuration - de message-definities (msgdefs) voor het uitlezen/aansturen van de Vaillant-warmtepomp via EBUS komen hiervandaan.
- PV-omvormer (Fronius, Modbus/SunSpec):
modpoll, een opdrachtregel-tool voor Modbus-communicatie.
Dit project is gelicenseerd onder CC BY-NC-SA 4.0 - vrij te gebruiken en te delen, aanpassingen toegestaan, maar niet voor commerciële doeleinden en met behoud van dezelfde licentie voor afgeleide werken. Zie LICENSE voor de volledige tekst.

