การตรวจจับสถานะ Raspberry Pi โดยใช้ Wi-Fi


12

ฉันจะให้ Raspberry Pi สแกนหาที่อยู่ MAC บนเครือข่ายของฉันอย่างต่อเนื่องจากนั้นทำงานเมื่อตรวจพบที่อยู่ MAC ที่ระบุได้อย่างไร

ฉันใช้ Pi ของฉันเพื่อทำงานบ้านอัตโนมัติต่างๆ ฉันต้องการให้ทำงานเมื่อรู้สึกว่าโทรศัพท์ของฉันเชื่อมต่อกับ Wi-Fi (หมายถึงฉันเพิ่งกลับถึงบ้าน) วิธีที่ดีที่สุดในการสแกน Pi สำหรับที่อยู่ MAC ของโทรศัพท์ของฉันคืออะไร ฉันรู้ว่าฉันสามารถใช้arp-scanสแกนหาที่อยู่ MAC ได้ แต่ฉันต้องการให้สแกนอย่างต่อเนื่อง ฉันแน่ใจว่ามีวิธีที่ดีกว่าแล้วarp-scanวิ่งวนเป็นวงกลมหรือใช้ cron เพื่อให้มันวิ่งทุกนาที


2
หากคุณไม่ต้องการ cron การตอบสนองแบบเรียลไทม์เป็นวิธีที่ดีที่สุด ก่อนอื่นคุณเขียนสคริปต์ที่ส่งคืนสิ่งที่เป็นจริงหรือเท็จใน sh (รหัสสถานะคือตัวเลือกที่ดีที่สุดในการตอบสนองแบบส่วนตัว) จากนั้นสคริปต์ที่จะเก็บค่าก่อนหน้าไว้ที่ / tmp และตรวจสอบการเปลี่ยนแปลง ถ้าเปลี่ยน happend มันจะเข้าสู่ระบบ
Misaz

คำตอบ:


3

PhoneHome

โทรศัพท์ของฉันทำงานแตกต่างกันเนื่องจากโทรศัพท์ทุกรุ่นมีความแตกต่างกันบ้าง การตอบสนองการ ping จะเกิดขึ้นเฉพาะเมื่อโทรศัพท์ตื่นเท่านั้น หาก Pi ถูกรีบูทและโทรศัพท์อยู่ในโหมดสลีปปิงหลายตัวจะวางที่อยู่ 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

หลังจากทดสอบวิธีแก้ปัญหาของฉันคือมีสองลูปภายในวงวนถาวร ลูปภายในวงแรกจะทำการ ping บนช่วงของที่อยู่ IP หลายครั้งซึ่งอาจเป็นไปได้สำหรับโทรศัพท์ของฉัน เราเตอร์ของฉันสงวนที่อยู่ IP 19 แห่งแรกและฉันอาจมีที่อยู่ประมาณครึ่งโหลที่ DHCP จะกำหนดรวมถึงโทรศัพท์ของฉันโดยเริ่มต้นจากที่อยู่ 192.168.0.20 ฉันจะ ping ที่อยู่ ip โหลหนึ่งครั้งในโหมดเบื้องหลังรอหนึ่งวินาทีเพื่อตอบสนองและทิ้งผลลัพธ์เป็นขยะ ฉันจะรอแปดวินาทีบนตาราง arp และเรียกใช้ip neighborคำสั่ง grep ที่อยู่ mac สำหรับที่อยู่ ip เราเตอร์และโทรศัพท์จะเก็บที่อยู่ IP เดียวกันนี้ไว้เว้นแต่จะมีบางอย่างผิดปกติเกิดขึ้น ตาราง ARP จะยังคงอยู่ในชิ้น แต่จะเปลี่ยนสถานะจากREACHABLE, STALEและFAILEDจากการส่ง Ping และเวลา

วงในด้านที่สองจะ ping และตรวจสอบตาราง arp ทุก ๆ ห้านาทีเพื่อดูว่าโทรศัพท์อยู่ที่บ้านหรือไม่ ด้วยสามปิง 'FAILED' ติดต่อกันโทรศัพท์ไม่ได้อยู่ที่บ้าน หนึ่ง 'ที่เข้าถึงได้' เมื่อโทรศัพท์ไม่ได้อยู่ที่บ้านจะทำให้โทรศัพท์กลับบ้าน (ทำอะไร) มีการตรวจสอบเพื่อตรวจสอบความถูกต้องของที่อยู่ 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 ของโทรศัพท์ของคุณและทำ ping ผ่านงาน cron ทุก ๆ สองสามนาที

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

ฉันทำสิ่งนี้ให้สำเร็จบน rpi ของฉันโดยใช้เพลงมันมีโมดูลตรวจจับสถานะที่มีอยู่ในตัวที่ให้ฉันตั้งสถานะผู้อยู่อาศัยที่สามารถสอบถามเพื่อโน้มน้าวงานบ้านอัตโนมัติได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.