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

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

Vorheriges Thema - Nächstes Thema

m311331

Hi Benni,

mir gefällt deine flexible Fenster-Türüberwachung sehr gut !  :)
sie ermöglicht bei den HM-FKTK eine wiederholung der Benarichtigung.
hatte Probleme damit bei meiner Lösung, daher würde ich gerne deine verwenden

habe alles so eingerichtet wie von dir beschrieben:

die zwei Notifys
define winOpen.OpenNotify notify F.Sensor.*:open {winOpenStart($NAME)}

define winOpen.CloseNotify notify F.Sensor.*:closed {winOpenStop($NAME)}


in der 99_myUtils.pm habe ich

#############################  test #############################

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));
   
          #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="Wecken()";
         
          #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");
    }
}


Attrib. am F.Sensor (den ich zum testen verwende sind gesetzt)
ZitatwinOpenMaxTrigger      3
winOpenTimer              00:00:15
winOpenTimer2            00:00:30


ich möchte aber statt der Pushover Funktion gerne eine akustische Ansage (Sonos)
daher wollte ich zum testen die Ansage von meinem "Wecker" nutzen
eine sub dafür hatte ich schon:
sub
Wecken()
{
  fhem("set Sonos_Schlafzimmer PlayURITemp \\\\192.168.xxx.xxx\\SonosSpeak\\Morgen.mp3 20");
}
 
   
ich habs leider nicht so mit'm Perlsyntax
bei dir wird ja auch eine weitere sub gestartet und Parameter übergeben wenn ich das richtig sehe
my $pushcmd="PushInfo('$devtype','$devname ist $immer $devstate');;";

ich wollte jetzt eifach meine wecken sub starten
my $pushcmd="Wecken()";

und genau hier hänge ich jetzt
Log:
2016.11.17 14:35:41 1: PERL WARNING: Bareword found where operator expected at (eval 29209) line 1, near ")winOpenStart"
2016.11.17 14:35:41 3: eval: {Wecken()winOpenStart('F.SensorSchlaf2','1');}
2016.11.17 14:35:41 1: PERL WARNING: (Missing operator before winOpenStart?)
2016.11.17 14:35:41 3: F.SensorSchlaf2_OpenTimer: syntax error at (eval 29209) line 1, near ")winOpenStart"


bitte um Hilfe

Benni

Da fehlen 2 Semikolons:


my $pushcmd="Wecken();;";


Die sind wichtig, da der Aufruf ja nachher im erzeugten at zusammengebaut wird.


m311331

Hi Benni,

ZitatDa fehlen 2 Semikolons:

:o ups

Vielen Dank !
super Support !!!


m311331

#93
Hi Benni,


habs jetzt mal ne Zeit getestet
funktioniert super  :)
besten Dank dafür !

ein/ausschalten wäre jetzt noch die Perfektion
hast du da eine Idee ? evtl. mit attrib ?

mfg. m311331

Benni

Danke für die Blumen! :D

Was meinst du mit ein-/ausschalten?

Du kannst ja einfach die beiden notify bei bedarf deaktivieren, entweder über das Attribut disable oder über set active, bzw. set inactive

m311331

Hi Benni,

ZitatWas meinst du mit ein-/ausschalten?
ja das hätte ich besser erläutern müssen  :-\

eigentlich wollte ich das so machen das die Ansage der Fenster
abhängig vom akt. Monat kommt.
kurz gesagt: Ansage nur in den Monaten: 11 - 04, von 04 - 11 keine Ansage

mein Ansatz kurz und knap war aber mist ;D habs nicht hin bekommen
define BadezimmerFensterAuf watchdog F.SensorBad.:open 00:15 F.SensorBad.:closed if (($month > 9 || $month < 4)){fhem ("set Sonos_Buero,Sonos_Bad,Sonos_Waschkueche,Sonos_Flur,Sonos_Wohnzimmer PlayURITemp \\IP.zum.Ser.ver\SonosSpeak\Badezfopen.mp3 30 )}} trigger BadezimmerFensterAuf .
perl ist einfach nicht meins  ???

letztändlich habe ich google bemüht für mich im Forum zu suchen, da die Forensuche vom SMF aus meiner sicht hmm .... nicht so dolle ist
... und durch einen link der wiederum in nem Beitrag hier im Forum war, bin ich auf deinen Beitrag gekommen  :)

mfg. m

Benni

Wie gesagt, ich würde das über ein deaktivieren, bzw. aktivieren der beteiligten nortify lösen.

Am einfachsten legst du dir ein at dafür an, das einmal am Tag ausgeführt wird (irgendwann kurz nach Mitternacht).

Im Ausführungsteil des at kannst du nun den aktuellen Monat prüfen und je nach dem die beiden notify mit set inactive deaktivieren oder mit set active wieder aktivieren. Diesen Teil lagerst du dann idealerweise noch in deine 99_myUtils aus.

Hollo

Zitat von: m311331 am 24 November 2016, 19:21:47
...
kurz gesagt: Ansage nur in den Monaten: 11 - 04, von 04 - 11 keine Ansage
...
kurz gesagt: eine Möglichkeit steht eine Seite vorher... https://forum.fhem.de/index.php/topic,36504.msg469018.html#msg469018   ;D

FHEM 6.x auf RPi 3B Buster
Protokolle: Homematic, Z-Wave, MQTT, Modbus
Temp/Feuchte: JeeLink-Clone und LGW mit LaCrosse/IT
sonstiges: Linux-Server, Dreambox, "RSS-Tablet"

Benni


visionsurfer

Hi Benni,

ich bin auf der Suche nach einer Möglichkeit bei meinem Fensterstatus eine genauere Nachricht zu bekommen.
Ich habe eine structure gebildet. Dort habe ich alle Fenster drin. Wenn ich das Haus verlasse und die Tür mit dem automatischen Türschloss verriegelt wird, bekomme ich eine Nachricht "Alle Fenster geschlossen". Wenn noch ein Fenster geöffnet ist, bekomme ich eine Nachricht "Fenster noch geöffnet".

Ich würde das nun gerne verbessern, in dem ich auch angezeigt bekomme, WELCHES Fenster noch geöffnet ist.

Nach dem Motto "Fenster Küche und Fenster Esszimmer noch offen". Damit ich nicht lange suchen muss.

Ist sowas mit deinem Modul auch möglich ?

Grüße,
Visionsurfer

Benni

So ohne weiteres ist das mit meinem Code nicht möglich, der dient ja eigentlich nur dazu die vergesslichen Stoßlüfter daran zu erinnern, Fenster, bzw. Türen auch zu schließen. Dabei meldet sich quasi jedes Fenster selbst, so nach dem Motto "Hey, ich bin noch offen, mach mal zu!" und "Halloooo, ich bin immer noch offen, mach mich doch endlich zu!"

Was du möchtest, sollte mit etwas Perl-Code zu bewerkstelligen sein. Dazu kannst du bspw. alle Fenster, die in der besagten Structure sind (devspec2array <- funktioniert aber nur, wenn structures nicht geschachtelt sind) prüfen, die offenen sammeln und dann in deiner Meldung ausgeben.

Ich habe beim Stöbern im Forum mal noch folgenden Thread gefunden:
https://forum.fhem.de/index.php/topic,56393.0.html

Dort sind übrigens mehrere Möglichkeiten beschrieben.

m311331

Hi Benni,

ZitatWie gesagt, ich würde das über ein deaktivieren, bzw. aktivieren der beteiligten nortify lösen.

besten Dank nochmal !  :)


mfg. m

c2j2

#102
@visionsurfer:

a) bei mir haben Fenster einen Device-Namen "Fenster_"... (hier irrelevant, aber das macht Attribut-Setzen einfacher, z.B. für die Icons)
b) und einen comment mit dem "lesbaren" Namen.

Dann z.B.:

define Fenster_wohnzimmer_balkon MAX ShutterContact 0a4c4b
attr Fenster_wohnzimmer_balkon comment Wohnzimmer zum Balkon
...
define Fenster_wohnzimmer_gaube MAX ShutterContact 0a4bf2
attr Fenster_wohnzimmer_gaube comment Wohnzimmer Gaube
...


In den myUtils:

sub Window_status {
my $resultstring='';
my @fhttks = devspec2array("DEF=ShutterContact .+");
my @wopen = ();
foreach(@fhttks) {
  my $fhttk_window = ReadingsVal($_, "state", "?");
  push (@wopen,AttrVal($_, "comment", "?")) if ($fhttk_window =~ m/open/ );
}
my $num_wopen = @wopen;
if ( $num_wopen gt 0 ) {
  $resultstring="folgende Fenster sind noch offen:\n\n";
  foreach(@wopen) {
   $resultstring.="- ".$_."\n";
   Log 4, "FHTTK_status: ". $_. "noch offen";
  }
} else {
  $resultstring.="alle Fenster sind geschlossen.";
}
return $resultstring;
}


und auf Tastendruck wird aufgerufen:

set MyTTS tts {Window_status()}


Und dann wird genau das vorgelesen, was Du haben möchtest.

visionsurfer

Hi c2j2,

tausend Dank. Ich versuche gerade den Code zu verstehen. Ich hab bisher noch nie mit der 99_myUtils.pm gearbeitet. Die hab ich nun erst mal richtig angelegt.

Ich habe KNX Fenstersensoren. Das müsste aber keine Rolle spielen.

Bei mir sind alle Devicenamen so aufgebaut: fensterstatus_buero, fensterstatus_kueche, fensterstatus_esszimmer_rechts, fensterstatus_esszimmer_links usw.

Mein State liefert immer nur closed oder open.

Jetzt kann ich ja noch das Command einfügen als attr.

Diese Zeile muss ich dann aber ändern, oder ?

Zitatmy @fhttks = devspec2array("DEF=ShutterContact .+");

Weil ich habe ja kein "ShutterContact".
Meine Definition für ein Gerät sieht so aus:

define fensterstatus_buero KNX 6/1/3:dpt1.009

Bei den anderen Fenstern einfach nur eine andere Gruppenadresse.

Kann ich deinen Code trotzdem verwenden ?

Grüße,
Visionsurfer


Benni

Bitte den Thread hier nicht mehr oder weniger als allgemeinen Perl-Lern-Thread mißbrauchen.

Danke!  :)