falsche Vergleiche von Gleitkommazahlen im Script

Einrichtung, Anschluss und Programmierung der HomeMatic CCU

Moderator: Co-Administratoren

Matsch
Beiträge: 5427
Registriert: 30.05.2019, 11:37
System: Alternative CCU (auf Basis OCCU)
Wohnort: Chemnitz
Hat sich bedankt: 114 Mal
Danksagung erhalten: 734 Mal

falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Matsch » 18.07.2019, 13:00

CCU3, V 3.45.7
Eigentlich eine auf den ersten Blick sehr einfache Aufgabe.
Ich möchte in einem Homematic-Script die Differenz zweier Temperatursensoren ermitteln und diese nur dann in eine Variable einschreiben, wenn sich der Wert gegenüber der Variablen geändert hat:

Code: Alles auswählen

! Differenz aussen-innen ermitteln                     

real T_out = dom.GetObject("Temperatur/Luftfeuchtigkeitssensor_Ch1").DPByHssDP("ACTUAL_TEMPERATURE").Value();
real T_in = dom.GetObject("SZ_Klimasensor_Ch1").DPByHssDP("ACTUAL_TEMPERATURE").Value();
var Delta = dom.GetObject("SV_SZ_Delta_Temperatur");

if ((T_out - T_in) <> Delta.Value())
{
   Delta.State(T_out - T_in);
}
Funktioniert aber nicht! Obwohl der Browser für den neu errechneten Wert und den früher gespeicherten Wert identisch gleich anzeigt (bis zur 6. Stelle nach dem Komma) liefert der if-Vergleich stets den Wert true. Ich bin fast daran verzweifelt, bis ich aus lauter Blödsinn die Werte vor dem Vergleich versuchsweise mal gerundet habe:

Code: Alles auswählen

if ((T_out - T_in).Round(4) <> Delta.Value())
{
   Delta.State(T_out - T_in);
}
Plötzlich geht alles einwandfrei, selbst dann, wenn ich als Rundung .Round(12) benutze!
Ich habe nach bekannten Problemen gesucht, aber dieses hier nicht gefunden.

Matsch
Beiträge: 5427
Registriert: 30.05.2019, 11:37
System: Alternative CCU (auf Basis OCCU)
Wohnort: Chemnitz
Hat sich bedankt: 114 Mal
Danksagung erhalten: 734 Mal

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Matsch » 18.07.2019, 13:09

OK, habe den Fehler gefunden.
Ich hatte als Grenzwerte der Variablen SV_SZ_Delta_Temperatur eingeben: -40 .... 50.
Damit bewertet die CCU die Variable wohl als Ganzzahl.

Ein neu definierter Bereich -40.0 ... 50.0 hat das Problem behoben!

dtp
Beiträge: 10658
Registriert: 21.09.2012, 08:09
System: CCU
Wohnort: Stuttgart
Hat sich bedankt: 320 Mal
Danksagung erhalten: 501 Mal

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von dtp » 18.07.2019, 15:32

Evtl. hätte ein

Code: Alles auswählen

Delta.Value().ToFloat()
das Problem auch gelöst.
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

Benutzeravatar
Black
Beiträge: 5472
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 419 Mal
Danksagung erhalten: 1071 Mal
Kontaktdaten:

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Black » 18.07.2019, 17:25

Matsch hat geschrieben:
18.07.2019, 13:09
OK, habe den Fehler gefunden.
Ich hatte als Grenzwerte der Variablen SV_SZ_Delta_Temperatur eingeben: -40 .... 50.
Damit bewertet die CCU die Variable wohl als Ganzzahl.

Ein neu definierter Bereich -40.0 ... 50.0 hat das Problem behoben!
Das darf es eigentlich nicht sein...

eine normale Systemvariable Type Zahl ergibt ValueType 4 bzw ValueTypeStr Float, eine IntegerSysvar (Aufzählung, oder Alarmmeldungen ergibt ValueType 16 bzw ValueTypeStr Integer

das blöde ist, ich konnte deinen Fehler bei mir Nachstellen, bis auf das Bereich umdefinieren, das hat darauf keinen Einfluss.
Testaa.jpg

Code: Alles auswählen

!- Differenz aussen-innen ermitteln

real T_out =23.6;
real T_in = 24.7;
object Delta = dom.GetObject("NeuTestZahl");
real diff= T_out-T_in;
WriteLine (diff);
WriteLine (Delta.Variable () );
if (diff != Delta.Variable())
{
   WriteLine ("SET");
   Delta.State(diff);
} else {
   WriteLine ("Not SET");
}    
ergab:

Code: Alles auswählen

------------------------------- Scriptausgabe -------------------------------
-1.100000
-1.100000
SET
------------------------------ Script Variablen -----------------------------
[T_out             ]: 23.600000
[T_in              ]: 24.700000
[Delta             ]: NeuTestZahl
[diff              ]: -1.100000
während das hier:

Code: Alles auswählen

!- Differenz aussen-innen ermitteln

real T_out =23.6;
real T_in = 24.7;
object Delta = dom.GetObject("NeuTestZahl");
real diff= T_out-T_in;
WriteLine (diff);
WriteLine (Delta.Variable () );
if (-1.100000 != Delta.Variable())
{
   WriteLine ("SET");
   Delta.State(diff);
} else {
   WriteLine ("Not SET");
} 
sauber durchgeht.

Code: Alles auswählen

------------------------------- Scriptausgabe -------------------------------
-1.100000
-1.100000
Not SET
------------------------------ Script Variablen -----------------------------
[T_out             ]: 23.600000
[T_in              ]: 24.700000
[Delta             ]: NeuTestZahl
[diff              ]: -1.100000
Black
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

Matsch
Beiträge: 5427
Registriert: 30.05.2019, 11:37
System: Alternative CCU (auf Basis OCCU)
Wohnort: Chemnitz
Hat sich bedankt: 114 Mal
Danksagung erhalten: 734 Mal

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Matsch » 20.07.2019, 11:39

@Black, genau dieses Verhalten hatte ich bei meinen Versuchen auch festgestellt und ins Grübeln gebracht!
Auch sehr komisch, dass allein ein Rundungsbefehl *.Round(12) zur korrekten Funktion führt! 12 Stellen nach dem Komma!

Aber wenn da doch noch ein Bug in der Software steckt, dann hätte das doch irgendeinem Anwender schon lange mal auffallen müssen. Ist doch eigentlich ein simpler alltäglicher Vergleich.

Interessant auch:
Die Datenpunkte aus den Sensoren sind eigentlich als integer definiert. Stelle ich alle Variablen im Script deshalb mal auf integer statt real um, hat das keinen Effekt, die Vergleichsauswertung ist auch dabei wieder falsch.

Benutzeravatar
Black
Beiträge: 5472
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 419 Mal
Danksagung erhalten: 1071 Mal
Kontaktdaten:

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Black » 20.07.2019, 15:59

die Datenpunkte Temperatur und Humidity sind zumindest beimeinem Wandthermosten und Heiszungsthermosten als float definiert.
Dev 4-2.jpg
Black
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

Matsch
Beiträge: 5427
Registriert: 30.05.2019, 11:37
System: Alternative CCU (auf Basis OCCU)
Wohnort: Chemnitz
Hat sich bedankt: 114 Mal
Danksagung erhalten: 734 Mal

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Matsch » 20.07.2019, 17:27

Was ist eigentlich der Unterschied zwischen logischem und physikalischem Datentyp?
In der Definition steht Logisch FLOAT, Physikalisch integer (es sind beides HmIP-Sensoren).

Heißt das, dass zwar der Wert in einer integer übertragen wird vom Sensor, dieser dann aber als float-Zahl zur Verfügung gestellt wird?

Dann wäre es also doch im Script eine float-Zahl.

jp112sdl
Beiträge: 12108
Registriert: 20.11.2016, 20:01
Hat sich bedankt: 848 Mal
Danksagung erhalten: 2148 Mal
Kontaktdaten:

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von jp112sdl » 20.07.2019, 17:40

Da physisch nur einzelne Bytes übertragen werden (die je nach Anzahl dann einen 8-, 16-, ... Bit breiten Ganzzahlwert ergibt), bedient man sich einem Divisor, um daraus dann eine Gleitkommazahl zu machen.

Beispiel Temperatursensor:
Es soll eine Temperatur von 10,7°C übertragen werden. Man multipliziert das im Sensor mit 10, überträgt ein Byte "107" und sagt der CCU dass der Wert wieder durch 10 geteilt werden muss (und eine Gleitkommazahl von 10,7 ergibt).
Sieht in der Geräte-XML so aus:

Code: Alles auswählen

<physical type="integer" interface="command" value_id="TEMPERATURE">
<conversion type="float_integer_scale" factor="10.0"/>

VG,
Jérôme ☕️

---
Support for my Homebrew-Devices: Download JP-HB-Devices Addon

Matsch
Beiträge: 5427
Registriert: 30.05.2019, 11:37
System: Alternative CCU (auf Basis OCCU)
Wohnort: Chemnitz
Hat sich bedankt: 114 Mal
Danksagung erhalten: 734 Mal

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Matsch » 20.07.2019, 17:51

Danke!

Benutzeravatar
Black
Beiträge: 5472
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 419 Mal
Danksagung erhalten: 1071 Mal
Kontaktdaten:

Re: falsche Vergleiche von Gleitkommazahlen im Script

Beitrag von Black » 20.07.2019, 17:55

das die kommunikation integer basiert ist mir klar.

seine probleme beruhen aber auf float operation der rega, nachdem der i8 bzw i16 in float konvertiert worden ist
Zuletzt geändert von Black am 20.07.2019, 20:27, insgesamt 1-mal geändert.
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

Antworten

Zurück zu „HomeMatic Zentrale (CCU / CCU2 / CCU3 / Charly)“