Rilevamento presenza Raspberry Pi tramite Wi-Fi


12

Come posso avere il mio Raspberry Pi continuamente alla ricerca di un indirizzo MAC sulla mia rete e quindi eseguire un'attività quando rileva un indirizzo MAC specifico?

Uso il mio Pi per eseguire varie attività di automazione domestica. Mi piacerebbe che eseguisse un'attività quando rileva che il mio telefono si connette al Wi-Fi (il che significa che sono appena tornato a casa). Qual è il modo migliore per avere continuamente la scansione Pi per l'indirizzo MAC del mio telefono? So che posso usare arp-scanper cercare gli indirizzi MAC, ma ho bisogno di questo per la scansione continua. Sono sicuro che esiste un metodo migliore che dopo aver arp-scaneseguito in un ciclo o utilizzando cron per farlo funzionare ogni minuto.


2
Se non hai bisogno di una risposta in tempo reale, cron è il modo migliore. Prima scrivi uno script che restituisce qualcosa di vero o falso in sh (il codice di stato è la migliore opzione per privare la risposta), quindi uno script che memorizzerà il valore precedente da qualche parte in / tmp e verificherà la modifica. Se il cambiamento accade, lo accederà.
Misaz,

Risposte:


3

PhoneHome

Il mio telefono funziona in modo diverso, poiché tutti i telefoni hanno qualche differenza. Una risposta al ping si verifica solo se il telefono è attivo. Se il Pi viene riavviato e il telefono è in modalità sospensione, più ping inseriranno i suoi indirizzi ip e mac nella tabella arp, con una perdita di pacchetti del 100%. Ho appena imparato che il arpcomando è obsoleto, ip neighborviene utilizzato ora.

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

Dopo il test, la mia soluzione sarebbe quella di avere due loop all'interno di un loop per sempre. il primo ciclo interno sarebbe quello di fare un ping su un intervallo di indirizzi IP, più volte, che sarebbe possibile per il mio telefono. Il mio router ha riservato il primo indirizzo IP 19 e potrei avere una mezza dozzina di indirizzi che DHCP assegnerà, incluso il mio telefono, a partire dall'indirizzo 192.168.0.20. Eseguirò il ping di una dozzina di indirizzi IP una volta, in modalità background, aspetterò un secondo per la risposta e getterò via i risultati come spazzatura. Aspetterò otto secondi sulla tabella arp ed eseguirò il ip neighborcomando, grep l'indirizzo mac per l'indirizzo IP. Il router e il telefono manterranno lo stesso indirizzo IP a meno che non accada qualcosa di insolito. La tabella ARP rimarrà nel Pi, ma cambierà stati da REACHABLE, STALEe FAILEDda ping e tempo.

Il secondo ciclo interno eseguirà il ping e controllerà la tabella ARP ogni cinque minuti per determinare se il telefono è a casa. Con tre ping "FAILED" di seguito, il telefono non è in casa. Un 'REACHABLE', quando il telefono non è in casa, farà tornare il telefono a casa (fare qualcosa). Ci sono controlli per convalidare l'indirizzo IP e tornare al primo ciclo interno se sono necessarie correzioni.

#!/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

3

Perché non aggiungere una prenotazione al tuo indirizzo IP del tuo telefono e semplicemente fare un ping tramite un processo cron ogni pochi minuti.

    #!/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

Lo realizzo sul mio rpi usando fhem , ha un modulo di rilevamento presenza incorporato che mi permette di impostare gli stati residenti che possono essere interrogati per influenzare le attività di automazione domestica.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.