hi, ich habs noch weiterentwickelt. allerdings hab ich kein wiregate, sondern einen server mit multihome, von daher habe ich nicht für das sql lite plugin weitergemacht. läuft bei mir seit 3 jahren ohne probs durch. das plugin ist nie ins svn aufgenommen worden.
gruß lars
Ankündigung
Einklappen
Keine Ankündigung bisher.
Alarmanlage Plugin auf Basis von Bewegungsmeldern
Einklappen
Dieses Thema ist geschlossen.
X
X
-
Hallo Lars,
gibt es für das Plugin (+ SQLite) mittlerweile neue Erkenntnisse? Funktioniert es bei dir wie erwartet? Läuft das so wie hier zuletzt gepostet oder gibt es eine neue/verbesserte Version (im SVN hab ich nichts gefunden)?
Danke,
Micha
Einen Kommentar schreiben:
-
Das sollte gar kein Problem sein. Ich werd mal schauen, ob ich das in die Config mitaufnehme:
Perl und SQLite - Mini-Howto [magenbrotWiki]
Es ändert sich ja eigentlich nur der Typ und eventuell Kleinigkeiten an den SQL Befehlen, muss mich damit mal beschäftigen.
MySQL
my $dbh = DBI->connect("dbi:mysql:$db:$host:$port", $dbusr, $dbusrpasswd, { RaiseError => 1, AutoCommit => 0, mysql_auto_reconnect => 1 }) or die ("Can not connect to DB");
SQLite
my $dbh = DBI->connect("dbi:SQLite2:dbname=$logdb", "", "", $dbargs);
Einen Kommentar schreiben:
-
So, das Ganze ist dann doch jetzt ausführlicher geworden, ich meine aber dafür auch sehr gut. Das Grundgerüst musste daher leider nochmal über den Haufen geschmissen werden, so wie es jetzt ist, wirds weiterentwickelt. Grund hierfür war zunächst das Logging meines Plugins über den Filehandler. 2 Gründe gegen das Logging über Files: die Auswertung aus Datenbanktabellen ist komfortabler, schneller und lässt einfachere Abfragelogiken zu, zum anderen sind Parallelzugriffe auf das Filehandle problematisch (im Test wurde hier wegen eines File-Locks eine 2. Datei mit XC am Ende des Dateinamens produziert). Leider ist somit ein MySQL-Server notwendig geworden, das hätte ich gerne vermieden, damit viele das auch Nutzen/Testen können. Aber gerade beim Alarmplugin sollte safty first sein, von daher ist mir das Filelocking zu unsicher. Der MySQL Server ist aber ganz einfach nachzuinstallieren:
Gerne kann das Plugin ins SV, wäre natürlich klasse, wenns aber zunächst fleissig getestet wird. Da ich eher keine Leuchte in der Dokumentation von Code bin, hoffe ich dennoch, dass das Meiste klar ist, falls nicht, einfach fragen.Code:apt-get install mysql-server apt-get install mysql-client
Folgende Logiken werden angenommen, um Fehlalarm (Auslösen von BM/PM durch Wärme etc.) vorzubeugen:
1. BW/PM aktiv -> GA Bewegungsmelder sendet Telegramm != Aus ( wegen Dimmen != 1 anstatt == 01 fürs reine Schalten) -> Analyse der gefundenen Treffer im Log -> wenn innerhalb my $match_intval gefunden Treffer grösser als action_match_counter -> Alarmauslösung
auf deutsch: wenn innerhalb von z.B. 5 Minuten mindestens 3 Einträge von in der Datenbank gefunden werden, dann wird die entsprechende Alarmhandlung ausgeführt
2. normaler Plugin Cycle (alle 60 Sekunden) oder bei aufgerufener GA Bewegungsmelder mit AUS Telegramm -> Kontrolle, wie lange ist Licht bereits an -> wenn Nachtriggerung (Zeit höher als Nachlaufzeit vom BM/PM) hohe Wahrscheinlichkeit für kein Fehlalarm
Datenbanktabelle:
PM_BM_Alarm.plCode:CREATE TABLE IF NOT EXISTS `pmbmalarm_log` ( `id` int(10) unsigned NOT NULL auto_increment, `name` varchar(255) NOT NULL, `schaltenGA` varchar(15) NOT NULL, `crtime` int(10) unsigned NOT NULL, `status_schalten` smallint(1) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `crtime` (`crtime`), KEY `status_schaltenGA` (`status_schalten`,`schaltenGA`), KEY `status_schaltenGA_crtime` (`status_schalten`,`schaltenGA`,`crtime`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
Code:############################################################################# # Plugin: Motion detector # V0.1 2012-07-11 # Copyright: Lars Tolkmitt (lars at stefla-web.de) # License: GPL (v3) # # Plugin for motion detector alarm / -> when moving -> Phone / send SMS / turn on all lights / TODO -> Multi-Room announcement # Alarmmelder-Plugin fuer Bewegungs/praesenzmelder -> bei Bewegung -> Anruf/SMS/alle Lichter an/TODO -> Multiroomansage # # Folgende Logiken werden angenommen, um Fehlalarm (Auslösen von BM/PM durch Wärme etc.) vorzubeugen # BW/PM aktiv -> Analyse der gefundenen Treffer im Log -> wenn innerhalb my $match_intval gefunden Treffer grösser als action_match_counter -> Alarmauslösung # Licht aus -> Kontrolle, wie lange war Licht bereits an -> wenn Nachtriggerung (Zeit höher als Nachlaufzeit vom BM/PM) hohe Wahrscheinlichkeit für kein Fehlalarm # normaler Plugin Cycle -> Kontrolle über StatusGAs, ob noch Licht an ist und wie lange dieses bereits an ist -> wenn Nachtriggerung (Zeit höher als Nachlaufzeit vom BM/PM) Ausschluss von Fehlalarm (angenommen wird, das bei Fehlalarm die Nachlaufzeit # ############################################################################# # #return; # uncomment to disable plugin # ############################################################################# ### Definitionen my $alarm_ga_control = "0/7/0"; # Gruppenadresse, auf die Alarm de- und aktiviert wird my $licht_ga = "1/2/0"; # Gruppenadresse fuer Zentralfunktion alle Lichter an/aus -> Zentralfunktion Licht my $ip_address = "XXX.XXX.XXX.XXX"; # IP-Adressse des Fritzbox Gateaways fuer Telnetzugriff my $user = ""; # Benutzername für telnet login my $passwd = ""; # Passwort des Benutzers my $remote_command1 = 'echo "ATDT**9" | nc 127.0.0.1 1011'; # Befehl zum Senden an alle internen Apparate per Telnet my $remote_command2 = 'echo "ATH0" | nc 127.0.0.1 1011'; # Befehl zum Auflegen, falls nicht abgenommen wurde per Telnet #my %notify_method("phone" => 1, "lights" => 0, "sms" => 0); my %notify_method; # Bei Alarmauslösung Festlegung von einzelnen Aktionen active = 1 = aktiviert, !=1 deaktiviert, Anzahl Treffer im Log $notify_method{'phone'}{'active'} = 1; # Alarmereignis aktivieren/deaktivieren $notify_method{'phone'}{'action_match_counter'} = 3; # ab wievielen Logeinträgen innerhalb von my $match_intval soll das Alarmereignis ausgelöst werden $notify_method{'lights'}{'active'} = 0; $notify_method{'lights'}{'action_match_counter'} = 5; $notify_method{'sms'}{'active'} = 0; $notify_method{'sms'}{'action_match_counter'} = 1; $notify_method{'email'}{'active'} = 0; $notify_method{'email'}{'action_match_counter'} = 1; my $alarm_email_ga = "8/0/100"; my @mail_recipients = ('XXX@gmx.de'); #Benachrichtigung an Emailadresse my @sms_recipients = ('0123465678'); #SMS an Handynummer my $read_alarm_ga_control = knx_read($alarm_ga_control,0,1); # Auslesen Wert von Gruppenadresse, auf die Alarm de- und aktiviert wird # Auswertungsfilter, um Fehlalarme zu vermeiden - Sensibilitätseinstellung my $match_intval = 86400; #Zeitintervall, innerhalb welches gefunde Treffer im Log ausgwertete werden dürfen, zB die letzten 5 Minuten my @watchGA; push @watchGA, { name => "Flur_Licht 2.1", schaltenGA => "2/1/21", statusGA => "2/2/21", nachlaufzeit => 20 }; push @watchGA, { name => "Diele-Licht 1.4", schaltenGA => "2/6/114", statusGA => "2/2/114", nachlaufzeit => 30 }; my $safty_nachlaufzeit = 30; # Wert in Sekunden ist hier sicherheitsfaktor für Laufzeiten im Bus #Datenbankparameter my $host = "localhost"; my $port = "3306"; my $db = "pmbmalarm"; my $dbusr = "dbuser"; my $dbusrpasswd = "dbuserpass"; # ab hier nichts mehr ändern ! my $unixzeit= time; #aktuelle Unixzeit my $plugin_pm_bm_alarm_retvalue = ""; #Debugging my $do_alarm_phone; my $do_alarm_lights; my $do_alarm_sms; my $do_alarm_email; ### Ende Definitionen use Getopt::Std; use Socket; use Net::Telnet; use DBI; ### Verbindung zur Datenbank/Server my $dbh = DBI->connect("dbi:mysql:$db:$host:$port", $dbusr, $dbusrpasswd, { RaiseError => 1, AutoCommit => 0, mysql_auto_reconnect => 1 }) or die ("Can not connect to DB"); # Plugin an Gruppenadresse "anmelden" $plugin_subscribe{$alarm_ga_control}{$plugname} = 1; $plugin_subscribe{$read_alarm_ga_control}{$plugname} = 1; $plugin_subscribe{$licht_ga}{$plugname} = 1; # aboniere alle zu überwachenden GAs aus @watchGA foreach my $element (@watchGA) { $plugin_subscribe{$element->{schaltenGA}}{$plugname} = 1; $plugin_subscribe{$element->{statusGA}}{$plugname} = 1; #Wert vom Bus if ($msg{'apci'} eq "A_GroupValue_Write" && $msg{'dst'} =~/$element->{schaltenGA}/ && $read_alarm_ga_control == 1) { if (defined $msg{'data'}) { ###Licht wird angeschaltet -> EIN Telegramm vom BM/PM -> $msg{'data'} kann bei Dimmwerten andere Werte als 01 annehmen -> daher else if ( $msg{'data'} != 00 ) { ### DBEintrag in den DBLog Tabelle mit status 1 = an my $log_action_return_value = &log_action($element->{name}, $element->{schaltenGA}); ### Suche in Logtabelle nach Anzahl von Treffern innerhalb von my $match_intval my $search_log_action_count_return_value = &search_log_action_count(); if( $search_log_action_count_return_value >= $notify_method{'phone'}{'action_match_counter'} ) { $do_alarm_phone = 1; } if( $search_log_action_count_return_value >= $notify_method{'lights'}{'action_match_counter'} ) { $do_alarm_lights = 1; } if( $search_log_action_count_return_value >= $notify_method{'sms'}{'action_match_counter'} ) { $do_alarm_sms = 1; } if( $search_log_action_count_return_value >= $notify_method{'email'}{'action_match_counter'} ) { $do_alarm_email = 1; } ##todo schleifen abbruch, ein alarm reicht $plugin_pm_bm_alarm_retvalue .= "Command1 ".$remote_command1." Command2 ".$remote_command2." an ".$ip_address." ".$log_action_return_value." counter ".$search_log_action_count_return_value." data".$msg{'data'}. " apci ". $msg{'apci'}. " read_alarm_ga_control ".$read_alarm_ga_control. " dst".$msg{'dst'}."\n"; } ###Licht wird ausgeschaltet -> AUS Telegramm vom BM/PM else { ##Update Datenbanktabelle Status Licht/PM/PM in der Datenbank von an auf aus my $log_action_return_value = &update_log_action($msg{'dst'}); #### schaue nach, wie lange der Bewegungsmelder lief -> Nachtriggerung -> hier muss noch funktionsaufruf rein } } } ### Cycle 60 Sekunden bei Aufruf durch cycle (nicht bei apci eq A_GroupValue_Write) -> alle 60 Sekunden wird über die Status GAs vom Licht geprüft, ob noch Licht an ist und die Zeit mit Hilfe des letzten Eintrages in der Datenbank verglichen elsif ($msg{'apci'} ne "A_GroupValue_Write") { my $read_status = knx_read($element->{statusGA},0,1); if($read_status == 1) { my $search_log_action_time_return_value = &search_log_action_time($element->{schaltenGA}); my $trigger_time = $unixzeit-$search_log_action_time_return_value; my $sum_nachlaufzeit = $element->{nachlaufzeit}+$safty_nachlaufzeit; ##alarm auslösen if($trigger_time > $sum_nachlaufzeit) { $do_alarm_phone = 1; $do_alarm_lights = 1; $do_alarm_sms = 1; $do_alarm_email = 1; ##todo schleifen abbruch, ein alarm reicht } $plugin_pm_bm_alarm_retvalue .= "statusGA $element->{statusGA} - read_status $read_status - search_log_action_time_return_value $search_log_action_time_return_value - trigger_time $trigger_time - sum_nachlaufzeit $sum_nachlaufzeit\n"; } } $plugin_pm_bm_alarm_retvalue .= "name ". $element->{name}." schaltenGA ". $element->{schaltenGA}. " dst".$msg{'dst'}." data ".$msg{'data'}."statusGA ". $element->{statusGA}."\n"; } # Eigenen Aufruf-Zyklus : alle 60 Sekunden wird unabhängig von zu lauschenden GAs nach Licht an kontrolliert $plugin_info{$plugname.'_cycle'} = 60; ###Mail Routine Alarmauslösung if( $notify_method{'phone'}{'active'} == 1 && $do_alarm_phone == 1 ) { my $fritz_telnet_login_return_value = fritz_telnet_login(); } if( $notify_method{'lights'}{'active'} == 1 && $do_alarm_lights == 1 ) { my $turn_on_lights_return_value = turn_on_lights(); } if( $notify_method{'sms'}{'active'} == 1 && $do_alarm_sms == 1 ) { my $send_sms_return_value = send_sms(); } if( $notify_method{'email'}{'active'} == 1 && $do_alarm_email == 1 ) { my $send_email_return_value = send_email(); } return $plugin_pm_bm_alarm_retvalue; ########################### Helper functions ########################### ### Logeinträge für Bewegungsmelder an sub log_action { my $name = shift; my $schaltenGA = shift; my $statement = "INSERT INTO pmbmalarm_log (name, schaltenGA, crtime, status_schalten) values (?,?,?,?);"; my $sth = $dbh->prepare($statement) or die $dbh->errstr(); my $anzahl = $sth->execute($name,$schaltenGA, $unixzeit, 1) or die $dbh->errstr(); $sth->finish(); $plugin_pm_bm_alarm_retvalue .= "log_action : $statement $msg{'dst'};$unixzeit : $anzahl \n"; return; } ### Update Logeinträge für BewegungsmelderGA von an auf aus (1 -> 0) sub update_log_action { my $schaltenGA = shift; my $statement = "UPDATE pmbmalarm_log SET status_schalten=0 WHERE status_schalten=1 && schaltenGA='$schaltenGA';"; my $sth = $dbh->prepare($statement) or die $dbh->errstr(); my $anzahl = $sth->execute() or die $dbh->errstr(); $sth->finish(); $plugin_pm_bm_alarm_retvalue .= "update_log_action: $statement $anzahl \n"; return; } ### Auswertung der Logeinträge nach Treffern innerhalb von my $match_intval sub search_log_action_count { my $statement = "SELECT count(id) as count FROM pmbmalarm_log WHERE crtime>=UNIX_TIMESTAMP(now())-$match_intval;"; my $sth = $dbh->prepare($statement) or die $dbh->errstr(); $sth->execute() or die $dbh->errstr(); my $result = $sth->fetchrow_array(); $sth->finish(); $plugin_pm_bm_alarm_retvalue .= "search_log_action_count: $statement \n"; return $result; } ### Auswertung, ob Licht länger an ist als Nachlaufzeit vom PM/BM sub search_log_action_time { my $schaltenGA = shift; my $statement = "SELECT crtime FROM pmbmalarm_log WHERE status_schalten=1 && schaltenGA='$schaltenGA' ORDER BY crtime DESC LIMIT 1;"; my $sth = $dbh->prepare($statement) or die $dbh->errstr(); $sth->execute() or die $dbh->errstr(); my $result = $sth->fetchrow_array(); $sth->finish(); $plugin_pm_bm_alarm_retvalue .= "search_log_action_time: $statement \n"; return $result; } sub fritz_telnet_login { my $command; my $tfritz = new Net::Telnet (Timeout => 10, Prompt =>'/#/'); $tfritz->open($ip_address); $plugin_pm_bm_alarm_retvalue .= "connecting............."; $tfritz->waitfor('/Fritz!Box web password:/'); $tfritz->print($passwd); $tfritz->waitfor('/#/'); $plugin_pm_bm_alarm_retvalue .= "done\n"; $plugin_pm_bm_alarm_retvalue .= "send command1...."; my @rc1 = $tfritz->cmd($remote_command1); $plugin_pm_bm_alarm_retvalue .= $rc1[1]; if(grep(/ERROR/i, @rc1)) { $plugin_pm_bm_alarm_retvalue .= "Fehler send command1\n"; $plugin_pm_bm_alarm_retvalue .= "send command2...."; my @rc2 = $tfritz->cmd($remote_command2); $plugin_pm_bm_alarm_retvalue .= $rc2[1]; $plugin_pm_bm_alarm_retvalue .= "done\n"; $plugin_pm_bm_alarm_retvalue .= "send command1...."; my @rc3 = $tfritz->cmd($remote_command1); $plugin_pm_bm_alarm_retvalue .= $rc3[1]; $plugin_pm_bm_alarm_retvalue .= "done\n"; $plugin_pm_bm_alarm_retvalue .= "sende close\n"; } $tfritz->close; return; } sub turn_on_lights { return knx_write($licht_ga,1,1); } sub send_sms { use LWP::UserAgent; use POSIX; my $user = "XXX"; my $pass = "XXX"; my $sender = "ALARM BEWEGUNGSMELDER"; my $text = "ALARM BEWEGUNGSMELDER"; my $type = '18'; foreach my $recipient (@sms_recipients){ my $caption = "$sender->$recipient"; my $url = 'http://soap.smscreator.de/send.asmx/SendText'; $url.= "?User=$user&Password=$pass&Caption=$caption&Sender=$sender&Recipient=$recipient&SMSTyp=$type&SMSText=$text&SendDate=".(&get_send_date); my $ua = LWP::UserAgent->new; my $res = $ua->get($url); } } sub get_send_date { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mon="0".$mon if(length($mon)==1); $mday="0".$mday if(length($mday)==1); $mon++; $year+=1900; return("$mday.$mon.$year $hour:$min:$sec"); } sub send_email { $plugin_pm_bm_alarm_retvalue .= " send email\n"; return knx_write($alarm_email_ga,1,1); }
Einen Kommentar schreiben:
-
Ah, sehr gut! Da hab ich wohl zu flüchtig gelesenZitat von larsknx Beitrag anzeigenhi makki, genau dieses schwelle hab ich eingebaut:
Wenns als halbwegs stabil angesehen wird, sollte das unbedingt ins SVN !
-> Entweder Sourceforge useraccount zum freischalten oder wenn das "too much" ist (was ich durchaus verstehe) -> Info, dann checke ich es ein.
Makki
Einen Kommentar schreiben:
-
Super Lars, dann warte ich noch ein bisschen auf die nächste Version und teste dann. Dann kann ich meinen angefangen Alarmanlagen-Code entsorgen
Einen Kommentar schreiben:
-
Hallo Wolfgang,
das in diesem Thread veröffentlichte Plugin ist für das WireGate 1 Multifunktionsgateway, nicht für den Gira Homeserver.Zitat von Wuifal2005 Beitrag anzeigenIch bekomme nächste Woche meinen HS4 geliefert.
Für Hilfe zum HS am besten einen Thread im entsprechenden Teil des Forums eröffnen.
lg
Stefan
Einen Kommentar schreiben:
-
Zitat von makki Beitrag anzeigenIch würde - aus Erfahrung - noch eine Schwelle einbauen (mehrere PM oder mehrfach nacheinander) weil so ein PM geht - nicht oft oder ständig - aber ab und zu auch mal völlig unmotiviert kurz an (starke Sonneneinstrahlung etc.)
Makki
hi makki, genau dieses schwelle hab ich eingebaut:
$notify_method{'phone'}{'action_match_counter'} = 3;
wenn im log innerhalb von 300 sekunden 3 oder mehr mal ein bewegungsmelder angeschaltet wurde, klingelt das Telefon
$notify_method{'lights'}{'action_match_counter'} = 5;
wenn im log innerhalb von 300 sekunden 5 oder mehr mal ein bewegungsmelder angeschaltet wurde, gehen alle lichter im haus an
$notify_method{'sms'}{'action_match_counter'} = 3;
wenn im log innerhalb von 300 sekunden 3 oder mehr mal ein bewegungsmelder angeschaltet wurde, wird eine sms verschickt
$notify_method{'email'}{'action_match_counter'} = 1;
wenn im log innerhalb von 300 sekunden 1 oder mehr mal ein bewegungsmelder angeschaltet wurde, wird eine email verschickt
die 300 sekunden können durch die variable my $match_intval = 300; eingestellt werden, stellt man es auf 3600, wirds natürlich noch empfindlicher.
über den paramter action_match_counter kann natürlich jeder selbst einstellen, ab wieviel logeinträgen innerhalb des intervalles die jeweilige aktion (per telefon, sms, email, etc.) ausgeführt werden soll.
über den parameter active kann man einstellen, ob die jeweilige aktion scharf (frei)geschaltete ist (1 = aktiv, != 1 nicht aktiv).
zusätzlich kommt heute noch ein update für fehlalarm rein. bei uns im haus ist es so, wenn der bewegungsmelder mal so angeht, entspricht die dauer licht an der dauer der nachlaufzeit vom bewegungsmelder
daher soll zusätzlich über die status ga vom licht (licht noch an, licht bereits aus) in einer 2. abfrage geschaut werden, ob der bewegungsmelder über die normale nachlaufzeit noch länger das licht angelassen hat und somit das AUS Telegramm zB erst nach 2 facher und längerer nachlaufzeit gesendet hat. dann ist davon auszugehen, dass nachgetriggert wurde und somit definitv jemand da ist.
klar , ist natürlich nicht eine aufwändige alarmtechnik, bei uns funktioniert es aber gut. wir haben die mdt präsenzmelder.
Hab noch mal ein Update reingespielt, die Email Routine wurde geändert (aus dem smtp-email.pl Plugin). leider war das file handling zwar richtig programmiert, wurde aber nicht zeilenweise in ein array gespeichert. warum auch immer, so gehts.
PM_BM_Alarm.pl
Code:############################################################################# # Plugin: Motion detector # V0.1 2012-07-11 # Copyright: Lars Tolkmitt (lars at stefla-web.de) # License: GPL (v3) # # Plugin for motion detector alarm / -> when moving -> Phone / send SMS / turn on all lights / TODO -> Multi-Room announcement # # Suggested settings: # =================== # ############################################################################# #return; # uncomment to disable plugin ############################################################################# # Alarmmelder-Plugin fuer Bewegungs/praesenzmelder -> bei Bewegung -> Anruf/SMS/alle Lichter an/TODO -> Multiroomansage ### Definitionen my $alarm_ga_control = "0/7/0"; # Gruppenadresse, auf die Alarm de- und aktiviert wird my $licht_ga = "1/2/0"; # Gruppenadresse fuer Zentralfunktion alle Lichter an/aus -> Zentralfunktion Licht my $ip_address = "192.168.2.1"; # IP-Adrassse des Fritzbox Gateaways fuer Telnetzugriff my $user = ""; # Benutzername für telnet login my $passwd = "XXX"; # Passwort des Benutzers my $remote_command1 = 'echo "ATDT**9" | nc 127.0.0.1 1011'; # Befehl zum Senden an alle internen Apparate per Telnet my $remote_command2 = 'echo "ATH0" | nc 127.0.0.1 1011'; # Befehl zum Auflegen, falls nicht abgenommen wurde per Telnet #my %notify_method("phone" => 1, "lights" => 0, "sms" => 0); my %notify_method; # Bei Alarmauslösung Festlegung von einzelnen Aktionen 1 = aktiviert, !=1 deaktiviert, Anzahl Treffer im Log $notify_method{'phone'}{'active'} = 0; $notify_method{'phone'}{'action_match_counter'} = 3; $notify_method{'lights'}{'active'} = 0; $notify_method{'lights'}{'action_match_counter'} = 5; $notify_method{'sms'}{'active'} = 1; $notify_method{'sms'}{'action_match_counter'} = 3; $notify_method{'email'}{'active'} = 0; $notify_method{'email'}{'action_match_counter'} = 1; my @mail_recipients = ('email@dddd.de'); #Benachrichtigung an Emailadresse my @sms_recipients = ('012345678'); #SMS an Handynummer my $read_alarm_ga_control = knx_read($alarm_ga_control,0,1); # Auslesen Wert von Gruppenadresse, auf die Alarm de- und aktiviert wird my $plugin_pm_bm_telnet_retvalue = ''; #Debuggin # Auswertungsfilter, um Fehlalarme zu vermeiden - Sensibilitätseinstellung my $match_intval = 300; #Zeitintervall, innerhalb welches gefunde Treffer im Log ausgwertete werden dürfen, zB die letzten 5 Minuten #my $action_match_counter = 3; # Einstellung fuer Anzahl von Treffern innerhalb von Zeitintervall, ab wann Alarm ausgelöst werden soll -> Routine, um Fehlalarme zu vermeiden, je kleiner die Zahl, je höher die Sensibilität my @watch_ga = ("1/2/139", "2/1/21", "2/6/114", "2/6/124", "2/6/137"); # Array für GA Bewegungsmelder, die zur Alarmmeldung rekrutiert werden my $logfile="/var/log/PM_BM_Telnet"; # Logile für Alarmanalyse my $unixzeit= time; ### Ende Definitionen use Getopt::Std; use Socket; use Net::Telnet; # Plugin an Gruppenadresse "anmelden" $plugin_subscribe{$alarm_ga_control}{$plugname} = 1; $plugin_subscribe{$read_alarm_ga_control}{$plugname} = 1; $plugin_subscribe{$licht_ga}{$plugname} = 1; # aboniere alle zu überwachenden GAs foreach my $i (@watch_ga){ $plugin_pm_bm_telnet_retvalue .= $i."\n"; $plugin_subscribe{$i}{$plugname} = 1; } # Eigenen Aufruf-Zyklus ausschalten $plugin_info{$plugname.'_cycle'} = 0; if ($msg{'apci'} eq "A_GroupValue_Write" && grep(/$msg{'dst'}/i, @watch_ga) && $read_alarm_ga_control == 1) { #Wert vom Bus if (defined $msg{'data'}) { if ( $msg{'data'} != 00 ) { my $log_search_log_action_return_value = search_log_action(); #my $log_action_return_value = log_action(); my $log_action_return_value; if( $notify_method{'phone'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'phone'}{'action_match_counter'} ) { my $remote_login_return_value = remote_login(); } if( $notify_method{'lights'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'lights'}{'action_match_counter'} ) { my $turn_on_lights_return_value = turn_on_lights(); } if( $notify_method{'sms'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'sms'}{'action_match_counter'} ) { my $send_sms_return_value = send_sms(); } if( $notify_method{'email'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'email'}{'action_match_counter'} ) { my $send_email_return_value = send_email(); } $plugin_pm_bm_telnet_retvalue .= "Command1 ".$remote_command1." Command2 ".$remote_command2." an ".$ip_address." ".$log_action_return_value." counter ".$log_search_log_action_return_value." data".$msg{'data'}. " apci". $msg{'apci'}. " read_alarm_ga_control ".$read_alarm_ga_control. " dst".$msg{'dst'}; } } } else { $plugin_pm_bm_telnet_retvalue .= "nicht zu tun an ip_address ".$ip_address." data".$msg{'data'}. " apci". $msg{'apci'}. " read_alarm_ga_control ".$read_alarm_ga_control. " dst".$msg{'dst'}; } return $plugin_pm_bm_telnet_retvalue; ### sub remote_login { my $command; my $tfritz = new Net::Telnet (Timeout => 10, Prompt =>'/#/'); $tfritz->open($ip_address); $plugin_pm_bm_telnet_retvalue .= "connecting............."; $tfritz->waitfor('/Fritz!Box web password:/'); $tfritz->print($passwd); $tfritz->waitfor('/#/'); $plugin_pm_bm_telnet_retvalue .= "done\n"; $plugin_pm_bm_telnet_retvalue .= "send command1...."; my @rc1 = $tfritz->cmd($remote_command1); $plugin_pm_bm_telnet_retvalue .= $rc1[1]; #foreach my $i (@rc1){ # $plugin_pm_bm_telnet_retvalue .= $i."\n"; # } if(grep(/ERROR/i, @rc1)) { $plugin_pm_bm_telnet_retvalue .= "Fehler send command1\n"; $plugin_pm_bm_telnet_retvalue .= "send command2...."; my @rc2 = $tfritz->cmd($remote_command2); $plugin_pm_bm_telnet_retvalue .= $rc2[1]; $plugin_pm_bm_telnet_retvalue .= "done\n"; $plugin_pm_bm_telnet_retvalue .= "send command1...."; my @rc3 = $tfritz->cmd($remote_command1); $plugin_pm_bm_telnet_retvalue .= $rc3[1]; $plugin_pm_bm_telnet_retvalue .= "done\n"; $plugin_pm_bm_telnet_retvalue .= "sende close\n"; } $tfritz->close; return; } sub turn_on_lights { return knx_write($licht_ga,1,1); } sub log_action { open(LOGFH, ">>$logfile") || die "Datei nicht gefunden\n"; print LOGFH "$msg{'dst'};$unixzeit\n"; close LOGFH; $plugin_pm_bm_telnet_retvalue .= "write LOG $msg{'dst'};$unixzeit\n"; } sub search_log_action { use strict; my $debug = `echo '$msg{'dst'};$unixzeit' >> $logfile`; my @linedata = (""); my $match_counter = 0; # Countervariable fuer Einträge im Alarm-Log innerhalb von $match_intval (zB wieoft ist ein Logneintrag fuer erkannte Bewegung innerhalb von 300 Sekunden, wenn mehr als zB 5 Einträge innerhalb von 300 Sekunden aktiviere Alarm) my @zeilen = (""); open SEARCHFH, "< $logfile" or die "Can't open $logfile : $!"; @zeilen=<SEARCHFH>; close(SEARCHFH); my @ntext = split(/\n/, $zeilen[0]); $plugin_pm_bm_telnet_retvalue .= "zeilen1neu -> $zeilen[0] <-\n"; for(@ntext) { chomp; my @linedata = split(/;/,$_); my $time_diff = $unixzeit-$linedata[1]; if($time_diff < $match_intval ) { $match_counter++; } $plugin_pm_bm_telnet_retvalue .= "adresse $linedata[0] logzeit $linedata[1] time_diff $time_diff\n"; } #use strict; # ## ##open(SEARCHFH, "<$logfile"); # || die "Datei nicht gefunden\n" #my $match_counter = 0; # #open SEARCHFH, "< $logfile" or die "Can't open $logfile : $!"; # #while (<SEARCHFH>) { # chomp; # # my $time_diff = $unixzeit-$linedata[1]; # if($time_diff < $match_intval ) { # $match_counter++; # } # # #$plugin_pm_bm_telnet_retvalue .= "adresse $linedata[0] logzeit $linedata[1] time_diff $time_diff\n"; # # } # #$plugin_pm_bm_telnet_retvalue .= " match_counter $match_counter \n"; # #close(SEARCHFH); # # return $match_counter; } sub send_sms { #use Configuration; #use Services; #use IPC::ShareLite; #use DBI; use LWP::UserAgent; #use File::stat; #use Data::Dumper; use POSIX; my $user = "STSMSC18296525"; my $pass = "3V5UNT"; my $sender = "ALARM BEWEGUNGSMELDER"; my $text = "ALARM BEWEGUNGSMELDER"; my $type = '18'; foreach my $recipient (@sms_recipients){ my $caption = "$sender->$recipient"; my $url = 'http://soap.smscreator.de/send.asmx/SendText'; $url.= "?User=$user&Password=$pass&Caption=$caption&Sender=$sender&Recipient=$recipient&SMSTyp=$type&SMSText=$text&SendDate=".(&get_send_date); my $ua = LWP::UserAgent->new; my $res = $ua->get($url); } } sub get_send_date { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mon="0".$mon if(length($mon)==1); $mday="0".$mday if(length($mday)==1); $mon++; $year+=1900; return("$mday.$mon.$year $hour:$min:$sec"); } sub send_email { # my $ret = shift; # foreach my $recipient (@mail_recipients){ # system("echo '$ret' | mail -s 'ALARM BEWEGUNGSMELDER' $recipient"); # } use Net::SMTP::SSL; use MIME::Base64; foreach my $recipient (@mail_recipients) { my $smtp = Net::SMTP::SSL->new("mail.stefla-web.de", Timeout => 10) or return "Fehler beim verbinden zu mail.stefla-web.de $!"; $smtp->auth($recipient, $passwd) or return "SASL Auth failed $!"; # try SASL $smtp->status() < 5 or return "Auth failed: $! ". $smtp->status(); $smtp->mail("WireGateAlarm <$recipient>") or return "Absender WireGate <$recipient> abgelehnt $!"; $smtp->to(split(',',$recipient)) or return "Empfaenger $recipient abgelehnt $!"; $smtp->data() or return "Data failed $!"; $smtp->datasend("To: $recipient\n") or return "Empfanger $recipient (Header-To) abgelehnt $!"; $smtp->datasend("Subject: ALARM\n") or return "Subject ALARM abgelehnt $!"; $smtp->datasend("\n") or return "Data failed $!"; $smtp->datasend("Alarm\n") or return "Data failed $!"; $smtp->dataend() or return "Data failed $!"; $smtp->quit or return "Quit failed $!"; $plugin_pm_bm_telnet_retvalue .= "eMail an $recipient gesendet"; } }
Einen Kommentar schreiben:
-
Ich werde testen und die Benachrichtigung via smsd einbauen -> https://knx-user-forum.de/wiregate/1...ht=sms-gateway
Einen Kommentar schreiben:
-
Nachtrag: ich bin zum ersten mal via Tapatalk im forum und habe nicht gesehen dass da noch mehr steht - habe nur deinen Einleitungssatz gesehen. Muss mich noch durch die Tapatalk Einstellungen kämpfen.
Werde das Script nächste Woche Testen.
Lieben Gruß
Wolfgang
Einen Kommentar schreiben:
-
Hallo,
Ich bekomme nächste Woche meinen HS4 geliefert. Ich habe im Haus alle Bewegungsmelder auch für Alarmanlage platziert. Bei Kellerfenster auch Sensoren (für Öffnen der Fenster). Im Experten kann ich (vom know how) dzt nur Standardsache wie Lich, Heizung... Im QC und Ajax Visu erstellen. Kannst Du mir hier bitte weiter helfen. Welche Idee steckt bei Dir dahinter? Ich habe es so geplant, dass die BWM Licht schalten und am Abend die Alarmschaltung aktiviert ist. Wenn ich zu Hause bin dann sollte Licht angehen etc. Und bei Abwesenheit eine SMS/e-mail abgesetzt werden.
Vielen Dank im Voraus
Gruß
Wolfgang
Einen Kommentar schreiben:
-
Ich würde - aus Erfahrung - noch eine Schwelle einbauen (mehrere PM oder mehrfach nacheinander) weil so ein PM geht - nicht oft oder ständig - aber ab und zu auch mal völlig unmotiviert kurz an (starke Sonneneinstrahlung etc.)
Makki
Einen Kommentar schreiben:
-
Alarmanlage Plugin auf Basis von Bewegungsmeldern
Hi Leute, hab die Tage mal ein Alarmplugin geschrieben, weil wir vor 1 Woche Einbrecher im Haus hatten.
Das ganze basiert auf die Auswertung der Daten der Bewegungsmelder/Präsenzmelder im Haus. Die Benachrichtigungsart kann eingstellt werden, derzeit ist folgendes möglich -> per Telefon (erfordert Fritzbox mit aktiviertem Telnet), per SMS (erfordert Account bei smscreator), per Email, alle Lichter im Haus an -> geplant Polizeisirene auf Paging Kanal -> Abspieler pulse/audio und Auslagerung ins conf File
Wenn Ihr Verbessungsideen habt oder Fehler seht, sagt bescheid.
TODO: Auslagerung in conf-File
Status: absolute alpha
PM_BM_Telnet.pl
Code:############################################################################# # Plugin: Motion detector # V0.1 2012-07-11 # Copyright: Lars Tolkmitt (lars at stefla-web.de) # License: GPL (v3) # # Plugin for motion detector alarm / -> when moving -> Phone / send SMS / turn on all lights / TODO -> Multi-Room announcement # # Suggested settings: # =================== # ############################################################################# #return; # uncomment to disable plugin ############################################################################# # Alarmmelder-Plugin fuer Bewegungs/praesenzmelder -> bei Bewegung -> Anruf/SMS/alle Lichter an/TODO -> Multiroomansage ### Definitionen my $alarm_ga_control = "0/7/0"; # Gruppenadresse, auf die Alarm de- und aktiviert wird my $licht_ga = "1/2/0"; # Gruppenadresse fuer Zentralfunktion alle Lichter an/aus -> Zentralfunktion Licht my $ip_address = "192.168.XXX.XXX"; # IP-Adrassse des Fritzbox Gateaways fuer Telnetzugriff my $user = ""; # Benutzername für telnet login my $passwd = "XXX"; # Passwort des Benutzers my $remote_command1 = 'echo "ATDT**9" | nc 127.0.0.1 1011'; # Befehl zum Senden an alle internen Apparate per Telnet my $remote_command2 = 'echo "ATH0" | nc 127.0.0.1 1011'; # Befehl zum Auflegen, falls nicht abgenommen wurde per Telnet #my %notify_method("phone" => 1, "lights" => 0, "sms" => 0); my %notify_method; # Bei Alarmauslösung Festlegung von einzelnen Aktionen 1 = aktiviert, !=1 deaktiviert, Anzahl Treffer im Log $notify_method{'phone'}{'active'} = 1; $notify_method{'phone'}{'action_match_counter'} = 3; $notify_method{'lights'}{'active'} = 0; $notify_method{'lights'}{'action_match_counter'} = 5; $notify_method{'sms'}{'active'} = 0; $notify_method{'sms'}{'action_match_counter'} = 3; $notify_method{'email'}{'active'} = 1; $notify_method{'email'}{'action_match_counter'} = 3; my @mail_recipients = ('mail@sld.tld'); #Benachrichtigung an Emailadresse my @sms_recipients = ('XXX'); #SMS an Handynummer my $read_alarm_ga_control = knx_read($alarm_ga_control,0,1); # Auslesen Wert von Gruppenadresse, auf die Alarm de- und aktiviert wird my $plugin_pm_bm_telnet_retvalue = ''; #Debuggin # Auswertungsfilter, um Fehlalarme zu vermeiden - Sensibilitätseinstellung my $match_counter = 0; # Countervariable fuer Einträge im Alarm-Log innerhalb von $match_intval (zB wieoft ist ein Logneintrag fuer erkannte Bewegung innerhalb von 300 Sekunden, wenn mehr als zB 5 Einträge innerhalb von 300 Sekunden aktiviere Alarm) my $match_intval = 300; #Zeitintervall, innerhalb welches gefunde Treffer im Log ausgwertete werden dürfen, zB die letzten 5 Minuten #my $action_match_counter = 3; # Einstellung fuer Anzahl von Treffern innerhalb von Zeitintervall, ab wann Alarm ausgelöst werden soll -> Routine, um Fehlalarme zu vermeiden, je kleiner die Zahl, je höher die Sensibilität my @watch_ga = ("1/2/139", "2/1/21", "2/6/114", "2/6/124", "2/6/137"); # Array für GA Bewegungsmelder, die zur Alarmmeldung rekrutiert werden my $logfile="/var/log/PM_BM_Telnet"; # Logile für Alarmanalyse my $unixzeit= time; ### Ende Definitionen use Getopt::Std; use Socket; use Net::Telnet; # Plugin an Gruppenadresse "anmelden" $plugin_subscribe{$alarm_ga_control}{$plugname} = 1; $plugin_subscribe{$read_alarm_ga_control}{$plugname} = 1; $plugin_subscribe{$licht_ga}{$plugname} = 1; # aboniere alle zu überwachenden GAs foreach my $i (@watch_ga){ $plugin_pm_bm_telnet_retvalue .= $i."\n"; $plugin_subscribe{$i}{$plugname} = 1; } # Eigenen Aufruf-Zyklus ausschalten $plugin_info{$plugname.'_cycle'} = 0; if ($msg{'apci'} eq "A_GroupValue_Write" && grep(/$msg{'dst'}/i, @watch_ga) && $read_alarm_ga_control == 1) { #Wert vom Bus if (defined $msg{'data'}) { if ( $msg{'data'} != 00 ) { my $log_search_log_action_return_value = search_log_action(); my $log_action_return_value = log_action(); if( $notify_method{'phone'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'phone'}{'action_match_counter'} ) { my $remote_login_return_value = remote_login(); } if( $notify_method{'lights'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'lights'}{'action_match_counter'} ) { my $turn_on_lights_return_value = turn_on_lights(); } if( $notify_method{'sms'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'sms'}{'action_match_counter'} ) { my $send_sms_return_value = send_sms(); } if( $notify_method{'email'}{'active'} == 1 && $log_search_log_action_return_value >= $notify_method{'email'}{'action_match_counter'} ) { my $send_email_return_value = send_email(); } $plugin_pm_bm_telnet_retvalue .= "Command1 ".$remote_command1." Command2 ".$remote_command2." an ".$ip_address." ".$log_action_return_value." counter ".$log_search_log_action_return_value." data".$msg{'data'}. " apci". $msg{'apci'}. " read_alarm_ga_control ".$read_alarm_ga_control. " dst".$msg{'dst'}; } } } else { $plugin_pm_bm_telnet_retvalue .= "nicht zu tun an ip_address ".$ip_address." data".$msg{'data'}. " apci". $msg{'apci'}. " read_alarm_ga_control ".$read_alarm_ga_control. " dst".$msg{'dst'}; } return $plugin_pm_bm_telnet_retvalue; ### sub remote_login { my $command; my $tfritz = new Net::Telnet (Timeout => 10, Prompt =>'/#/'); $tfritz->open($ip_address); $plugin_pm_bm_telnet_retvalue .= "connecting............."; $tfritz->waitfor('/Fritz!Box web password:/'); $tfritz->print($passwd); $tfritz->waitfor('/#/'); $plugin_pm_bm_telnet_retvalue .= "done\n"; $plugin_pm_bm_telnet_retvalue .= "send command1...."; my @rc1 = $tfritz->cmd($remote_command1); $plugin_pm_bm_telnet_retvalue .= $rc1[1]; #foreach my $i (@rc1){ # $plugin_pm_bm_telnet_retvalue .= $i."\n"; # } if(grep(/ERROR/i, @rc1)) { $plugin_pm_bm_telnet_retvalue .= "Fehler send command1\n"; $plugin_pm_bm_telnet_retvalue .= "send command2...."; my @rc2 = $tfritz->cmd($remote_command2); $plugin_pm_bm_telnet_retvalue .= $rc2[1]; $plugin_pm_bm_telnet_retvalue .= "done\n"; $plugin_pm_bm_telnet_retvalue .= "send command1...."; my @rc3 = $tfritz->cmd($remote_command1); $plugin_pm_bm_telnet_retvalue .= $rc3[1]; $plugin_pm_bm_telnet_retvalue .= "done\n"; $plugin_pm_bm_telnet_retvalue .= "sende close\n"; } $tfritz->close; return; } sub turn_on_lights { return knx_write($licht_ga,1,1); } sub log_action { open(LOGFH, ">>$logfile") || die "Datei nicht gefunden\n"; print LOGFH "$msg{'dst'};$unixzeit\n"; close LOGFH; } sub search_log_action { my @data = (""); open(SEARCHFH, "< $logfile") || die "Datei nicht gefunden\n"; while (chop(my $zeile = <SEARCHFH>)) { @data = split(/;/,$zeile); my $time_diff = $unixzeit-$data[1]; $plugin_pm_bm_telnet_retvalue .= "adresse $data[0] logzeit $data[1] time_diff $time_diff\n"; if($time_diff <= $match_intval ) { $match_counter++;} } #close(SEARCHFH); return $match_counter; } sub send_sms { #use Configuration; #use Services; #use IPC::ShareLite; #use DBI; use LWP::UserAgent; #use File::stat; use strict; #use Data::Dumper; use POSIX; my $user = ''; my $pass = ''; my $sender = 'ALARM BEWEGUNGSMELDER'; my $text = shift; my $type = '18'; foreach my $recipient (@sms_recipients){ my $caption = "$sender->$recipient"; my $url = 'http://soap.smscreator.de/send.asmx/SendText'; $url.= "?User=$user&Password=$pass&Caption=$caption&Sender=$sender&Recipient=$recipient&SMSTyp=$type&SMSText=$text&SendDate=".(&get_send_date); my $ua = LWP::UserAgent->new; my $res = $ua->get($url); } } sub get_send_date { my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mon="0".$mon if(length($mon)==1); $mday="0".$mday if(length($mday)==1); $mon++; $year+=1900; return("$mday.$mon.$year $hour:$min:$sec"); } sub send_email { my $ret = shift; foreach my $recipient (@mail_recipients){ system("echo '$ret' | mail -s 'ALARM BEWEGUNGSMELDER' $recipient"); } }Stichworte: -


Einen Kommentar schreiben: