Runden von Nachkommastellen in Statistics Modul

Begonnen von Adimarantis, 30 März 2023, 10:00:24

Vorheriges Thema - Nächstes Thema

Adimarantis

Bei meinen Statistics haben sich teilweise viele Nachkommastellen angesammelt.
Hour: 0.00000000000000000 Day: 0.08309999999999999 Month: 307.61254000000002407 Year: 129.31880000000001019Die wilden Zahlen sind ursprünglich vom eigentlichen Reading reingekommen (durch eine Division durch 1000, bei der Perl plötzlich "ungenau" wurde). Das wird aber inzwischen gerundet.
Leider hilft das aber nichts für die Statistics selbst.
Gibt es eine Möglichkeit in Statistics zu runden?
Wenn nicht, wo muss ich readings überschreiben um das zu korrigieren?
Hab schon versucht das statXXX reading mit sowas wie
Hour: 0.0 Day: 0.083 Month: 307.61254 Year: 129.3188zu überschreiben, aber wahrscheinlich puffert das Modul die Daten noch irgendwo intern, denn nach dem nächsten Update waren die wilden Nachkommastellen wieder da.
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

Aurel_B

Hmmm, ich habe jetzt auf die schnelle auch nicht herausgefunden, wo die Readings intern gespeichert werden. Im Sourcecode "98_statistics.pm" ist von "hidden readings" die Rede:

########################################
sub statistics_Notify($$)
{
   my ($hash, $dev) = @_;
   my $name = $hash->{NAME};
   my $devName = $dev->{NAME};

 # At startup: delete old Readings of monitored devices and rebuild from hidden readings
  if ($devName eq "global" && grep (m/^INITIALIZED|REREADCFG$/,@{$dev->{CHANGED}})) {
     foreach my $r (keys %{$hash->{READINGS}}) {
         if ($r =~ /^monitoredDevices.*/) {
            statistics_Log $hash,5,"Initialization - Delete old reading '$r'.";
            delete($hash->{READINGS}{$r});
         }
     }
     my %unknownDevices;
     foreach my $r (keys %{$hash->{READINGS}}) {
         if ($r =~ /^\.(.*):.*/) { $unknownDevices{$1}++; }
     }
     my $val="";
     foreach my $device (sort (keys(%unknownDevices))) {
        if (not exists ($defs{$device})) {
         if ($val ne "") { $val.=","; }
         $val .= $device;
        }
     }
     if ($val ne "") {
       statistics_Log $hash, 4, "Initialization - Found hidden readings for device(s) '$val'.";
       readingsSingleUpdate($hash,"monitoredDevicesUnknown",$val,1);
     }
     return;
   }

Was ich mal versuchen würde: fhem herunterfahren, manuell die Readings ändern in fhem.save und fhem wieder starten?

betateilchen

Das Problem ist, dass das statistics-Modul intern die größtmögliche Anzahl von Nachkommastellen erzwingt, die für eine vollständige Darstellung benötigt werden. Da müsste man mal mit dem Modulautor in die Diskussion gehen, ob er nicht ein entsprechendes Attribut einbauen möchte, um dem Anwender eine Möglichkeit zu geben, diese Darstellung zu beeinflussen.

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Adimarantis

#3
Das mit fhem.save hatte ich mir als letzten Notnagel auch schon überlegt und jetzt mal probiert.
Nutzt leider gar nichts - die Geisterstellen tauchen wieder auf.
Nach etwas Googeln scheint das ein generelle Floatingpoint Problem zu sein.
Wenn man in der FHEM Kommandozeile
{print 10000.129-10000.12;;}eingibt, dann steht nachher im logfile (nicht auf dem Bildschirm):
0.00900000000001455genau das scheint eben bei einigen meiner Statistiken zuzuschlagen - warum nicht für alle, verstehe ich auch nicht ganz.

Ich habe mir jetzt folgenden Fix überlegt:
Anscheinend verwaltet statistics intern die Anzahl der Dezimalstellen - ich vermute mal um alle Werte auch die selbe Anzahl von Nachkommastellen zu runden. (was @betateilchen gerade auch gepostet hat)
Wenn eine Zahl aufgrund des Floating Point Problems plötzlich viele Nachkommastellen kriegt, dann beissen die sich für alle Statistiken einer Zeile fest.
Daher verwende ich jetzt diesen Wert (was dann wahrscheinlich ursprünglich die Nachkommastellen vom Quellreading sind) um das Ergebnis der Substraktion zu runden, damit es gar nicht erst dazu kommt.

      my $deltaValue = $value - $hidden[1];
      #Adimarantis 30.3.2023: Round to the previous number of decimalplaces to avoid issue with floating point precision adding a lot of decimals
      $deltaValue=int($deltaValue*(10**$decPlaces)+0.5)/(10**$decPlaces);

Um bereits verhunzte Werte zu korrigieren, sollte jetzt ein update des stat-readings reichen. Auf den ersten Blick scheint das bei mir zumindest zu klappen.
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

RalfRog

Hallo

Da scheine ich bisher Glück gehabt zu haben, vielleicht weil die Werte die ins statistics-Modul wandern bei mir vorher durch ein sprintf "formatiert" werden (Workaround bevor ich von ReadingsNum erfuhr).

Wo genau hast du gefixt?

Wenn tupol noch Maintainer ist, ist es vielleicht schwierig.
Er hatte sich schon von der FritzBox zurück gezogen  :( , die jetzt Jo Wiemann nach Rücksprache mit ihm macht....
FHEM auf Raspi 2B mit nanoCUL, HM-MOD-RPI-PCB und über LAN MAX!Cube mit a-culFW (Stack 868 + 433)
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder

Adimarantis

Den letzten Fix für das Modul hatte Beta-User eingepflegt.

Ich habe jetzt nochmal weiter rumgefeilt und dem Modul ein Attribut "limitDecimals" spendiert. Nur rudimentär getestet.
Da kann man eine Liste im Format Reading:decimals (Leerzeichen getrennt) hinterlegen.
Damit ist die maximale Anzahl von Nachkommastellen festgelegt (greift bei Delta und Avg)

Update anbei falls es jemand brauchen kann.
Ohne Gewähr :)
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

Aeroschmelz

#6
Hallo,

ich teste das jetzt mal und habe eine Leerzeichen generierte Liste von Delta-Readings erzeugt:

kWh:7 Pipeline_VolumeTot:5 Schlauch_VolumeTot:5

Danach bin ich auf do_Statistics, in der Annahme, dass dann die vielen Nachkommastellen wegfallen. Da passiert aber erst einmal noch nichts, muss ich warten, bis ein neues Event generiert wird?

Danke.

Viele Grüsse
Marcus

P.S. scheint wohl so zu sein, jetzt bekomme ich aber folgende Readings für die Statistik:

statKWhDay%.0.071f



Adimarantis

Scheint so als hätte ich versehentlich nicht die neuste Version angehängt.
Zumindest ist in der Version ein eindeutiger Fehler - weiss aber nicht ob der dann dein Symptom erzeugt.
Probier auf jeden Fall mal diese.
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

Aeroschmelz

Jetzt läuft ist, allerdings wird die Statistik der in limitDecimals angegeben Werte dann auf 0 gesetzt. Das sollte man bei der Verwendung u.U. berücksichtigen 



Adimarantis

Das sollte eigentlich nicht so sein (bei mir zumindest nicht) - allerdings wurde deine Statistik durch den Fehler auf Quatsch gesetzt, was wohl als 0 interpretiert wird. Wenn du die vorherigen Werte nicht hast, dann sollte es gehen sie mit "setreading statXXXX ....." wiederherzustellen.
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

Aeroschmelz

Hallo,

bei dem Ansatz werden die Readings beim nächsten Update des Statistics Modul wieder auf die Ursprungs-Werte gesetzt. Es gibt wohl diesen Ansatz hier, aber der will bei mir nicht so ;-)

https://forum.fhem.de/index.php/topic,34497.msg279246.html#msg279246

VG
Marcus

Adimarantis

Nachdem ich aus diversen Gründen auch schon mal die Notwendigkeit hatte Werte zu korrigieren, mal eine Bastelversion dazu.
Mit der neuen set Methode
setStatistics <device> <reading> <Hour|Day|Month|Year> <value>sollte man jetzt ganz spezifisch einen Wert korrigieren können.

Klappt bei mir soweit im Test. Der gesetzte Wert bleibt erhalten.
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

Adimarantis

Habe noch einen Fehler entdeckt der zu falschen Nachkommastellen geführt hat, wenn man keine limits definiert hat.
Ich pflege meine Version hier:
https://github.com/bublath/FHEM-Statistics
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

Aeroschmelz

Kann man die Version eventuell zur offiziellen Version machen, das Update der letzten ist doch schon etwas länger her?

Adimarantis

Nach Rücksprache mit Rudi habe ich die Version jetzt engecheckt.
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)