DOIF warnung isn't numeric in numeric lt (<)

Begonnen von neyzen, 02 April 2020, 15:09:02

Vorheriges Thema - Nächstes Thema

neyzen

Hallo,
habe heute ein Fhem update gemacht und jetzt bekomme ich in meinem Doif eine warnung was vorher nicht aufgetaucht war
Wie bekomme ich diese warnung wieder weg?
folgendes DOIF

Internals:
   DEF        ([KalanZamaniHesapla:Sabaha] < [KalanZamaniHesapla:Oeglene] and [KalanZamaniHesapla:Sabaha] < [KalanZamaniHesapla:Ikindiye] and  [KalanZamaniHesapla:Sabaha] < [KalanZamaniHesapla:Aksama] and  [KalanZamaniHesapla:Sabaha] < [KalanZamaniHesapla:Yatsiya]) (set  NamazaKalanZaman {(ReadingsVal("KalanZamaniHesapla","Sabaha","18:00"))}) (set HangiNamaz Sabaha)

DOELSEIF ([KalanZamaniHesapla:Oeglene] < [KalanZamaniHesapla:Sabaha] and  [KalanZamaniHesapla:Oeglene] < [KalanZamaniHesapla:Ikindiye] and  [KalanZamaniHesapla:Oeglene] < [KalanZamaniHesapla:Aksama] and  [KalanZamaniHesapla:Oeglene] < [KalanZamaniHesapla:Yatsiya]) (set  NamazaKalanZaman {(ReadingsVal("KalanZamaniHesapla","Oeglene","18:00"))}) (set HangiNamaz Öglene)

DOELSEIF ([KalanZamaniHesapla:Ikindiye] < [KalanZamaniHesapla:Oeglene] and  [KalanZamaniHesapla:Ikindiye] < [KalanZamaniHesapla:Sabaha] and [KalanZamaniHesapla:Ikindiye] < [KalanZamaniHesapla:Aksama] and  [KalanZamaniHesapla:Ikindiye] < [KalanZamaniHesapla:Yatsiya]) (set  NamazaKalanZaman {(ReadingsVal("KalanZamaniHesapla","Ikindiye","18:00"))}) (set HangiNamaz Ikindiye)

DOELSEIF ([KalanZamaniHesapla:Aksama] < [KalanZamaniHesapla:Oeglene] and  [KalanZamaniHesapla:Aksama] < [KalanZamaniHesapla:Ikindiye] and  [KalanZamaniHesapla:Aksama] < [KalanZamaniHesapla:Sabaha] and  [KalanZamaniHesapla:Aksama] < [KalanZamaniHesapla:Yatsiya]) (set  NamazaKalanZaman {(ReadingsVal("KalanZamaniHesapla","Aksama","18:00"))}) (set HangiNamaz Aksama)

DOELSEIF ([KalanZamaniHesapla:Yatsiya] < [KalanZamaniHesapla:Oeglene] and  [KalanZamaniHesapla:Yatsiya] < [KalanZamaniHesapla:Ikindiye] and  [KalanZamaniHesapla:Yatsiya] < [KalanZamaniHesapla:Aksama] and  [KalanZamaniHesapla:Yatsiya] < [KalanZamaniHesapla:Sabaha]) (set  NamazaKalanZaman {(ReadingsVal("KalanZamaniHesapla","Yatsiya","18:00"))}) (set HangiNamaz Yatsiya)


   FUUID      5dbcb5bc-f33f-2b39-7b46-462d22ae2ea9cd1f
   MODEL      FHEM
   NAME       KalanZamanDOIF
   NOTIFYDEV  KalanZamaniHesapla,global
   NR         126
   NTFY_ORDER 50-KalanZamanDOIF
   STATE      cmd_3
   TYPE       DOIF
   VERSION    20268 2019-09-28 21:00:39
   READINGS:
     2020-04-02 15:07:06   Device          KalanZamaniHesapla
     2020-04-02 15:07:06   cmd             3.2
     2020-04-02 15:07:06   cmd_event       KalanZamaniHesapla
     2020-04-02 15:07:06   cmd_nr          3
     2020-04-02 15:07:06   cmd_seqnr       2
     2020-04-02 15:07:06   e_KalanZamaniHesapla_Aksama 04:54:54
     2020-04-02 15:07:06   e_KalanZamaniHesapla_Ikindiye 01:57:54
     2020-04-02 15:07:06   e_KalanZamaniHesapla_Oeglene 22:24:54
     2020-04-02 15:07:06   e_KalanZamaniHesapla_Sabaha 14:14:54
     2020-04-02 15:07:06   e_KalanZamaniHesapla_Yatsiya 06:14:54
     2020-04-02 14:59:55   mode            enabled
     2020-04-02 15:07:06   state           cmd_3
     2020-04-02 15:07:06   warning         condition c03: Argument "01:57:54" isn't numeric in numeric lt (<)

neyzen

ich hab in der Zwischenzeit mein bisherige Variable
von z.B
[KalanZamaniHesapla:Sabaha]

in

[KalanZamaniHesapla:Sabaha:d]
geändert und bekomme keine warnung mehr. Ist das die richtige Lösung?

Otto123

#2
Ich denke nicht. So extrahiert er nur die Stunden.
Du kannst Zeiten in der Form hh:mm:ss nicht einfach numerisch vergleichen!
Hier gibt es ein paar Betrachtungen dazu: https://wiki.fhem.de/wiki/Zeitangaben,_rechnen_mit
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

neyzen

#3
Aber das Doif vergleicht richtig.
Das was ich nicht verstehe ist warum ich vorher diese Warnung vor dem Update nicht hatte und jetzt habe.
Was für Möglichkeiten habe ich den damit ich das herrausfinde?

Edit:
Ich hab jetzt nochmal das :d entfernt, jetzt taucht die Warnung nicht mehr im Event Monitor auf, hab die Warnung nur im Doif Warnung Readings

amenomade

Zitat von: Otto123 am 02 April 2020, 16:09:19
Du kannst Zeiten in der Form hh:mm:ss nicht einfach numerisch vergleichen!
alphabetisch vergleichen sollte aber hier funktionieren => lt oder gt
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Otto123

#5
@neyzen Du kannst gern der Meinung sein Dein DOIF macht es richtig. Dann behaupte ich es wird jedes Ergebnis zufällig sein!
Die Warnungen siehst Du übrigens nie im Eventmonitor sondern immer im LOG!
Ich habe Dir ein paar Beispiele, gemacht. Spiele selbst einfach mal in der FHEM Kommandozeile damit
{if ("10:11:20" > "10:11:10") {"wahr"} else {"falsch"}}
{if ("10:11:20" gt "10:11:10") {"wahr"} else {"falsch"}}
{if ("10:11:20" > "10:11:25") {"wahr"} else {"falsch"}}
{if ("10:11:20" gt "10:11:25") {"wahr"} else {"falsch"}}
{if ("10:11:20" < "10:11:25") {"wahr"} else {"falsch"}}
{if ("10:11:20" lt "10:11:25") {"wahr"} else {"falsch"}}
{if ("01:11:20" lt "10:11:25") {"wahr"} else {"falsch"}}
{if ("01:11:20" < "10:11:25") {"wahr"} else {"falsch"}}
{if ("01:11:20" gt "10:11:25") {"wahr"} else {"falsch"}}
{if ("01:11:20" > "10:11:25") {"wahr"} else {"falsch"}}

Wenn Du hier vielleicht auch im Buch nachlesen möchtest, dass die Warnung berechtigt ist:
https://perldoc.perl.org/5.30.0/perlop.html#Operator-Precedence-and-Associativity, Abschnitt: Relational Operators

Und amenomade hat Recht - wäre ich jetzt freiwillig nicht drauf gekommen! :) Mit Stringoperatoren geht es offenbar.

Ich weiß Perl versucht Strings immer irgendwie zu "verstehen", am Ende macht er auch Zahlen draus und meckert nicht beim numerischen Vergleich. Was er aus einer Zeit im Format hh:mm:ss macht und sich überlegt -ich will es gar nicht wissen ;)

Gruß Otto

P.S. im Ausführungsteil kannst Du übrigens auch die kürzere Form von set magic verwenden:
set  NamazaKalanZaman {(ReadingsVal("KalanZamaniHesapla","Yatsiya","18:00"))} -> set  NamazaKalanZaman [KalanZamaniHesapla:Yatsiya]
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Damian

Perl kennt Zeitformate nicht und wird sie auch nicht von sich aus in irgendetwas wandeln - es sind einfach Zeichenketten mit aphanumerischen Zeichen genannt Strings.

DOIF hat intern Zeitvariablen mit aktueller Zeit und Datum, die man als Zeichenkette vergleichen kann.

z. B.

($hms gt "11:00:30" ...)

bedeutet nach 11:00:30 Uhr. Hinzu muss natürlich noch ein Trigger kommen.

Besser ist es aber beim DOIF mit Zeitintervallen zu arbeiten, diese triggern auch.

Oder Datumsvergleiche:

(($md le "04-01" or $md ge "10-01") and [04:30-22:00]) (set heizung on)  DOELSE (set heizung off)

Bedeutet: Heizen von Oktober bis April in der angegebenen Zeitspanne


Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Otto123

@Damian Was willst Du damit sagen? Das DOIF vom TE kann funktionieren wenn er gt und lt nimmt und das es dann funktioniert ist eine DOIF Spezialität und nicht zu verallgemeinern?
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Damian

#8
Zitat von: Otto123 am 03 April 2020, 09:53:37
@Damian Was willst Du damit sagen? Das DOIF vom TE kann funktionieren wenn er gt und lt nimmt und das es dann funktioniert ist eine DOIF Spezialität und nicht zu verallgemeinern?

Es kommt darauf an, was in den Readings drin steht.

Bei HH:MM sollte man mit $hm und bei HH:MM:SS mit $hms vergleichen, es sollten also die gleichen Stringlängen sein.

gt, ge, lt, le sind dann sinnvoll anwendbar, siehe Perlreferenz.

Das Einzige was DOIF spezifisch ist, sind die vorbelegten Variablen $hm, $hms, $ymd $md siehe DOIF-Kurzreferenz, alles andere ist Perl und funktioniert dort genauso mit Strings wie beschrieben.

Edit: [KalanZamaniHesapla:Sabaha] lt [KalanZamaniHesapla:Oeglene] funktioniert korrekt, wenn die Strings gleiche Länge haben, ansonsten wird der Prefix verglichen, was meistens auch funktioniert ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Otto123

#9
Ich verstehe Deinen Einwand mit den Variablen $hm und $hms nicht. Die aktuellen Zeiten spielen doch im DOIF von neyzen keine Rolle, er vergleicht doch Zeit A mit Zeit B!?
Die Erklärung warum amenomade Recht hat, ist der lexigraphische Vergleich der bei Stringketten zum Einsatz kommt. Also nur bei der Anwendung von gt und lt!
ZitatDabei wird Element für Element der beiden Sequenzen verglichen, bis der Algorithmus auf zwei verschiedene Elemente stößt. Ist das Element der ersten Sequenz kleiner als das entsprechende der zweiten, wird true zurückgegeben.
Kann man vielleicht hiermit gut nachvollziehen:
{if ("2" gt "123456") {"wahr"} else {"falsch"}}
{if ("122" gt "123456") {"wahr"} else {"falsch"}}

Wie man sieht, ist der kürzere String nicht zwangsläufig kleiner.

Die Länge der Strings spielt für das Ergebnis keine Rolle, außer:
ZitatFalls eine der beiden Sequenzen bereits vollständig durchsucht ist, ehe ein unterschiedliches Element gefunden wurde, gilt die kürzere Sequenz als kleiner.

Nachtrag:
Mann kann sich auch anschauen was Perl im String als Zahl interpretiert und was nicht:
{2+4}
{"3:2"+4}
{"a:3:2"+4}

Falls der Anfang des Strings eine Zahl ist wird diese offenbar so transformiert.

Insofern: neyzen, dein DOIF hat die Stunden verglichen sonst nichts, insofern hat es "funktioniert" ::)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

neyzen

Puh, bin leider nur Anwender.
Also ich habe immer nur dieses Zeitformat mit der ich es vergleiche.

e_KalanZamaniHesapla_Aksama
09:13:46
2020-04-03 10:50:14
e_KalanZamaniHesapla_Ikindiye
06:15:46
2020-04-03 10:50:14
e_KalanZamaniHesapla_Oeglene
02:41:46
2020-04-03 10:50:14
e_KalanZamaniHesapla_Sabaha
18:29:46
2020-04-03 10:50:14
e_KalanZamaniHesapla_Yatsiya
10:33:46


Bisher habe ich immer < > genommen um es zu vergleichen, dabei hat es auch immer funktioniert und er Vergleicht auch richtig, wenn das nur Zufall ist müsste ab und zu fehler drin sein und es nicht passen, tut es aber nicht, funktioniert. Allerdings mit der Warnung eben.
So wie es gelesen habe könnte ich anstatt < auch lt und > gt nehmen damit würde er dann immer noch richtig vergleichen aber ich hätte dann diese Warnung nicht mehr?

Otto123

Ja - und damit würde er ab JETZT die komplette Zeit (Zeichenkette) vergleichen. Bisher hat er nur die Stunden verglichen (ich weiß manchmal erzähle ich zuviel)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

neyzen

ich habe jetzt in mein Doif alle < in lt umgeändert und bekomme keine Warnung mehr in den readings und Logfile. Doif funktioniert auch.
Dank dir Otto!

.