![如何仅在我不在家时(手机不在局域网上)运行网络摄像头软件?](https://linux22.com/image/1335118/%E5%A6%82%E4%BD%95%E4%BB%85%E5%9C%A8%E6%88%91%E4%B8%8D%E5%9C%A8%E5%AE%B6%E6%97%B6%EF%BC%88%E6%89%8B%E6%9C%BA%E4%B8%8D%E5%9C%A8%E5%B1%80%E5%9F%9F%E7%BD%91%E4%B8%8A%EF%BC%89%E8%BF%90%E8%A1%8C%E7%BD%91%E7%BB%9C%E6%91%84%E5%83%8F%E5%A4%B4%E8%BD%AF%E4%BB%B6%EF%BC%9F.png)
目前我已经启动了我的用户 cron运动在我通常去上班的计时器,然后在我通常到家时杀死它,这样我就可以观察我的猫/窃贼/等等:
0 9 * * * killall motion ; motion
30 18 * * * killall motion
使用的配置文件是~/.motion/motion.conf
并且具有daemon on
。
但如果它可以检测我何时真正在家,并在这些时间禁用网络摄像头,在其他时间启用它,那就更好了。我在想,我的存在可以通过我的 Android 手机加入 LAN 来检测。所以像
- 每隔几分钟检查一次我的手机主机名或 MAC 地址是否当前在 LAN 上的脚本
- A塔斯克我手机上的脚本在加入某个 SSID 时会以某种方式(简单的 Web 服务器?)与家里的电脑联系
- 以上内容的组合
- ...
关于如何实现其中之一,还有什么更好的想法或建议吗?Tasker 易于使用,但价格为 6 美元,因此不依赖于它的解决方案将对更广泛的受众有用。
我第一次尝试使用 arp-scan 解决方案,但效果并不好。它会创建多个实例,motion
并且无法可靠地检测到手机,导致摄像头偶尔打开和关闭。 所以也许它应该更像是“每分钟检查一次手机是否存在。只有 15 分钟内没有看到手机时才打开摄像头”。
好的,我编写了一个 Python 脚本,每分钟进行一次 arp 扫描,它可以完美地检测到手机:
2012-11-27 18:29:10.551552 No
2012-11-27 18:30:22.295997 No
2012-11-27 18:31:34.077431 No
2012-11-27 18:32:45.804675 No
2012-11-27 18:33:57.545211 No
2012-11-27 18:35:09.261680 No
2012-11-27 18:36:20.974378 Yes
2012-11-27 18:37:21.901076 Yes
2012-11-27 18:38:22.417423 Yes
2012-11-27 18:39:22.836101 Yes
2012-11-27 18:40:23.463507 Yes
2012-11-27 18:41:23.876693 Yes
因此,cron 或者我启动运动的方式或者其他什么方式有问题。
我尝试以/etc/init.d/motion start
用户身份运行它而不是运行它然后杀死它,但是该方法不起作用:
* Not starting motion daemon, disabled via /etc/default/motion
因此我进行了修改/etc/default/motion
并start_motion_daemon=yes
再次尝试:
~> /etc/init.d/motion start
mkdir: cannot create directory `/var/run/motion': Permission denied
我甚至不知道那是什么意思。
答案1
在计算机上运行脚本比设置等待手机与其通信的网络服务器要容易得多,而且肯定更干净。因此,我将采纳您的第一个想法。
假设:
- 您具有 root 访问权限。
/etc/init.d/motion
用于启动和停止motion
。systemctl start|stop motion.service
为了systemd
- 您使用 连接到与您的手机相同的网络
eth0
。 - 您的 cron 实现使用了该
crontab
命令。
获取 MAC 地址:
得到arp-scan
并arp-scan -I eth0 -l -r 10
以 root 身份运行。(我发现-r 10
这对于始终检测我的 Android 手机很重要)
这将返回您网络中的设备列表。第三列应该可以轻松识别您的手机。假设我们得到了01:01:01:01:01:01
。
编写脚本:
以 root身份运行。仅当手机已连接时arp-scan -I eth0 -l -r 10 | grep -q '01:01:01:01:01:01'
才会返回。0
以 root 身份运行crontab -e
并添加此行以检查您的手机是否每分钟连接到网络:
* * * * * arp-scan -I eth0 -l -r 10 | grep -q '01:01:01:01:01:01' && /etc/init.d/motion stop || /etc/init.d/motion start
保存文件并退出编辑器。
请记住,我们不需要motion
自己检查是否正在运行。服务脚本在内部执行此操作。
答案2
zmode 的答案很有帮助,但对我没用。经过大量阅读,我想出了这个解决方案:
#!/bin/sh
if arp-scan -I eth0 -r 10 android | grep -q '12:34:56:78:90:ab'
then
echo "Phone present, killing motion"
killall motion
echo "Done killing motion"
else
echo "Phone absent, starting motion"
if ! ps -A | grep -q motion
then
echo "Motion is not running - starting it"
su -c 'motion' - username
echo "Motion started"
else
echo "Motion already running"
fi
echo "Done starting motion"
fi
exit
(需要替换 MAC 地址、主机名和用户名。)它会检查手机是否在网络上,使用手机的主机名android
来避免扫描不相关的地址。它会检查 motion 是否已在运行,因此它不会在 motion 运行时启动多个实例或反复将其终止。
然后运行sudo crontab -e
编辑root用户的cron,并添加如下行:
*/5 * * * * /home/username/phone_webcam/phone_webcam.sh >> /var/log/cron.log 2>&1
这将每 5 分钟运行一次脚本,并记录输出以便您进行调试。运行该命令tail -f /var/log/cron.log
以确保其正常运行。确认其正常运行后,从 crontab 中删除日志记录行:
*/5 * * * * /home/username/phone_webcam/phone_webcam.sh
答案3
以上述回应为基础,您可以对其进行调整,使其效果略好一些。
#!/bin/sh
if arp-scan -I wlan0 -r 10 android-11111111111111111111 | grep -qi '11:11:11:11:11:11'
then
echo "Phone present, killing motion"
killall motion
echo "Done killing motion"
else
echo "Phone absent, starting motion"
if ! ps -A | grep -q motion
then
echo "Motion is not running - starting it"
su -c 'motion'
echo "Motion started"
else
echo "Motion already running"
fi
echo "Done starting motion"
fi
exit
通常,对于 wifi,接口称为 wlan0。Android 设备的名称通常是 android-,后跟序列号。通过在 grep 命令中添加 -i,您可以不区分大小写地运行搜索(花了一段时间才弄清楚)。在我的计算机上,启动 motion 需要 root 访问权限。这可以通过从 su 命令中删除用户名来实现。
通过这些修改并遵循上述答案中的所有内容,您可以在离开家时(带着手机)立即启动 Motion,没有任何问题。完美无缺!
答案4
我有一个 bash 脚本每 4 分钟运行一次来执行此操作。它运行得很好。以下是代码及其一些说明。
#!/bin/bash
############################################################################
## looking for iPhone, 1 if iPhone logged in, else 0
## IPhoneIP.txt contains local IP-adress (also bash-based)
IPhoneIP=$(cat /home/pi/motion/IPhoneIP.txt)
NMAP=$(nmap -sn -oG - ${IPhoneIP})
iPhoneActive=$(echo $NMAP | grep -c "Status: Up")
############################################################################
## alternatively finding iPhone with Bluetooth
if [ "$iPhoneActive" -eq 0 ]; then
#save former value ofiPhoneActive if zero
iPhoneActive=$(cat /home/pi/motion/IPhoneBluetoothCheck.txt)
fi
############################################################################
##if network down do nothing
NetworkDown=$(echo $NMAP | grep -c "Unable to determine any DNS servers")
############################################################################
##now checking whether motion is activ
MotionDetectionActive=$(wget -O - -o /dev/null http://localhost:8086/0/detection/status | grep -c "ACTIVE")
############################################################################
##if iPhone in Wifi and Motion active activate
if [ "$iPhoneActive" -eq 1 ] && [ "$MotionDetectionActive" -eq 1 ]
then
wget -O - http://localhost:8086/0/detection/pause > /dev/null 2>&1
echo "Deactivating motion detection, iPhone entered WLAN" ##logging
fi
if [ "$iPhoneActive" -eq 0 ] && [ "$MotionDetectionActive" -eq 0 ] && [ "$NetworkDown" -eq 0 ]
then
wget -O - http://localhost:8086/0/detection/start > /dev/null 2>&1
echo "Activating motion detection, iPhone left WLAN or other error" ## logging
fi
每周都会使用以下工具检测 iPhoneIP:
#!/bin/bash
########################################################
#writes iPhoneIP into /home/pi/motion/IPhoneIP.txt / IP-range might be different!!
########################################################
#
IP=$(nmap -sP 192.168.2.100-199 >/dev/null 2>&1 && /usr/sbin/arp -an | grep "01:01:01:01:01:01" | awk '{print $2}' | sed 's/[()]//g')
if [[ "${IP}" != "" ]]; then
echo "${IP}" >/home/pi/motion/IPhoneIP.txt
fi
蓝牙检测也是基于 bash 的,使用以下脚本(每 3 分钟运行一次):
#!/bin/bash
############################################################################
## bash checks whether iPhone is detected via bluetooth
############################################################################
##
############################################################################
BLUET=$(sudo l2ping -c 1 01:01:01:01:01:01 2>/dev/null | grep -c "44 bytes")
echo "${BLUET}" > /home/pi/motion/IPhoneBluetoothCheck.txt