DOIF Optimierung - Bitte um Unterstützung - Komme nicht weiter

Begonnen von forum-merlin, 06 November 2021, 13:36:10

Vorheriges Thema - Nächstes Thema

forum-merlin

Hi Experts!
Ich brauche mal Eure Hilfe bei einer Optimierung eines DOIF bzw. eines Szenarios.

Kurz zur Erklärung...
Ich habe einen LaCross Temp/Feuchte Sensor im Schlafzimmer
Dieser soll einen Homematic Zwischenstecker triggern wenn Luftfeuchtewert X% über- oder unterschritten wurde. Drumrum noch einen Deckenventilator und einen Dummy.
Es soll aber auch Ruhezeiten geben weil der am Zwischenstecker angeschlossene Luftentfeuchter im Schlafzimmer schon etwas laut ist.

Das "Problem" das ich (wahrscheinlich) identifiziert habe ist, dass bei einer Meldung des Sensors der HM-Stecker immer wieder mit z.B. einem AUS befeuert wird wenn der Sensor seine Werte aktualisiert und der Luftfeuchtewert eben unterschritten wurde. Is ja vom prinzip richtig, aber jedes Mal ein AUS sprengt meine 1%-Regel für den Funk.
Ja, es gibt ein event-on-change-reading und auch ein event-on-update-reading, aber in Kombination mit den Ruhezeiten oder Schwellwerten kann es vorkommen, dass Werte über-/unterschritten sind und dann keine Schlatung am Zwischenstecker passiert. Oder eben weil werte schon erreicht sind und somit der Schaltzustand schon erreicht sein sollte aber aufgrund von Ruhezeit nicht ausgeführt wurde.
Ich weiss also nicht wie ich das am besten einsetze.

Mein stümperhafter Ansatz wäre nun noch eine Zwischenebene einzuziehen und die Messwerte per weiterem DOIF in ein Dummy zu schreiben und dann, ach ich weiss auch nicht...
Sowas wie...
Wenn Sensor wert <=60 set Du_Sensorwert HumidityOK
Wenn Sensor wert <=40 set Du_Sensorwert HumidityTooDry
Wenn Sensor wert >=68 set Du_Sensorwert HumidityTooWet
Und dann den unten stehenden DOIF eben nicht direkt auf den SZ.TempSensor:humidity zu prüfen sondern auf den Du_Sensorwert:state <value>


Das is mein derzeitiges DOIF welches direkt auf den Sensor auswertet und optimiert werden müsste:


defmod doif_luftfeuchte_Schlafzimmer_neu DOIF ([20:01-07:59|Mo Di Mi Do Fr]) (set HM.Zwischenstecker_Sw off, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)\
DOELSEIF \
([08:00-10:00|Mo Di Mi Do Fr] and [SZ.TempSensor:humidity] >= 60) (set HM.Zwischenstecker_Sw on, set du_SZ.Ventilator reset, set du_SZ.Ventilator 1)\
DOELSEIF \
([10:01-18:00|Mo Di Mi Do Fr] and [SZ.TempSensor:humidity] >= 60) (set HM.Zwischenstecker_Sw on, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)\
DOELSEIF \
([18:01-20:00|Mo Di Mi Do Fr] and [SZ.TempSensor:humidity] >= 65) (set HM.Zwischenstecker_Sw on, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)\
DOELSEIF \
([SZ.TempSensor:humidity] <= 57) (set HM.Zwischenstecker_Sw off, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)\
DOELSEIF \
([20:01-10:29|Sa So]) (set HM.Zwischenstecker_Sw off, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)\
DOELSEIF \
([10:30-12:00|Sa So] and [SZ.TempSensor:humidity] >= 60) (set HM.Zwischenstecker_Sw on, set du_SZ.Ventilator reset, set du_SZ.Ventilator 1)\
DOELSEIF \
([12:01-18:00|Sa So] and [SZ.TempSensor:humidity] >= 60) (set HM.Zwischenstecker_Sw on, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)\
DOELSEIF \
([18:01-20:00|Sa So] and [SZ.TempSensor:humidity] >= 65) (set HM.Zwischenstecker_Sw on, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)\
DOELSE
attr doif_luftfeuchte_Schlafzimmer_neu disable 0
attr doif_luftfeuchte_Schlafzimmer_neu room Logik->DOIF

setstate doif_luftfeuchte_Schlafzimmer_neu cmd_5
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 13:16:00 Device SZ.TempSensor
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 12:01:00 cmd 5
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 12:01:00 cmd_event SZ.TempSensor
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 12:01:00 cmd_nr 5
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 13:16:00 e_SZ.TempSensor_humidity 54
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-01-03 19:39:38 mode enabled
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 12:01:00 state cmd_5
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 07:59:00 timer_01_c01 06.11.2021 20:01:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 07:59:00 timer_02_c01 07.11.2021 07:59:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 10:00:00 timer_03_c02 07.11.2021 08:00:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 10:00:00 timer_04_c02 07.11.2021 10:00:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 18:00:00 timer_05_c03 06.11.2021 10:01:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 18:00:00 timer_06_c03 06.11.2021 18:00:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 20:00:00 timer_07_c04 06.11.2021 18:01:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 20:00:00 timer_08_c04 06.11.2021 20:00:00|MoDiMiDoFr
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 10:29:00 timer_09_c06 06.11.2021 20:01:00|SaSo
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 10:29:00 timer_10_c06 07.11.2021 10:29:00|SaSo
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 12:00:00 timer_11_c07 07.11.2021 10:30:00|SaSo
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-06 12:00:00 timer_12_c07 07.11.2021 12:00:00|SaSo
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 18:00:00 timer_13_c08 06.11.2021 12:01:00|SaSo
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 18:00:00 timer_14_c08 06.11.2021 18:00:00|SaSo
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 20:00:00 timer_15_c09 06.11.2021 18:01:00|SaSo
setstate doif_luftfeuchte_Schlafzimmer_neu 2021-11-05 20:00:00 timer_16_c09 06.11.2021 20:00:00|SaSo





Das muss doch insg. sicher eleganter gehen als mein verschachtelter, stümperhafter Ansatz oder?

Wer kann mir hier mal ein ready-to-use beispiel für mein Szenario schreiben damit ich davon lernen kann?
Und eben auch mit den Attributes wie event-on-.*
Ich habe nämlich einige DOIfs dann zu optimieren.


Ich danke euch schonmal!
Gruß
Holger
FHEM 5.8 auf RasPi3; CULv3-868; RFXtrx433; HM-Sec-SC-2; HM-CFG-LAN; HM-LC-Bl1-FM; HM-CC-RT-DN; HM-ES-PMSw1-Pl; HM-LC-Sw4-DR; Hunter Ventile; 8ch Relais; ENIGMA2; ONKYO_AVR; SONOS; Harmony; telegram; HM-PB-6-WM55; GPIO; HM-Sen-MDIR-O; HM-SEC-SD; HM-LC-Dim1L-Pl-3;

Otto123

#1
Hallo Holger,

bei HM machst Du als allerersten (auch leicht stümperhaften) Ansatz:
attr TYPE=CUL_HM event-on-change-reading .*
Es sei denn Du hast schon welche gesetzt, das kannst Du so prüfen:
list TYPE=CUL_HM event-on-change-reading
Besser wäre es zu ermitteln welche Events brauche ich und die anderen quasi abzuschalten (nur als Beispiel):
attr SZ.TempSensor event-on-change-reading humidity

Dein DOIF würde ich so zusammenfassen, dass Du gleiche Ausführungsteile zusammenfasst - Beispiele :
([20:01-07:59|Mo Di Mi Do Fr] or [20:01-10:29|Sa So] or [SZ.TempSensor:humidity] <= 57) (set HM.Zwischenstecker_Sw off, set du_SZ.Ventilator reset, set du_SZ.Ventilator Aus)

Bei den mit komplexeren musst Du manchmal Klammern https://perldoc.perl.org/perlop#Operator-Precedence-and-Associativity:
([12:01-18:00|Sa So] and [SZ.TempSensor:humidity] >= 60 or [18:01-20:00|Sa So] and [SZ.TempSensor:humidity] >= 65)
( ( [10:30-12:00|Sa So] or [08:00-10:00|Mo Di Mi Do Fr] ) and [SZ.TempSensor:humidity] >= 60)

Gruß Otto
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

forum-merlin

Danke Otto!

Aber lieber nochmal nachgefragt...
Event-on-change-reading setze ich Deiner Aussage nach hier auf die HM-Geräte. Aber warum?

Der Sensor der hier am der die Luftfeuchte misst und andauernd sein Reading updatet ist ein LaCrosse Sensor.
Der schickt alle 15 sek oder so ein Update des Wertes an FHEM.
Der kann aber eben auch ein Update der Luftfeuchte senden obwohl sich der Wert nicht stark verändert hat.
15:20:00 > 50%
15:20:15 > 51%
15:20:30 > 51%

Auf dieses Sensor Reading lausche ich jetzt mit einem DOIF.
50 oder 51% Luftfeuchte sind aber weiterhin Werte wo ein AUS an den Homematic Zwischenstecker gesendet wird. Und ein doppeltes AUS soll eben vermieden werden. Doppeltes AN natürlich auch.
Was ich jetzt nicht weiss ist, ob das AUS an den HM Zwischenstecker geschickt wird, wenn wie im obigen Beispiel 2x 51% hintereinander kam.

Ich hab jetzt verstanden, dass ich beim Temp Sensor das Attribut setzen kann. Dann wird der LogEintrag und das reading auch nur dann aktualisiert wenn sich der Wert auch ändert. soweit richtig?
Aber das is halt nur die halbe Miete oder?
Denn wenn 50% oder 51% hin und her schwanken, wird trotzdem jedes Mal ein AUS an den HM geschickt oder irre ich mich da?

Gruß
Holger


FHEM 5.8 auf RasPi3; CULv3-868; RFXtrx433; HM-Sec-SC-2; HM-CFG-LAN; HM-LC-Bl1-FM; HM-CC-RT-DN; HM-ES-PMSw1-Pl; HM-LC-Sw4-DR; Hunter Ventile; 8ch Relais; ENIGMA2; ONKYO_AVR; SONOS; Harmony; telegram; HM-PB-6-WM55; GPIO; HM-Sen-MDIR-O; HM-SEC-SD; HM-LC-Dim1L-Pl-3;

Otto123

#3
Hallo Holger,

sorry Missverständnis meinerseits (mit HM).
Du solltest die eocr natürlich auf deinen Sensor setzen.

Allerdings werden diese Werte immer etwas schwanken und damit wieder Events auslösen. DOIF wird aber normal darauf nicht reagieren.
Ich würde allerdings dieses DOELSE ohne was am Ende wegnehmen - ich sehe darin keinen Sinn. Kann aber sein ich liege verkehrt.
Ich finde immer mit einem DOELSE () am Ende hat man was verkehrt gemacht :)

Also: Ein DOIF führt normal den Ausführungsteil nicht aus, wenn sich der Zustand (die Bedingung ) nicht ändert, ergo wird auch nicht gesendet!
Du kannst in den Readings genau sehen was passiert!
Beispiel aus dem Code oben: 13:16 kam ein Event vom Sensor, cmd_nr 5 wurde aber schon 12:01 ausgeführt, danach nicht wieder.
Zitat2021-11-06 12:01:00 cmd_nr 5
2021-11-06 13:16:00 e_SZ.TempSensor_humidity 54

Gruß Otto
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

sash.sc

Setze doch bei deinen doif doch ds wait Attribut ein. So kannst du Schwankungen abfangen
Raspi 4B+ Bullseye ;LaCrosse; HomeMatic; MapleCUL; ZigBee; Signalduino ESP32 ; Shellys; MQTT2; Grafana mit Influxdb

Otto123

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

Adimarantis

Warum nimmst du den Zustand nicht in die Bedingung auf? Also noch ein "and Zwischenstecker eq "off" .... set Zwischenstecker on

Bzw. hilft hier evtl. auch einfach eine kleine Funktion. Ich hab mir etwas ähnliches für meine Rollos gebaut, um zu vermeiden, dass die sinnlos auf eine Position gefahren werden, auf der sie schon sind und dazu in 99_MyUtils.pm folgendes eingebaut:
#Rollo: Fahre Rollo $Device Zustand $To - aber nur wenn es nicht schon in $To steht
sub RolloTo($$) {
  my ($Device, $target) = @_;
  if (ReadingsVal($Device,"control",0) != $target)
    {fhem("set $Device control $target");}
  return 0;
}

Wenn ich jetzt RolloTo(Rollodevice,position) mache, dann wird nur gefunkt, wenn das Rollo nicht eh schon da ist.
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

McShire

#7
Zitat von: Otto123 am 06 November 2021, 14:30:29
Hallo Holger,

bei HM machst Du als allerersten (auch leicht stümperhaften) Ansatz:
attr TYPE=CUL_HM event-on-change-reading .*
Es sei denn Du hast schon welche gesetzt, das kannst Du so prüfen:
list TYPE=CUL_HM event-on-change-reading
Besser wäre es zu ermitteln welche Events brauche ich und die anderen quasi abzuschalten (nur als Beispiel):
attr SZ.TempSensor event-on-change-reading humidity


Gruß Otto

event-on-change reading würde ich nur dort setzen, wo es unbedingt notwendig ist. Sonst kann es leicht passieren, dass events, die ich (auch später vielleicht mal) brauche, ausbleiben, z.B. battery low für eine Meldung, dass die Batterie leer ist.
Im o.a. DOIF ist ja das reading humidity eindeutig spezifiziert, damit triggern andere events zwar die Ausführung des DOIFs aber haben keinen Einfluss auf  das Ergebnis.

Zitat von: Otto123 am 06 November 2021, 21:29:33
ich würde eher eine Hysterese einbauen. Siehe DOIF Beispiel THRESHOLD
https://fhem.de/commandref_DE.html#DOIF_Weitere_Anwendungsbeispiele

Eine Hysterese ist dadurch eingebaut, dass erst bei humidity < 57 wieder ausgeschaltet wird. Wie Otto oben richtig anmerkt, wird bei Schwankungen im Bereich > 60 bzw. 65 nicht noch einmal eingeschaltet wenn schon eingeschaltet ist und die anderen Bedingungen (Uhrzeit, Wochentag) sich nicht geändert haben.
Im Bereich 57 - 60 bzw. 65 geschieht nichts. Das DOELSE () bewirkt allerdings, dass sich der Status auf cmd_10 ändert, wird dann 60 bzw 65 wieder überschritten, wird allerdings wieder ein Einschaltbefehl gesendet, bei Unterschreitung von 57 ein Ausschaltbefehl, auch wenn vorher aus war. das passiert jedoch sicher nicht dauernd, da die humidity sicher nicht dauernd an der Grenze schwankt. Trotzdem würde ich das DOELSE weglassen, dann sind diese Schaltvorgänge vorbei, weil dann ein kein Statuswechsel bei überschreiten von 57 und bei unterschreiten von 60 bzw. 65 mehr auftritt.

Zitat von: forum-merlin am 06 November 2021, 13:36:10
Hi Experts!
Ich brauche mal Eure Hilfe bei einer Optimierung eines DOIF bzw. eines Szenarios.

Kurz zur Erklärung...
Ich habe einen LaCross Temp/Feuchte Sensor im Schlafzimmer
Dieser soll einen Homematic Zwischenstecker triggern wenn Luftfeuchtewert X% über- oder unterschritten wurde. Drumrum noch einen Deckenventilator und einen Dummy.
Es soll aber auch Ruhezeiten geben weil der am Zwischenstecker angeschlossene Luftentfeuchter im Schlafzimmer schon etwas laut ist.
...

aber in Kombination mit den Ruhezeiten oder Schwellwerten kann es vorkommen, dass Werte über-/unterschritten sind und dann keine Schlatung am Zwischenstecker passiert. Oder eben weil werte schon erreicht sind und somit der Schaltzustand schon erreicht sein sollte aber aufgrund von Ruhezeit nicht ausgeführt wurde.

Gruß
Holger


Das ein Schaltzustand in der Ruhezeit erreicht wird und dann nicht ausgeführt wird, kann eigentlich nicht zu Problemen führen. Da der Sensor permanent events liefert, also auch nach dem Ende der Ruhezeit, wird der Schaltzustand nach der Ruhezeit ausgeführt, sofern die Bedingung noch besteht.

Zur Klärung sind noch ein paar Fragen offen.
- schick doch mal ein list vom DOIF, welche Attribute sind gesetzt, womöglich do always
- Woraus schliesst du, das der Schaltbefehl immer durch das DOIF ausgelöst wird, dann müsste ja im Log immer ein entsprechender Eintrag stehen
- kann es sein, dass das HM-device schlechten Empfang hat und keine Bestätigung sendet und deshalb der Schaltvorgang wiederholt wird?

Viele Grüße
Werner

McShire

#8
Zitat von: forum-merlin am 06 November 2021, 13:36:10
Hi Experts!
Ich brauche mal Eure Hilfe bei einer Optimierung eines DOIF bzw. eines Szenarios.

Kurz zur Erklärung...
Ich habe einen LaCross Temp/Feuchte Sensor im Schlafzimmer
Dieser soll einen Homematic Zwischenstecker triggern wenn Luftfeuchtewert X% über- oder unterschritten wurde. Drumrum noch einen Deckenventilator und einen Dummy.
Es soll aber auch Ruhezeiten geben weil der am Zwischenstecker angeschlossene Luftentfeuchter im Schlafzimmer schon etwas laut ist.

Das "Problem" das ich (wahrscheinlich) identifiziert habe ist, dass bei einer Meldung des Sensors der HM-Stecker immer wieder mit z.B. einem AUS befeuert wird wenn der Sensor seine Werte aktualisiert und der Luftfeuchtewert eben unterschritten wurde. Is ja vom prinzip richtig, aber jedes Mal ein AUS sprengt meine 1%-Regel für den Funk.

Ich danke euch schonmal!
Gruß
Holger

Das ein Aus befehl gesendet wird, liegt der eingebauten Hysterese 57 - 60 bzw. 65 in Kombination mit DOELSE().
Wie oben von mir beschrieben, erfolgt bei Überschreiten von 57 ein Statuswechsel ohne Einschalten und dann bei Unterschreitung wieder die Befehlsausführung AUS
Lass DOELSE () einfach weg.

Viele Grüße
Werner

locodriver

Zitat von: Adimarantis am 06 November 2021, 21:36:18
Warum nimmst du den Zustand nicht in die Bedingung auf? Also noch ein "and Zwischenstecker eq "off" .... set Zwischenstecker on

Bzw. hilft hier evtl. auch einfach eine kleine Funktion. Ich hab mir etwas ähnliches für meine Rollos gebaut, um zu vermeiden, dass die sinnlos auf eine Position gefahren werden, auf der sie schon sind und dazu in 99_MyUtils.pm folgendes eingebaut:
#Rollo: Fahre Rollo $Device Zustand $To - aber nur wenn es nicht schon in $To steht
sub RolloTo($$) {
  my ($Device, $target) = @_;
  if (ReadingsVal($Device,"control",0) != $target)
    {fhem("set $Device control $target");}
  return 0;
}

Wenn ich jetzt RolloTo(Rollodevice,position) mache, dann wird nur gefunkt, wenn das Rollo nicht eh schon da ist.

Erreicht man das nicht auch mit FILTER...? Oder übersehe ich da etwas?
fhem 6.0 auf Rpi3 Bookworm
HM-LAN-CFG (FW 0.965), HM-MOD-UART, 2x HM-TC-IT-WM-W-EU, 4x HM-Sec-RHS und 3x HM-CC-RT-DN, 6x HM-LC-Bl1-FM mit je 1x Somfy-Motor,
2x HM-LC-SW2-FM für Licht und Lüfter, 2x HM-PB-6-WM55, Alexa, Jeelinkcross, CUL, CUNO2, IR-Blaster