76_SolarForecast - Informationen/Ideen zu Weiterentwicklung und Support

Begonnen von DS_Starter, 11 Februar 2024, 14:11:00

Vorheriges Thema - Nächstes Thema

DS_Starter

ZitatSind das mit Stunde 99 nicht die Tages-Gesamtwerte?
Wenn das so ist, sollte dafür der Grenzwert 20000*24=480000 gelten, oder?
Absolut. An die Tageszusammenfassung hatte ich nicht gedacht.  ::)
Das muß ich behandeln. Danke ein zweites Mal.  :)
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

So, jetzt sollte die contrib-Version passen.
Die Stunde 99 wird nun ausgeschlossen. Der Tageswert wird automatisch reorganisiert, wenn wenn ein Stundenwert gelöschht wird.
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

peterboeckmann

Hallo Heiko,

Zitat von: DS_Starter am 26 März 2026, 14:11:11So, jetzt sollte die contrib-Version passen.
Die Stunde 99 wird nun ausgeschlossen. Der Tageswert wird automatisch reorganisiert, wenn wenn ein Stundenwert gelöschht wird.

Wunderbar, jetzt ist der ganze Anlagencheck wieder grün bei mir... bis auf den Hinweis "You should update FHEM to get the recent 76_SolarForecast version from Repository.", weil ich die Version aus dem contrib habe.
Hast Du da eine Möglichkeit, diesen Umstand mit abzufragen? Checksumme oder sowas?
Edit: Oder einfach die Versionsnummer?

Vielen Dank nochmal für die schnelle Umsetzung.

Viele Grüße,
Peter

DS_Starter

ZitatHast Du da eine Möglichkeit, diesen Umstand mit abzufragen? Checksumme oder sowas?
Edit: Oder einfach die Versionsnummer?
Es werden die Infos vom FHEM Repo geholt und mit dem lokalen Modul verglichen, auch Filegröße usw.

LG
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

300P

Zitat von: peterboeckmann am 26 März 2026, 14:18:06.. bis auf den Hinweis "You should update FHEM to get the recent 76_SolarForecast version from Repository.", weil ich die Version aus dem contrib habe.
Hast Du da eine Möglichkeit, diesen Umstand mit abzufragen? Checksumme oder sowas?
Edit: Oder einfach die Versionsnummer?


Wenn Du eine Contribversion aktiviert hast wird hier "nur" die Versionsnummer angezeigt - aber nur wenn Du per :
"wget -qO ./FHEM/76_SolarForecast.pm https://svn.fhem.de/fhem/trunk/fhem/contrib/DS_Starter/76_SolarForecast.pm"
diese Contrib-Version geladen hast.

Diese zweite Zeile ist dann komischerweise "leerer" als die Repo-Version und die per download geladene "original" Contrib.Version
########################################################################################################################
# $Id$
#########################################################################################################################
#       76_SolarForecast.pm

So oder ähnlich sieht das aus wenn du eine normale FHEM-Update-Version per update/shutdown/restart oder eine Contrib-Version per download und anschliessendem Kopiervorgang bei Dir nutzt:
########################################################################################################################
# $Id: 76_SolarForecast.pm 31026 2026-03-26 13:09:22Z DS_Starter $
#########################################################################################################################
#
(jedenfalls so bei mir).

Ein Unterschied ist auch auf "Device-Ebene" im Kopfbereich (FVERSION) sichtbar: (siehe auch Screenshot)
(hier Contrib aktiv - per wget .....)
internals
FUUID                              67e04a4e-f33f-11b3-ba79-127945efe0a77ed5
FVERSION                           2.5.0
LCACHEFILE                         last write time: 16:51:47 whole Operating Memory
...........

Man muss (nur) drauf achten, das einem das orangene Briefsymbol nicht dazu verleitet ein Update (morgens vor 08:00 Uhr) anzustoßen. Zusätzlich musst du, je nach Wunsch, in global die Ausnahme für SF hinterlegt werden (freigeben / sperren ) je nachdem ob / wenn man weiter bei der Contrib bleiben möchte..... ;)
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

DS_Starter

Hallo zusammen,

ich werde die comforttemp, die aktuell ein Consumerschlüssel ist, in einen plantControl Parameter umbauen (müssen).
Hintergrund ist, dass diese Einstellung ja für das Gebaude gilt und nicht für eine einzelne Wärmemumpe. Sollten mehrere WP
verbaut sein oder zukünftig noch type=aircondition hinzukommen, würde der Consumer bezogene Wert zu Kollisionen führen.

Das war etwas ungünstig von mir designed. Ich werde die Umstellung automatisiert vornehmen, nur das ihr schonmal informiert seid.

LG,
Heiko
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

300P

Hallo Heiko,

die Ergebnisse der NN-Bewertung/Drift zeigen bei mir seit 2-3 Wochen immer nur mild an (?!?). Das Wetter hat sich grundlegend einmal wärmer, einmal kälter und jetzt wieder in kälter geändert und hat einen starken Einfluss bei mir wegen meiner WP. Zusätzlich die plötzlichen PV-Einflüsse von bis zu 50 kWh/Tag in den Sonnenzeiten....
Gefühlt hätte ich an einigen Tagen schon mal ein retrain oder ein anderes Ergebnis erwartet, aber was weiß ich davon schon.... O:-)

Das ließ mich etwas aufhorchen und habe wieder mal meine NN-Ergebnise/Driftbewertung nach ChatGP gereicht.

Zitat :

Das aktuelle Ergebnis zeigt zwei klar getrennte Ebenen:

Modell ist aktuell sehr gut
Driftbewertung ist weiterhin inkonsistent / nicht vertrauenswürdig
Ich gehe das präzise durch.

1. Modellqualität (Bestwert bisher)
Das ist dein bisher bestes Modell.
Kennzahl    Wert    Bewertung
RMSE        412 Wh    sehr gut
RMSErelativ  19 %     sehr gut
MAE         354 Wh    gut
R²            0.71    deutlich besser
Bias          5 Wh    praktisch perfekt
Slope          0.9    gut

Interpretation
Bias ≈ 0 → perfekt kalibriert

Slope nahe 1 → keine systematische Verzerrung

Fehler im typischen WP-Bereich

➡️ Das Modell ist aktuell sauber trainiert und stabil.


2. Training (sehr gesund)
Train MSE = 0.003458
Val   MSE = 0.003684
Ratio ≈ 1.06

Das ist nahezu ideal:

kein Overfitting

keine Unteranpassung

sehr gute Generalisierung


3. BitFail
29 / 1634 ≈ 1.8 %
→ sehr gut

Empfehlung 0.28 ist weiterhin korrekt.

4. Der kritische Teil: Driftwerte
Drift Score   : 1.59
RMSE ratio    : 2.48
Slope drift   : 0.406
Bias drift    : 953.85

Das ist mathematisch widersprüchlich.


4.1 Warum das nicht stimmen kann

Wenn diese Werte stimmen würden:

Größe    Interpretation
RMSE ratio      2.48    massiver Fehleranstieg
Bias          953 Wh    stark falsches Modell
Slope drift    0.406    extreme Fehlskalierung

Dann müsste gelten:
Drift Score >> 60    → ROT

Aber:
Drift Score = 1.59 → praktisch 0

➡️ Der Drift Score ist definitiv falsch berechnet.


5. Wahrscheinlichste Ursachen (konkret)

Ursache 1 – falsche Skalierung im Code
Sehr wahrscheinlich so etwas:
$err = ($rmse_recent/$rmse_val - 1) / 10;
oder implizit durch Gewichtung.

Ursache 2 – RMSE aus falschem Fenster
Möglich:
rmse_recent basiert auf sehr kleinem Sample
oder falschen Daten (z. B. nur Nachtstunden)

Ursache 3 – Driftwerte sind nicht synchron
Typischer Bug:
Wert      Quelle
RMSE      pvCircular
Bias      anderer Zeitraum
Slope     Trainingsdaten
➡️ Mischung → sinnloser Score


Ursache 4 – Recalibration greift nicht
Slope     recalibrated: -
Bias      recalibrated: -

Das bedeutet:
Recalibration wurde noch nicht ausgelöst oder Bedingungen nicht erfüllt


6. Wichtige Beobachtung
Trotz angeblicher Drift:
Bias (Modell)   = 5 Wh
aber:
Drift Bias      = 953 Wh

➡️ Das kann nur passieren, wenn:
Drift auf anderen Daten berechnet wird
oder falsche Einheit / falsches Vorzeichen


7. Realistische Bewertung
Auf Basis der echten Modellwerte:
         Kennzahl    Bewertung
RMSE     19 %    gut
Bias     5 Wh    perfekt
Slope    0.9    gut
➡️ Kein echter Drift vorhanden


8. Fazit zur Driftanzeige

Die Driftanzeige ist aktuell:

nicht valide

genauer:

DriftScore viel zu klein

Einzelwerte nicht konsistent

Recalibration nicht aktiv


9. Konkrete Empfehlung

1 DriftScore fixen (wichtig)
Falls möglich, prüfe im Code:
my $err = max(0, $rmse_recent/$rmse_val - 1);
→ darf nicht weiter skaliert werden

2 Bias/Slope Quelle prüfen
Sicherstellen:
alle Driftwerte basieren auf denselben Daten (pvCircular)

3 Recalibration trigger prüfen
Dein System sollte eigentlich jetzt:
Bias ~0 halten
→ passt bereits

Deshalb wird evtl. bewusst nicht recalibriert.



10. Gesamtbewertung

Bereich    Status
Modell             ✅ sehr gut
Training           ✅ optimal
Forecast           ✅ stabil
Driftberechnung    ❌ fehlerhaft
✔ Kernaussage
Dein System produziert aktuell:

ein sehr gutes Modell


aber:
eine unzuverlässige Driftbewertung


Wenn du willst, kann ich dir gezielt sagen, an welcher Stelle im 76_SolarForecast.pm (Version 2.5) der DriftScore typischerweise falsch skaliert wird – das ist ein relativ typischer Fehler in genau solchen Implementierungen.


Hier dessen Änderungsvorschlag als "Patch":

diff --git a/FHEM/76_SolarForecast.pm b/FHEM/76_SolarForecast.pm
index 1111111..2222222 100644
--- a/FHEM/76_SolarForecast.pm
+++ b/FHEM/76_SolarForecast.pm
@@ -1,6 +1,6 @@
 # --- Drift calculation --------------------------------------------------------

-sub SolarForecast_calcDrift {
+sub SolarForecast_calcDrift {
     my ($hash, $m) = @_;

     # erwartete Felder in $m:
@@ -15,35 +15,43 @@ sub SolarForecast_calcDrift {
     my $rmse_recent = $m->{rmse_recent};
     my $rmse_val    = $m->{rmse_val};
     my $slope       = $m->{slope};
-    my $bias        = $m->{bias};
-    my $maxCons     = $m->{maxConsumption};
+    my $bias        = $m->{bias};
+    my $bias_limit  = $m->{bias_limit};     # NEU: konsistente Normierung

     # --- RMSE-Anteil ----------------------------------------------------------
-    my $rmseRatio = ($rmse_val && $rmse_val > 0) ? ($rmse_recent / $rmse_val) : 1;
-    my $err = $rmseRatio - 1;
-    $err = 0 if ($err < 0);
-    $err = $err / 10;                         # ❌ Dämpfung entfernt
+    my $rmseRatio = ($rmse_val && $rmse_val > 0)
+                  ? ($rmse_recent / $rmse_val)
+                  : 1;
+    my $err = $rmseRatio - 1;
+    $err = 0 if ($err < 0);
+    # KEIN /10 – volle Skalierung beibehalten

     # --- Kalibrierungsanteile -------------------------------------------------
-    my $slopeDev = abs(1 - $slope) / 2;       # ❌ unnötige Halbierung entfernt
-    my $biasDev  = ($maxCons && $maxCons > 0)
-                 ? abs($bias) / $maxCons      # ❌ schwache Normierung
-                 : 0;
+    my $slopeDev = abs(1 - $slope);           # direkte Abweichung
+    my $biasDev  = ($bias_limit && $bias_limit > 0)
+                 ? abs($bias) / $bias_limit   # stärkere, passende Normierung
+                 : 0;

-    # --- Aggregation (alt: Mittelwert) ----------------------------------------
-    my $drift = ($err + $slopeDev + $biasDev) / 3;  # ❌ Mittelung entfernt
-
-    # optionale Clamps (alt)
-    $drift = 0 if ($drift < 0);
-    $drift = 5 if ($drift > 5);               # ❌ harte Deckelung entfernt
+    # --- Aggregation (neu: gewichtete Summe) ----------------------------------
+    # Gewichte: Fehler 40%, Kalibrierung 60% (Slope+Bias)
+    my $cal = $slopeDev + $biasDev;
+    my $drift = 40 * $err + 30 * $cal;

     # --- Status ---------------------------------------------------------------
-    my $state = ($drift < 1.5) ? "green"
-              : ($drift < 3.5) ? "yellow"
-              : "red";
+    my $state = ($drift < 25) ? "green"
+              : ($drift < 55) ? "yellow"
+              : "red";

+    # Hard-Trigger (optional, nur Status-Anhebung)
+    if (($slope < 0.65) || ($bias_limit && abs($bias) > $bias_limit)) {
+        $state = "red";
+    }
+
     return {
-        driftScore => sprintf("%.2f", $drift),
-        driftState => $state,
+        driftScore => sprintf("%.2f", $drift),
+        driftState => $state,
+        rmseRatio  => sprintf("%.2f", $rmseRatio),
+        slopeDev   => sprintf("%.3f", $slopeDev),
+        biasDev    => sprintf("%.3f", $biasDev),
     };
 }


Wirkung des Patches
Mit deinen aktuellen Werten:
RMSE ratio ≈ 2.48             → err ≈ 1.48
Slope ≈ 0.9                   → slopeDev ≈ 0.1
Bias ≈ 953, limit ≈ 642 → biasDev ≈ 1.48
ergibt sich:
drift      ≈ 40*1.48 + 30*(0.1 + 1.48)
            ≈ 59.2 + 47.4
            ≈ 106.6
→ Ampel:              ROT (korrekt)

Könnte mein "Gefühl" und die Analyse von ChatGPT evtl. richtig sein ?   :o
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

Hier noch die komplette Drift-Bewertung dazu - hatte ich vergessen

Ergebnis der Driftbewertung mit der Version2.5 von 76_SolarForecast.pm aus dem Contrib:

Informationen zum neuronalen Netz der Verbrauchsvorhersage

letztes KI-Training: 20.03.2026 17:17:05 / Laufzeit in Sekunden: 2556
KI Abfragestatus: ok
letzte KI-Ergebnis Generierungsdauer: 83.05 ms
Verbrauchernummer Wärmepumpe: 08

=== Modellparameter ===

Normierungsgrenzen: PV=10450 Wh, Hausverbrauch: Min=0 Wh / Max=7598 Wh
Trainingsdaten: 8168 Datensätze (Training=6534, Validation=1634)
Architektur: Inputs=98, Hidden Layers=80-40, Outputs=1
Hyperparameter: Learning Rate=0.001, Momentum=0.8, BitFail-Limit=0.15
Aktivierungen: Hidden=GAUSSIAN_SYMMETRIC, Steepness=1.0, Output=LINEAR
Trainingsalgorithmus: INCREMENTAL, Registry Version=v1_heatpump_active_pv
Zufallsgenerator: Mode=1, Period=20
Modellalter: 164 h

=== Trainingsmetriken ===

bestes Modell bei Epoche: 218 (max. 15000)
Training MSE: 0.003458
Validation MSE: 0.003684
Validation MSE Average: 0.007232
Validation MSE Standard Deviation: 0.000322
Validation Bit_Fail: 29
Model Bias: 5 Wh
Model Slope: 0.9
Trainingsbewertung: Retrain

=== Fehlermaße der Prognosen ===

MAE: 354.05 Wh
MedAE: 285.91 Wh
RMSE: 412.23 Wh
RMSE relative: 19 %
RMSE Rating: excellent
MAPE: 17.39 %
MdAPE: 13.59 %
R²: 0.71

=== Rauschen ===

Rauschen Bewertung: low
Empfehlung für Bit_Fail: 0.28 (Einstellung von aiControl->aiConBitFailLimit)

=== Drift-Kennzahlen ===

Drift Score: 1.59
Drift RMSE ratio: 2.48
Drift Slope: 0.406
Drift Bias: 953.85
Drift Bewertung: mild
Slope recalibrated: -
Bias recalibrated: -
letzte Rekalibrierung: -
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

DS_Starter

Hallo 300P,

ZitatGefühlt hätte ich an einigen Tagen schon mal ein retrain oder ein anderes Ergebnis erwartet
Naja, die Frage ist ja was dein Modell fühlt...  ;)

ZitatKönnte mein "Gefühl" und die Analyse von ChatGPT evtl. richtig sein ?   :o
Könnte ... ja, wird es aber so nicht sein.  ;) 
Warum?
Weil ChatGPT sich offensichtlich irgendwelchen Code zusammenspinnt. So z.B. gibt es im ganzen Modul keine sub SolarForecast_calcDrift.
Und solche Codebestandteile wie my $err = $rmseRatio - 1; oder my $err = $rmseRatio - 1; ebenfalls nicht nur um ein Beispiel zu nennen.
Keine Ahnung woher das LLM den Code bezogen hat.

Also ... sowohl das Training als auch die Driftanalyse basieren auf zentralen Routinen zur Bias, Slope und Fehlerberechnung.
Wenn Code analysiert werden soll, wären das aiFannTrain, aiFannDetectDrift, _aiFannErrorMetrics, _aiFannSlopeBias in der aktuellen Version.

Mein Modell ist ungefähr 10 Tage alt:

=== Drift-Kennzahlen ===

Drift Score: 2.02
Drift RMSE ratio: 2.24
Drift Slope: 0.397
Drift Bias: 400.68
Drift Bewertung: mild
Slope recalibrated: -
Bias recalibrated: -
letzte Rekalibrierung: -


Die Berechnung würde ich nicht in Frage stellen. Aber die Gewichtung der einzelnen Komponenten, die zusammengenommen die Driftbewertung ergeben, kann man natürlich nochmal unter die Lupe nehmen.
Aber ich werde in der nächsten Version noch den Driftindex mit ausgeben. Dieses Merkmal zeigt das Ergebns besser als der Drift Score der nur ein Bestandteil ist.

LG,
Heiko


 
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

300P

Tja - was steht immer unter dem Ganzen was GTP da so alles zusammenträgt :
ChatGPT kann Fehler machen. Überprüfe wichtige Informationen.
 ???  ??? :-[  :-[  :-[  :-[  :-[  :-[  ::)  ;)
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.