树莓派安全监控系统
自动启用/停用。运动检测。手机图文信息通知。
此项目用到的零件和工具
硬件组件
软件APP和在线服务
树莓派安全监控系统
一个运行在树莓派上的简单安全监控系统。
主要功能:
- 使用摄像头进行运动检测和拍照
- 移动电话图文信息通知
- 检测您何时在家,自动启用/停用监控服务
- 可使用Telegram远程控制
类似产品:
必备材料和工具
您将需要这些硬件:
- 带摄像头接口的树莓派。
- 树莓派摄像头模块
- 支持监控模式的USB Wi-Fi。我用了一个基于RT5370的适配器,很便宜,大约6欧元,而且很容易买到
软件环境需求:
- 一个Telegram机器人。完全免费而且容易设置
- 已安装Raspbian系统。我使用Stretch Lite。你可以用不同的操作系统,但我有没试过
- Python 3
工作原理
自动在场检测
我的主要目标之一是使系统完全自动化。我不想在离开或回到家的时候,不得不手动去启用或停用。我想实现这一点最简单的方法是尝试检测家中住户的手机。从概念上讲,这很简单,但实际上却是最具挑战性的部分,因为:
- 在Wi-Fi接口上捕获所有数据包太耗费资源。
- 移动电话并不总是在线并且通过Wi-Fi发送数据包。有时他们保持15分钟或更长时间的离线状态。
- 即使有99%的准确率,假警报也很烦人。
经过大量测试后,我使用了一种基于已知手机MAC地址通过Wi-Fi适配器混合主动(ARP扫描)和被动(包捕获)检测的方法。移动电话MAC地址在配置中设置,并且RPI安全监控系统应用以下过滤器在监控模式接口上捕获数据包:
- 来自任何已知MAC的Wi-Fi探测请求。
- 从已知MAC发送到运行RPI安全监控系统的主机的任何数据包。
当检测到数据包时,应用程序重置计数器,如果计数器的时间超过10分钟,则系统将启用。为了消除许多假警报,当系统在启用状态和停用状态之间切换时,应用程序将对每个已知的MAC地址执行ARP扫描,以确保它们确实在线或离线。iOS和Android在ICMP ping不可靠的情况下99%都会响应ARP扫描。通过结合捕捉Wi-Fi探测请求和使用ARP扫描,Wi-Fi频率无关紧要,因为移动电话在两个频率上发送探测请求,而ARP扫描也可以跨两个频率进行。
运动检测
运动检测是通过OpenCV来实现的。 每个运动检测将在/tmp
目录中保存4张图片:
- frame.jpg: 用矩形标示运动的图片
- gray.jpg: 带有灰度和模糊的图片(用于检测当前帧和上一帧之间的运动)
- abs_diff.jpg: 灰度图像之间的绝对差异(当前帧和上一帧)
- thresh.jpg: 已经应用了一个阈值,以确保运动足够重要而可以被检测到。
信息通知
Telegram机器人用于发送带有捕获图像的通知。有很好的移动应用和很好的API。您还可以在浏览器中查看消息,并在设备之间同步消息。
如果系统处于启用状态并且检测到运动,则会从Telegram机器人向您发送一条包含捕获图像的消息。
警报状态发生变化时也会发送通知。
远程控制
您可以给Telegram机器人发送触发某些操作的命令。
- /disable: 禁用该服务知到重新启用。
- /enable:禁用服务后启用该服务。
- /status:发送状态报告。
- /photo:捕获并发送照片。
- /gif:捕获并发送gif。
Python
应用程序是用python 3编写的。大部分功能由以下pip模块提供:
应用程序使用多线程来异步处理事件。有4个线程:
- telegram_bot: 响应命令。
- monitor_alarm_state: 启用和停用系统。
- capture_packets: 从移动设备捕获数据包。
- process_photos: 通过Telegram发送捕获的图像。
安装、配置和运行
首先确保您的WiFi设置正确.
确保你的GPU/内存分割给GPU 128MB。您可以使用raspi config
查看或设置这个值。
安装Python所需的软件包:
sudo apt update
sudo apt install -y tcpdump iw python3-dev python3-pip python3-numpy
安装OpenCV所需的软件包:
sudo apt install -y libhdf5-103 libharfbuzz0b libwebp6 libjasper1 libopenexr23 libgstreamer1.0-0 libatlas-base-dev libgtk-3-0 libqtgui4 libqt4-test libilmbase23 libavcodec-extra58 libavformat58 libswscale5 libjpeg8-dev zlib1g-dev libffi-dev libopenjp2-7-dev libtiff5
安装OpenCV和rpi-security:
sudo pip3 install opencv-contrib-python==3.4.6.27 opencv-contrib-python-headless==3.4.6.27
sudo pip3 install --no-binary :all: https://github.com/FutureSharks/rpi-security/archive/1.5.zip
重新加载系统配置并启用rpi-security服务:
sudo systemctl daemon-reload
sudo systemctl enable rpi-security.service
添加您的MAC地址、Telegram bot API密钥以及对/etc/rpi-security.conf
的必要修改.
确保已使用raspi-config
启用摄像头模块。
启动服务:
sudo systemctl start rpi-security.service
你至少需要向Telegram机器人发送一条消息,否则它将无法向你发送消息。这样服务就可以保存Telegram的chat_id。只需发送/status
命令。
它作为服务运行并记录到syslog。请在/var/log/syslog
查看日志。
调试与故障排除
你可以手动启用rpi-security.py
的调试输出。
首先添加监控模式网络接口:
root@raspberrypi:~# iw phy phy1 interface add mon0 type monitor
root@raspberrypi:~# ifconfig mon0 up
然后用调试选项启动服务
root@raspberrypi:~# rpi-security.py -d
2016-05-28 14:43:30 DEBUG rpi-security.py:73 MainThread State file read: /var/lib/rpi-security/state.yaml
2016-05-28 14:43:30 DEBUG rpi-security.py:44 MainThread Calculated network: 192.168.178.0/24
2016-05-28 14:43:41 INFO rpi-security.py:214 monitor_alarm_state thread running
2016-05-28 14:43:41 INFO rpi-security.py:196 capture_packets thread running
2016-05-28 14:43:41 INFO rpi-security.py:259 telegram_bot thread running
2016-05-28 14:43:41 INFO rpi-security.py:154 process_photos thread running
2016-05-28 14:43:43 INFO rpi-security.py:392 MainThread rpi-security running
2016-05-28 14:43:43 INFO rpi-security.py:112 MainThread Telegram message Sent: "rpi-security running"
2016-05-28 14:44:29 DEBUG rpi-security.py:191 capture_packets Packet detected from aa:aa:aa:bb:bb:bb
2016-05-28 14:44:29 DEBUG rpi-security.py:191 capture_packets Packet detected from aa:aa:aa:bb:bb:bb
2016-05-28 14:44:48 DEBUG rpi-security.py:280 Dummy-1 Motion detected but current_state is: disarmed
调试完成后记得移除监控模式网络接口:
iw dev mon0 del
WiFi适配器配置
您的WiFi适配器必须支持监控模式。默认情况下,树莓派内置无线LAN适配器当前不支持监控模式。目前,使内置WiFi适配器的监控模式工作的唯一方法是使用nexmon,而且并不简单。
获得监控模式WiFi适配器的最简单方法是购买支持监控模式的USB适配器。目前最好的选择是:
- RT5370: 很便宜而且容易买到。但是只支持2.4Ghz
- RT3572: 比较贵而且较难买到。但同时支持2.4Ghz和5Ghz
现在大多数现代手机和路由器都使用5Ghz,所以如果您的适配器只支持2.4Ghz,结果可能不太可靠。
用于连接到WiFi网络的接口必须与支持监控模式的接口相同。这必须是手机连接的同一个WiFi网络。因为有一个运行着的抓包程序在监听移动电话的ARP回复以及WI-FI探测请求。
这个应用程序的默认配置假定您使用的USB适配器为phy#1/mon0/wlan1
。
如果您不使用板载WiFi适配器,则可以通过运行以下命令停止它与WiFi网络的连接:
echo -e "interface wlan0\nnohook wpa_supplicant" >> /etc/dhcpcd.conf
这显示了一个有效的WiFi适配器配置:
root@raspberrypi:~ # iw dev
phy#1
Interface mon0
ifindex 4
wdev 0x100000002
addr 00:0e:8e:58:d6:af
type monitor
txpower 26.00 dBm
Interface wlan1
ifindex 3
wdev 0x100000001
addr 00:0e:8e:58:d6:af
ssid Connecting...
type managed
channel 124 (5620 MHz), width: 40 MHz, center1: 5630 MHz
txpower 26.00 dBm
phy#0
Interface wlan0
ifindex 2
wdev 0x1
addr b8:27:eb:cb:b6:5d
type managed
channel 34 (5170 MHz), width: 20 MHz, center1: 5170 MHz
txpower 31.00 dBm
您可以使用不同名称的接口,只需确保更改`/etc/rpi security environment中的参数即可。
基于PIR传感器运动检测的旧版本
目前运动检测是基于摄像头实现。如果要使用基于PIR传感器的旧版本,请查看0.7版:
连接丢失时重新启动
大约每一两个月我的树莓派就会断开WLAN连接。我创建了一个cron作业来检查连接,如果检查失败,就重新启动。
wget https://raw.githubusercontent.com/FutureSharks/rpi-security/master/bin/check-telegram-connectivity.sh -O /usr/local/bin/check-telegram-connectivity.sh
chmod 0755 /usr/local/bin/check-telegram-connectivity.sh
echo '*/20 * * * * root /usr/local/bin/check-telegram-connectivity.sh' > /etc/cron.d/reboot-on-connection-failure
定制零件和外壳:cad-files.zip
完整代码:rpi-security.zip或者前往作者GitHub代码仓库下载最新代码
英文链接:Raspberry Pi Security System With Motion Detection / Camera
英文作者:Max Williams [GitHub]
中文翻译:fibx
©GPL3+