Verständnisfrage HM Script IF-Abfrage

Allgemeines zur HomeMatic Haussteuerung

Moderator: Co-Administratoren

Antworten
Benutzeravatar
Yosh
Beiträge: 90
Registriert: 24.07.2021, 23:30
System: CCU
Hat sich bedankt: 21 Mal
Danksagung erhalten: 11 Mal

Verständnisfrage HM Script IF-Abfrage

Beitrag von Yosh » 17.09.2021, 08:26

Moin zusammen,

ich bastel gerade an einer Rolladensteuerung nach dem Vorbild aus dem Beitrag von MichaelN.

Im Sinne der "Funkhygiene" will ich nur etwas an den Aktor senden, wenn sich die Zielbehanghöhe von der Aktuellen unterscheidet. Eigentlich ganz einfach. Hat mich gestern aber "Blut, Schweiß und Tränen" gekostet und ich verstehe immer noch nicht, warum das Script so verhält...

Bei folgendem Code wird der If-Block nicht angesprochen wenn die aktuelle Höhe nicht 1 ist:

Code: Alles auswählen

real hoehe_ziel;
real hoehe_aktuell;

hoehe_aktuell = dom.GetObject("HmIP-RF.00111BE9A58AF7:3.LEVEL").Value(); !- HM-IP-BROLL
hoehe_ziel = 0;

WriteLine("aktuelle Höhe:" # hoehe_aktuell # " Zielhöhe:" # hoehe_ziel);

if (hoehe_ziel != hoehe_aktuell)
{
  WriteLine("IF Block wird ausgeführt");
}

WriteLine("Script beendet");    


Ausgabe:

Code: Alles auswählen

aktuelle Höhe:0.965000 Zielhöhe:0
Script beendet
Bei aktueller Höhe von 1:

Code: Alles auswählen

aktuelle Höhe:1.000000 Zielhöhe:0
IF Block wird ausgeführt
Script beendet
Es funktioniert immer, wenn ich die Zielhöhe auf 0.000000 (mit 6 Nachkommastellen) setze:

Code: Alles auswählen

aktuelle Höhe:0.965000 Zielhöhe:0.000000
IF Block wird ausgeführt
Script beendet
Hat jemand dafür eine Erklärung?

Gruß,
Yosh
Umgebung: CCU3 (FW 3.69.7) / FB 7590 / Hue Bridge mit 17 Lampen (Hue, TRÅDFRI, Osram) / 6x Amazon Echo
Geräte: 505 Kanäle in 83 Geräten // 42 Kanäle in 6 Heizgruppen // 140 CUxD-Kanäle in 20 CUxD-Geräten
Addons: NEO Server 2.12.2 / CUx-Daemon 2.10.1 / CUxD-Highcharts 1.4.5 / Programme drucken 2.6 / HM Pdetect 1.15 / Philips Hue 3.2.5 / HQ WebUI 2.5.9
API Keys: Google (Script , Maps, Calendar) / AccuWeather / Tankerkönig / PushOver
Sonstige: SDV v4.09.04G / AIO Creator NEO v3.0.3 mit 2x Samsung S20FE und 1x Tab A6 / Mediola Cloud / Alexa.sh

Benutzeravatar
jmaus
Beiträge: 9818
Registriert: 17.02.2015, 14:45
System: Alternative CCU (auf Basis OCCU)
Wohnort: Dresden
Hat sich bedankt: 459 Mal
Danksagung erhalten: 1855 Mal
Kontaktdaten:

Re: Verständnisfrage HM Script IF-Abfrage

Beitrag von jmaus » 17.09.2021, 08:47

Yosh hat geschrieben:
17.09.2021, 08:26
ich bastel gerade an einer Rolladensteuerung nach dem Vorbild aus dem Beitrag von MichaelN.

Bei folgendem Code wird der If-Block nicht angesprochen wenn die aktuelle Höhe nicht 1 ist:

[...]

Es funktioniert immer, wenn ich die Zielhöhe auf 0.000000 (mit 6 Nachkommastellen) setze:

Code: Alles auswählen

aktuelle Höhe:0.965000 Zielhöhe:0.000000
IF Block wird ausgeführt
Script beendet
Hat jemand dafür eine Erklärung?
Ja, habe ich:

Es findet auch bei den if() anweisung immer eine implizite Typwandlung statt. Deine "Zielhöhe" hast du zwar oben als "real" d.h. floating point definiert, dann aber ein integer (Ganzzahlenwert) zugewiesen. Insofern wird aus der Variable dann in dem moment eine Integervariable (weil ReGaHss eben implizite Typwandlungen macht). Und wenn du nun ein if(real != integer) vergleich machst werden die variablen abgearbeitet und dann passiert genau das was du da bemerkst: Er sieht die zielhöhe variable, merkt das es eine integer variable ist und will folglich ein integer vergleich machen. Dann sieht er die aktuell variable im if() und merkt, das ist aber eine float/real und wandelt die implizit in ein integer um. Folglich wird aus einer 0.9 dann eben eine 0 und schwubs hat er einen if(0 != 0) vergleich der nicht wahr wird und deshalb auch nicht ausgeführt wird. Du musst also entweder sicherstellen das die beiden variablen wirklich zum zeitpunkt des vergleiches vom gleichen typ sind oder musst die reihenfolge des vergleiches umdrehen damit die typwandlung eben andersherum passiert (integer -> real) und nicht wie jetzt (real -> integer). Deshalb ist es IMHO auch richtig wenn du die zielhöhe als "0.0" angibst (wie du das erwähnt hast) und damit der Skriptengine explizit sagst du willst da nen floating point wert in der variable sehen.

Als weiteren Hinweis will ich dir aber noch auf den Weg geben, dass ungerundete floating point Vergleiche mit dem Wert 0 fast nie eine gute Idee sind in Programmiersprachen, denn der Wert den du vielleicht vorliegen hast wird fast nie exakt auf 0 fallen. Es ist daher immer eine gute idee entweder einen gewissen threshold im vergleich vorauszusetzen (z.B. "if( x < 0.005)") damit keine numerischen Instabilität dir deine logik kaputt machen oder du rundest den zu vergleichenden wert explizit auf eine nachkommastelle, also sowas wie "if(x.Round(2) != 0.0)" damit der wert wirklich dann auch auf 0.0 fallen kann.
RaspberryMatic 3.75.6.20240316 @ ProxmoxVE – ~200 Hm-RF/HmIP-RF/HmIPW Geräte + ioBroker + HomeAssistant – GitHub / Sponsors / PayPal / ☕️

Benutzeravatar
Yosh
Beiträge: 90
Registriert: 24.07.2021, 23:30
System: CCU
Hat sich bedankt: 21 Mal
Danksagung erhalten: 11 Mal

Re: Verständnisfrage HM Script IF-Abfrage

Beitrag von Yosh » 17.09.2021, 09:22

Hallo Jens,

Wow!!! Vielen lieben Dank! Das ist ja eine "böse Falle" wenn man es nicht weiß...

Ich habe mich im Laufe meines Lebens zwar schon in diversen Script- und Progammiersprachen getummelt aber jede hat halt so ihre Eigenarten...

Nochmals Danke, auch für den Tip mit dem Null-Vergleich,
Yosh
Umgebung: CCU3 (FW 3.69.7) / FB 7590 / Hue Bridge mit 17 Lampen (Hue, TRÅDFRI, Osram) / 6x Amazon Echo
Geräte: 505 Kanäle in 83 Geräten // 42 Kanäle in 6 Heizgruppen // 140 CUxD-Kanäle in 20 CUxD-Geräten
Addons: NEO Server 2.12.2 / CUx-Daemon 2.10.1 / CUxD-Highcharts 1.4.5 / Programme drucken 2.6 / HM Pdetect 1.15 / Philips Hue 3.2.5 / HQ WebUI 2.5.9
API Keys: Google (Script , Maps, Calendar) / AccuWeather / Tankerkönig / PushOver
Sonstige: SDV v4.09.04G / AIO Creator NEO v3.0.3 mit 2x Samsung S20FE und 1x Tab A6 / Mediola Cloud / Alexa.sh

Antworten

Zurück zu „HomeMatic allgemein“