長年Amazon Echoを使ってきましたが、試しに触ってみたHomebridgeの使い勝手がAlexaとは雲泥の差だったので、Siri+Homekit+Homebridgeに乗り換えることにしました。プラグインで対応デバイスを増やせる上に、プラグイン開発が盛んなのが良いですね。
で、我が家のガレージの電動シャッター(文化シヤッター製)には、USB経由で給電されている間はシャッター開放の信号を送り続け、給電が止まったりシャッターから離れたりして信号が届かなくなるとシャッターが閉まる、という仕組みの「セレクルーズII」というリモコンが付属していたんですが、これを使ってHomebridge経由でシャッターを開閉出来ないかな?と。
まずUSB給電のオンオフですが、どこのご家庭にも一つか二つか三つは転がっているRaspberry PiってUSBバスパワーのオンオフが可能なので、これを使おうと。USBポートひとつひとつを制御するのはちょっと面倒なんですが、ポート全体なら以下のコマンドでオンオフ出来ます。
# オフにする時: echo -n "1-1" > /sys/bus/usb/drivers/usb/unbind # オンにする時: echo -n "1-1" > /sys/bus/usb/drivers/usb/bind
で、せっかくなので同じRasPi上でHomebridgeも動かしちゃいます。HomebridgeにはRasPi用のイメージもあるので楽チンです。あとはHomebridgeがインストールされたマシン上でコマンドを実行できるCMD4というプラグインがあるので、このプラグインの仕様に合わせてバスパワーをオンオフするシェルスクリプトを書いて登録すれば完成です。
今回はCMD4を使用。Homebridgeの設定からJSON Configを開き、GarageDoorOpenerというデバイスを直書きで追加します。
"platforms": [ { "name": "Config", "port": 8581, "platform": "config" }, { "platform": "Cmd4", "name": "Cmd4", "debug": true, "accessories": [ { "type": "GarageDoorOpener", "displayName": "Shutter", "currentDoorState": "OPEN", "targetDoorState": "OPEN", "obstructionDetected": "FALSE", "lockCurrentState": "UNSECURED", "lockTargetState": "UNSECURED", "name": "Shutter", "manufacturer": "Bunka Shutter", "model": "Anything", "serialNumber": "12345", "stateChangeResponseTime": 30, "state_cmd": "/home/pi/bin/shopen.sh", "polling": [ { "characteristic": "targetDoorState", "interval": 60, "timeout": 8000 }, { "characteristic": "currentDoorState", "interval": 60, "timeout": 8000 } ] } ] } ]
そしてCMD4から実行されるシェルスクリプトを作成。こちらはCMD4の Extras/Cmd4Scripts/Examples/ExampleShellScript_template.sh
をほぼそのまま使っています。ざっくり説明するとシェルスクリプトは「Get/Set」「デバイス名」「特性」「true/false」の4つの引数付きで実行され、Getは現在の状態を取得、Setは状態を変更する場合(ドアの開閉)に用いられます。
#!/bin/bash
set -e
length=$#
device=""
io=""
characteristic=""
option=""
if [ $length -le 1 ]; then
printf "Usage: $0 Get < AccessoryName > < Characteristic >\n"
printf "Usage: $0 Set < AccessoryName > < Characteristic > < Value >\n"
exit -1
fi
if [ $length -ge 1 ]; then
io=$1
# printf "io=$io\n" # debug
fi
if [ $length -ge 2 ]; then
device=$2
# printf "device = ${device}\n" # debug
fi
if [ $length -ge 3 ]; then
characteristic=$3
# printf "Characteristic = ${characteristic}\n" # debug
fi
if [ $length -ge 4 ]; then
option=$4
# printf "option = ${option}\n" # debug
fi
if [ "${io}" == 'Get' ]; then
case $characteristic in
'CurrentDoorState')
PSTATUS=$(lsusb | wc -l)
if [ $PSTATUS -gt 2 ]; then
printf "0\n"
else
printf "1\n"
fi
exit 0
;;
'TargetDoorState')
printf "0\n"
exit 0
;;
'ObstructionDetected')
printf "0\n"
exit 0
;;
'LockCurrentState')
printf "0\n"
exit 0
*)
printf "UnHandled Get ${device} Characteristic ${characteristic}\n"
exit -1
;;
esac
fi
if [ "${io}" == 'Set' ]; then
case $characteristic in
'CurrentDoorState')
exit 0
;;
'TargetDoorState')
if [ $option -eq 0 ]; then
sudo sh -c "echo -n \"1-1\" > /sys/bus/usb/drivers/usb/bind"
else
sudo sh -c "echo -n \"1-1\" > /sys/bus/usb/drivers/usb/unbind"
fi
exit 0
;;
'ObstructionDetected')
exit 0
;;
'LockCurrentState')
exit 0
;;
*)
printf "UnHandled Set GarageDoorOpenner Characteristic ${characteristic}"
exit -1
;;
esac
fi
printf "Unknown io command ${io}\n"
exit -1
あとはHomekitにHomebrigeを追加して「Siri、シャッターを開けて」「シャッターを閉めて」みたいな感じで操作します。
使ってみた感想ですが、「開放の電波が途絶えるとシャッターを下ろす」というセレクルーズの仕様上、セレクルーズは「閉」の状態&通常のリモコンで開けた状態で「シャッターを閉めて」と言っても閉まらないのは、動作として正しいのだけど使い勝手としてはイマイチだなあと。やはり指ロボットでリモコンを操作するのが正しいのか……