Globale, flexible Fenster-/Tür-Offen-Meldungen

Begonnen von Benni, 20 April 2015, 20:19:31

Vorheriges Thema - Nächstes Thema

Benni

Zitat von: flummy1978 am 10 April 2019, 22:25:33
Wenn das für alle anderen so funtioniert, wie für mich könntest Du das auch im ersten Beitrag mit anpinnen, als Option oder Benni?

Erledigt!
Und ebenfalls Danke!  ;)

Gruß Benni.

marty29ak

Hallo, hoffentlich liest hier noch Jemand.....

Bisher hatte ich mit dieser Zeile die Meldungen über einen Echo ausgegeben:

my $pushcmd="fhem(\"set ECHO_GxxxxxxxxxxxQ speak ('$devname ist $immer $devstate')\");;";

Da ich die Meldung aber jetzt gerne über ein Terminal mit Fully ausgeben möchte, habe ich die Zeile in:

my $pushcmd="fhem(\"set terminal_unten speak ('$devname ist $immer $devstate')\");;";

umgestellt. Leider liest er mir nur "klammerauf S devname" vor also nicht den Inhalt der Variable. Den Rest "ist $immer $devstate" garnicht.

Hat Jemand eine Idee wie ich die Zeile ändern muss?
Gruß Martin

flummy1978

Holla,

Wenn es sich um den Inhalt  der myUtils handelt, dann hast Du da ganz viele (vor)Zeichen durcheinander gebracht, beim hin und her kopieren:

Wenn Du Dir anschaust, was in meinem (durchaus nicht unkompliziertem) Beispiel mit der $pushcmd gemacht wurde und was in deinem Fall passiert ist, sollte Dir der Unterschied auffallen.

my $pushcmd="PushInfo('$devtype','";
$pushcmd.=$retrigger+1;
$pushcmd.=".Meldung: $devname ist $immer $devstate');;";

my $pushcmd="fhem(\"set terminal_unten speak ('$devname ist $immer $devstate')\");;";
      
Zitat (Quelle: https://de.wikibooks.org/wiki/Perl-Programmierung:_Variablen#Zeichenketten_(Strings)
Skalarvariablen können auch Zeichenketten (Strings) enthalten. Diese werden, von einfachen (') oder doppelten (") Anführungszeichen umschlossen, der Variablen zugewiesen. Der Unterschied zwischen einfachen und doppelten Anführungszeichen besteht in der sogenannten Variableninterpolation. Dazu ein Beispiel:

#!/usr/bin/perl

use strict;
use warnings;

my $var = 5;
my $text = "Variable enthält: $var";
my $text2 = 'Variable enthält: $var';
print $text;
print "\n";
print $text2;
print "\n";

erzeugt folgende Ausgabe:

Variable enthält: 5
Variable enthält: $var


Bedeutet in Deinem Fall, dass Du die Variablen außerhalb der einzelnen ' ' aufführen musst:

my $pushcmd="fhem(\"set terminal_unten speak ('".$devname." ist $immer $devstate"."')\");;";
................................................................................^ Mit diesen " beendest Du die umschlossene Variable und hängst mit .$devname direkt den Inhalt der $devname an .... danach folgt der Rest und in doppelten " " kann man Variablen benutzen, deren Inhalt (und nicht name) auch wiedergeben wird.

( Ich bin mir sicher, dass die laienhafte Erklärung fachlich vielleicht nicht perfekt erklärt ist, aber ich hoffe verständlich. Und mit der Doku oben, hast Du noch mal andere Erklärungen dazu ;)  )

Hoffe das hilft

Grüße
Andreas

marty29ak

Vielen Dank, für deine Hilfe!!!
Ich werde mich das heute mal in ruhe durchlesen und hoffentlich dann verstehen.
Trotzdem sehr komisch, da ich nur das Device von Amazon Echo auf den Fully gewechselt habe.
Gruß Martin

marty29ak

So, mit dieser Zeile funktioniert es jetzt wie gewünscht:

my $pushcmd="fhem(\"set terminal_unten speak '$devname ist $immer $devstate' \");;";

Fhem erstellt auch wie gewollt das richtige "at"

defmod MAX_11fdd0_OpenTimer at 2019-10-27T14:12:59 {fhem("set terminal_unten speak 'Das linke Fenster im Wohnzimmer ist noch offen' ");;winOpenStart('MAX_11fdd0','2');;}

Wichtig beim Fully Browser sind die zwei ' , da er sonst nur das erste Wort ausgibt.
Gruß Martin

dennis_n

Hallo Benni,

ich hoffe Dein Modul wird noch supported ;-)

Gerne würde ich Deine Funtion nutzen, habe aber das Problem, dass scheinbar der Event Trigger schon nicht funktioniert.

Hier mal ein list meines Device:

Internals:
   DEF        c1aa9dda 17
   FUUID      5ddb935d-f33f-8212-587c-a5ecfd591e77da1b
   IODev      ZWDongle_0
   LASTInputDev ZWDongle_0
   MSGCNT     6
   NAME       ZWave_SENSOR_NOTIFICATION_17
   NR         99
   STATE      closed
   TYPE       ZWave
   ZWDongle_0_MSGCNT 6
   ZWDongle_0_RAWMSG 00040011097105000000ff061700
   ZWDongle_0_TIME 2020-03-02 18:03:52
   ZWaveSubDevice no
   homeId     c1aa9dda
   isWakeUp   1
   nodeIdHex  11
   READINGS:
     2019-11-23 17:21:45   alarm           AccessControl: Window/Door is closed
     2020-03-02 18:03:52   alarm_AccessControl Window/Door is closed, notificationIsOn
     2020-03-02 08:30:28   battery         80 %
     2020-03-02 08:30:28   batteryPercent  80
     2020-03-02 08:30:28   batteryState    ok
     2019-11-23 17:14:18   model           FIBARO System FGDW002 Door Opening Sensor 2
     2019-11-23 17:14:18   modelConfig     fibaro/fgdw2.xml
     2019-11-23 17:14:18   modelId         010f-0702-1000
     2019-11-23 17:14:16   state           wakeupInterval 86400 1
     2020-03-02 14:10:39   temperature     21.6 C
     2020-03-02 08:30:30   timeToAck       0.023
     2020-03-02 08:30:30   transmit        OK
     2020-03-02 08:30:28   wakeup          notification
Attributes:
   IODev      ZWDongle_0
   alias      Sensor_Buero_rechts
   classes    ZWAVEPLUS_INFO ASSOCIATION ASSOCIATION_GRP_INFO APPLICATION_STATUS BATTERY CONFIGURATION CRC_16_ENCAP DEVICE_RESET_LOCALLY FIRMWARE_UPDATE_MD MANUFACTURER_SPECIFIC MULTI_CHANNEL_ASSOCIATION ALARM POWERLEVEL SECURITY SENSOR_MULTILEVEL VERSION WAKE_UP
   extendedAlarmReadings 1
   room       ZWave
   stateFormat {(split(/,|is /, ReadingsVal($name,"alarm_AccessControl","")))[1]}
   userattr   winOpenMaxTrigger:1 winOpenName:rechts winOpenTimer:00:00:20 winOpenTimer2:00:01:00 winOpenType:Fenster
   vclasses   ALARM:5 APPLICATION_STATUS:1 ASSOCIATION:2 ASSOCIATION_GRP_INFO:1 BATTERY:1 CONFIGURATION:1 CRC_16_ENCAP:1 DEVICE_RESET_LOCALLY:1 FIRMWARE_UPDATE_MD:4 MANUFACTURER_SPECIFIC:2 MULTI_CHANNEL_ASSOCIATION:3 POWERLEVEL:1 SECURITY:1 SENSOR_MULTILEVEL:5 VERSION:2 WAKE_UP:2 ZWAVEPLUS_INFO:2


Hier meine 99_myUtils:

ub PushInfo($$) {
   my ($msgsubj,$msgtext) = @_;
   Log3(undef,1,"winOpenMessage: $msgsubj - $msgtext");
   # fhem("set pushmsg msg 'winOpenMessage' '$msgsubj - $msgtext' ")
}

sub winOpenStart($;$) {
    #Als Parameter muss der device-Name übergeben werden
    my $dev=shift(@_);
   
    #Optional kann noch ein Zähler für das erneute Triggern übergeben werden,
    #dieser ist per default 0
    my $retrigger=shift(@_);
    $retrigger=0 if (!$retrigger);
   

    #Erst mal prüfen, ob das übergebene device überhaupt existiert
    if ($defs{$dev}) {
   
        #Aus dem device, sofern vorhanden das Attribut winOpenMaxTrigger auslesen, das
        #angibt, wie oft eine Meldung ausgegeben werden soll.
        #Fehlt dieses Attribut oder ist 0, dann wird für das device gar keine Offen-Meldung ausgegeben
        my $maxtrigger=AttrVal($dev,'winOpenMaxTrigger',0);
   
        if($maxtrigger) {
   
      #Festlegen des Namens für den Timer, der angelegt wird um die Meldung nach gewünschter
          #Zeit auszugeben.
          my $devtimer=$dev.'_OpenTimer';

          #Sollte dieser Timer bereits existieren, so wird er zunächst gelöscht.
          fhem("delete $devtimer") if ($defs{$devtimer});


          #Holen von weiteren Attributen, sofern vorhanden:
         
          #Zeit, nach der die Meldung ausgegeben werden soll
          #Default sind 10 Minuten, falls nicht angegeben
          my $waittime=AttrVal($dev,'winOpenTimer','00:10:00');

          #Zeit für die Folge-Meldungen, sofern abweichend angegeben
          #Default ist die normale Zeit, die oben schon ermittelt wurde
          my $devtimer2=AttrVal($dev,'winOpenTimer2',$waittime);

          #Ein eventuell definierter "schöner" Name für das Device, der in der Meldung ausgegeben werden soll.
          #Ist der nicht angegeben, wird das Device-Alias genommen, fehlt auch das, wir einfach der
          #device-Name genommen.
          my $devname=AttrVal($dev,'winOpenName',AttrVal($dev,'alias',$dev));
         
          #Eine Art Typ (Tür oder Fenster), der bei mir quasi im Betreff der Offen-Meldung angegeben wird
          my $devtype=AttrVal($dev,'winOpenType','Fenster/Tür');

          #Hier wandeln wir noch den state des devices in deutschen Klartext um
          my $devstate='offen';
          #$devstate='gekippt' if (ReadingsVal($dev,'state','') eq 'tilted');
          $devstate='gekippt' if (ReadingsVal($dev,'alarm_AccessControl','') eq 'Window/Door is open, notificationIsOn');
         
          #Hier wird, sofern bereits eine Wiederholung der Offen-Meldung ausgegeben werden soll,
          #dies textlich auch so berücksichtigt.
          my $immer='noch ';
          $immer='immer noch ' if ($retrigger>0);

          #Jetzt wird der Ausgabebefehl für die Offenmeldung zusammengebaut
          #(Ich habe eine sub PushInfo, die Betreff und Text als Parameter erhält und aktuell
          # meine Meldungen über Pushover ausgibt)
          my $pushcmd="PushInfo('$devtype','$devname ist $immer $devstate');;";
         
          #Sind wir schon beim Einrichten einer Folgemeldung, muss die Wartezeit für die Folgemeldungen
          #genommen werden.
          $waittime=$devtimer2 if ($retrigger);

          #Wir erhöhen hier den Trigger-Zähler um 1...
          $retrigger+=1;
          #... und fügen das Re-Triggern als weitere Code-Zeile für das at-DEF an.
          #das sorgt dann dafür, dass diese Funktion hier nach Ablauf des Timers einfach wieder
          #getriggert wird, um einen neuen Timer anzulegen für die Folgemeldung
          $pushcmd.="winOpenStart('$dev','$retrigger');;" if($retrigger < $maxtrigger);

         
          #Nachdem wir hier alles zusammen haben,
          #legen wir den Timer (das at) an und legen ihn freundlicherweise in den, bzw. die
          #selben Räumen ab, wie auch das auslösende device.
          fhem("define $devtimer at +$waittime {$pushcmd}");
          fhem("attr $devtimer room ".AttrVal($dev,'room','Unsorted'));
        }
    }
}

sub winOpenStop($) {
    #Dazu muss das entsprechende device (TK/FK) per Name hierher übergeben werden

    #Den übergebenen device-Namen holen
    my ($dev)=@_;

    #Den Namen des Timers zusammenbauen
    my $devtimer=$dev.'_OpenTimer';
       
    #Existiert ein Timer diesen Namens, so wird er jetzt gelöscht und das war's auch schon.
    if ($defs{$devtimer}) {
        fhem("delete $devtimer");
    }
}


Es wird weder ein Log eintrag erzeugt, noch ein notify angelegt.
Wo ist mein Fehler?

Danke
Gruss
Dennis

Timo_FHEM

Hast du denn ein notify, das die myutils Funktion aufruft?
So ungefähr:
defmod winOpen.OpenNotify notify .*:(open|tilted) {winOpenStart($NAME)}
attr winOpen.OpenNotify room Logik

defmod winOpen.CloseNotify notify .*:closed {winOpenStop($NAME)}
attr winOpen.CloseNotify room Logik

Bei mir läuft das mittlerweile ganz gut.

Gruß Timo

Gesendet von meinem MI 9 mit Tapatalk


dennis_n

Hi,

ja klar. Die beiden notify habe ich auch angelegt.
Irgendwie habe ich das Gefühl, dass es am trigger für open liegt.
Denn bei den Fibaro Sensoren wird das Reading "alarm_AccessControl" mit den Werten "Window/Door is closed, notificationIsOn" oder "Window/Door is open, notificationIsOn" belegt.

Das eigentliche state Reading verändert sich nicht.

Könnte es daran liegen?

Gruss
Dennis

CoolTux

Zitat von: dennis_n am 02 März 2020, 22:54:04
Hi,

ja klar. Die beiden notify habe ich auch angelegt.
Irgendwie habe ich das Gefühl, dass es am trigger für open liegt.
Denn bei den Fibaro Sensoren wird das Reading "alarm_AccessControl" mit den Werten "Window/Door is closed, notificationIsOn" oder "Window/Door is open, notificationIsOn" belegt.

Das eigentliche state Reading verändert sich nicht.

Könnte es daran liegen?

Gruss
Dennis

Du solltest vielleicht nicht versuchen 1 zu 1 ab zu schreiben sondern versuchen zu verstehen was genau passiert und gebraucht wird. Deswegen ist das ja auch kein Modul sondern eine Beispiellösung für eine Anforderung.
Du musst natürlich das RegEx des Notify entsprechend des Events anpassen. Leider bist Du kein list vom Notify. Und am besten noch ein Eventlogauszug mit geben damit man Sich unterstützen kann.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

ChristianR

Guten Abend,
besteht die Möglichkeit beim Auslösen der zweiten Erinnerung (winOpenTimer2) meine Lüftungsanlage (existiert bereits als Device) vorübergehend auszuschalten?
Sobald die Tür bzw. das Fenster dann nach der "Overtime Warnung" wieder geschlossen wurde, soll die Lüftungsanlage wieder eingeschaltet werden...
Danke vorweg für eure Mühe / Ideen!

Gruß Christian

flummy1978

Guten Morgen,

die Frage ist ob du komplett kopiert hast, oder Dir auch selbst Gedanken dazu gemacht hast / machen möchtest. Ersteres macht das Ganze mit Sonderwünschen auszustatten schwierig, weil Dir immer jemand etwas vorkauen müsste, bis man an der richtigen Lösung ist. Zweiteres ist wiederum möglich:

Du musst an der Stelle:
#Jetzt wird der Ausgabebefehl für die Offenmeldung zusammengebaut
          my $pushcmd="PushInfo('$devtype','";
  $pushcmd.=$retrigger+1;
  $pushcmd.=".Meldung: $devname ist $immer $devstate');;";
  #my $pushcmd="PushInfo('$devtype',                '        $devname ist $immer $devstate');;";
#####<----HIER---->
         


prüfen ob:


  • $devname das betroffenne Fenster ist, dass die Lüftungsanlage ausschalten soll
  • Deine Lüftungsanlage läuft oder bereits ausgeschaltet wurde
  • es andere Widersprüche gegen das Ausschalten gibt
  • und und und
  • ... + zusätzlich noch wo anders im Code die Prüfung einbauen, ob das Fenster geschlossen wurde und die Lüftung wieder eingeschaltet werden kann

In meinen Augen verlierst Du hier aber die "globalität" der Fenstermeldung, Du hättest dann eine Besonderheit für (ein?) bestimmtes Fenster z.B.....

Ich würde es mit einem "lüftungsanlage" notify machen, das explizit auf ALLE Meldungen achtet die die Lüftungsanlage betrifft und diese dann schaltet. Sonst hast Du mal das Fenster, mal manuell, dann wieder durch einen Raumluftsensor ......... geschaltet und weisst nicht, wer jetzt eigentlich der Ausschlaggebende zum Schalten war.
In einem "Überwachungsgerät" hast Du eine bessere Möglichkeit das zu kontrollieren

Ich habe mittlerweile die Fenster Meldung nicht mehr drin, sondern eine eigene Geschichte gebaut, die meldet wenn was passiert UND / ODER die etwas schaltet wenn eine gewisse Zeit etwas nicht passiert. Das könnte man bsw für Deine Bedürfnisse umbauen / anpassen.

Viele Grüße
Andreas 

ChristianR

Vielen Dank erstmal für deine Antwort.
Ich habe das Beispiel aus diesem Beitrag zunächst komplett übernommen und mit dem Dummy getestet --> funktioniert!
Danach habe ich den Part Pushover auf meine Bedürfnisse angepasst --> funktioniert!
Danach habe ich das Dummy gelöscht und einer meiner Magnetkontakte (Typ=IT) mit den erforderlichen Attributen bestückt --> funktioniert!
Danach habe ich die beiden notify so umgebogen, dass sie nicht auf "open,tilted,closed" reagieren, sondern nur auf "offen,geschlossen" und die entsprechenden Magnetkontakte ebenfalls angepasst --> funktioniert!
Soviel zur groben Beschreibung, was ich übernommen bzw. angepasst habe.  :)

Nun möchte ich die Lüftungsanlage automatisiert schalten lassen. Wie gesagt, die KWL lese ich über HTTPMOD aus und habe die Möglichkeit die unterschiedlichen Leistungsstufen 0,1,2 und 3 anzusteuern.
Jetzt soll die Lüftungsanlage aber nur ausgeschaltet werden wenn mindestens einer von zwei bestimmten Magnetkontakten öffnet. Als Beispiel, ich habe 4 Magnetkontakte (2x Fenster und 2x Tür) und ich möchte lediglich beim triggern der Türen über "winOpenTimer2" die KWL ausschalten.
Die Idee mit dem separaten notify auf die KWL führt hier bestimmt eher zum Ziel. Evtl. probiere ich noch ein Dummy (a la Lüften aktiv / nicht aktiv) als Schnittstelle zwischen dem Notify und der KWL, mal schauen.
Will den Beitrag hier aber auch nicht in die falsche Richtung lenken (OT)...

sigma415

Hallo, vielen Dank für die Hinweise hier, meine Fensterüberwachung funtioniert sehr gut mit den sleep Timern.
Allerdings suche ich jetzt eine Möglichkeit, bereits laufende Fenster-sleeps mit einem Schlag zu löschen.
cancel HMFen.* funktioniert leider nicht, da cancel kein RegEx bei den Namen kann.
siehe auch https://forum.fhem.de/index.php?topic=135359.0

Wie müsste eine for-Schleife in Perl aussehen, die alle sleeps mittels cancel ausliest, entsprechend dem RegEx filtert und dann die betreffenden sleeps löscht ?

Bin leider auch alles anders als ein Perl-Guru :(
Vielen Dank für Eure Unterstützung.
FHEM auf ubuntu-Server (Notebook), CUNO's via LAN, 3x HMLAN, 2x goE, Tasmota-Devices via MQTT, Home Connect, Velux-KLF200, Harmony, SMA STP10, SMA HM2.0, BYD HVS7.7, etc. pp.  ....
Und immer noch viele, viele (Alt-) HM's (ohne -IP).

fiedel

Hast du es mal mit delete statt cancel versucht?

Gruß
Frank
FeatureLevel: 6.1 auf Wyse N03D ; Deb. 11 ; Perl: v5.14.2 ; IO: HM-MOD-RPI-PCB + VCCU|CUL 868 V 1.66|LinkUSBi |TEK603
HM: SEC-SCO|SCI-3-FM|LC-SW4-PCB|ES-PMSW1-PL|RC-4-2|SEN-MDIR-O|SEC-WDS-2
CUL: HMS100TF|FS20 S4A-2 ; OWDevice: DS18S20|DS2401|DS2406|DS2423

eisman

Hi,

ich habe eine Frage:

sub winOpenStart($;$) {
    my $dev=shift(@_)

entspricht Übergabe Device? ($;$) es wird aber nur ein Device übergeben.
ich habe dazu auch nichts bei Tante Google gefunden.

sub winOpenStop($) {
    my ($dev)=@_;

entspricht Übergabe Device? ($) es wird ein Device übergeben.
So mache ich das seit Jahren.

Was ist der Unterschied zwischen den beiden Aufrufen?

Ich suche auch schon seit tagen nach einer Möglichkeit, meine Fensterprozedur zu verbessern.
Z.z. mache es mit mehreren Watchdog.

bisher bin ich dabei an zwei punkten gescheitert.
Watchdog mit flexibler Zeit. (aus einem Reading)
Device während der Laufzeit anlegen. (Es wird immer ein save verlangt)

gruss
1x FHEM Debian, Homematic,ZigBee,FS20 / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian, Homematic,ZigBee         / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian,MQTT                               / 1X Raspberry, i2c,onewire,gpio
1x auf Windows 2012 Hyper-V-S