Hallo zusammen,
auf Wunsch (siehe dieser Thread) habe ich mal eine Anwesenheitssimulation als Wiregate-Plugin zusammengehackt. Wie immer "ohne Gewehr" :-)
Folgender Disclaimer: es handelt sich um einen Quick Hack, auch um zu zeigen, wie schön Perl doch ist, wenn es um Quick Hacks geht :-)
Ich selbst brauche keine Anwesenheitssimulation, deshalb bittet mich nicht um eure 10.000 Wunschfeatures. Wer das Plugin erweitern will - be my guest, aber beachtet die GPL und postet das verbesserte Plugin hier bzw. im SVN.
Das Ganze funktioniert so: das Plugin Anwesenheitssimulation abonniert eine einzige GA (im Skript festgelegt, extra dafür wollte ich kein .conf-File schreiben). Diese GA sollte (wie immer) in der eibga.conf hinterlegt sein und DPT-Typ 1 haben (wie ein Schalter: an/aus).
Wird die Anwesenheitssimulation über die GA angeschaltet (Telegrammwert 1), so erzeugt sie ein neues Plugin aus der eib.log. Das neue Plugin wird danach vom Wiregate-Daemon ausgeführt und wiederholt einfach die Telegramme, die im eib.log gefunden wurden. (Beispielhaft steht im Skript auch drin, wie man bestimmte GAs ausfiltern kann).
Wird die Anwesenheitssimulation über die GA ausgeschaltet (Telegrammwert 0), so löscht sie das erzeugte Plugin wieder.
Und hier das Skript, wie immer auch im SVN zu finden:
Bitte holt das Plugin aus dem SVN - dort stehen ggf. neuere Versionen.
Have fun!
VG, Fry
auf Wunsch (siehe dieser Thread) habe ich mal eine Anwesenheitssimulation als Wiregate-Plugin zusammengehackt. Wie immer "ohne Gewehr" :-)
Folgender Disclaimer: es handelt sich um einen Quick Hack, auch um zu zeigen, wie schön Perl doch ist, wenn es um Quick Hacks geht :-)
Ich selbst brauche keine Anwesenheitssimulation, deshalb bittet mich nicht um eure 10.000 Wunschfeatures. Wer das Plugin erweitern will - be my guest, aber beachtet die GPL und postet das verbesserte Plugin hier bzw. im SVN.
Das Ganze funktioniert so: das Plugin Anwesenheitssimulation abonniert eine einzige GA (im Skript festgelegt, extra dafür wollte ich kein .conf-File schreiben). Diese GA sollte (wie immer) in der eibga.conf hinterlegt sein und DPT-Typ 1 haben (wie ein Schalter: an/aus).
Wird die Anwesenheitssimulation über die GA angeschaltet (Telegrammwert 1), so erzeugt sie ein neues Plugin aus der eib.log. Das neue Plugin wird danach vom Wiregate-Daemon ausgeführt und wiederholt einfach die Telegramme, die im eib.log gefunden wurden. (Beispielhaft steht im Skript auch drin, wie man bestimmte GAs ausfiltern kann).
Wird die Anwesenheitssimulation über die GA ausgeschaltet (Telegrammwert 0), so löscht sie das erzeugte Plugin wieder.
Und hier das Skript, wie immer auch im SVN zu finden:
Code:
#!/usr/bin/perl -w
##########################
# Anwesenheitssimulation #
##########################
# Wiregate-Plugin
# (c) 2012 Fry under the GNU Public License
#$plugin_info{$plugname.'_cycle'}=0; return 'deaktiviert';
# Aufrufgrund ermitteln
my $event=undef;
if (!$plugin_initflag)
{ $event='restart'; } # Restart des daemons / Reboot
elsif ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'})
{ $event='modified'; } # Plugin modifiziert
elsif (%msg) { $event='bus'; } # Bustraffic
elsif ($fh) { $event='socket'; } # Netzwerktraffic
else { $event='cycle'; } # Zyklus
# eine Gruppenadresse zum Starten und Stoppen. Diese ist vom Typ DPT 1 (An/Aus)
$plugin_subscribe{'1/2/0'}{$plugname}=1;
# kein regelmaessiger Aufruf
$plugin_info{$plugname.'_cycle'}=0;
# Nur auf Bustraffic reagieren
return unless $event=~/bus/ && $msg{apci} eq "A_GroupValue_Write";
my $in=int($msg{value});
# Name des Simulationsskriptes
my $simscript="/etc/wiregate/plugin/generic/Anwesenheitssimulationsskript.pl";
unless($in) { system "rm", "-f", $simscript; return "Anwesenheitssimulation gestoppt"; }
# Start Anwesenheitssimulation: einfach ein neues Plugin aus eib.log erzeugen, der wiregate-Daemon fuehrt es dann aus
open SIM, ">$simscript";
my $line=1;
print SIM <<EOF;
#!/usr/bin/perl -w
\$plugin_info{\$plugname.'_line'}=1 unless defined \$plugin_info{\$plugname.'_line'};
given(\$plugin_info{\$plugname.'_line'}) {
when($line) {
EOF
my $time=`/bin/date +%X`; $time=~/^([0-9][0-9])\:([0-9][0-9])\:([0-9][0-9])/; my ($h,$m,$s)=($1,$2,$3);
my $lastdaynum=undef;
open IN, "</var/log/eib.log";
$/="\n";
while($_=<IN>)
{
chomp;
next unless /^([0-9][0-9][0-9][0-9])\-([0-9][0-9])\-([0-9][0-9]) ([0-9][0-9])\:([0-9][0-9])\:([0-9][0-9])[^,]*,[^,]*,[^,]*,([0-9]+\/[0-9]+\/[0\
-9]+),[^,]*,([^,]*),[^,]*,([^,]*),.*$/;
my ($year, $month, $day, $hour, $min, $sec, $ga, $val, $dpt)=($1, $2, $3, $4, $5, $6, $7, $8, $9);
$val="'$val'" if $dpt=~/^16/;
# Alle Telegramme auf manchen Hauptgruppen ausfiltern
next if $ga=~m!^(5|6)/0!;
my $daynum=365*$year; $year-- if $month<=2; $daynum+=int($year/4) - int($year/100) + int($year/400);
my $delta = (defined $lastdaynum) ? $daynum-$lastdaynum : 0;
$lastdaynum=$daynum;
$delta=(($delta*24+($hour-$h))*60+($min-$m))*60+($sec-$s);
next if $delta<0;
($h,$m,$s)=($hour,$min,$sec);
if($delta>0)
{
$line++;
print SIM <<EOF;
\$plugin_info{\$plugname.'_cycle'}=$delta; }
when($line) {
EOF
}
print SIM <<EOF;
# $_
knx_write('$ga', $val, $dpt);
EOF
}
close IN;
print SIM <<EOF;
}
}
default { \$plugin_info{\$plugname.'_line'}=1; }
}
\$plugin_info{\$plugname.'_line'}++;
return \$plugin_info{\$plugname.'_line'}-1;
EOF
close SIM;
return "Anwesenheitssimulation gestartet";
Have fun!
VG, Fry



Kommentar