Hallo Leute,
auch mit hat das Thema umgetrieben, wie die An-/Abwesenheitserkennung per WLAN über die Fritz.Box realisiert werden kann.
Da es bereits ein ähnliches Projekt auf Laxone unter Perl gibt, habe ich dieses adaptiert.
Der Code läuft per CRON Job alle Minute auf einem RaspberryPi und prüft ob einer der Anwohner mit dem WLAN verbunden ist.
Anbei der Code:
#!/usr/bin/perl -w`
######################################################################
Script zur Anwesenheitserkennung von WLAN-Geräten
an einer Fritz!Box 7490 in Verbindung mit einem
Loxone Miniserver
Version: 2016.02.27.15.09.14
Quelle: http://www.loxwiki.eu/pages/viewpage.action?pageId=6258848
2016.12.23 Überarbeitung für Homee
######################################################################
Miniserver UDP Information
my $mshost = ‘homee’; # Miniserver-IP oder Hostname
my $msprotocol = ‘udp’; #tcp
my $msport = 7681;
Fritz!Box Information
my $ip = ‘fritz.box’; # Fritz!Box-IP oder Hostname
my $port = 49443; # Fritz!Box Port
Flushing to STDOUT after each write
$| = 1;
use strict;
use warnings;
use LWP::Simple;
use LWP::UserAgent;
use XML::Simple;
use Getopt::Long;
use open qw(:std :utf8);
use POSIX qw/ strftime /;
use IO::Socket;
Check Command Line parameters
Minumum 2 - Resident and at least one Phone-MAC address
my $num_args = $#ARGV + 1;
if ($num_args < 2)
{
print “Missing command line argument!”;
print “\nUsage: fritzbox-bewohner.pl []”;
print “\nExample: fritzbox-bewohner.pl Bewohner1 00:00:00:00:00:00\n”;
exit;
}
Alle MACs sammeln und im Array macs_to_check speichern
my @macs_to_check =($ARGV[1]);
my $bewohner = $ARGV[0];
print "Checking presence for User “.$bewohner.” with MAC ".$ARGV[1];
for (my $mac=1; $mac <= $num_args-2; $mac++)
{
push @macs_to_check, $ARGV[$mac+1];
print " or MAC “.$ARGV[($mac+1)];
}
print " at " . $ip .” on port " . $port . “…\n”;
disable SSL checks. No signed certificate!
$ENV{‘PERL_LWP_SSL_VERIFY_HOSTNAME’} = 0;
$ENV{HTTPS_DEBUG} = 1;
Discover Service Parameters
my $ua = new LWP::UserAgent;
$ua->default_headers;
$ua->ssl_opts( verify_hostname => 0 ,SSL_verify_mode => 0x00);
Read all available services
my $resp_discover = $ua->get(“https://$ip:$port/tr64desc.xml”);
my $xml_discover;
if ( $resp_discover->is_success )
{
$xml_discover = $resp_discover->decoded_content;
}
else
{
die $resp_discover->status_line;
}
my $discover = XMLin($xml_discover);
print “$discover->{device}->{modelName} detected…\n”;
Parse XML service response, get needed parameters for LAN host service
my $control_url = “not set”;
my $service_type = “not set”;
my $service_command = “GetSpecificHostEntry”; # fixed command for requesting info of specific MAC
foreach(@{$discover->{device}->{deviceList}->{device}->[0]->{serviceList}->{service}})
{
if(“urn:LanDeviceHosts-com:serviceId:Hosts1” =~ m/.$_->{serviceId}./)
{
$control_url = $->{controlURL};
$service_type = $->{serviceType};
}
}
if ($control_url eq “not set” or $service_type eq “not set”)
{
die “control URL/service type not found. Cannot request host info!”;
}
Prepare request for query LAN host
$ua->default_header( ‘SOAPACTION’ => “$service_type#$service_command” );
my $xml_mac_resp;
my $any_online = 0; # if arg any specified
foreach my $mac (@macs_to_check)
{
my $init_request = <<EOD;
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/” xmlns:s=“http://schemas.xmlsoap.org/soap/envelope/” >
<s:Header>
</s:Header>
<s:Body>
<u:$service_command xmlns:u="$service_type">
$mac
</u:$service_command>
</s:Body>
</s:Envelope>
EOD
my $init_url = "https://$ip:$port$control_url";
my $resp_init = $ua->post($init_url, Content_Type => 'text/xml; charset=utf-8', Content => $init_request);
$xml_mac_resp = XMLin($resp_init->decoded_content);
if(exists $xml_mac_resp->{'s:Body'}->{'s:Fault'})
{
if($xml_mac_resp->{'s:Body'}->{'s:Fault'}->{detail}->{UPnPError}->{errorCode} eq "714")
{
print "Mac $mac not found in FritzBox Database!\n";
}
}
if(exists $xml_mac_resp->{'s:Body'}->{'u:GetSpecificHostEntryResponse'})
{
if($xml_mac_resp->{'s:Body'}->{'u:GetSpecificHostEntryResponse'}->{NewActive} eq "1")
{
my $name = $xml_mac_resp->{'s:Body'}->{'u:GetSpecificHostEntryResponse'}->{NewHostName};
my $ip = $xml_mac_resp->{'s:Body'}->{'u:GetSpecificHostEntryResponse'}->{NewIPAddress};
my $iftype = $xml_mac_resp->{'s:Body'}->{'u:GetSpecificHostEntryResponse'}->{NewInterfaceType};
print "Mac $mac ($name) is online with IP $ip on $iftype\n";
$any_online = 1;
}
if($xml_mac_resp->{'s:Body'}->{'u:GetSpecificHostEntryResponse'}->{NewActive} eq "0")
{
my $name = $xml_mac_resp->{'s:Body'}->{'u:GetSpecificHostEntryResponse'}->{NewHostName};
print "Mac $mac ($name) is offline\n";
}
}
}
#print “Sending Data '”.$bewohner.":".$any_online."’ to $mshost on port $msport …\n";
use LWP 5.64;
my $url = “”;
if ($any_online == 0) {
$url = ‘http://homee:7681/api/v2/webhook_trigger?webhooks_key=ALILTNZNZWNTUOYWXEPPJNDEOLTVNNIYBTEMHCEXWPOHNRNORSPXBOZCZQQGREWV&event=Alarm%20An’;
} else {
$url = ’ http://homee:7681/api/v2/webhook_trigger?webhooks_key=ALILTNZNZWNTUOYWXEPPJNDEOLTVNNIYBTEMHCEXWPOHNRNORSPXBOZCZQQGREWV&event=Alarm%20aus’;
}
my $browser = LWP::UserAgent->new;
my $response=$browser->get($url);
die “Couldn’t get $url”, $response->status_line
unless $response->is_success;