
Vor einem Fenster des Davinci-Labors befinden sich zwei Balkonkraftwerke mit jeweils zwei Paneelen. Die Leistungsdaten werden über ein OpenDTU ausgelesen und in Home Assistant gespeichert.
Fläche: 175cm x 110cm (pro Panel, 2 Panels)
Neigungswinkel: 35°
Fläche: 175cm x 110cm (pro Panel, 2 Panels)
Neigungswinkel: 25°
Für die Analyse wurde ein Datensatz aus Home Assistant im Zeitraum vom 03.08.2025 bis zum 04.05.2026 exportiert. Die Rohdaten findest du hier
Die Rohdaten enthalten stündliche Messwerte des Energieertrags. Für die Auswertung wurde jeweils der tägliche Maximalwert pro Anlage betrachtet.
| Monat | West | Ost |
| 2025-09 | 58243 Wh | 56918 Wh |
| 2025-10 | 38738 Wh | 35950 Wh |
| 2025-11 | 20736 Wh | 19478 Wh |
| 2025-12 | 13324 Wh | 12547 Wh |
| 2026-01 | 23961 Wh | 23061 Wh |
| 2026-02 | 30680 Wh | 28104 Wh |
| 2026-03 | 33132 Wh | 30931 Wh |
| 2026-04 | 108700 Wh | 100490 Wh |
| 2026-ß5 | 18864 Wh | 18104 Wh |
Im betrachteten Zeitraum ergibt sich:
Damit ist das westliche Balkonkraftwerk insgesamt etwa 6,4 % effizienter als das östliche.
Auch in der grafischen Auswertung zeigt sich, dass der tägliche Ertrag des Westlichen Systems in den meisten Fällen über dem des Östlichen liegt.

Die Ergebnisse sollten mit Vorsicht interpretiert werden, da mehrere Einflussfaktoren bestehen:
Photovoltaik-Module verlieren im Laufe der Zeit an Effizienz. Typische Werte (insbesondere bei günstigeren Modulen): (Quelle)
Da die Östliche Paneele etwa 1,5 Jahre älter sind, ergibt sich ein geschätzter Effizienzverlust von etwa:
Berücksichtigt man diesen Alterungseffekt, reduziert sich der reale Effizienzunterschied auf etwa 3,5 % zugunsten des Westlichen Kraftwerks.
Das folgende Python-Skript wurde zur Auswertung der Daten verwendet:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime
import seaborn as sns
# Set style
sns.set_style("whitegrid")
plt.rcParams["figure.figsize"] = (14, 8)
# Einlesen der CSV-Datei
df = pd.read_csv("history.csv")
# Konvertiere Datentypen
df["last_changed"] = pd.to_datetime(df["last_changed"])
df["state"] = pd.to_numeric(df["state"], errors="coerce") # Konvertiere zu numerisch
# Entferne Zeilen mit NaN in state
df = df.dropna(subset=["state"])
# Extrahiere das Datum (ohne Zeit)
df["date"] = df["last_changed"].dt.date
print("=" * 80)
print("BALKONKRAFTWERK EFFIZIENZ ANALYSE")
print("=" * 80)
print(f"\nDateibereich: {df['last_changed'].min()} bis {df['last_changed'].max()}")
print(f"\nVerfügbare Sensoren:")
print(df["entity_id"].unique())
# Gruppiere nach Sensor und extrahiere das Maximum pro Tag
max_per_day = df.groupby(["entity_id", "date"])["state"].max().reset_index()
max_per_day.columns = ["entity_id", "date", "max_yield"]
max_per_day["date"] = pd.to_datetime(max_per_day["date"])
print("\n" + "=" * 80)
print("TÄGLICHE MAXIMALE ERTRÄGE PRO PANEL")
print("=" * 80)
for sensor in df["entity_id"].unique():
sensor_data = max_per_day[max_per_day["entity_id"] == sensor]
total_yield = sensor_data["max_yield"].sum()
avg_yield = sensor_data["max_yield"].mean()
max_yield = sensor_data["max_yield"].max()
min_yield = sensor_data["max_yield"].min()
std_yield = sensor_data["max_yield"].std()
count_days = len(sensor_data)
print(f"\nSensor: {sensor}")
print(f" Anzahl Tage: {count_days}")
print(f" Gesamtertrag: {total_yield:.0f} Wh")
print(f" Durchschnitt/Tag: {avg_yield:.1f} Wh")
print(f" Maximum/Tag: {max_yield:.0f} Wh")
print(f" Minimum/Tag: {min_yield:.0f} Wh")
print(f" Std. Abweichung: {std_yield:.1f} Wh")
# Erstelle eine Pivot-Tabelle für Vergleich
pivot_data = max_per_day.pivot(index="date", columns="entity_id", values="max_yield")
# Berechne Statistiken für Vergleich
print("\n" + "=" * 80)
print("VERGLEICH DER PANEL-EFFIZIENZ")
print("=" * 80)
for col in pivot_data.columns:
total = pivot_data[col].sum()
avg = pivot_data[col].mean()
print(f"\n{col}:")
print(f" Gesamt: {total:.0f} Wh")
print(f" Mittel: {avg:.1f} Wh/Tag")
# Berechne relative Effizienz
if len(pivot_data.columns) == 2:
col1, col2 = pivot_data.columns[0], pivot_data.columns[1]
total1 = pivot_data[col1].sum()
total2 = pivot_data[col2].sum()
if total1 > total2:
efficiency_diff = ((total1 - total2) / total2) * 100
more_efficient = col1
else:
efficiency_diff = ((total2 - total1) / total1) * 100
more_efficient = col2
print(f"\n{'=' * 80}")
print(f"ERGEBNIS: {more_efficient} ist {efficiency_diff:.1f}% effizienter!")
print(f"{'=' * 80}")
# Erstelle Visualisierungen
fig, axes = plt.subplots(2, 1, figsize=(16, 12))
# Plot 1: Zeitreihe der täglichen Maxima
ax = axes[0]
for sensor in pivot_data.columns:
ax.plot(
pivot_data.index,
pivot_data[sensor],
marker="o",
label=sensor,
linewidth=2,
markersize=4,
)
ax.set_xlabel("Datum", fontsize=12)
ax.set_ylabel("Täglicher Ertrag (Wh)", fontsize=12)
ax.set_title("Tägliche Maximale Erträge pro Panel", fontsize=14, fontweight="bold")
ax.legend(fontsize=11)
ax.grid(True, alpha=0.3)
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
ax.xaxis.set_major_locator(mdates.MonthLocator())
plt.setp(ax.xaxis.get_majorticklabels(), rotation=45)
# Plot 2: Kumulativer Ertrag
ax = axes[1]
for sensor in pivot_data.columns:
cumsum = pivot_data[sensor].fillna(0).cumsum()
ax.plot(cumsum.index, cumsum, marker="o", label=sensor, linewidth=2, markersize=4)
ax.set_xlabel("Datum", fontsize=12)
ax.set_ylabel("Kumulativer Ertrag (Wh)", fontsize=12)
ax.set_title("Kumulativer Gesamtertrag pro Panel", fontsize=14, fontweight="bold")
ax.legend(fontsize=11)
ax.grid(True, alpha=0.3)
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
ax.xaxis.set_major_locator(mdates.MonthLocator())
plt.setp(ax.xaxis.get_majorticklabels(), rotation=45)
plt.tight_layout()
plt.savefig("balkonkraftwerk_analyse.png", dpi=600, bbox_inches="tight")
print(f"\n✓ Grafik gespeichert: balkonkraftwerk_analyse.png")
# Erstelle noch eine Monatsanalyse
print("\n" + "=" * 80)
print("ANALYSE NACH MONATEN")
print("=" * 80)
max_per_day["month"] = max_per_day["date"].dt.to_period("M")
monthly_data = (
max_per_day.groupby(["entity_id", "month"])["max_yield"].sum().reset_index()
)
for sensor in df["entity_id"].unique():
sensor_monthly = monthly_data[monthly_data["entity_id"] == sensor]
print(f"\n{sensor}:")
for _, row in sensor_monthly.iterrows():
print(f" {row['month']}: {row['max_yield']:.0f} Wh")
print("\n" + "=" * 80)
print("Analyse abgeschlossen!")
print("=" * 80)