Skip to content

Repository files navigation

E_manager

Een zelfbouw energiemanagementsysteem voor een Raspberry Pi, dat warmtepomp-, laadpaal- en PV-sturing combineert met dynamische energieprijzen (day-ahead).

Wat doet dit systeem

  • 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.

Dashboard

Energiedashboard

De pijlen en waardes verversen elke 5 seconden, gebaseerd op energy.json.

Architectuur

Architectuurschema van E_manager

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 door E_manager.py.
  • setpoints.json - geschreven door E_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.

Scope

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.

Vereisten

  • Python 3.11
  • Packages: python-dotenv, requests, APScheduler, Flask, Flask-Cors, pyserial
  • python3-systemd (via apt 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)

Installatie

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.

Opstarten en testen

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.py
python3 p1_reader.py
python3 E_manager.py
cd webapp && python3 app.py

Dashboard 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.json

Zet 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.

Let op: uur- en dagcijfers verschijnen pas na verloop van tijd

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 in HourlyMeter terechtkomt - dat vereist echte DSMR-telegrammen via p1_reader.py.

Tot die tijd toont het dashboard hier 0.00 (geen foutmelding of NaN) - dat is verwacht gedrag, geen bug.

Credits / gebruikte externe bibliotheken

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.

Licentie

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.

Releases

Packages

Contributors

Languages