Alarm, wenn niemand Anwesend (WLAN) + Bewegungsmelder meldet

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;

3 „Gefällt mir“

Ich habe ein ähnliches Script am laufen und dafür den Code von @marjue angepasst und erweitert.
Damit ist es auch möglich mehrere Fritzboxen & Fritz WLAN Repeater abzufragen (wie bei mir nötig), zudem habe ich noch ein Timeout von 5 Min für die Abwesenheitsmeldung eingebaut, das lief bei mir damit fehlerfreier.

In deinem Code finde ich gut, das man die MAC’s gesammelt übergibt, bei mir werden diese einzeln überprüft. Das werde ich vlt auch mal anpassen :slight_smile:
Ausserdem könnte ich das auch mal zusammenfassen, damit alles über eine Datei gesteuert wird und nicht - wie aktuell - über 2 verschiedene.

Wer Interesse hat kann sich mein Script auch mal anschauen: https://codeking.de/smarthome/hostwatchdog.zip

Einfach wie folgt vorgehen (im Falle eines Raspberry Pi):

  • Entpacken und in /home/pi/hostwatchdog/ kopieren
  • config.conf anpassen und User & Mac Adressen hinterlegen
  • hostwatchdog.sh anpassen und Homee ID, Webhook und Daten der Fritzbox anpassen, ggf. erweitern
  • chmod +x hostwatchdog.sh fritzbox_user.pl
  • sudo ./hostwatchdog.sh ausführen und später minütlich per Cronjob einstellen

Es muss Perl und Soap::Lite installiert sein, also ggf. noch
apt-get install perl libsoap-lite-perl

Viele Grüße,

Frank

2 „Gefällt mir“

Sehr gutes Script… zwei Hineise:

  1. Die MAC in “Kleinbuchstaben” eintragen (wollte bei sonst nicht)
  2. cUrl muss installiert sein (ist nicht immer und überall dabei)

Habs mal auf den Pogo installiert, der läuft sowieso… Meine bisherigen Lösungen hatten immer das Problem das sie kurz Abwesend und wieder Anwesend gemeldet haben, hier mit dem einstellbarem “Puffer” sehr schön gelöst - hätte ich mal bei meiner Lösung machen können. Hier wird gegen die FB geprüft, prima Lösung.

bekomme den Fehler hier:

401 Unauthorized at /root/hostwatchdog/fritzbox_user.pl line 87.
./hostwatchdog.sh: Zeile 87: [: -eq: Einstelliger (unärer) Operator erwartet.
:frowning:

Aber es wird mir angezeigt, wenn WLAN verlassen wird…Hast ne Idee was der Fehler bedeutet?

EIDT: Lag am komplizierten Passwort!

Nutze dieses Skript nun, um Abends Alarm scharf zu stellen, da wir die Smartphones immer abschalten…bzw. in Flugmodus versetzen;-)

1 „Gefällt mir“

Moin, das Skript läuft… leider bekomme ich ab und zu ne Meldung, dass sich mein IPhone 6+ mit Ios10 vom WLAN abgemeldet hat…

Dann den Parameter timeout im Shellscript anpassen. Aktuell (ip 6) reicht bei mir 180 Sekunden.

Ich Habs auf 300 gelassen… kann das daran liegen?

Ja, dann den Wert weiter erhöhen… Wie oft wird der Cron ausgeführt?

Minütlich… Wird ausgeführt.

Probleme mit der Erkennung von Geräten.
Hardware: Fritz!Box 7490, Repeater, iPhone 6 + iPhone 7

Die Erkennung des iPhone 6 funktioniert problemlos. Das iPhone 7 wird nicht “erkannt”.

Mac-Adressen wurden kontrolliert.

Jemand eine Idee?

Hi,

Was wurde konkret kontrolliert. Die MAC die in der Fritzbox angezeigt wird wenn das iPhone angemeldet ist? MAC klein geschrieben? Die MAC des iPhone6 entfernt und nur die des 7er verwendet?

Grüße

…genau das Alles. Sämtliche Kombinationen und die des 7er alleine und Schreibweisen.

Du könntest noch das Perl Skript alleine ausführen: perl fritzbox.pl > out.txt (fritzbox.pl musst du halt entsprechend anpassen).

Anschließend müssten alle an der FB angemeldeten Geräte in der Textdatei drin sein. Wenn dort das iPhone 7 drin ist, sollte es gehen.

Danke! Ein Neustart der FritzBox hat geholfen!

Hallo Frank,
leider funktioniert der Link zu Deinem Code nicht mehr.
Ich wollte nachschauen, wie Du das mit der Abfrage mehrerer FritzBoxen und Repeater realisiert hast.
Bitte aktualisiere den Link.
Danke & Gruß
Mike