使用Wi-Fi的Raspberry Pi存在检测


12

我如何让Raspberry Pi连续扫描网络上的MAC地址,然后在检测到特定的MAC地址时执行任务?

我使用Pi来运行各种家庭自动化任务。我希望它在感应到我的手机已连接到Wi-Fi(即我刚回到家)时执行一项任务。进行Pi连续扫描手机MAC地址的最佳方法是什么?我知道我可以arp-scan用来扫描MAC地址,但是我需要它不断进行扫描。我敢肯定有一个更好的方法,那arp-scan就是循环运行,或者使用cron使其每分钟运行一次。


2
如果您不需要实时响应,那么cron是最好的方法。首先,您编写脚本,该脚本在sh中返回诸如true或false之类的东西(状态代码是他对响应进行响应的最佳选择),然后编写脚本,该脚本会将先前的值存储在/ tmp中,并检查更改。如果发生更改,它将记录下来。
米萨兹'17

Answers:


3

电话首页

我的手机的行为有所不同,因为所有手机都有所不同。仅当电话苏醒时才会执行ping响应。如果Pi重新启动并且手机处于睡眠模式,则多次ping将把其ip和mac地址放置在arp表中,丢包率为100%。我刚刚了解到该arp命令已过时,ip neighbor现在已使用。

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

经过测试后,我的解决方案是在一个永久循环中包含两个循环。第一个内部循环将是对我的手机可能多次对一个IP地址范围执行ping操作。我的路由器保留了前19个ip地址,我可能会为DHCP分配大约六个地址,包括我的电话,从地址192.168.0.20开始。我将在后台模式下ping通十二个IP地址一次,等待一秒钟以进行响应,然后将结果作为垃圾丢弃。我将在arp表上等待八秒钟,然后运行ip neighbor命令grep将mac地址用作IP地址。除非发生异常情况,否则路由器和电话将保留此IP地址。ARP表将留在皮,但会改变状态的REACHABLESTALE以及FAILED从ping和时间。

第二个内部循环将ping并每五分钟检查一次arp表,以确定电话是否在家。连续三个ping“失败”表示电话不在家。当电话不在家里时,一个“可到达”将使电话返回家中(执行某项操作)。如果需要更正,会进行检查以验证ip地址并返回到第一个内部循环。

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

为什么不将保留添加到您的电话ip地址,而仅每隔几分钟就通过cron工作执行ping操作。

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

我使用fhem在rpi上完成此操作,它具有一个内置的状态检测模块,可让我设置居民身份,可以查询这些居民身份以影响家庭自动化任务。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.