Ein intelligentes Monitoring-System für Balkonkraftwerke. Es kombiniert Echtzeit-Daten via MQTT mit Wettervorhersagen von Open-Meteo, um mittels Machine Learning den Ertrag der nächsten Tage vorherzusagen.
- Echtzeit-Monitoring: Empfängt sekündliche Live-Werte (Leistung/Watt, Strom/Ampere, Spannung/Volt, Temperatur) des Wechselrichters via MQTT (OpenDTU/AhoyDTU).
- Energie-Statistiken & Live-Metriken: Präzise Errechnung der produzierten kWh mittels Trapez-Regel sowie automatische Berechnung der Ersparnis (EUR) und Spitzenwerte.
- ML-gestützter Forecast: Vorhersage des Ertrags (Best/Worst/Expected Case) basierend auf Bewölkung und Temperatur.
- Quantil-Regression: Nutzt GradientBoosting zur Berechnung eines 80%-Konfidenzintervalls für die erwartete Tagesproduktion.
- SHAP-Integration (Erklärbare KI): Das System zeigt im Tooltip genau an, warum eine bestimmte Vorhersage getroffen wurde (z. B. "Wolkenbedeckung senkt den Ertrag um X Watt").
- Interaktive Visualisierungen (Chart.js):
- Dynamisches Donut-Chart: Zeigt die DC-Leistung pro Panel. Durch Antippen/Hovern ändert sich die zentrale Anzeige.
- Hourly Heatmap: Visualisiert historische Erträge auf Stundenbasis für jeden Monat.
- Automatische Wetterdaten: Integriert die kostenlose Open-Meteo API für aktuelle Bewölkung und stündliche Prognosen.
- Leichtgewichtig, Lokal & Self-Healing: Kein Cloud-Zwang. Speicherung erfolgt in einer lokalen SQLite-Datenbank (
solar_data.db) mit automatischer Nachberechnung fehlender Tage (Self-Healing). Das Training des ML-Modells läuft automatisch im Hintergrund. - Staging-System: Vollautomatisches Deployment via GitHub Actions auf eine Live- (Port 5000) und Test-Umgebung (Port 5001).
- Backend: Python 3.11, Flask, Flask-MQTT
- Machine Learning: Scikit-Learn (RandomForest, GradientBoosting), SHAP, Pandas, Numpy
- Frontend: HTML5, CSS3 (CSS Variables für konsistentes Theming), Vanilla JavaScript (ES6)
- Charts & Icons: Chart.js (inkl. datalabels-Plugin), Phosphor Icons
- Datenbank: SQLite3
.
├── .github/workflows/
│ ├── deploy.yml # Live-Deployment (Main Branch)
│ └── deploy-staging.yml # Staging-Deployment (Dev Branch)
├── static/
│ ├── css/
│ │ └── styles.css
│ └── js/
│ └── script.js
├── templates/
│ └── index.html
├── app.py
├── requirements.txt
├── .env
├── .gitignore
└── README.md
git clone https://github.com/jacquesbach/balkonkraftwerk.git
cd balkonkraftwerkpython3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtErstelle eine .env Datei im Hauptverzeichnis:
ADMIN_PASS=dein_passwort
LATITUDE=49.xxxx
LONGITUDE=8.xxxx
MQTT_BROKER_URL=deine_ip
MQTT_BROKER_PORT=1883
MQTT_USERNAME=dein_user
MQTT_PASSWORD=dein_pwUm das System mit Live- und Staging-Umgebung dauerhaft zu betreiben, werden zwei separate Instanzen und Services auf dem Ubuntu-Server eingerichtet.
Klone das Projekt zweimal in unterschiedliche Ordner:
# Live-Instanz (Port 5000)
git clone [https://github.com/jacquesbach/balkonkraftwerk.git](https://github.com/jacquesbach/balkonkraftwerk.git) /home/ubuntu/balkonkraftwerk
# Staging-Instanz (Port 5001)
git clone -b dev [https://github.com/jacquesbach/balkonkraftwerk.git](https://github.com/jacquesbach/balkonkraftwerk.git) /home/ubuntu/balkonkraftwerk-stagingErstelle zwei Service-Dateien, um beide Instanzen unabhängig voneinander zu steuern.
Live-Service: sudo nano /etc/systemd/system/balkonkraftwerk.service
[Unit]
Description=Balkonkraftwerk Analytics - Live (Port 5000)
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/balkonkraftwerk
ExecStart=/home/ubuntu/balkonkraftwerk/venv/bin/python3 app.py
Restart=always
Environment="PORT=5000"
[Install]
WantedBy=multi-user.targetStaging-Service: sudo nano /etc/systemd/system/balkonkraftwerk-staging.service
[Unit]
Description=Balkonkraftwerk Analytics - Staging (Port 5001)
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/balkonkraftwerk-staging
ExecStart=/home/ubuntu/balkonkraftwerk-staging/venv/bin/python3 app.py
Restart=always
Environment="PORT=5001"
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
# Live starten
sudo systemctl enable --now balkonkraftwerk
# Staging starten
sudo systemctl enable --now balkonkraftwerk-stagingDamit das automatische Deployment funktioniert, müssen zwei Dinge konfiguriert sein:
Stelle sicher, dass die Zielverzeichnisse in deinen .github/workflows/*.yml Dateien exakt mit der Serverstruktur übereinstimmen:
- deploy-staging.yml: Zielpfad
/home/ubuntu/balkonkraftwerk-staging - deploy.yml: Zielpfad
/home/ubuntu/balkonkraftwerk
Hinterlege in deinem GitHub-Repository unter Settings > Secrets and variables > Actions folgende Secrets, damit die Action auf deinen Server zugreifen kann:
| Secret Name | Beschreibung |
|---|---|
SERVER_IP |
Die IP-Adresse deines Ubuntu-Servers |
SERVER_USER |
Dein Benutzername (z. B. ubuntu) |
SSH_PRIVATE_KEY |
Dein privater SSH-Schlüssel (für den passwortlosen Login) |
Das Projekt nutzt einen automatisierten Staging-Workflow via GitHub Actions:
- Entwicklung: Änderungen werden in den
devBranch gepusht. Die GitHub Action führt einen Deploy auf dem Server im Verzeichnis/home/ubuntu/balkonkraftwerk-stagingaus. - Vorschau: Änderungen sind sofort unter
http://deine-ip:5001sichtbar. - Production: Nach einem erfolgreichen Merge von
devin denmainBranch aktualisiert die Action das Live-Verzeichnis und startet den Dienstbalkonkraftwerk.serviceneu.
Staging-URL: http://deine-ip:5001
Live-URL: http://deine-ip:5000
Die App verwendet einen RandomForestRegressor für den Erwartungswert und zwei GradientBoostingRegressor, um ein Konfidenzintervall (Quantile Regression) zu berechnen.
- Input-Features: Sonnenstand, Tag des Jahres (Sin/Cos), Bewölkung, Temperatur, Rollierender Durchschnitt (7 Tage).
- Modell-Datei:
pv_model.pkl(wird nach jedem Tagesabschluss automatisch neu trainiert).
Pull Requests sind herzlich willkommen. Für größere Änderungen öffne bitte zuerst ein Issue, um zu diskutieren, was du ändern möchtest.
- Forke das Projekt
- Erstelle deinen Feature Branch (
git checkout -b feature/AmazingFeature) - Commit deine Änderungen (
git commit -m 'Add some AmazingFeature') - Push auf den Branch (
git push origin feature/AmazingFeature) - Öffne einen Pull Request