基於WiFi的防盜報警Python指令碼

mariocanfly發表於2024-03-12

學校圖書館有一本電子書,可以供學生閱讀,但是怎麼防止學生將其帶出圖書館呢?我把它連上館內的一臺電腦的WiFi熱點,間隔一段時間就從電腦ping這臺電子書,如果ping不通,說明電子書脫離了WiFi訊號範圍,電腦就會響起報警聲。
程式碼思路如下,先透過Windows上的arp命令,用裝置的MAC地址獲取其IP,再用ping命令檢測裝置是否線上,如果不在,就輸出現在的時間、丟失裝置IP和MAC地址,儲存日誌到檔案,並播放報警聲。
我嘗試過給電子書貼RFID標籤,但是RFID會受到電子書干擾,在透過門禁時無法像普通書籍一樣報警。
如果各位還有什麼好方法,歡迎評論!

import datetime
import sys
import time
import sched
import subprocess
from io import StringIO

try:
    import playsound
except ImportError:
    import os
    os.system("pip install playsound")
    import playsound

MY_DEVICE = ["48-e7-da-13-9e-b3"] # MAC addresses of my devices
device_ip = [""] * len(MY_DEVICE)
DETECT_DELAY = 5  # seconds
SOUND_PATH = "my_alert.mp3" # alert sound path


def detector():
    lost = []
    for i in range(len(device_ip)):
        if device_ip[i] != "":
            if subprocess.run("ping -n 2 -w 2500 " + device_ip[i], capture_output=True).returncode != 0:
                lost.append(i)

    if len(lost) > 0:
        buffer = StringIO()
        sys.stdout = buffer
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print()
        print(now_time)
        print("Device lost:")
        for dev_id in lost:
            print(device_ip[dev_id], "", MY_DEVICE[dev_id])
        output = buffer.getvalue()
        sys.stdout = sys.__stdout__
        print(output)
        with open("./log.txt", "a") as file:
            file.write(output)

        while True:
            playsound.playsound(SOUND_PATH)
    else:
        print("ok.")
        loop_detect()


def loop_detect():
    s = sched.scheduler(time.time, time.sleep)
    s.enter(DETECT_DELAY, 6, detector, ())
    s.run()


#get ip from its MAC address
def get_ip():
    for line in subprocess.check_output("arp -a", shell=True).decode("gbk").splitlines():
        for index in range(len(MY_DEVICE)):
            if MY_DEVICE[index] in line:
                ip = line[0:line.index(MY_DEVICE[index])].strip()
                device_ip[index] = ip

    for index in range(len(device_ip)):
        if device_ip[index] == "":
            print("Device not found in arp: ", MY_DEVICE[index])
        else:
            print("Device found in arp: ", device_ip[index], "", MY_DEVICE[index])


if __name__ == "__main__":
    get_ip()
    all_offline = True
    for ip in device_ip:
        if ip != "":
            all_offline = False
            break
    if not all_offline:
        print("Start detecting...")
        loop_detect()
    else:
        print("All offline")

相關文章