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

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

Vorheriges Thema - Nächstes Thema

lestat.le

Hallo.
Sehr gern.

Hier für die Variante 1:

Internals:
   DEF        (["^Fensterkontakt_"] eq "open" and [?ALARM_armed] eq "an") ({DebianMail('xxxxxxx')})
   NAME       DOIF_Alarm_Fenster_Kontakt_EMail
   NR         284
   NTFY_ORDER 50-DOIF_Alarm_Fenster_Kontakt_EMail
   STATE      initialized
   TYPE       DOIF
   Readings:
     2016-11-25 00:03:15   cmd             0
     2016-11-25 00:03:15   state           initialized
   Condition:
     0          EventDoIf('^Fensterkontakt_',$hash,'',0) eq "open" and InternalDoIf($hash,'ALARM_armed','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "an"
   Devices:
   Do:
     0:
       0          {DebianMail(xxxxxxxx)}
   Helper:
     globalinit 1
     last_timer 0
     sleeptimer -1
   Internals:
     0           ALARM_armed:STATE
     all         ALARM_armed:STATE
   Itimer:
   Regexp:
     0:
       0          ^Fensterkontakt_
     All:
       0          ^Fensterkontakt_
   State:
Attributes:
   room       Alarm



und dann noch für die andere Variante:

Internals:
   DEF        (["^Fensterkontakt_:open"] and [?ALARM_armed] eq "an") ({DebianMail('xxxxx')})
   NAME       DOIF_Alarm_Fenster_Kontakt_EMail2
   NR         284
   NTFY_ORDER 50-DOIF_Alarm_Fenster_Kontakt_EMail2
   STATE      initialized
   TYPE       DOIF
   Readings:
     2016-11-25 00:07:58   cmd             0
     2016-11-25 00:07:58   state           initialized
   Condition:
     0          EventDoIf('^Fensterkontakt_',$hash,'open',0) and InternalDoIf($hash,'ALARM_armed','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "an"
   Devices:
   Do:
     0:
       0          {DebianMail('xxxxxxx')}
   Helper:
     globalinit 1
     last_timer 0
     sleeptimer -1
   Internals:
     0           ALARM_armed:STATE
     all         ALARM_armed:STATE
   Itimer:
   Regexp:
     0:
       0          ^Fensterkontakt_:open
     All:
       0          ^Fensterkontakt_:open
   State:
Attributes:
   room       Alarm

l2r

hi,

sieht erstmal gut aus.

probier mal die Abfrage ob der Alarm scharf ist zum testen rauszulassen und mach dann das Fenster los. Dann sollte er eig 1 mal in cmd_1 wechseln.

(["^Fensterkontakt_:open"]) ({DebianMail('xxxxx')})

und schau auch bitte im Eventmonitor wie das Event genau aussieht.

EDIT:

Zusätzlich könnte noch ein Grund gewesen sein, dass ALARM_armed noch kein Event generiert hat und das DOIF somit den aktuellen Status noch nicht kennt. Das ist der kleine, aber feine Unterschied zwischen triggerden und nicht triggernden Bedingungen. Die Werte werden in beiden Fällen erst bei Events dem DOIF bekannt. Nur das bei nicht triggernden Bedingungen die Auswertung bei Aktualisierung des Readings nicht stattfindet.

Dazu noch eine Anmerkung:
Du hast ALARM_armed nicht triggernd definiert. Gesetzt der Fall, dass dein Fenster offen steht und du scharf schaltest, wird nichts passieren, da die Bedingungen nur überprüft werden wenn dein Fensterkontakt ein "open" sendet. Das open wurde aber in diesem Fall gesendet BEVOR scharf geschaltet wurde und somit war die Bedigung nicht wahr.
Sendet er das zyklisch, dann ist es wieder fast egal, da dann beim nächsten "open" überprüft wird und dann die Mail rausgeht

Gruß Michael
Wissen ist Macht.
Ich weiß nix.
Macht nix.

Brockmann

Zitat von: lestat.le am 25 November 2016, 00:10:10
Hier für die Variante 1:
(["^Fensterkontakt_"] eq "open" and [?ALARM_armed] eq "an") ({DebianMail('xxxxxxx')})

Das kann so nicht funktionieren. Du kannst zwar auf Events triggern, aber nicht gleichzeitig den "Wert" des Events auswerten (bzw. das wird wohl in der nächsten DOIF-Version möglich sein, an der Damian gerade arbeitet).
Aktuell müsste es nach meinem Verständnis immer noch so gelöst werden:

(["^Fensterkontakt_"] and [$DEVICE:state] eq "open" and [?ALARM_armed] eq "an")


Oder Du triggerst eben direkt auf den Schlüsselwort open in Events.

lestat.le

@Brockmann

Dankeschön!
Jetzt funktioniert es.
Deine Variante hatte ich eigentlich auch schon probiert aber wahrscheinlich irgendwo mit Drehern.

@Michael
Auch herzlichen Dank.
Das ALARM_armed nicht triggert ist für mich ok. Dann kann ich schon mal scharf schalten ohne das es Alarm gibt, falls noch ein Fenster geöffnet ist.
Aber ich müsste mir dennoch dringend einen Workflow überlegen, wie ich die Alarmierung angehen möchte. Hauptsache das System muss transparent und simple bleiben.

Viele Grüße

hatamoto

Hallo,

ich versuche gerade meine etwas komplexe Rollladen-Steuerung zu vereinfache.
Aktuell gibt es für jedes Fenster/Rollladen ein DOIF. (Auf, Zu, Beschattung, Lüften mit unterschiedlichen Bedingungen)
Änderungen in der grundsätzlichen Logik müssen ziemlich mühsam auf alle übertragen werden.

Ist es möglich Teile des $DEVICE in der set-Anweisung weiter zu verwenden?

Also in der Art:
["*.fensterkontakt.*:open|tilted"] (set *.gurtwickler.* Lueften)

z.b. ["buero.fensterkontakt.ostseite:open|tilted"] (set buero.gurtwickler.ostseite Lueften)

Ist so etwas überhaupt möglich?
Bräuchte hier einen Denkanstoß. Bekomme das Thema leider nicht richtig gegriffen.

Gruß Chris

Brockmann

Zitat von: hatamoto am 23 Februar 2017, 21:03:08
Ist es möglich Teile des $DEVICE in der set-Anweisung weiter zu verwenden?
Ist so etwas überhaupt möglich?
Bräuchte hier einen Denkanstoß. Bekomme das Thema leider nicht richtig gegriffen.

DOIF selbst bietet dafür kein Werkzeug. Aber Du kannst ja beliebige Perl-Funktionen einsetzen, um Strings zu zerlegen und wieder zusammenzusetzen.
Alternative: Du könntest bei den Fensterkontakten jeweils den Namen des dazugehörenden Gurtwicklers als Userreading ablegen. Darauf kannst Du ja mit DOIF direkt referenzieren, also

set buero.fensterkontakt.ostseite userReadings mein_gurtwickler {"buero.gurtwickler.ostseite"}

und dann

["*.fensterkontakt.*:open|tilted"] (set [$DEVICE:mein_gurtwickler] Lueften)

Ungetestet und ohne Gewähr

Ellert

Im Prinzip müsste es so klappen

({"$DEVICE"=~/\.(.*)\./;;fhem ("set *.$1.* Luften")})

Bei einer Namensgebung a.B.c findet /\.(.*)\./  B und schreibt den Inhalt der ersten Klammer in die Variable $1. Die benutzt Du dann im set-Befehl.

Ich sehe gerade, Du möchtest a,c verwenden

dann geht's mit

({"$DEVICE"=~/(.*)\..*\.(.*)/;;fhem ("set $1.gurtwickler.$2 Luften")})

siehe http://perldoc.perl.org/perlre.html

Damian

Ich habe hier https://forum.fhem.de/index.php/topic,67351.0.html eine neue Version abgelegt (v0.7)

Nun werden Angaben im Ausführungsteil, die Perlcode in {(...)} beinhalten differenzierter betrachtet. Bisher wurden die runden Klammern an Perl übergeben, dass hatte den Vorteil, dass man z. B. set bla {(2+3)/2} angeben konnte, allerdings den Nachteil, dass aufgrund der runden Klammern kein beliebiger Perl-Code ausführbar war. Die neue Version erkennt nun, ob die dazugehörige runde Klammer "zu" ganz am Ende ist und eliminiert beide runden Klammern. Damit bleibt die alte Kompatibilität erhalten und es lässt sich nun beliebiger Perlcode ausführen. z. B.

set bla {(my $test=2;return ($test+3))}

damit lässt sich jetzt auch das Filter-Problem wie folgt lösen:

(set {("$DEVICE"=~/(.*)\..*\.(.*)/;"$1.gurtwickler.$2")} on)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hatamoto

Danke für den Input. Das hat so auch geklappt. :D

Jetzt würde ich gerne im Bedingungsteil noch ein paar Infos abfragen.
z.B. welchen Zustand der betroffene Gurtwickler hat (auf, zu, lüften,...). Ein offener Rollladen muss ja nicht auf Lüften gefahren werden.

Das müsste dann ja ungefähr so lauten:

([".fensterkontakt.:offen|gekippt"] and
[?{("$DEVICE"=~/(.*)\..*\.(.*)/;"$1.gurtwickler.$2")}] eq "auf")
(set {("$DEVICE"=~/(.*)\..*\.(.*)/;"$1.gurtwickler.$2")} Lueften)


Ist das möglich oder wird $DEVICE erst mit Ende des Durchlaufen der Bedingung generiert?

Mir ist außerdem noch aufgefallen, dass wenn man, in der regex-Angabe, "*" als Wildcard verwendet, fhem komplett abschießt. Zumindest ist es mir so gegangen...
Also z.B. (["*.fensterkontakt.*:offen|gekippt"])

Gruß Chris

JoeALLb

FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

Damian

[?{("$DEVICE"=~/(.*)\..*\.(.*)/;"$1.gurtwickler.$2")}] eq "auf")

Nette Idee :) funktioniert aber leider nicht.
Die Syntax {(...)} wurde eingeführt um innerhalb eines FHEM-Befehls Perl ausführen zu können. Die Bedingung von DOIF ist aber bereits schon Perl und innerhalb der eckigen Klammern ist es nicht vorgesehen.
Da du noch mehr Abfragen machen willst und bereits mit Perl hantierst, bietet sich in diesem Fall an, das neue Device in eine Perlvariable zu packen und dann auf der Perlebene weiter zu machen, z. B.

DOIF ([".fensterkontakt.:offen|gekippt"])
  ({"$DEVICE"=~/(.*)\..*\.(.*)/;
      my $gw="$1.gurtwickler.$2";
      if (Value($gw) eq "auf) {fhem "set $gw 80";};
      if ....
     ...
  })


Alternativ könnte man auch den Gurtwickler per setreading in ein temporäres Reading des DOIF-Moduls legen und dann mit FHEM-IF-Befehl auf der FHEM-Ebene weiter machen.



     
     


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

Ellert

ZitatJetzt würde ich gerne im Bedingungsteil noch ein paar Infos abfragen.
z.B. welchen Zustand der betroffene Gurtwickler hat (auf, zu, lüften,...). Ein offener Rollladen muss ja nicht auf Lüften gefahren werden.

Du könntest im Befehl FILTER verwenden

set {("$DEVICE"=~/(.*)\..*\.(.*)/;"$1.gurtwickler.$2")}:FILTER=state!=offen Lueften

siehe https://fhem.de/commandref_DE.html#devspec

JoeALLb

Ich stehe gerade vermutlich am Schlauch:

Ich habe schon verschiedenstes probiert, aber es klappt nicht.
Was ich gerne möchte ist, die userReadings von dummy1 nach dummy2 zu kopieren.
Das klappt bis num ersten Kommentar (#) im Code.
({ my $a = AttrVal("dummy1","userReadings","");; fhem("attr dummy2 userReadings $a")})

Gibt es eine bessere Möglichkeit, dieses Attribut 1:1 zu kopieren?

So etwas in dieser Art fnktioniert ja nicht, da das § für den Zugriff auf Attribute nicht umgesetzt wurde, oder habe ich da was übersehen?
(attr dummy2 userReadings [dummy1:userReadings])
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

Ellert

Zitat von: JoeALLb am 22 März 2017, 12:52:48
Ich stehe gerade vermutlich am Schlauch:

Ich habe schon verschiedenstes probiert, aber es klappt nicht.
Was ich gerne möchte ist, die userReadings von dummy1 nach dummy2 zu kopieren.
Das klappt bis num ersten Kommentar (#) im Code.
({ my $a = AttrVal("dummy1","userReadings","");; fhem("attr dummy2 userReadings $a")})

Gibt es eine bessere Möglichkeit, dieses Attribut 1:1 zu kopieren?

So etwas in dieser Art fnktioniert ja nicht, da das § für den Zugriff auf Attribute nicht umgesetzt wurde, oder habe ich da was übersehen?
(attr dummy2 userReadings [dummy1:userReadings])
Funktioniert {fhem("attr dummy2 userReadings ".AttrVal("dummy1","userReadings",""))}?


JoeALLb

Zitat von: Ellert am 22 März 2017, 15:20:12
Funktioniert {fhem("attr dummy2 userReadings ".AttrVal("dummy1","userReadings",""))}?

Nein. Danke für die Hilfe! Übernommen wird bis zum ersten ;

dummy1:userReadings sieht in etwa so aus;
desired-manual:(desired-temp|controlMode|set_desired-temp).* {
my $tempProfile="";
my $wTagN = strftime('%w', localtime);
}


in
dummy2:userReadings kommt dann folgendes an:
desired-manual:(desired-temp|controlMode|set_desired-temp).* {
my $tempProfile="";

Hier stimmt ja schon die normale Klammerprüfung nicht.

im DOIF- "error" erhalte ich damit:
{fhem("attr dummy2 userReadings ".AttrVal("dummy1","userReadings",""))}: Unknown command my, try help.

Bei mehr Zeilen wiederholt sich das "Unknown command my, try help", so als ob jede zeile einzeln ausgeführt wird?!?

Hast Du noch eine weitere Idee dazu?

sG
joe
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270