...
- Linux-Server (raspberry pi ist ausreichend)
- eingerichter Webserver (Apache oder lighthttp)
- Fritzbox
- iPhone oder Android mit aktiviertem WLAN
...
11:22:33:44:55:66 und 22:33:44:55:66:77, wobei eins davon ein iPhone und das andere ein Android-Handy ist.
Einrichten des
...
Perl-
...
Falls ein Webserver noch nicht eingerichtet sein sollte, lässt sich das relativ schnell nachholen mit folgendem Befehl:
Codeblock | ||||
---|---|---|---|---|
| ||||
sudo apt-get install apache2 |
Anschließende muss für die Funktionalität des Perl-Skriptes noch etwas nachinstalliert werden.
Codeblock | ||||
---|---|---|---|---|
| ||||
sudo apt-get install libxml-simple-perl libio-all-lwp-perl libgetopt-long-descriptive-perl |
Test des Webservers
Ein erster Test sollte der Ereichbarkeit des Webservers gelten, dazu die IP-ADRESSE des Servers eingeben und über folgenden Text freuen
Codeblock |
---|
It works!
This is the default web page for this server.
The web server software is running but no content has been added, yet. |
Einrichten des Perl-Skriptes
Anschließend folgendes Perl-Skript in einem beliebigen Verzeichnis unter etwa folgendem Namen speichern, /home/pi/fritzbox-bewohner1.pl.
Funktionsweise des Skripts
Das Perl-Skript fragt die Fritzbox die MAC-Adressen ab und sendet per UDP "xxx-1" für online und "xxx"-0 für offline.
Die Information kann dann wie auf der Seite UDP Eingang definieren ausgewertet werden.
...
language | perl |
---|---|
title | Perl-Skript zur Fritzbox-Abfrage |
linenumbers | true |
...
Skriptes
Anschließend folgendes Perl-Skript in einem beliebigen Verzeichnis unter etwa folgendem Namen speichern, /home/pi/fritzbox-bewohner1.pl.
Funktionsweise des Skripts
Das Perl-Skript fragt die Fritzbox die MAC-Adressen ab und sendet per UDP "xxx-1" für online und "xxx"-0 für offline.
Die Information kann dann wie auf der Seite UDP Eingang definieren ausgewertet werden.
Codeblock | ||||||
---|---|---|---|---|---|---|
| ||||||
#!/usr/bin/perl -w
use strict;
use warnings;
use LWP::Simple;
use LWP::UserAgent;
use XML::Simple;
use Getopt::Long;
use open qw(:std :utf8);
use HTTP::Request::Common;
use IO::Socket::INET;
# ------------- Konfiguration -------------
my $ip = "192.168.xxx.xxx"; # IP Fritzbox
my $port = "49443"; # Port Fritzbox
my @macs_to_check = ("AA:BB:CC:DD:EE:FF"); # MAC Adresse der Geraete, es können mehrere eingetragen werden
my $LOXIP = "192.168.xxx.xxx"; # IP Miniserver
my $udpport = "34435"; # UDP-Port
my $online = "xxx-1"; # Person Online
my $offline = "xxx-0"; # Person Offline
# ---------------- Programm ----------------
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
$ENV{HTTPS_DEBUG} = 1;
my $ua = new LWP::UserAgent;
$ua->default_headers;
$ua->ssl_opts( verify_hostname => 0 ,SSL_verify_mode => 0x00);
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} gefunden...\n";
my $control_url = "not set";
my $service_type = "not set";
my $service_command = "GetSpecificHostEntry";
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!";
}
$ua->default_header( 'SOAPACTION' => "$service_type#$service_command" );
my $xml_mac_resp;
my $any_online = 0;
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">
<NewMACAddress>$mac</NewMACAddress>
</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 nicht in der FritzBox gefunden!\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) ist online mit der IP $ip mit $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) ist offline\n";
}
}
}
if ($any_online){
my $sock = new IO::Socket::INET(PeerAddr => $LOXIP,
PeerPort => $udpport,
Proto => 'udp', Timeout => 1) or die('Error opening socket.');
print $sock $online;
exit 1;
}
else{
my $sock = new IO::Socket::INET(PeerAddr => $LOXIP,
PeerPort => $udpport,
Proto => 'udp', Timeout => 1) or die('Error opening socket.');
print $sock $offline;
exit 0;
} |
...
Um das ganze automatisiert abfragen zu können ist wieder ein cronjob und die Ausführberechtigung für das Skript notwendig.
Codeblock | ||
---|---|---|
| ||
chmod +x /home/pi/fritzbox-Bewohner1.pl |
Codeblock | ||||
---|---|---|---|---|
| ||||
sudo crontab -e |
Folgende Zeilen am Ende einfügen:
die Ausführberechtigung für das Skript notwendig.
Codeblock | ||
---|---|---|
| ||
* * * * * /usr/bin/perl /home/pi/fritzbox-Bewohner1.pl -any >/dev/null 2>&1 |
Nun fragt der raspberry pi jede Minute den Status der anwesenden WLAN-Geräte bei der Fritzbox ab.
Einrichtung Loxone
In Loxone muss als Erstes folgendes erstellt werden:
Einen virtuellen HTTP-Eingang mit folgenden Einstellungen:
Anschließend ein Virtueller HTTP Eingang Befehl mit folgenden Einstellungen:
Anschließend noch eine leicht abgewandelte Config-Version von dott:
Der Statusbaustein sieht folgendermaßen aus:
...
chmod +x /home/pi/fritzbox-Bewohner1.pl |
Codeblock | ||||
---|---|---|---|---|
| ||||
sudo crontab -e |
Folgende Zeilen am Ende einfügen:
Codeblock | ||
---|---|---|
| ||
* * * * * /usr/bin/perl /home/pi/fritzbox-Bewohner1.pl -any >/dev/null 2>&1 |
Nun fragt der raspberry pi jede Minute den Status der anwesenden WLAN-Geräte bei der Fritzbox ab.
Den Empfang der UDP - Telegramme und die Verwertung im Miniserver ist unter UDP Eingang definieren beschrieben.