Onderdeel van het E_manager-ecosysteem - dit is het hardware-specifieke laadpaal-onderdeel (Alfen Eve), losstaand van de generieke
E_manager-kernlogica. Zie Integratie met E_manager hieronder voor hoe de twee samenwerken.
Sturing en monitoring van een Alfen Eve-laadpaal via Modbus TCP (uitlezen) en OCPP 1.6 (aansturen).
- Leest de laadpaal continu uit via Modbus TCP (status, geleverd vermogen, sessie-energie).
- Stelt de laadstroom in via OCPP 1.6 (SetChargingProfile) - dit kan niet via Modbus alleen, zie Waarom twee protocollen?.
- Registreert start/stop van laadsessies naar CSV.
- Past de laadstroom dynamisch aan op basis van een extern bepaalde
setpoint (
LPnew, normaal gesproken geschreven doorE_manager) en een dag/nacht-onderscheid.
De Alfen Eve ondersteunt smart-charging (het daadwerkelijk begrenzen van
de laadstroom per sessie) alleen via een OCPP-SetChargingProfile-
bericht van een centraal systeem (CSMS) - dat kan niet via de Modbus
TCP/IP EMS-interface. Modbus TCP wordt in dit project daarom alleen
gebruikt om te lezen (status, energie, vermogen) en voor de
laagdrempelige modbus_slave_max_current-begrenzing; het daadwerkelijk
instellen van de gewenste laadstroom loopt via een eigen, lokale
OCPP-server (ocpp_server.py), die Alfen_manager.py via een REST-
aanroep (POST /set_current?amps=...) aanstuurt.
| Component | Rol |
|---|---|
Alfen_manager.py |
Hoofdproces: 3 threads (changeAmp, readLP, check_laadpaal) + scheduler |
ocpp_server.py |
OCPP 1.6 websocket-server (poort 9000) + REST-API (poort 9001) waarmee Alfen_manager.py de laadstroom instelt |
laadpaal.py |
Helper die alle Modbus-registers dumpt naar lp_values.json |
shared_store.py |
Gedeelde, file-locked JSON-opslag (atomic writes) |
Alfen_manager.py's threads:
changeAmp()(elke 60s): leest laadstatus via Modbus, bepaalt de nieuwe laadstroom (dag/nacht-logica + externe setpoint), stuurt die via de lokale OCPP-server aan, registreert sessie-start/stop.readLP()(elke 2s, alleen tijdens een actieve sessie): leest het actuele laadvermogen.check_laadpaal()(elk kwartier, via scheduler): dumpt alle Modbus-registers naarlp_values.json(vialaadpaal.py).
Beide car_charger-gebruikende threads delen een threading.Lock() om
gelijktijdige Modbus-toegang (en de daaruit voortvloeiende race-
condition-crashes) te voorkomen.
- Python 3.11
- Packages: zie
requirements.txt(alfen-eve-modbus-tcpenapschedulervoorAlfen_manager.py/laadpaal.py;websockets,ocppenaiohttpvoorocpp_server.py) python3-systemd(viaapt install python3-systemd, niet via pip - vereist libsystemd-dev)- Een Alfen Eve-laadpaal met Modbus TCP EMS en OCPP 1.6 geactiveerd (zie hieronder)
Download de ACE Service Installer via Alfen's kennisbank en configureer het volgende op de laadpaal:
Load balancing → TCP/IP EMS
- Mode: Socket
- ValidityTime: 120s
Connectivity → Network Profile 1
- Connect method: Wired (Ethernet)
- Protocol: OCPP 1.6
- CSMS URL:
ws://<ip-van-je-server>:9000/ocpp(poort 9000 =ocpp_server.py's websocket-poort) - Security Profile: 0: Default
- Websocket timeout: 10s
Connectivity → Meter value
- Meter value sample interval: 900s
- Clock aligned data interval: 900s
- Sampled data:
Energy.Active.Import.Register,Power.Active.Import,Current.Import,Energy.Active.Export.Register(naar wens aan te vullen/wijzigen)
Load balancing → SCN
- Total current / Socket Safe Current / Total Safe Current: naar jouw eigen aansluitwaarde (bijv. 16A)
- Alternating period: 900s
- Phase mapping: L1L2L3
Na het opslaan: Save → Exit, en herstart de laadpaal indien gevraagd.
git clone <deze-repo>
cd Alfen_manager
pip install -r requirements.txt --break-system-packages
sudo apt install python3-systemd
mkdir -p share logsPas config.py aan naar jouw situatie: URL_LAADPAAL, MIN_AMP,
MAX_AMP, en de paden naar reader_data.json/setpoints.json (zie
Integratie met E_manager). Geen secrets
nodig - dit bestand bevat geen wachtwoorden of tokens.
Beide processen zijn bedoeld om als systemd-service te draaien. Twee voorbeeld-unit-files:
/etc/systemd/system/alfen-manager.service
[Unit]
Description=Alfen laadpaal manager
After=network.target
[Service]
Type=notify
ExecStart=/home/pi/Programs/.venv/bin/python3.11 /pad/naar/Alfen_manager.py
WorkingDirectory=/pad/naar/Alfen_manager
Restart=on-failure
WatchdogSec=30
User=pi
[Install]
WantedBy=multi-user.target/etc/systemd/system/alfen-ocpp.service
[Unit]
Description=Alfen OCPP-server
After=network.target
[Service]
Type=notify
ExecStart=/home/pi/Programs/.venv/bin/python3.11 /pad/naar/ocpp_server.py
WorkingDirectory=/pad/naar/Alfen_manager
Restart=on-failure
WatchdogSec=30
User=pi
[Install]
WantedBy=multi-user.targetBeide services melden zich correct bij systemd (READY=1 zodra de
websocket- en REST-server actief zijn, periodieke WATCHDOG=1 daarna),
dus Type=notify + WatchdogSec zijn voor beide veilig te gebruiken -
systemd herstart het proces automatisch als de watchdog een keer wordt
gemist.
Activeren:
sudo systemctl daemon-reload
sudo systemctl enable --now alfen-ocpp.service
sudo systemctl enable --now alfen-manager.service(Start bewust eerst de OCPP-server, dan pas de manager - die laatste
verwacht de eerste al te draaien voor zijn set_current-aanroepen.)
Dit project wisselt data uit via dezelfde reader_data.json/
setpoints.json-conventie als E_manager (zie diens
DATA_CONTRACT.md):
| Bestand | Key | Richting |
|---|---|---|
reader_data.json |
LP_reader (laadpower, status, maxcurrent, LPsetpoint) |
Geschreven door Alfen_manager.py |
reader_data.json |
laadsessie (laden, start) |
Geschreven door Alfen_manager.py |
setpoints.json |
LPnew (setpoint) |
Gelezen door Alfen_manager.py, geschreven door E_manager |
Zorg dat READER_DATA_JSON/SETPOINTS_JSON in config.py naar
dezelfde bestanden wijzen als E_manager's eigen config.py.
- Modbus TCP: alfen_eve_modbus_tcp
- OCPP 1.6: ocpp-library van Mobility House
Zie LICENSE.