冬天到了,为避免每天一觉睡到中午(闹钟叫不醒的那种),我打算做一个能够在早上自动亮起的小灯放在床头帮助早起。宿舍里恰好有一块闲置的树莓派 3B+,非常适合用来实现这个功能,将其利用起来,就不用另购昂贵的智能家居设备了。上网买了个 ¥7 包邮的 USB 小灯,没有电池,没有亮度或色温调节,就是最普通的“即插即亮”的 LED 灯。
基本思路如下:使用 uhubctl 来控制树莓派 USB 端口的供电,从而控制小灯;在树莓派上安装 Homebridge 用于对接 HomeKit(Apple 的智能家居平台);最后在 Apple 设备上安装“家庭”App 并接入即可。
本文地址:https://www.jeddd.com/article/control-usb-light-on-raspberry-pi-with-homekit.html
用 uhubctl 控制 USB 供电
安装 uhubctl
uhubctl 是一款用于控制 USB 端口供电的开源工具,支持包括但不限于树莓派的多种设备。按照官方文档的步骤安装 uhubctl:
sudo apt install libusb-1.0-0-dev
git clone https://github.com/mvp/uhubctl
cd uhubctl
make
sudo make install
测试 uhubctl
将 USB 小灯、USB 风扇或者手机等设备插入树莓派的任意 USB 端口用于测试。执行以下命令,确认能够正常控制 USB 供电的开关:
sudo uhubctl -l 1-1 -p 2 -a on # turn power on
sudo uhubctl -l 1-1 -p 2 -a off # turn power off
由于树莓派 USB 的拓扑结构,四个 USB 端口的供电是统一控制的,所以该命令将同时开启或关闭四个端口的供电。uhubctl 主页上有详细的参数说明,并解释了无法单独控制一个端口的原因。
权限问题
在 Linux 上,需要配置 udev USB 权限,否则必须使用 sudo
来以 root 权限运行 uhubctl,而默认情况下 Homebridge 不会以 root 运行。
- 运行
sudo uhubctl
,查看要控制的端口的 VID(或直接在 uhubctl 文档中查看)。 将下列 udev 规则添加至
/etc/udev/rules.d/52-usb.rules
文件,注意替换规则中的 VID:在树莓派 3B+ 上:
SUBSYSTEM=="usb", ATTR{idVendor}=="0424", MODE="0666"
在树莓派 4 上(USB2 和 USB3 各一条):
SUBSYSTEM=="usb", ATTR{idVendor}=="2109", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="1d6b", MODE="0666"
要使 udev 规则生效,执行:
sudo udevadm trigger --attr-match=subsystem=usb
不使用
sudo
,执行以下命令,确认能够正常控制 USB 供电的开关:uhubctl -l 1-1 -p 2 -a on # turn power on uhubctl -l 1-1 -p 2 -a off # turn power off
安装 Homebridge 并接入 HomeKit
对于那些非原生支持 HomeKit 的配件,可以使用 Homebridge 作为桥梁将它们接入 HomeKit,从而可以使用 iPhone/iPad/Mac 上的“家庭”App 或 Siri 控制。
安装 Node.js
Homebridge 基于 Node.js,因此需要先安装依赖项:
# setup repo
curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
# install Node.js
sudo apt install -y nodejs gcc g++ make python net-tools
# test node is working
node -v
# upgrade npm (version 6.13.4 has issues with git dependencies)
sudo npm install -g npm
由于众所周知的原因,在大陆地区可能无法正常使用 npm。解决方法是换源,在 npm install
命令后添加 --registry https://registry.npm.taobao.org
以使用淘宝 npm 镜像:
sudo npm install -g npm --registry https://registry.npm.taobao.org
安装 Homebridge 主程序与管理后台界面
Homebridge Config UI X 是一款 Homebridge 插件,它提供了一个方便管理 Homebridge 的 Web 后台界面。安装该插件:
sudo npm install -g --unsafe-perm homebridge homebridge-config-ui-x
Homebridge Config UI X 还提供了一个名为 hb-service 的工具,它可以将 Homebridge 设置为服务,并支持开机自启。
sudo hb-service install --user homebridge
上述命令将创建一个名为 homebridge 的用户来运行 Homebridge,同时生成配置文件并保存在 /var/lib/homebridge/config.json
。
访问 http://<IP address>:8581
进入管理后台。默认用户名为 admin
,密码为 admin
。
接入 Apple 设备
打开 iOS 设备中的“家庭”App,扫描 Homebridge 管理后台上的二维码并添加此网桥。iOS 设备与树莓派需要处于同一局域网内。添加完成后,在家庭设置中可以查看到该 Homebridge 网桥的信息。
安装 Script2 插件
Homebridge 的 Homebridge Script2 插件支持通过 HomeKit 执行自定义脚本。在 Web 管理后台的【插件 (Plugins)】选项卡中搜索“Script2”,或执行以下命令安装:
sudo npm install -g homebridge-script2
进入 Homebridge 管理后台的【配置 (Config)】选项卡,在配置文件中添加一个配件(accessory):
"accessories": [
{
"accessory": "Script2",
"name": "LED Light",
"on": "uhubctl -l 1-1 -p 2 -a on",
"off": "uhubctl -l 1-1 -p 2 -a off",
"state": "uhubctl -l 1-1 -p 2 2>/dev/null | grep -c 'power'",
"on_value": "1"
}
]
上述配置中,name
表示配件名称,可以随意更改;on
、off
分别为开启和关闭该配件时要执行的命令;state
为查询状态时要执行的命令,当该命令的输出等于 on_value
的值时表示该配件处于开启状态。(state
的命令中使用了 2>/dev/null
是因为 uhubctl 可能会向 stderr 中输出内容,干扰状态判断。)
保存配置文件,点击管理后台右上角的电源按钮重启 Homebridge。待重启完成后,到 iOS 设备的“家庭”App 中就可以看到新添加的配件了。点击该配件并测试是否可以正常开关,以及状态显示是否正常。
定时开关灯
家居中枢
通过将 HomePod、HomePod mini、Apple TV 或 iPad 设置为家居中枢,即可在“家庭”App 中制定自动化规则,还支持远程控制设备,即使手机未接入 HomeKit 所在的局域网。
添加一个自动化任务,每天 8:30 AM 开灯,30 分钟后关灯:
Crontab 定时任务
如果没有适合作为家居中枢的设备,也可以在树莓派上使用 crontab 来定时执行命令。编辑 crontab 文件:
crontab -e
增加两条定时任务,每天 08:30 AM 开灯,9:00 AM 关灯:
30 8 * * * /usr/sbin/uhubctl -l 1-1 -p 2 -a on
0 9 * * * /usr/sbin/uhubctl -l 1-1 -p 2 -a off
重启后自动关灯
树莓派断电重启后,USB 供电会自动开启。要在系统重启后自动关灯,添加如下 crontab:
@reboot /usr/sbin/uhubctl -l 1-1 -p 2 -a off
本文地址:https://www.jeddd.com/article/control-usb-light-on-raspberry-pi-with-homekit.html
谢谢作者提供的教程,请问为什么不能显示状态呢,只能打开再关闭才能关闭
判断状态的命令是 uhubctl -l 1-1 -p 2 2>/dev/null | grep -c 'power',输出 0 表示关闭,1 表示打开。你在树莓派直接执行这个命令试试?
没有0或1,只有一个>,按回车还会有>,在>后输入uhubctl -l 1-1 -p 2 2>/dev/null | grep -c 'power结果为2
好了好了,谢谢作者,我把on_value改成2就可以了,谢谢作者提供教程
好的,解决了就行。另外想问下你用的是树莓派4吗?文中的是树莓派3B+,树莓派4支持了USB3.0,所以会显示两个port。
是树莓派4是两个port,都是一样,不能单独开关
厉害了,这个正是我需要的