DOIF neue Features: Generalisierung, $DEVICE, $EVENT, Attribut notexist

Begonnen von Damian, 28 Dezember 2015, 22:06:42

Vorheriges Thema - Nächstes Thema

Damian

Zitat von: Per am 21 Oktober 2023, 22:59:47Wenn ein Timer der Trigger ist, hat man mit $DEVICE auch ein Problem. Und bei mehreren Readings hat man mit der split-Methode auch ein Problem. Ohne "Eigenverantwortung" kommt man so oder so nicht aus.

BTW: kann man mit [$DEVICE:reading] oder [$device:reading] bzw [$_:reading] auch im Perl-Mode im Ausführungsteil arbeiten? Ich bekomme bei den verschiedenen Versuchen entweder eine Fehlermeldung oder "komische" Werte ("HASH(xxxxxx)"...). Mit ReadingsVal geht es natürlich, ist aber viel umständlicherer Code.

Also $DEVICE wird konsequent im Perl- und FHEM-Modus durch das triggernde Device ersetzt. Daher ist [$DEVICE:reading] die optimale Lösung, um aus einem allgemeinen Event-Trigger den Inhalt eines bestimmten Readings in beiden Modi zu erhalten. Das ist auch so beabsichtigt und im Modul programmiert.

Daher ist es nicht unbedingt sinnvoll noch mehr Platzhalter wie z. B. $READING einzubauen. Denn solche Platzhalter wie z. B. $DEVICE oder eben $READING müssen bei jedem Trigger im Code durchsucht und ersetzt werden. Das kostet unnötig Performance insb. für die, die es nicht brauchen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per


Damian

Zitat von: Per am 22 Oktober 2023, 23:17:11Und Teil 2 des Postes?

Was ist damit?

[$DEVICE:reading] geht, die anderen nicht. Zu bedenken ist, dass im Perlmodus eine Perlfunktion an dieser Stelle eingesetzt wird, im FHEM-Modus wird dagegen der Wert selbst eingestellt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

LutzG

Hallo @all,

ich buddel das hier noch Mal aus, da ich $EVENT gern verwenden möchte und mein Problem (meine Meinung) hier sehr gut zum Tread passt!?

Es geht um meinen Bewegungsmelder (BM): https://forum.fhem.de/index.php?msg=1241211 der leider einen Schönheitsfehler hat. Obwohl niemand mehr in der Küche ist, wird das Licht ab und an Mal eingeschaltet. Inzwischen sind 3 BM verbaut und als Event werden von: "presence/occupancy" "true" und "false" gefeuert.

Die TRADFRI (IKEA) und Lidl BM melden teilweise erst 90 Sekunden später, dass keine Bewegung mehr festgestellt wurde und wenn das doif bei dem "false" Event prüft, ist einer von den "langsamen" BM manchmal immer noch "true" und das doif schaltet das Licht wieder an.

Ich möchte jetzt nur noch reagieren, wenn "true" gefeuert wird, finde aber auch nach mehreren Tagen Suche kein Beispiel. Leider verstehe ich auch die Logik hinter $EVENT / $EVENTS nicht und das trifft bei mir auch noch zu:
Zitat von: Damian am 19 Oktober 2023, 22:21:46ja, allerdings werden im $EVENT ggf. mehrere Reading mit Komma getrennt abgelegt, wenn sie in einem gemeinsamen Event-Block liegen und dann hat man evtl. das falsche Reading (falschen Wert), nämlich das erste des Eventblocks
Log Auszug:
2024.10.08 23:13:20.689 1:      event: presence: true
2024.10.08 23:13:20.690 1:     events: presence: true
2024.10.08 23:13:20.690 1: gesplittet: presence, true - Das Device: MQTT2_OMG_Kueche
2024.10.08 23:13:21.914 1:      event: presence: false
2024.10.08 23:13:21.914 1:     events: presence: false
2024.10.08 23:13:21.915 1: gesplittet: presence, false - Das Device: MQTT2_OMG_Kueche
2024.10.08 23:13:24.680 1:      event: batteryPercent: 60,occupancy: false
2024.10.08 23:13:24.680 1:     events: batteryPercent: 60,occupancy: false
2024.10.08 23:13:24.680 1: gesplittet: batteryPercent, 60 - Das Device: MQTT2_zigbee_TRADFRI_MotionSensor1
2024.10.08 23:14:21.838 1:      event: occupancy: false,last_seen: 2024-10-08T23:14:21+02:00
2024.10.08 23:14:21.838 1:     events: occupancy: false,last_seen: 2024-10-08T23:14:21+02:00
2024.10.08 23:14:21.839 1: gesplittet: occupancy, false - Das Device: MQTT2_zigbee_Lidl_BWM_1
2024.10.08 23:16:27.084 1:      event: occupancy: true,last_seen: 2024-10-08T23:16:27+02:00,batteryPercent: 60
2024.10.08 23:16:27.084 1:     events: occupancy: true,last_seen: 2024-10-08T23:16:27+02:00,batteryPercent: 60
2024.10.08 23:16:27.084 1: gesplittet: occupancy, true - Das Device: MQTT2_zigbee_TRADFRI_MotionSensor1
2024.10.08 23:16:32.029 1:      event: last_seen: 2024-10-08T23:16:31+02:00,occupancy: true
2024.10.08 23:16:32.030 1:     events: last_seen: 2024-10-08T23:16:31+02:00,occupancy: true
2024.10.08 23:16:32.030 1: gesplittet: last_seen, 2024-10-08T23:16:31+02:00 - Das Device: MQTT2_zigbee_Lidl_BWM_1
2024.10.08 23:16:37.089 1:      event: occupancy: false,batteryPercent: 60
2024.10.08 23:16:37.089 1:     events: occupancy: false,batteryPercent: 60
2024.10.08 23:16:37.089 1: gesplittet: occupancy, false - Das Device: MQTT2_zigbee_TRADFRI_MotionSensor1
2024.10.08 23:17:33.923 1:      event: presence: true
2024.10.08 23:17:33.923 1:     events: presence: true
2024.10.08 23:17:33.924 1: gesplittet: presence, true - Das Device: MQTT2_OMG_Kueche
2024.10.08 23:17:35.163 1:      event: presence: false
2024.10.08 23:17:35.163 1:     events: presence: false
2024.10.08 23:17:35.163 1: gesplittet: presence, false - Das Device: MQTT2_OMG_Kueche
2024.10.08 23:17:39.715 1:      event: occupancy: false,last_seen: 2024-10-08T23:17:39+02:00
2024.10.08 23:17:39.716 1:     events: occupancy: false,last_seen: 2024-10-08T23:17:39+02:00
2024.10.08 23:17:39.716 1: gesplittet: occupancy, false - Das Device: MQTT2_zigbee_Lidl_BWM_1
In dem doif habe ich die Log Ausgabe rein gebastelt, darum stelle ich es hier mal als RAW rein:
defmod doif_BM_Kueche DOIF {\
  Log 1, "     event: $event";;\
  Log 1, "    events: $events";;\
  # my $Ereignis = $events;; # neuer Test\
  # my $Ereignis = $EVENT;; # funktioniert nicht?\
  my($reading,$value)=split(": |,",$event);;\
  Log 1, "gesplittet: $reading, $value - Das Device: $DEVICE";;\
  # Log 1, "Das Device hat ausgelöst: $DEVICE - Der Event sah so aus: $EVENT";;\
  if (([MQTT2_OMG_Kueche:presence] eq "true" or [MQTT2_zigbee_TRADFRI_MotionSensor1:occupancy] eq "true" or [MQTT2_zigbee_Lidl_BWM_1:occupancy] eq "true") and ([?MQTT2_OMG_Kueche:lux:d] < 50) and [?Automatik] eq "on" ) {\
    # Es rennt jemand rum, es ist zu dunkel und ich soll was tun!\
    if ([?TasmStd_8A9714_LichtKueche:state] eq "on") {     # Das Licht ist schon an!\
      if (get_Exec("BM_Kueche_off") > 0) {                 # Gibt es auch einen Timer?\
        set_Reading("IchWars","on");;           # Dann war ich das!\
      }\
      else { # Timer ist abgelaufen, ich hab das Licht nicht eingeschaltet!\
        set_Reading("IchWars","off");;          # Merker zurück setzen.\
        # eine halben Stunde ohne Bewegung, bestimmt vergessen Licht auszuschalten. \
        set_Exec("BM_Kueche_long_off",1800,'fhem_set("TasmStd_8A9714_LichtKueche off")');;\
      }\
    }\
    else { # Licht ist aus -> einschalten.\
      fhem_set("TasmStd_8A9714_LichtKueche on");;\
      Log("3", "Küche: Bewegungsmelder hat Licht angeschaltet!");;\
      set_Reading("IchWars","on");;             # Merker setzen, das das DOIF geschaltet hat\
    }\
    if (get_Reading("IchWars") eq "on") {      # Da ich das war, Ausschalttimer setzen\
      if ([?MQTT2_myMQTT2Client:LutzesPC] eq "present") {  # der Rechner läuft, langer Timer\
        set_Exec("BM_Kueche_off",[?$SELF:work],'fhem_set("TasmStd_8A9714_LichtKueche off")');;\
        Log("3", "Küche: Bewegungsmelder: Der Rechner läuft, langer Timer!");;\
        set_State("Timer:Work");;\
      }\
      elsif ([?shelly3em:emeter_1_power] > 5) {       # Herd ist an / kochen, normaler Timer\
        set_Exec("BM_Kueche_off",[?$SELF:food],'fhem_set("TasmStd_8A9714_LichtKueche off")');;\
        Log("3", "Küche: Bewegungsmelder: Es wird gekocht, Licht Kochzeit an!");;\
        set_State("Timer:Food");;\
      }\
      elsif ([?22:00-09:00]) {     # In der Nacht, alle schlafen, kurzer Timer\
        set_Exec("BM_Kueche_off",[?$SELF:night],'fhem_set("TasmStd_8A9714_LichtKueche off")');;\
        Log("3", "Küche: Bewegungsmelder: Bewohner schlafen, Licht kurz an!");;\
        set_State("Timer:Night");;\
      }\
      else {\
        set_Exec("BM_Kueche_off",[?$SELF:default],'fhem_set("TasmStd_8A9714_LichtKueche off")');;\
        Log("3", "Küche: Bewegungsmelder: Nichts los, Licht normal an!");;\
        set_State("Timer:Default");;\
      }\
    }\
  }\
}\

attr doif_BM_Kueche DbLogExclude .*
attr doif_BM_Kueche alias doif_BM_Kueche
attr doif_BM_Kueche event-on-change-reading .*
attr doif_BM_Kueche group Bewegungsmelder
attr doif_BM_Kueche icon motion_detector
attr doif_BM_Kueche readingList state work food night default
attr doif_BM_Kueche room Geräte->Virtuell,Zimmer->Küche
attr doif_BM_Kueche setList work:slider,0,10,1800 food:slider,0,5,600 night:slider,0,1,60 default:slider,0,10,300
attr doif_BM_Kueche verbose 5
attr doif_BM_Kueche webCmd work:food:night:default

setstate doif_BM_Kueche initialized
setstate doif_BM_Kueche 2024-10-09 00:19:45 Device MQTT2_OMG_Kueche
setstate doif_BM_Kueche 2024-10-09 00:19:43 IchWars off
setstate doif_BM_Kueche 2024-10-09 00:19:45 block_01 executed
setstate doif_BM_Kueche 2023-11-28 02:48:27 default 80
setstate doif_BM_Kueche 2024-10-09 00:19:45 e_MQTT2_OMG_Kueche_presence false
setstate doif_BM_Kueche 2024-10-08 23:53:15 e_MQTT2_zigbee_Lidl_BWM_1_occupancy false
setstate doif_BM_Kueche 2024-10-08 23:52:15 e_MQTT2_zigbee_TRADFRI_MotionSensor1_occupancy false
setstate doif_BM_Kueche 2022-10-23 02:28:07 food 450
setstate doif_BM_Kueche 2024-10-08 23:12:52 mode enabled
setstate doif_BM_Kueche 2021-11-15 02:37:25 motion detect
setstate doif_BM_Kueche 2023-11-28 03:05:24 night 40
setstate doif_BM_Kueche 2024-10-08 23:12:53 state initialized
setstate doif_BM_Kueche 2024-10-08 23:12:53 timer_01_c01 09.10.2024 22:00:00
setstate doif_BM_Kueche 2024-10-08 23:12:53 timer_02_c01 09.10.2024 09:00:00
setstate doif_BM_Kueche 2024-10-09 00:19:43 timer_BM_Kueche_long_off 09.10.2024 00:49:43
setstate doif_BM_Kueche 2023-09-19 19:34:42 work 600
Ich hoffe, keinen neuen Traed aufgemacht zu haben, ist OK? Ich finde mein Problem hier echt dazu passend.

Herzliche Grüße, Lutz
DMZ: J5040 mit OpenMediaVault, in Docker: Portainer, Fhem, MariaDB, zigbee2mqtt, esphome, NextCloudPi, Jellyfin, Grocy.
Intranet: J5005 mit OpenMediaVault, in Docker: Portainer, Fhem-minimal, urbackup - läuft nur, wenn Rechner laufen.

LutzG

Dann antworte ich mir mal selber. Mit "index" scheint es zu funktionieren:
defmod doif_BM_Kueche DOIF {\
  if (index($event, "occupancy: true") != -1 or index($event, "presence: true") != -1) {\
    Log 1, "     event: $event - TRUE";;\
  }\
  else {\
    Log 1, "     event: $event - FALSE";;\
  }\
[...]
Gruß Lutz
DMZ: J5040 mit OpenMediaVault, in Docker: Portainer, Fhem, MariaDB, zigbee2mqtt, esphome, NextCloudPi, Jellyfin, Grocy.
Intranet: J5005 mit OpenMediaVault, in Docker: Portainer, Fhem-minimal, urbackup - läuft nur, wenn Rechner laufen.