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
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
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
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
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 :-)
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.
Auch eine schöne Lösung.
Wie man sieht gibt es viele Wege nach Rom...
Gruß
Dan
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
Hmmm, das kommt mir doch irgendwie bekannt vor ;)
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?
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
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 :-(
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
... irgendwie beängstigend, dass sich google besser in dem Forum auskennt als die eigene Suchmaschine...
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.
Zitat von: Damu am 13 August 2016, 21:24:49
Wie erreiche ich das nur Fenster_XXX im Text steht, ohne Alias zu benützen.
Am einfachsten:
Vergib entsprechende attr alias mit den jeweiligen Namen!
Oder ändere die sub wie folgt:
Zeile 10:
my $alias = AttrVal($dev,"alias",$dev);
ändern in:
my $alias = (split("Fenster_",$dev))[1];
Gruß
Dan
Hallo
Hat geklappt, vielen Dank.
Meine Fenster und Tür Melder beginnen alle mit SE_Fenster_XXX oder SE_Tuere_XXX.
Die Sub hab ich so:
sub OffenCheck($)
{
my ($list) = @_;
my @aliases;
my $text = undef;
foreach my $dev (split(",",$list))
{
if (Value($dev) eq "open")
{
my $alias = (split("SE_",$dev))[1];
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;
}
Dazu hab ich ein Dummy erstellt:
Zitatdefine OffenCheck_FT Dummy
attr webcmd push
Ein Doif lost das ganze aus und schreibt mir eine Pushmitteilung
Zitatdefine OffenCheck_Doif DOIF ([Offencheck_FT_Du] eq "push") (set pushmsg_B msg '{(OffenCheck("SE_Tuere_Freisitz,SE_Fenster_Schlafzimmer,........."))}{(localtime)}')
attr to always
Vielen Dank klappt super.
Einziges Problem ist, es zeigt nur die Fenster und Türen mit Status "open" an.
Die gekippten "tilted" zeigt es als geschlossen an.
Meine Fenster sind alle Innen verschliesbar, (mit Drehgrifsicherung) deshalb kann und will ich das so lassen.
Hallo alle Zusammen
ich bekomme das nicht ans laufen, habe bei mir MAX Sensoren dran die melden ja opened anstatt open, habe dieses auch in der SUB angepasst. Aber trotz alle dem bekomme ich kein Meldung wenn ich ein Fenster aufmachen & dann in der FHEM Befehlzeile das teste.
Hat einer eine Idee?
Gruß
Markus
meine angepasste SUB
sub OffenCheck($)
{
my ($list) = @_;
my @aliases;
my $text = undef;
foreach my $dev (split(",",$list))
{
if (Value($dev) eq "opened")
{
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;
}