DOIF mit and or und vergleichstabelle

Begonnen von Olaf234, 09 September 2022, 15:29:49

Vorheriges Thema - Nächstes Thema

Olaf234

Hallo,
ich arbeite seit einigen Stunden und Tagen an einer Temperaturauswertung die folgendes machen soll:
- positive und negative Temperaturen verarbeiten können
- Übertemperaturalarm ausgeben
-  Untertemperaturalarm ausgeben
- anzeigen, wenn der Normalberich (innerhalb einer Toleranz) erreicht wurde

Mein Grundgedanke ist:
Die Auswertung muss zwischen positiven und negativen Vorzeichen unterscheiden, da sich eine positive Zahl (also über 0 Grad im plusbereich mit einer Toleranzzahl (Hysterese) addiert und mit - substrahiert. Bei Negativzahlen ist es genau umgekehrt. Daher nehme ich als Hilfsparameter den Temperatur_Soll. Ein Beispiel:
Eine Temperatur von 20°C  verglichen mit [Solltemperatur 20°C] + [Toleranz 5°C] ist eine Untertemperatur
Eine Temperatur von -20°C verglichen mit [Solltemperatur -20°C] + [Toleranz 5°C] ist eine Übertemperatur
Mein Code sieht folgerndermaßen aus

### 01 Übertemperatur
(
([?Temperatursensor01_T_Soll] > 0 and [Sensor01:temperature] > ([?Temperatursensor01_T_Soll] - [?Temperatursensor01_T_Hysterese])
or [?Temperatursensor01_T_Soll] < 0 and [Sensor01:temperature] > ([?Temperatursensor01_T_Soll] + [?Temperatursensor01_T_Hysterese]))
)

(setreading doif_Sensor01_Auswertung T high)


### 02 Unterpemperatur
DOELSEIF (
([?Temperatursensor01_T_Soll] > 0 and [Sensor01:temperature] < ([?Temperatursensor01_T_Soll] + [?Temperatursensor01_T_Hysterese])
or [?Temperatursensor01_T_Soll] < 0 and [Sensor01:temperature] < ([?Temperatursensor01_T_Soll] - [?Temperatursensor01_T_Hysterese]))
)

(setreading doif_Sensor01_Auswertung T low)


## 03 T:Rückkehr zur Normalität (Temp innerhalb der Grenze zwischen zu viel und zu wenig)
DOELSEIF(
([?doif_Sensor01_Auswertung:T] ne "normal"
and ([?Temperatursensor01_T_Soll] >= 0
and [Sensor01:temperature] < ([?Temperatursensor01_T_Soll] + [?Temperatursensor01_T_Hysterese])
and [Sensor01:temperature] > ([?Temperatursensor01_T_Soll] - [?Temperatursensor01_T_Hysterese]))
or ([?Temperatursensor01_T_Soll] < 0
and [Sensor01:temperature] > ([?Temperatursensor01_T_Soll] + [?Temperatursensor01_T_Hysterese])
and [Sensor01:temperature] < ([?Temperatursensor01_T_Soll] - [?Temperatursensor01_T_Hysterese]))
))
(setreading doif_Sensor01_Auswertung T normal)


Ich habe den totalen Knoten im Kopf, gestern schien mir alles noch klar - heute bin ich vor lauter Klammern fix und fertig. Kann sich bitte jemand mit mir über die richtige Verknüpfung der and/or Bedingungen machen? Ich wäre super dankbar



Damian

Es ist egal, ob die Temperatur größer oder kleiner als Null ist.

Es gibt eine Obergrenze mit: Zieltemperatur+Hysterese/2 und eine Untergrenze: Zieltemperatur-Hysterese/2

Dann funktioniert ein Thermostat zum Heizen wie folgt:

define di_threshold DOIF ([sensor:temperature] < [$SELF:desired]-[$SELF:hysteresis]/2)
(set heating on)
DOELSEIF ([sensor:temperature] > [$SELF:desired]+[$SELF:hysteresis]/2)
(set heating off)


und das bei positiven wie auch bei negativen Werten ;)

siehe auch https://fhem.de/commandref_DE.html#DOIF_Weitere_Anwendungsbeispiele
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Olaf234

#2
Vielen Dank für Deine Antwort. Ich habe das mal geändert wie du sast, muss aber noch verstehen warum das so funktioniert.
Ich habe aber auch noch eine Auswertung erdacht, die anzeigen soll, wann der Normalbereich wieder erreicht wurde. bei mir sieht das so aus:DOELSEIF(
([?doif_Sensor01_Auswertung:T] ne "normal"
and ([?Temperatursensor01_T_Soll] >= 0
and [Sensor01:temperature] < ([?Temperatursensor01_T_Soll] + [?Temperatursensor01_T_Hysterese])
and [Sensor01:temperature] > ([?Temperatursensor01_T_Soll] - [?Temperatursensor01_T_Hysterese]))
or ([?Temperatursensor01_T_Soll] < 0
and [Sensor01:temperature] > ([?Temperatursensor01_T_Soll] + [?Temperatursensor01_T_Hysterese])
and [Sensor01:temperature] < ([?Temperatursensor01_T_Soll] - [?Temperatursensor01_T_Hysterese]))
))
(setreading doif_Sensor01_Auswertung T normal)


was ich jetzt kurzerhand in
DOELSEIF(
[?doif_Sensor01_Auswertung:T] ne "normal"
and ([Sensor01:temperature] < [?Temperatursensor01_T_Soll] + [?Temperatursensor01_T_Hysterese]/2
and [Sensor01:temperature] > [?Temperatursensor01_T_Soll] - [?Temperatursensor01_T_Hysterese]/2
)
)

abgeändert habe. Bist Du so gut und schaust Dir das noch einmal an? Kann das funktionieren?

Damian

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

Olaf234

#4
Der Probelauf war leider negativ. Nach etlichen Versuchen und mit Hilfe von Excel-Wahrheitstabellen glaube ich nun, dass wenn eine Fehlermeldung ausgegeben werden soll die über den gesamten Temperaturbereich funktioniert (-40 bis +60) und z.B. bei -17°C (ist) und -20°C (soll) einen Low temperatur Alarm auslösen soll die Vorzeichen verändern werden müssen, sobald es über den 0 Punkt geht weil rechnerisch -17 größer ist als -20. Im Plusbereich wäre 17 aber kleiner als 20.

Damit FHEM die Vorzeichen ändert dient die Solltemperatur als Referenz:
## 01 T: zu hoch im Plusbereich
(
[?$SELF:Desired_T] >= 0
and [Sensor01:temperature] > ([?$SELF:Desired_°C]) + [?$SELF:Hysterisis_°C]/2
)
(setreading $SELF T high)

## 02 T: zu tief im Plusbereich
DOELSEIF (
[?$SELF:Desired_T] >= 0
and [Sensor01:temperature] < [?$SELF:Desired_°C] - [?$SELF:Hysterisis_°C]/2
)
(setreading $SELF T low)

## 03 T: zu tief im Minunsbereich
(
[?$SELF:Desired_T] < 0
and [Sensor01:temperature] < ([?$SELF:Desired_°C]) - [?$SELF:Hysterisis_°C]/2
)
(setreading $SELF T high)

## 04 T: zu Hoch im Minusbereich
DOELSEIF (
[?$SELF:Desired_T] < 0
and [Sensor01:temperature] > [?$SELF:Desired_°C] + [?$SELF:Hysterisis_°C]/2
)
(setreading $SELF T low)


um dies zu vereinfachen, könnteman aber mit "or" arbeiten, nur bin ich mir nicht sicher ob es so richtig geschrieben ist.
## 01 T: zu hoch
(
[?$SELF:Desired_T] >= 0 and ([Sensor01:temperature] > ([?$SELF:Desired_°C]) + [?$SELF:Hysterisis_°C]/2
or ([?Sensor01:temperature] < 0 and [Sensor01:temperature] < ([?$SELF:Desired_°C]) - [?$SELF:Hysterisis_°C]/2))
)
(setreading $SELF T high)

## 02 T: zu tief
DOELSEIF (
[?$SELF:Desired_T] >= 0 and ([Sensor01:temperature] < [?$SELF:Desired_°C] - [?$SELF:Hysterisis_°C]/2
or ([?Sensor01:temperature] < 0 and [Sensor01:temperature] > [?$SELF:Desired_°C] + [?$SELF:Hysterisis_°C]/2))
)
(setreading $SELF T low)


Das Vorzeichen macht  dann aber bei der Abfrage ob der Temperaturwert wieder im Normalberich liegt keinen Unterschied.
DOELSEIF (
[?$SELF T] ne "normal"
and [Sensor01:temperature] < ([?$SELF:Desired_°C]) + [?$SELF:Hysterisis_°C]/2
and [Sensor01:temperature] > ([?$SELF:Desired_°C]) - [?$SELF:Hysterisis_°C]/2
)
(setreading $SELF T normal)

Damian

Also dann rechne ich mal nach. Ausgehend von dieser Regelung eines Thermostats:

define di_threshold DOIF ([sensor:temperature] < [$SELF:desired]-[$SELF:hysteresis]/2)
(set heating on)
DOELSEIF ([sensor:temperature] > [$SELF:desired]+[$SELF:hysteresis]/2)
(set heating off)


Bei einer Zieltemperatur von 20 und eine Hysterese von 1 Grad ergibt sich der obere Punkt als 20+1/2=20,5 und der untere Punkt mit 20-1/2=19,5, dh. es wird geheizt wenn die Temperatur unter 19,5 Grad fällt (cmd_1), die Heizung wird ausgeschaltet wenn die Temperatur über 20,5 geht.

Bei einer Zieltemperatur von -20 Grad ergibt sich der obere Punkt als -20+1/2=-19,5 und der untere Punkt mit -20-1/2=-20,5, dh. es wird geheizt, wenn die Temperatur unter -20,5 fällt (cmd_1), die Heizung wird ausgeschaltet wenn die Temperatur über -19,5 geht.

Und so sollte es funktionieren.

Für dich bedeutet das:

alles ok wenn

[sensor:temperature] >= [$SELF:desired]-[$SELF:hysteresis]/2 and [sensor:temperature] <= [$SELF:desired]+[$SELF:hysteresis]/2

und sonst nicht.

Und auch das kannst du gerne für 20 bzw. -20 Grad durchspielen - es ist und bleibt vom Minuszeichen unabhängig.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Olaf234

ich gebe Dir 100% Recht. In diesem Szenario ist das absolut richtig. Was passiert aber, wenn ich in einem CMD errechnen möchte, dass die Temperatur unter, bzw. über dem min/max Wert liegt und darüber ein Alarm augegeben werden soll?

[sensor:temperature] < [$SELF:desired]-[$SELF:hysteresis] (setreading $SELF T low)
gemessen 18°C. soll 20°C, Hysterese -2 (Min.Bereich). Die Meldung lautet: Temperatur tiefer als min.
18 < 20-1 (19) = true

Nun die selbe Rechnung im Minusbereich:
gemessen -18°C. Soll -20°C, Hysterese -2 (Max.Bereich). Die Meldung lautet: alles gut!
-18 < -20-1 (-21) = false

Nobbynews

Zitat von: Olaf234 am 13 September 2022, 13:21:49
und z.B. bei -17°C (ist) und -20°C (soll) einen Low temperatur Alarm auslösen soll die Vorzeichen verändern werden müssen, sobald es über den 0 Punkt geht weil rechnerisch -17 größer ist als -20. Im Plusbereich wäre 17 aber kleiner als 20.
Nach meinem Verständnis muss hier aber ein High Alarm ausgelöst werden.
In Deinem Überlegungen setzt Du mMn gedanklich immer die absoluten Werte an.
Also würde ich es mal mit abs() probieren.

Damian

#8
Zitat von: Olaf234 am 13 September 2022, 16:15:51
ich gebe Dir 100% Recht. In diesem Szenario ist das absolut richtig. Was passiert aber, wenn ich in einem CMD errechnen möchte, dass die Temperatur unter, bzw. über dem min/max Wert liegt und darüber ein Alarm augegeben werden soll?

[sensor:temperature] < [$SELF:desired]-[$SELF:hysteresis] (setreading $SELF T low)
gemessen 18°C. soll 20°C, Hysterese -2 (Min.Bereich). Die Meldung lautet: Temperatur tiefer als min.
18 < 20-1 (19) = true

Nun die selbe Rechnung im Minusbereich:
gemessen -18°C. Soll -20°C, Hysterese -2 (Max.Bereich). Die Meldung lautet: alles gut!
-18 < -20-1 (-21) = false

Es ist nicht die selbe Rechnung.

Wenn du die selben Sachen vergleichen willst, dann musst du Min.Bereich mit Min.Bereich vergleichen einmal im negativen und einmal im positiven Bereich.

Mathematisch ist -18 ja auch nicht tiefer als -20, 18 ist dagegen tiefer als 20.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF