树莓派安防系统:运动检测与远程监控解决方案

自动布防与撤防、运动检测及图片通知功能
图片
项目所需物品

硬件组件

  • Raspberry Pi 1 Model A+ 一个:任何支持摄像头模块的 Raspberry Pi 均可使用。
  • Raspberry Pi 摄像头模块 一个。
  • USB WLAN/WiFi 适配器 一个:须支持监控模式,推荐使用 RT5370。
  • Makerbeam(可选) 一个:用于制作外壳。

软件应用及在线服务

  • Raspberry Pi Raspbian
  • Telegram Bot

项目概述
Raspberry Pi 安防系统是一个基于 Raspberry Pi 的简易安防系统,具备以下核心功能:

  • 利用摄像头进行运动检测和拍照。
  • 发送带照片的移动通知。
  • 自动检测家庭成员在家与否,并自动布防或撤防。
  • 可通过 Telegram 进行远程控制和查询。

类似产品:

图片
所需条件

硬件需求

  • 带有摄像头接口的 Raspberry Pi(我使用的是 Model A+)。
  • Raspberry Pi 摄像头模块。
  • 支持监控模式的 USB Wi-Fi 适配器(我使用的是基于 RT5370 的适配器,价格约为 6 欧元,易于购买)。
  • 某种形式的外壳(硬件详细信息将在后续部分提供)。

其他需求

  • Telegram 机器人:免费且易于设置。
  • 已安装的 Raspbian 发行版(我使用的是 Jessie lite,其他操作系统也可使用但未经过测试)。
  • Python 3。

工作原理

自动化检测
该系统的主要目标是实现完全自动化,用户在离家或回家时无需手动设置布防或撤防。为实现这一目标,我尝试检测家中成员的手机。这个概念上简单,但在实际操作中面临诸多挑战:

  • 在 Wi-Fi 接口上捕获所有数据包非常耗费资源。
  • 当前没有良好的支持监控模式的 5GHz USB Wi-Fi 适配器,因此数据包监控仅限于 2.4GHz,而大多数现代手机使用的是 5GHz。
  • 手机并非始终在线并发送数据包,有时可能长达 15 分钟或更久处于未连接状态。
  • 即使准确率达到 99%,误报也会非常烦人。

经过大量测试,我采用了一种结合主动(ARP 扫描)和被动(数据包捕获)检测的方法,通过 Wi-Fi 适配器进行,并基于已知的手机 MAC 地址。手机的 MAC 地址在配置中设置,rpi-security 应用程序在监控模式接口上捕获符合以下过滤条件的数据包:

  • 来自任何已配置 MAC 的 Wi-Fi 探测请求。
  • 从已配置 MAC 发送到运行 rpi-security 的主机的任何数据包。

当检测到数据包时,应用程序会重置计数器,如果计数器超过约 10 分钟,则系统布防。为减少误报,在布防与撤防状态转换过程中,应用程序会对每个已配置的 MAC 地址执行 ARP 扫描,确保它们确实在线或离线。iOS 和 Android 在 99% 的情况下会响应此 ARP 扫描,而 ICMP ping 的可靠性较低。结合捕获 Wi-Fi 探测请求与使用 ARP 扫描可以有效应对不同频率,因为手机在两个频率上都发送探测请求,ARP 扫描也适用于两个频率。

通知
使用 Telegram 机器人发送带有捕获图片的通知。Telegram 具备良好的移动应用和友好的 API,您还可以在浏览器中查看消息,并且消息会在设备之间同步。如果系统处于布防状态并检测到运动,则 Telegram 机器人将向您发送带有捕获图片的消息,任何警报状态更改时也会发送通知。

图片
远程控制
您可以向 Telegram 机器人发送命令以触发特定操作:

  • /disable:禁用服务,直到重新启用。
  • /enable:在禁用后启用服务。
  • /status:发送状态报告。
  • /photo:捕获并发送照片。
  • /gif:捕获并发送 GIF。

图片
Python
该应用程序使用 Python 3 编写,大部分功能由以下 pip 模块提供:

  • picamera
  • Scapy
  • python-telegram-bot

应用程序以多线程方式异步处理事件,共有四个线程:

  • telegram_bot:响应命令。
  • monitor_alarm_state:负责布防和撤防系统。
  • capture_packets:捕获来自移动设备的数据包。
  • process_photos:通过 Telegram 消息发送捕获的图片。

安装、配置与运行
连接到您的 WiFi 网络的接口必须是支持监控模式的,并且这必须是手机连接的同一 WiFi 网络。首先安装必要的软件包:

sudo apt-get update
sudo apt-get install -y tcpdump iw python3-dev python3-pip libjpeg8-dev zlib1g-dev libffi-dev python3-numpy
sudo pip3 install --upgrade pip

安装 rpi-security 服务,重新加载 systemd 配置并启用服务:

sudo pip3 install https://github.com/FutureSharks/rpi-security/archive/master.zip
sudo systemctl daemon-reload
sudo systemctl enable rpi-security.service

/etc/rpi-security.conf 文件中添加您的 MAC 地址、Telegram 机器人 API 密钥以及其他需要更改的配置。确保您已使用 raspi-config 启用相机模块。启动 rpi-security 服务:

sudo systemctl start rpi-security.service

您需要至少向 Telegram 机器人发送一条消息,以便服务能够保存您的 Telegram chat_id。发送 /status 命令即可。rpi-security 作为服务运行并将日志记录到 syslog。要查看日志,请检查 /var/log/syslog。还有一个调试选项,它将日志输出到 stdout:

root@raspberrypi:~# iw phy phy0 interface add mon0 type monitor
root@raspberrypi:~# ifconfig mon0 up
root@raspberrypi:~# rpi-security.py -d

这就是 Raspberry Pi A+ 模型所需的全部内容。以下是我的无线局域网网络设备布局:

root@raspberrypi:~# iw dev phy#0
        Interface mon0
                ifindex 4
                wdev 0x3
                addr 00:0f:60:08:9c:01
                type monitor
        Interface wlan0
                ifindex 2
                wdev 0x1
                addr 00:0f:60:08:9c:01
                type managed
                channel 1 (2412 MHz), width: 40 MHz, center1: 2422 MHz

您可能会遇到不同名称的接口,只需在 /etc/rpi-security.conf 文件中更改 network_interface 参数,并同时更改 rpi-security.service 中对 mon0 的引用即可。

带有 PIR 传感器的旧版运动检测
当前,该摄像头用于运动检测。如果您想使用支持 PIR 传感器的旧版本,请查看 0.7 版本:0.7 Version

连接丢失时重启
大约每月或每两个月,我的 Raspberry Pi 会丢失 WLAN 连接。我创建了一个 cron 作业以检查连接,并在检查失败时重启:

echo '*/20 * * * * root /usr/bin/host api.telegram.org > /dev/null 2>&1 || (/usr/bin/logger "Rebooting due to connectivity issue"; /sbin/shutdown -r now)' > /etc/cron.d/reboot-on-connection-failure

自定义部件和外壳

硬件详情
摄像头和 PIR 传感器 Makerbeam 支架的 CAD 文件:
硬件文件

代码
Github 链接(安装、配置等):GitHub - rpi-security
一个用 Python 编写的安全系统,旨在在 Raspberry Pi 上运行,并具备运动检测和移动通知功能。