[gelöst] 98_SVG.pm - PERL WARNING: Argument "" isn't numeric

Begonnen von kadettilac89, 24 Oktober 2017, 20:35:18

Vorheriges Thema - Nächstes Thema

kadettilac89

Hi,

ich sehe immer wieder folgende 2 Meldungen im Log


2017.10.24 15:10:50.197 1: PERL WARNING: Argument "" isn't numeric in numeric gt (>) at ./FHEM/98_SVG.pm line 1550.
2017.10.24 15:10:50.211 1: PERL WARNING: Argument "" isn't numeric in subtraction (-) at ./FHEM/98_SVG.pm line 2060.


Alle Plots werden korrekt angezeigt, die Warnung tritt nur sporadisch auf, habe noch nicht rausgefunden wie ich diese reproduzieren kann. Es sind keine Einträge im DBLog enthalten die   Value = ""   sind. Ich denke an dieser Stelle wird das Design der Plots aufgebaut und nicht Werte für die Plots eingelesen.

Stacktrace oder wie der Befehl heißt ist wahrscheinlich wenig hilfreich da das Problem nur manchmal auftritt. Permanent aktiviert wird mir vermutlich das Log überlaufen.

Gibt es eine Möglichkeit, die Warnung abzufangen und die Aufrufparameter und andere Debugwerte ins Log schreiben? Wäre hilfreich wenn mir jemand Sourcecode zeigen könnte, den ich hier temporär einbaue (ggf. hier in einem anderen Post).

Ich schließe gar nicht aus, dass ich irgendwo in einer Definition einen Tippfehler oder anderen Fehler habe.

Informationen zu meiner Installation:
Fhem aktuell, alle heutigen Updates drin. Warnung habe ich schon "lange"
DBLog auf MySQL
RPi3
Kein LogProxy im Einsatz (da gab es mal ein ähnliches Problem bzw. Warnungen)

Danke schon mal!

kadettilac89

EDIT: Ich habe nun mit Verbose 5 etwas ins Log gebracht ...


2017.10.24 22:13:56.808 4: Processing Statement: SELECT
/
2017.10.24 22:13:56.806 4: WEB: /fhem/SVG_showLog?dev=Plot_Twilight_light&logdev=myDbLog&gplotfile=myTwilight_DB&logfile=HISTORY&pos=off=-1;zoom=0 / RL:2700 / image/svg+xml / Content-Encoding: gzip
2017.10.24 22:13:56.802 1: PERL WARNING: Argument "" isn't numeric in subtraction (-) at ./FHEM/98_SVG.pm line 2060.
/
2017.10.24 22:13:56.802 4: WEB: /fhem/SVG_showLog?dev=Plot_Wetter_xxx_Luftdruck&logdev=myDbLog&gplotfile=myPress_DB&logfile=HISTORY&pos=off=-1;zoom=0 / RL:2223 / image/svg+xml / Content-Encoding: gzip
2017.10.24 22:13:56.796 1: PERL WARNING: Argument "" isn't numeric in numeric gt (>) at ./FHEM/98_SVG.pm line 1550.
2017.10.24 22:13:56.793 4: WEB_127.0.0.1_39480 GET /fhem/SVG_showLog?dev=Plot_Wetter_xxx_Wind&logdev=myDbLog&gplotfile=myWind_DB&logfile=HISTORY&pos=off=-1;zoom=0; BUFLEN:0
2017.10.24 22:13:56.790 4: Connection accepted from WEB_127.0.0.1_39480
2017.10.24 22:13:56.789 5: Cmd: >{ "HISTORY" }<


Es liegt vermutlich an meinen SVG
-  Plot_Wetter_xxx_Luftdruck
-  Plot_Twilight_light

Alle defines s. u. Habe ich hier etwas falsch gemacht?


List Plot1

Internals:
   DEF        myDbLog:myPress_DB:HISTORY
   GPLOTFILE  myPress_DB
   LOGDEVICE  myDbLog
   LOGFILE    HISTORY
   NAME       Plot_Wetter_xxx_Luftdruck
   NOTIFYDEV  global
   NR         222
   STATE      initialized
   TYPE       SVG
Attributes:
   plotfunction Wetter_xxx
   room       Wetter_History


List Plot2


Internals:
   DEF        myDbLog:myTwilight_DB:HISTORY
   GPLOTFILE  myTwilight_DB
   LOGDEVICE  myDbLog
   LOGFILE    HISTORY
   NAME       Plot_Twilight_light
   NOTIFYDEV  global
   NR         686
   STATE      initialized
   TYPE       SVG
Attributes:
   DbLogExclude .*
   group      Twilight
   label      "Helligkeit Twilight: Min: $data{min2}, Max: $data{max2}, Aktuell: $data{currval2}"
   plotfunction twilight
   room       Wetter
   sortby     2


SVG1

# Created by FHEM/98_SVG.pm, 2014-06-09 16:45:57
set terminal png transparent size <SIZE> crop
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set title 'Luftdruck'
set ytics
set y2tics
set grid ytics
set ylabel "Pressure in kPa"
set y2label ""
set yrange [900:1100]

#DbLog <SPEC1>:pressure

plot "<IN>" using 1:2 axes x1y1 title 'Luftdruck kPa' ls l3fill lw 2 with quadraticSmooth


SVG2

# Created by FHEM/98_SVG.pm, 2017-10-16 09:14:34
set terminal png transparent size <SIZE> crop
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set title '<L1>'
set ytics ("Dunkel" 2, "Hell" 6)
set y2tics
set grid y2tics
set ylabel ""
set y2label "Helligkeit"
set yrange [0:8]
set y2range [0:120]

#myDbLog twilight:light:::$val=4
#myDbLog twilight:light::
#myDbLog twilight:twilight_weather::

plot "<IN>" using 1:2 axes x1y1 title 'Dämmerung' ls l5 lw 2 with lines,\
     "<IN>" using 1:2 axes x1y1 title 'Twilight Light' ls l3 lw 2 with steps,\
     "<IN>" using 1:2 axes x1y2 title 'twilight weather' ls l2fill lw 1 with lines

rudolfkoenig

SVG erwartet eine Liste von Zeitpunkt & Wert, ich vermute, das ist nicht durchgehend der Fall.
Mit "Show preprocessed input" in der SVG-Detailansicht sollte das Problemfeld identifiziert werden koennen.

kadettilac89

Zitat von: rudolfkoenig am 25 Oktober 2017, 07:38:29
SVG erwartet eine Liste von Zeitpunkt & Wert, ich vermute, das ist nicht durchgehend der Fall.
Mit "Show preprocessed input" in der SVG-Detailansicht sollte das Problemfeld identifiziert werden koennen.

Danke, werde mal versuchen den Fehler in einem einzelnen Plot nachzustellen und dann die Inputdaten ansehen.

kadettilac89

So, nächster Input:

Datenbank hat nicht numerische Einträge für Ping im speedtest modul.


23.10.2017 18:01 speedtest SPEEDTEST ping: Cannot ping Cannot
23.10.2017 17:01 speedtest SPEEDTEST ping: Cannot ping Cannot
23.10.2017 16:01 speedtest SPEEDTEST ping: Cannot ping Cannot
23.10.2017 15:01 speedtest SPEEDTEST ping: Cannot ping Cannot
23.10.2017 14:01 speedtest SPEEDTEST ping: Cannot ping Cannot
23.10.2017 13:01 speedtest SPEEDTEST ping: Cannot ping Cannot
23.10.2017 12:01 speedtest SPEEDTEST ping: Cannot ping Cannot
23.10.2017 11:01 speedtest SPEEDTEST ping: Cannot ping Cannot


Filter im SVG um nur Zahlen zu erhalten (bereits vom Wiki übernommen):

#DbLog <SPEC1>:ping:::$val=~s/([\d.]*).*/$1/eg


Filter greift scheinbar, da im SVG nur Timestamp und als Wert <space> verarbeitet wird ...

..
..
..
2017-10-23_09:02:14 45.969
2017-10-23_10:02:12 50.006
2017-10-23_11:01:58
2017-10-23_12:01:58
2017-10-23_13:01:58
2017-10-23_14:01:58
2017-10-23_15:01:58
2017-10-23_16:01:58
2017-10-23_17:01:58
2017-10-23_18:01:58
2017-10-23_19:02:07 51.457
2017-10-23_20:02:06 53.623
..
..
..
#speedtest:ping:::$val=~s/([\d.]*).*/$1/eg


Nun frage ich wieder um weiterzukommen ... gibt es hier eine Möglichkeit im SVG eine andere Regexp zu nutzen damit solche Zeilen überhaupt nicht verarbeitet werden?

Lt. Wiki ...
Zitat
Fehlermeldung isn't numeric in sprintf at ./FHEM/98_SVG.pm
Dieses kommt grundsätzlich immer dann vor, wenn SVG versucht einen Wert einzulesen, der neben der Zahl auch die Einheit enthält. Dieses kann bei der Verwendung von DbLog vorkommen, weil DbLog nicht weiß, wie es Wert und Einheit trennen soll. Abhilfe schafft eine entsprechende Regular Expression, die nur den Zahlenwert liefert.

==> habe ich das nicht schon durch "$val=~s/([\d.]*).*/$1/eg" aus dem Wiki befolgt? Wie müsste die Regex aussehen damit überhaupt keine Zeile verarbeitet wird?

rudolfkoenig

Zitatgibt es hier eine Möglichkeit im SVG eine andere Regexp zu nutzen damit solche Zeilen überhaupt nicht verarbeitet werden?
Dazu muss man alle Daten anschauen, evtl reicht der "Example lines for input:" Abschnitt im Plot-Editor.
Oder man steigt auf FileLog um, da gibt es diese Probleme nicht :)

Btw. die von dir gezeigte Liste der Datensaetze ist eindeutig kaputt, und ist mAn ein Bug im DbLog get.

kadettilac89

Zitat von: rudolfkoenig am 26 Oktober 2017, 07:54:08
Dazu muss man alle Daten anschauen, evtl reicht der "Example lines for input:" Abschnitt im Plot-Editor.
Oder man steigt auf FileLog um, da gibt es diese Probleme nicht :)

Btw. die von dir gezeigte Liste der Datensaetze ist eindeutig kaputt, und ist mAn ein Bug im DbLog get.

Ich möchte keinem Entwickler oder Architekt irgend eines Moduls auf die Füße steigen, ich war selber Entwickler und weiß schnell die Motivation am Boden ist. Wo das Problem herkommt verstehe ich, jedes Modul für sich "works as designed" es ist einfach eine Kombination ungünstiger ... du weißt schon :)

1) Readings können Text enthalten --> Wert in Spalte VALUE ist eine Fehlermeldung aber Text ist per Definition erlaubt
2) Im Fehlerfall wird von Modul SPEEDTEST das Ping-Reading mit "cannot ping" gefüllt statt mit einem Wert in Einheit ms
3) DBLog hat hier keine Möglichkeit bzw. Logik zu entscheide was gut und was böse ist ... Es weiß nicht ob ein numerischer Wert erwartet wird, oder ob Text auch OK ist
4) Plotdefinition hat schon REGEX die nur Werte zurückliefert in diesem Fall ist bei mir der "Rückgabewert" dummerweiße ein "" (leere Menge, leerer String) weil Text drin steht jedoch Werte erwartet werden

Was fehlt bzw. das Problem lösen würde
- SVG-Modul das Zeilen mit Datum aber ohne Wert ignoriert (ggf. per Attribut?)

Alternative für meine Definition
--> Gibt es in REGEX eine Möglichkeit einen Defaultwert zu liefern, .... so in etwa      IF [Rückgabewert = ''] THEN [Rückgabewert = 0]    ???   Mit Rückgabewert meine ich $val mit dem der Plot erstellt wird

--> Kann man Reading irgendwie filtern, so dass nur Numerische Werte ein EVENT feuern?

Ich würde eine allgemeine Lösung bevorzugen bevor ich mit Userreadings auswerte, Trigger in der Datenbank diesen Fall beim Einfügen prüfen lasse ...

rudolfkoenig

Zitat- SVG-Modul das Zeilen mit Datum aber ohne Wert ignoriert (ggf. per Attribut?)
Klar kann man defensiv programmieren, um Probleme bei Verwendung von nicht-kooperativen Modulen zu vermeiden, es geht halt leider auf die Kosten von Performance. Ploterstellung ist eine (die?) bekannte Performance-Engstelle in FHEM. Ich habe es schon optimiert (z.Bsp. indem das Filtern nah an der Quelle - in FileLog - erfolgt), weitere Optimierung ist aber meiner Ansicht nach nur mit Architekturwechsel zu erreichen, und ich will die vorhandene Geschwindigkeit, wenn moeglich, nicht verschlechtern mit defensiver Programmierung.

Lieber waere es mir, wenn das DbLog Modul die Daten filtert, und bei get in diesem Form nur Zeilen mit einem Zeitstempel und einer Zahl zerueckliefert. Der Maintainer bzw. seine Mitstreiter muessten dafuer auf diese Diskussion aufmerksam gemacht werden.

Zitat--> Gibt es in REGEX eine Möglichkeit einen Defaultwert zu liefern, .... so in etwa      IF [Rückgabewert = ''] THEN [Rückgabewert = 0]    (https://forum.fhem.de/Smileys/default/huh.gif)   Mit Rückgabewert meine ich $val mit dem der Plot erstellt wird
Ich kenne die Moeglichkeiten von DbPlot nicht, in FileLog ist sowas moeglich, da jedes Wert mit einem Perl-Ausdruck bearbeitet werden kann.

frank

als filelog nutzer hätte ich folgenden workaround:
du könntest dir doch sicherlich im speedtestmodul mit userreadings ein "numerisches" reading erstellen.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

sfancy

DbLog kann auch Werte vor dem speichern filtern und umschreiben.
Schau dir dazu die Commandref von DbLog an. Insbesondere das Attribut valueFn.

Bestehende Werte in der Datenbank löschen oder umschreiben geht leider nur mit SQL-Befehlen.

Bei mir sieht das Attribut valueFn z.B. so aus:


attr LogDB valueFn
{
  if ($DEVICETYPE eq 'GPIO4')
  {
    if ($EVENT eq 'temperature: 85')
    {
      $IGNORE = 1;
    }
  }
  elsif ($DEVICETYPE eq 'CUL_HM')
  {
    if ($READING eq 'desired-temp' && $VALUE eq 'off')
    {
      $VALUE = 4.5;
    }
    elsif ($READING eq 'desired-temp' && $VALUE eq 'on')
    {
      $VALUE = 30.5;
    }
    elsif ($READING eq 'desired-temp' && $VALUE !~ m/^[-+]?[\.\d]/)
    {
      $IGNORE = 1;
    }
  }
}

kadettilac89

Zitat von: rudolfkoenig am 26 Oktober 2017, 10:02:52
Klar kann man defensiv programmieren, um Probleme bei Verwendung von nicht-kooperativen Modulen zu vermeiden, es geht halt leider auf die Kosten von Performance. Ploterstellung ist eine (die?) bekannte Performance-Engstelle in FHEM. Ich habe es schon optimiert (z.Bsp. indem das Filtern nah an der Quelle - in FileLog - erfolgt), weitere Optimierung ist aber meiner Ansicht nach nur mit Architekturwechsel zu erreichen, und ich will die vorhandene Geschwindigkeit, wenn moeglich, nicht verschlechtern mit defensiver Programmierung.

Das verstehe ich, irgend wann muss man sich auch auf die Werte die vorgelagerte Funktionen liefern verlassen. Nur weil man der Letzte in der Kette ist sollte man nicht für früher entstandene Daten oder Vorgaben noch Workarounds oder Prüfungen einbauen.

Zitat von: frank am 26 Oktober 2017, 12:24:04
als filelog nutzer hätte ich folgenden workaround:
du könntest dir doch sicherlich im speedtestmodul mit userreadings ein "numerisches" reading erstellen.

Zitat von: kadettilac89 am 26 Oktober 2017, 09:04:44
Ich würde eine allgemeine Lösung bevorzugen bevor ich mit Userreadings auswerte, Trigger in der Datenbank diesen Fall beim Einfügen prüfen lasse ...
--> auf Userreadings wollte ich wenn möglich verzichten ... dass es damit geht wusste ich, aber Danke für deinen Post.

Zitat von: sfancy am 26 Oktober 2017, 13:24:53
DbLog kann auch Werte vor dem speichern filtern und umschreiben.
Schau dir dazu die Commandref von DbLog an. Insbesondere das Attribut valueFn.

Bestehende Werte in der Datenbank löschen oder umschreiben geht leider nur mit SQL-Befehlen.

Das kannte ich noch nicht, werde ich mal testen

Zitat von: sfancy am 26 Oktober 2017, 13:24:53
Bestehende Werte in der Datenbank löschen oder umschreiben geht leider nur mit SQL-Befehlen.
Das Aufräumen ist weniger das Problem, das bekomme ich schon hin. Ich gehe halt gerne den Weg "fehlerhafte" Werte von vornherein zu vermeiden bzw. so allgemein wie möglich damit umzugehen damit ich nicht bei jedem neuen Device wieder von vorne beginne.

Danke euch allen, durch Input habe ich die Verursacher gefunden. Wie ich im Einzelnen die Werte behandle muss ich mir noch überlegen.

Ich setzte auf "gelöst" da ich ursprünglich nach der Ursache gesucht hatte, und daraus eine interessante Diskussion entstand.

kadettilac89

Sollte jemand auf diesen Post gelangen hier MÖGLICHE Lösungen für diese oder ähnliche Fehlermeldung. Je nach Anwendungsfall:

1) Userreading anlegen das Readingwerte auf Nummern bzw. Zahlen abfrägt. Für den Fall, dass ein String wie "Cannot Ping" enthalten ist einen passenden Defaultwert, z. B. Ping 0 ms setzen und im Anschluss den Plot auf das Userreading verlinken und nicht auf ursprüngliche Spalte ping. Details wie Userreadings anzulegen sind sollten im Forum zu finden sein.

2) Die genannte Funktion bzw. Attribut valueFn im DbLog ...

3) ggf. Trigger in MySQL "before insert" ... Vorsicht, kann Performance beeinflussen

Per Regex in SVG vermutlich nicht lösbar, zumindest mir nicht bekannt wie es ginge.