Funktion für Tür/Fenster offen Warnungen

Begonnen von DeeSPe, 07 August 2016, 15:05:24

Vorheriges Thema - Nächstes Thema

DeeSPe

Hallo,

da mich beim Aktivieren der Alarmanlage (FHEM-Eigenbau mit Kontakten und Bewegungsmeldern) immer interessiert ob eventuell noch irgendwelche Außenfenster und -türen offen stehen, habe ich mir gestern eine kleine Funktion dafür gebaut.
Diese Funktion reagiert auf state bei Zustand open von Kontaktsensoren (bei mir HomeMatic).
Man übergibt der Funktion einfach alle zu prüfenden Kontakte in einer kommaseparierten Liste und bekommt ein "undef" zurück wenn kein open erkannt wurde. Wenn ein oder mehrere open erkannt werden, so bekommt man eine Warnmeldung mit den Aliases aller geöffneten Fenstern/Türen als korrekt formulierten Satz zurück. Diesen Satz kann man dann beliebig weiter verarbeiten, z.B. per TelegramBot versenden oder als Sprachansage auf den Lautsprechern ausgeben. Ich bekomme bei Anwesenheit beides, bei Abwesenheit nur eine Nachricht per TelegramBot.

Hier die Funktion die Ihr in der 99_myUtils.pm ablegen könnt.
sub OffenCheck($)
{
  my ($list) = @_;
  my @aliases;
  my $text = undef;
  foreach my $dev (split(",",$list))
  {
    if (Value($dev) eq "open")
    {
      my $alias = AttrVal($dev,"alias",$dev);
      push @aliases,$alias;
    }
  }
  if (@aliases > 0)
  {
    $text = "ACHTUNG! ".$aliases[0];
    if (@aliases > 1)
    {
      for (my $i = 1; $i < @aliases; $i++)
      {
        $text .= " und " if ($i == @aliases - 1);
        $text .= ", " if ($i < @aliases - 1);
        $text .= $aliases[$i];
        $text .= " sind" if ($i == @aliases - 1);
      }
    }
  }
  $text .= " ist" if (@aliases == 1);
  $text .= " noch geöffnet." if (@aliases > 0);
  return $text;
}


Aufgerufen wird die Funktion dann beispielsweise so (bei mir beim Scharfschalten der Alarmanlage):
my $msg = OffenCheck("fl_Tuer,sz_Fenster,bk_Tuer,ku_Fenster,bz_Fenster,bz_Tuer");
fhem("msg push 0 $msg") if ($msg);
fhem("set TTS tts $msg") if ($msg && Value("rgr_Residents") eq "home");


In der ersten Zeile wird der Variablen msg die Funktion zum prüfen der Kontakte zugewiesen.
In der zweiten Zeile wird msg als push Nachricht versendet (bei mir TelegramBot) falls sie definiert ist (also einen Rückgabewert hat).
In der dritten Zeile wird bei Anwesenheit die Nachricht (hier) per TTS ausgegeben (macht bei mir ein Sonos).

Das kann man z.B. aber erst einmal auch prima in der FHEM Eingabezeile testen:
{OffenCheck("fl_Tuer,sz_Fenster,bk_Tuer,ku_Fenster,bz_Fenster,bz_Tuer")}

Eine Rückmeldung würde dann so aussehen:
ACHTUNG! Balkontür und Küchenfenster sind noch geöffnet.

Eventuell kann der/die Eine oder Andere mit so einem einfachen Konstrukt etwas anfangen in seinem/ihrem Setup.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

DeeSPe

Das obige Beispiel lässt sich natürlich auch um eine Meldung erweitern falls alle Fenster/Türen geschlossen sind. Falls man diese Info haben möchte bzw. man die Bestätigung haben möchte dass die Funktion funktioniert/ausgeführt wird.

my $msg = OffenCheck("fl_Tuer,sz_Fenster,bk_Tuer,ku_Fenster,bz_Fenster,bz_Tuer");
fhem("msg push 0 $msg") if ($msg);
fhem("msg push 0 Alle Außenfenster und -türen sind geschlossen.") if (!$msg);
fhem("set TTS tts $msg") if ($msg && Value("rgr_Residents") eq "home");


Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Devender

Hey Dan,

vielen Dank für deinen Code. Ich habe das gestern Abend ebenfalls für meine HM Fensterkontakte implementiert.
Ich musste lediglich deine msg Funktion auf mein, seit einigen Tagen laufendes Jabbermodul, umbauen.  :)

sprich aus fhem("msg push 0 $msg") if ($msg);
wurde bei mir dann
hem("sendJabberMessage('meinAccount@jabber.org', $msg)") if ($msg);
der dann eine Funktion in der 99_myUtils aufruft.

Ich bekomme jetzt, wenn ein Fenster offen steht eine Mitteilung. Einziger Nachteil; ich kann nix machen, wenn ich nicht zu Hause bin, außer den Rollladen remote dann schließen.
Die Idee waere jetzt, dass ich nach dem ein Fenster offen ist oder geöffnet wurde und ich nicht anwesend bin, den zugehörigen Rollladen zu schließen - automatisch aber anhand der "Alarmfunktion".

Nun scheitere ich aber an dem Problem, dass deine Funktion ja erst einmal nur den Namen des HM-Kontakts beinhaltet. Die Verknüpfung zum Rollladen z.B.
set Badezimmer zu fehlt. Diese könnte ich per if fest setzen indem ich sage: if HM_BAD = offen then set Badezimmer zu.
Ich würde das aber gerne generisch lösen. :-)

Beispiel: Ist ein Fenster X (return aus deiner OffenCheck) offen dann suche den passenden Rollladen zu Fenster X und schließe ihn.
Die verknüpfung von Fensterkontakt zu Rollladen findet man im FHEM ja unter "Probably associated with".

Hast du eine Idee oder vielleicht schon eine Umsetzung in die Richtung durchgeführt?

Grüße,
Dirk

FHEM 5.8 auf RasPi mit Jessy - CUL868, JeeLink Lacrosse
Komponenten: HM, IT, ELV, FB7390, FritzPL543,Sonos Play3
Mehrere Wandtablets sowie einen Smart Mirror
https://wiki.fhem.de/wiki/Anwesenheitserkennung#PRESENCE-Modul

DeeSPe

Das sollte relativ einfach machbar sein.
z.B. wenn Dein Fenster "sz_Fenster1" heißt, dann nenne doch den Rollladen "sz_Fenster1_RL".
Dann die Funktion am Anfang so erweitern (nur die vorletzte Zeile ist dazu gekommen):
sub OffenCheck($)
{
  my ($list) = @_;
  my @aliases;
  my $text = undef;
  foreach my $dev (split(",",$list))
  {
    if (Value($dev) eq "open")
    {
      fhem("set ".$dev."_RL" zu") if (defined $defs{$dev."_RL"}); # Hier wird dann der zum Fenster gehörende Rollladen geschlossen falls das Fenster offen ist und der zugehörige Rollladen auch definiert ist.
      my $alias = AttrVal($dev,"alias",$dev);


Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Devender

Danke dir!

das klingt super. Jetzt muss ich mir nur überlegen, ob ich meine Rollläden umbenenne, dass die Namen zu den Fensterkontakten passen.
bzw. ich muss mir mal über eine sinnvolle Namensgebung Gedanken machen und dann die Alias Attribute in Betracht ziehen.
Das mache ich aber lieber in Ruhe am Wocheende - nicht das dann irgendwas schief geht beim Umbenennen :-)
FHEM 5.8 auf RasPi mit Jessy - CUL868, JeeLink Lacrosse
Komponenten: HM, IT, ELV, FB7390, FritzPL543,Sonos Play3
Mehrere Wandtablets sowie einen Smart Mirror
https://wiki.fhem.de/wiki/Anwesenheitserkennung#PRESENCE-Modul

CoolTux

Damit werden alle Fenster aufgelistet die nicht auf closed stehen.
Meine Fensterkontakte fangen vom namen her alle mit FensterKontakt an.


sub statusFensterOffen() {

my @monitored=devspec2array("(FensterKontakt.*):FILTER=STATE!=closed");
my $cnt_devs=@monitored;
my $i = 0;
my $msgtext = "";
foreach(@monitored) {
$msgtext .= AttrVal($_,"alias",$_);
if ($i < $cnt_devs - 2) {
  $msgtext .= ", ";
}
if ($i == $cnt_devs - 2) {
  $msgtext .= " und ";
}
$i++;
}

return $msgtext if ($cnt_devs > 0);
}


Vielleicht mag das ja jemand gebrauchen können.
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

DeeSPe

Auch eine schöne Lösung.
Wie man sieht gibt es viele Wege nach Rom...

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Wuppi68

#7
Benni hat letztens auch eine coole Sache gepostet ....

ich kopiere mal meine Anpassung hier rein:
Edith: Original Threat im Forum: https://forum.fhem.de/index.php?topic=36504.0 incl Support

##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;

use strict;
use warnings;
use POSIX;

sub
myUtilsWindow_Initialize($$)
{
  my ($hash) = @_;
}

# Enter you functions below _this_ line.

sub
CheckOpenWindows()
{
#keine Parameter werden angegeben

my @Kontakte = devspec2array("a:model=HM-SEC-SC");
my $Response = "";
my $Count = 0;

foreach my $retVal (@Kontakte) {
$Response = $Response . AttrVal($retVal, 'alias', $retVal) . ', ' if (ReadingsVal($retVal,'state','undef') eq 'open');
$Count += 1;
}

$Response = "Es sind keine Fenster offen !!!" if ($Count == 0);
$Response = "Es ist ein Fenster offen: $Response" if ($Count == 1);
PushInfo("Offene Fenster", "$Response");
}

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');
         
          #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').",Timer");
        }
    }
}

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");
    }
}

1;


und noch ein "paar" notifies

hier der DEF für open:
.*:(open|tilted) {winOpenStart($NAME)}

hier der DEF für close:
.*:closed {winOpenStop($NAME)}

und es läßt sich dann für jedes Fenster/Tür mit Attributen einstellen, wie es gewertet werden soll:

userattr winOpenMaxTrigger winOpenTimer winOpenTimer2 winOpenType:Fenster,Türe winOpenName
winOpenMaxTrigger 3
winOpenName Fenster Küche
winOpenTimer 00:10:00
winOpenTimer2 00:20:00
winOpenType Fenster



Funktioniert sehr gut bei mir

und noch einmal: Es ist nicht mein Code

Tante Edit hat aus Bennemann Benni gemacht
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

Benni

Hmmm, das kommt mir doch irgendwie bekannt vor ;)

Wuppi68

#9
Zitat von: Benni am 10 August 2016, 23:12:07
Hmmm, das kommt mir doch irgendwie bekannt vor ;)

Dann war es Benni und nicht Bennemann - wieder rausnehmen den Post?
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

Benni

#10
Zitat von: Wuppi68 am 10 August 2016, 23:16:58
Dann war es Benni und nicht Bennemann - wieder ruasnehmen den Post?


Du hättest doch nur auf den ursprünglichen Thread zu verweisen brauchen, der wird nämlich sogar von mir supportet.

https://forum.fhem.de/index.php?topic=36504.0

Wuppi68

Zitat von: Benni am 10 August 2016, 23:19:39

Du hättest doch nur auf den ursprünglichen Thread zu verweisen brauchen, der wird nämlich sogar von mir supportet.

https://forum.fhem.de/index.php?topic=36504.0

wenn ich den gefunden hätte ..... die Suche nach winOpenMaxTrigger hat mir den nicht geliefert :-(
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

Benni

Zitat von: Wuppi68 am 10 August 2016, 23:23:49
wenn ich den gefunden hätte ..... die Suche nach winOpenMaxTrigger hat mir den nicht geliefert :-(

Ja, die Forensuche ...  ::)
Ich habe damit auch so meine liebe Not, deshalb lasse ich i.d.R. Google für mich im Forum suchen:

https://www.google.de/search?q=site%3Aforum.fhem.de&rct=j#q=site:forum.fhem.de+winopenmaxtrigger

;D


automatisierer

... irgendwie beängstigend, dass sich google besser in dem Forum auskennt als die eigene Suchmaschine...

Damu

Hallo

Ich hab die Sub auch eingefügt.
Funktioniert super.

Die Textnachricht geht über den Alias_Name.
Bei mir heisen die Fenstermelder SE_Fenster_XXX.
Wie erreiche ich das nur Fenster_XXX im Text steht, ohne Alias zu benützen.

Geht schon mit, aber jetzt steht bei der Batteriewarnung immer "Fenster_XXX Baterie ok"?
Hab beide Sub getestet, gehen beide sehr gut.