Raspberry Pi Anwesenheitserkennung mit Wi-Fi

12

Wie kann ich meinen Raspberry Pi kontinuierlich nach einer MAC-Adresse in meinem Netzwerk suchen lassen und dann eine Aufgabe ausführen, wenn er eine bestimmte MAC-Adresse erkennt?

Ich benutze meinen Pi, um verschiedene Hausautomationsaufgaben auszuführen. Ich möchte, dass es eine Aufgabe ausführt, wenn es feststellt, dass mein Telefon mit dem Wi-Fi verbunden ist (was bedeutet, dass ich gerade zu Hause bin). Wie kann ich den Pi am besten kontinuierlich nach der MAC-Adresse meines Telefons durchsuchen lassen? Ich weiß, dass ich arp-scannach MAC-Adressen suchen kann, aber ich muss dies kontinuierlich tun. Ich bin mir sicher, dass es eine bessere Methode gibt, als arp-scanin einer Schleife oder mit cron jede Minute ausgeführt zu werden.

gsears
quelle
2
Wenn Sie keine Echtzeit-Antwort benötigen, ist cron der beste Weg. Zuerst schreiben Sie ein Skript, das in sh so etwas wie true oder false zurückgibt (der Statuscode ist die beste Option, um die Antwort zu priviligieren), dann ein Skript, das den vorherigen Wert irgendwo in / tmp speichert und auf Änderungen überprüft. Wenn eine Änderung eintrifft, wird sie protokolliert.
Misaz

Antworten:

3

Zuhause anrufen

Mein Telefon verhält sich anders, da alle Telefone einen Unterschied aufweisen. Eine Ping-Antwort erfolgt nur, wenn das Telefon wach ist. Wenn der Pi neu gestartet wird und sich das Telefon im Energiesparmodus befindet, werden seine IP- und Mac-Adressen mit 100% Paketverlust durch mehrere Pings in der ARP-Tabelle abgelegt. Ich habe gerade erfahren, dass der arpBefehl veraltet ip neighborist, wird jetzt verwendet.

pi@RPi0:~ $ ip neighbor
169.254.65.43 dev eth0 lladdr 64:31:00:00:00:00 REACHABLE
192.168.0.1 dev wlan0 lladdr ac:b3:00:00:00:00 STALE
fe80::aeb3:13ff:fe00:000 dev wlan0 lladdr ac:b3:00:00:00:00 router STALE

pi@RPi0:~ $ ping 192.168.0.22
PING 192.168.0.22 (192.168.0.22) 56(84) bytes of data.
From 192.168.0.10 icmp_seq=1 Destination Host Unreachable
From 192.168.0.10 icmp_seq=2 Destination Host Unreachable
From 192.168.0.10 icmp_seq=3 Destination Host Unreachable
--- 192.168.0.22 ping statistics ---
34 packets transmitted, 0 received, +3 errors, 100% packet loss, time 34303ms

pi@RPi0:~ $ ip neighbor
192.168.0.1 dev wlan0 lladdr ac:b3:00:00:00:00 REACHABLE
169.254.65.43 dev eth0 lladdr 64:31:00:00:00:00 REACHABLE
192.168.0.22 dev wlan0 lladdr ac:37:00:00:00:00 REACHABLE
fe80::aeb3:13ff:fe00:000 dev wlan0 lladdr ac:b3:00:00:00:00 router STALE

Nach dem Testen würde meine Lösung darin bestehen, zwei Schleifen in einer Endlosschleife zu haben. Die erste innere Schleife wäre, mehrmals einen Ping auf einen Bereich von IP-Adressen durchzuführen, der für mein Telefon möglich wäre. Mein Router hat die ersten 19 IP-Adressen reserviert und ich habe möglicherweise etwa ein halbes Dutzend Adressen, die von DHCP zugewiesen werden, einschließlich meines Telefons, beginnend mit der Adresse 192.168.0.20. Ich werde ein Dutzend IP-Adressen einmal im Hintergrund anpingen, eine Sekunde auf eine Antwort warten und die Ergebnisse als Müll wegwerfen. Ich werde acht Sekunden auf dem ARP-Tisch warten und den ip neighborBefehl ausführen, indem ich die MAC- Adresse nach der IP-Adresse durchsucht . Der Router und das Telefon behalten dieselbe IP-Adresse, sofern nichts Ungewöhnliches passiert. Die arp - Tabelle wird in dem Pi bleiben, sondern Zustände ändert aus REACHABLE, STALEund FAILEDvon Pings und Zeit.

Die zweite interne Schleife pingt alle fünf Minuten und überprüft die Arptabelle, um festzustellen, ob das Telefon zu Hause ist. Mit drei aufeinanderfolgenden Pings 'FAILED' ist das Telefon nicht zu Hause. Wenn das Telefon nicht zu Hause ist, kann das Telefon mit der Einstellung "REACHABLE" (Erreichbar) nach Hause zurückkehren (etwas tun). Es werden Überprüfungen durchgeführt, um die IP-Adresse zu validieren und zur ersten internen Schleife zurückzukehren, wenn Korrekturen erforderlich sind.

#!/bin/bash
# A script to do something when Phone returns Home.

mac="ac:37:00:00:00:00"    # Your phone mac address
ip_addr=""                 # Leave blank or ip for test
network="192.168.0.0"      # Your network (Class C only)
range="20 32"              # ip address possible range
pgm='echo "do something"'  # program to exec when Phone returns Home

start=$(echo "$range" | cut -d " " -f1)
stop=$(echo "$range" | cut -d " " -f2)
network=$(echo "$network" | cut -d. -f1-3)

echo "Start  $(date)"
while [ 1 ]; do
    cnt=0
    fail=0
    [ "$ip_addr" ] || while [ ! "$ip_addr" ]; do
        for x in $(seq "$start" "$stop"); do
            (junk=$(ping -c1 -W1 "$network"."$x") & )
            wait
        done
        sleep 8
        ip_addr=$(ip neighbor | grep "$mac" | cut -d " " -f1)
        ((cnt++))
        if (( $cnt > 15 )); then
            cnt=0
            echo "--- Phone not Home  $(date)"
            sleep 300      # 5 minutes
        fi
        if [ "$ip_addr" ]; then
            echo "--- Phone is Home, Count = $cnt, Date = $(date)"
            echo "Phone ip = $ip_addr  mac = $mac"
        fi
    done

    while [ "$ip_addr" ]; do
        junk="$(ping -c1 -W1 $ip_addr)"
        sleep 8
        home_nw="$(ip neighbor | grep $ip_addr | cut -d ' ' -f 1,5,6)"
        echo "$home_nw - $(date)"
        is_home=$(echo "$home_nw" | cut -d " " -f3)
        if [ "$is_home" == "REACHABLE" ] && (( "$fail" >= 3 )); then
            echo "--- Phone returned Home - $(date)"
            $pgm
        fi
        [ "$is_home" == "REACHABLE" ] && fail=0
        mac_stat=$(echo "$home_nw" | cut -d " " -f2)
        if [ "$mac_stat" == "FAILED" ]; then
            (( "$fail" < 10 )) && ((fail++))
            ip_test="$(ip neighbor | grep $mac | cut -d ' ' -f1)"
            if [ "$ip_test" ]; then
                [ "$ip_test" == "$ip_addr" ] || ip_addr=""
            fi
            if (( "$fail" == 3 )); then
                echo "--- Phone not at Home  $(date)"
            fi
        else
            if [ "$mac_stat" != "$mac" ]; then
                ip_addr=""
            fi
        fi
        sleep 300          # 5 minutes
    done
done
bstipe
quelle
3

Fügen Sie Ihrer IP-Adresse eine Reservierung hinzu und senden Sie alle paar Minuten einen Ping-Befehl über einen Cron-Job.

    #!/bin/bash
    HOSTS="x.x.x.1 x.x.x.2"
    COUNT=10
    for myHost in $HOSTS
    do
      count=$(ping -c $COUNT $myHost | grep 'received' | awk -F',' '{ print $2 }' | awk '{ print $1 }')
      if [ $count -eq 10 ]; then
        # 100% response
        # let the cat out
      fi
    done

Ich bewerkstellige dies auf meinem RPI mithilfe von fhem . Es verfügt über ein integriertes Anwesenheitserkennungsmodul , mit dem ich den Aufenthaltsstatus festlegen kann, der abgefragt werden kann, um die Hausautomationsaufgaben zu beeinflussen.

paj
quelle