Probleme mit Lüftungssteuerung nach Co2 & Feuchte (Hysterese gesucht)

Begonnen von guna83, 08 Oktober 2017, 11:20:26

Vorheriges Thema - Nächstes Thema

guna83

Hallo zusammen,

ich finde leider hier im Forum keine richtige Lösung für mein Problem, ohne dass der Code noch unübersichtlicher wird.
Ich möchte die Lüftungssteuerung wie folgt haben:
- wenn wir nicht schlafen (Szene.Schlafen.Status off) wird der Co2 Wert dort ignoriert
- wenn wir schlafen (Szene.Schlafen.Status on) wird der Co2 Wert im Wohnzimmer (Umwelt.Co2.Wohnen) ignoriert

- Steuerung nach Co2-Wert (wenn zu hoch => mehr Lüften)
- Steuerung nach Feuchte 1 => wenn der Taupunkt außen höher ist (es ist absolut feuchter) als drinnen und es drinnen zu trocken ist => mehr lüften
- Steuerung nach Feuchte 2 => wenn der Taupunkt außen niedriger ist (es ist absolut trockener) als drinnen und es drinnen zu feucht ist => mehr lüften

Das DOIF soll immer durchlaufen wenn jemand: Lüftungsautomatik ein schaltet, Co2 und/oder Feuchte sich ändern, sich der "Schlafenstatus" ändert.

An sich funktioniert das auch recht gut - bloss fehlt eine Hysterese, im Moment "springt" die Lüftungsanlage immer lustig wenn sich Co2 und/oder Feuchte rund um einen der festgelegten Werte dreht :-/. Wie kann ich das "schön" lösen ohne den Code noch mehr aufzublähen?

([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"]) and [Szene.Schlafen.Status] eq "off" and
(([Umwelt.Co2.Wohnen:state:d] > 1500) or
(([Taupunktverhaeltnis:state] > 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] > 65 or [Umwelt.Feuchte.Schlafen:state:d] > 65)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] < 35 or [Umwelt.Feuchte.Schlafen:state:d] < 35))) )
(set Lueftung.Wert.Stufe value 50 g2)
DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"]) and [Szene.Schlafen.Status] eq "off" and
(([Umwelt.Co2.Wohnen:state:d] > 1000) or
(([Taupunktverhaeltnis:state] > 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] > 60 or [Umwelt.Feuchte.Schlafen:state:d] > 60)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] < 40 or [Umwelt.Feuchte.Schlafen:state:d] < 40))) )
(set Lueftung.Wert.Stufe value 37 g2)
DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"]) and [Szene.Schlafen.Status] eq "off" and
(([Umwelt.Co2.Wohnen:state:d] > 800) or
(([Taupunktverhaeltnis:state] > 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] > 55 or [Umwelt.Feuchte.Schlafen:state:d] > 55)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] < 45 or [Umwelt.Feuchte.Schlafen:state:d] < 45))) )
(set Lueftung.Wert.Stufe value 25 g2)

DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"]) and [Szene.Schlafen.Status] eq "on" and
(([Umwelt.Co2.Schlafen:state:d] > 1500) or
(([Taupunktverhaeltnis:state] > 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] > 65 or [Umwelt.Feuchte.Schlafen:state:d] > 65)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] < 35 or [Umwelt.Feuchte.Schlafen:state:d] < 35))) )
(set Lueftung.Wert.Stufe value 50 g2)
DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"]) and [Szene.Schlafen.Status] eq "on" and
(([Umwelt.Co2.Schlafen:state:d] > 1000) or
(([Taupunktverhaeltnis:state] > 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] > 60 or [Umwelt.Feuchte.Schlafen:state:d] > 60)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] < 40 or [Umwelt.Feuchte.Schlafen:state:d] < 40))) )
(set Lueftung.Wert.Stufe value 37 g2)
DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"]) and [Szene.Schlafen.Status] eq "on" and
(([Umwelt.Co2.Schlafen:state:d] > 800) or
(([Taupunktverhaeltnis:state] > 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] > 55 or [Umwelt.Feuchte.Schlafen:state:d] > 55)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([Umwelt.Feuchte.Wohnen:state:d] < 45 or [Umwelt.Feuchte.Schlafen:state:d] < 45))) )
(set Lueftung.Wert.Stufe value 25 g2)

DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"] or ["Szene.Schlafen.Status"]))
(set Lueftung.Wert.Stufe value 12 g2)
DOELSE ()


Danke & Gruß
Guna
1x Intel(R) Atom(TM) with FHEM@2.4GHz, CUNX/KS300, CUNO/Max, KNXD, FTUI 2.2
1x RasPi 2 mit 7" Touch-Display für FTUI

Per

Schon mal versucht, eine "Formel" aufzustellen und dem Ergebnis entsprechend zu schalten?
Allerdings die "Formel" auslagern in ein Dummy oder ein DOIF_Reading (dauert aber noch ;)).

guna83

Danke für den Tipp! Formel war ein gutes Stichwort - auch wenn ich die jetzt im Userreading untergebracht habe.:
myCo2 { abs(ReadingsNum($name,"state",500)-ReadingsNum($name,"myCo2",500))>22 ? ReadingsVal($name,"state",500) : ReadingsVal($name,"myCo2",500);; }

Somit kann das eigentlich DOIF auch wieder einfacher ausfallen:
([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"] or [Szene.Schlafen.Status]) and
((([Umwelt.Co2.Wohnen:myCo2:d] > 1500) and ([Szene.Schlafen.Status] eq "off")) or
(([Umwelt.Co2.Schlafen:myCo2:d] > 1500) and ([Szene.Schlafen.Status] eq "on")) or
(([Taupunktverhaeltnis:state] > 0 ) and ([#max:d:"^Umwelt.Feuchte":myFeuchte] > 65)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([#max:d:"^Umwelt.Feuchte":myFeuchte] < 35))) )
(set Lueftung.Wert.Stufe value 50 g2)
DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"] or [Szene.Schlafen.Status]) and
((([Umwelt.Co2.Wohnen:myCo2:d] > 1000) and ([Szene.Schlafen.Status] eq "off")) or
(([Umwelt.Co2.Schlafen:myCo2:d] > 1000) and ([Szene.Schlafen.Status] eq "on")) or
(([Taupunktverhaeltnis:state] > 0 ) and ([#max:d:"^Umwelt.Feuchte":myFeuchte] > 60)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([#max:d:"^Umwelt.Feuchte":myFeuchte] < 40))) )
(set Lueftung.Wert.Stufe value 37 g2)
DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"] or [Szene.Schlafen.Status]) and
((([Umwelt.Co2.Wohnen:myCo2:d] > 800) and ([Szene.Schlafen.Status] eq "off")) or
(([Umwelt.Co2.Schlafen:myCo2:d] > 800) and ([Szene.Schlafen.Status] eq "on")) or
(([Taupunktverhaeltnis:state] > 0 ) and ([#max:d:"^Umwelt.Feuchte":myFeuchte] > 55)) or
(([Taupunktverhaeltnis:state] < 0 ) and ([#max:d:"^Umwelt.Feuchte":myFeuchte] < 45))) )
(set Lueftung.Wert.Stufe value 25 g2)
DOELSEIF ([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"] or ["Szene.Schlafen.Status"])) 
(set Lueftung.Wert.Stufe value 12 g2)
DOELSE ()


Jetzt muss ich nur noch die optimalen Werte für die "Hysterese" finden (es ist ja eigentlich keine Hysterese - aber es erfüllt so seinen Zweck ;-) )
1x Intel(R) Atom(TM) with FHEM@2.4GHz, CUNX/KS300, CUNO/Max, KNXD, FTUI 2.2
1x RasPi 2 mit 7" Touch-Display für FTUI

Per

([Auto.Schalter.Lueften] eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"] or [Szene.Schlafen.Status])
würde ich noch "ausklammern". Entweder als Dummy oder als Userreading (soviel ich weiss, können die auch Triggern).

DOELSE solltest du ersatzlos streichen können:
(V0 and (V1 > 1500 or V2 > 65 or V3 < 35))
(set Lueftung.Wert.Stufe value 50 g2)
DOELSEIF (V0 and (V1 > 1000 or V2 > 60 or V3 < 40))
(set Lueftung.Wert.Stufe value 37 g2)
DOELSEIF (V0 and (V1 > 800 or V2 < 55 or V3 <45))
(set Lueftung.Wert.Stufe value 25 g2)
DOELSEIF (V0)
(set Lueftung.Wert.Stufe value 12 g2)


Den Rest als Userreadings (bzw. Dummies):
V0: {"[Auto.Schalter.Lueften]" eq "on" and (["^Umwelt"] or ["Taupunktverhaeltnis"] or ["Szene.Schlafen.Status"])}
V1: {("[Szene.Schlafen.Status]" eq "off"?[Umwelt.Co2.Wohnen:myCo2:d]:[Umwelt.Co2.Schlafen:myCo2:d])}
V2: {([Taupunktverhaeltnis:state] > 0?[#max:d:"^Umwelt.Feuchte":myFeuchte]:0)}
V3: {([Taupunktverhaeltnis:state] < 0?[#max:d:"^Umwelt.Feuchte":myFeuchte]:100)}


V2 und V3 könnte man zusammenfassen, ergibt aber nur Sinn, wenn man wirklich eine "Weltformel" ;) will. Sonst wird es wieder aufwendiger.
V23: {([Taupunktverhaeltnis:state] > 0?[#max:d:"^Umwelt.Feuchte":myFeuchte] - 50 :50 - ([Taupunktverhaeltnis:state] < 0?[#max:d:"^Umwelt.Feuchte":myFeuchte]:50))}
Und dann
V23 > 15
V23 > 10
V23 > 5

Ich würde auch die Aggregatsfunktionen als jeweils eigenes Userreadings machen, dann werden sie nur einmal errechnet. Spart Ressourcen.
Gibt es kein "set Lueftung.Wert.Stufe value 0 g2"?

Kommas und Klammern musst du aber auf jeden Fall überprüfen, habe das nur im Editor geschrieben!