Homebridge-CMD4の使い方

#Homebridge-CMD4とは？
###[homebridge-cmd4 - npm](https://www.npmjs.com/package/homebridge-cmd4)
Homebridge-CMD4とは、任意のコマンドをHomekitアクセサリのように登録し、実行可能になるプラグインです。
特長としては、Homekitのほぼすべてのアクセサリに対応しており、Homekitによって提供されるSiriでのコントロールなどの恩恵を最大限受けることが可能です。
![Homekit_screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339688/b3df9658-5342-9c09-1f88-e7ccaf782499.png)

#インストール
Homebridge本体は既にあるものとします。

###Step1 Homebridge-CMD4のインストール
State.jsについては後ほど解説します。

```
sudo npm install -g --unsafe-perm homebridge-cmd
```

###Step2 State.jsのインストール

```
mkdir $HOME/.homebridge

mkdir $HOME/.homebridge/Cmd4Scripts

cp /usr/lib/node_modules/homebridge-cmd4/Extras/Cmd4Scripts/State.js $HOME/.homebridge/Cmd4Scripts/

cp /usr/lib/node_modules/homebridge-cmd4/Extras/Cmd4Scripts/CheckYourScript.sh $HOME/.homebridge/Cmd4Scripts/

chmod 700 .homebridge/Cmd4Scripts/State.js
```

#Homebridge-CMD4の基本概念

###config.jsonの記述

Homebridge-CMD4も他のHomebridgeプラグインと同じように、config.jsonに設定を記述することで利用できます。
公式ページに載っているPS4の例を用いてこのプラグインの利用の基本について解説します。
こちらがそのconfig.jsonです。

```config.json
  ...
   {
      "platform": "Cmd4",
      "name": "Cmd4",
      "accessories":
      [
         {
             "type": "Switch",
             "name": "PS_4",
             "on": false,
             "state_cmd": "bash .homebridge/Cmd4Scripts/PS4.sh"
             "polling": true,     <OR>
             "polling": [{"on": false, "interval": 5, "timeout": 4000}
                        ],
             "interval": 5,
             "timeout": 4000,
          }
      ]
   }
   ...
```

**platform**及び**name**はHomebridgeの基本動作に必要なものですからそには触れずに、**accessories**以下にどんどん書き加えて増やしていく形になります。
利用可能なアクセサリー一覧は**[こちら](https://github.com/ztalbot2000/homebridge-cmd4/blob/master/Extras/config.json)**にあります。
そして、この`config.json`で重要なのは**state_cmdのみ**です。
デバイス上からHomekitアクセサリを実行した時、実行されるのは上記の例では`bash .homebridge/Cmd4Scripts/PS4.sh`だけです。

つまり、このプラグインでは**state_cmd**に設定したシェルスクリプトに、**引数によって**ONにするかOFFにするかを与え、シェルスクリプト 内のif文によって実行するコマンドを変化させるのです。

### state_cmdについて

ではサンプルの`PS4.sh`を見てみます。

```PS4.sh
#!/bin/bash 
 
# Notes 
# 1) This script is called as defined by the config.json file as: 
#    "state_cmd": "bash .homebridge/Cmd4Scripts/PS4.sh" 
#    $1 = 'Get' 
#    $2 = <Device name>    DO NOT USE SPACES IN DEVICE NAME. It causes problems parsing the command line. 
#    $3 = <Characteristic> 
#    $4 = <Device option> 
# 
# 2) For a set of On, the command issued would be: 
#    bash $HOME/.homebridge/Cmd4Scripts/PS4.sh Set PS_4 On false 
#       or 
#    bash $HOME/.homebridge/Cmd4Scripts/PS4.sh Set PS_4 On true 
# 
# 3) For a Get of On, the command issued would be: 
#    bash $HOME/.homebridge/Cmd4Scripts/PS4.sh Get PS_4 On  
#   
#    Homebridge-cmd4 will interpret the result of false to be 1 
#    and true to be 0 so either 0/1  or true/false can be returned. 
 
 
# echo "\$1='$1' \$2='$2' \$3='$3' \$4='$4'" 
 
# This is only here for the first run. 
if [ ! -f "/tmp/fileVariableHolder" ]; then
   echo "0" > "/tmp/fileVariableHolder"
fi
 
if [ "$1" = "Get" ]; then
   # This line is commented out and would be 
   # interchangeable with ps4-waker. It is here 
   # as an example 
   # ps4-waker search | grep -i '200 Ok' 
   cat /tmp/fileVariableHolder
   rc=$?
   if [ "$rc" = "0" ]; then
      exit 0
   else
      echo "failed"
      exit -1
   fi
fi
 
if [ "$1" = "Set" ]; then
   if [ "$3" = "On" ]; then
      if [ "$4" = "true" ]; then
         # This line is commented out and would be 
         # interchangeable with ps4-waker. It is here 
         # as an example 
         # ps4-waker 
         echo $4 > /tmp/fileVariableHolder
         exit $?
      else
         # This line is commented out and would be 
         # interchangeable with ps4-waker. It is here 
         # as an example 
         # ps4-waker standby 
         echo $4 > /tmp/fileVariableHolder
         exit $?
      fi
   fi
fi
 
 
exit -1
```

Notesに書いてあることが全てです。

実際にどのようにこのシェルスクリプトが呼ばれるかというと、例えば、
PS4をONにする時、

```
./PS4.sh Set My_PS4 On true
```
OFFにする時

```
./PS4.sh Set My_PS4 On false
```
また現在の状況を得る時は

```
./PS4.sh Get My_PS4 On
```
のような形で実行されます。

`config.json`の**state_cmd**に設定された`PS4.sh`が実行された時、まず最初の引数として**Get**または**Set**が渡されます。
**Get**は特に頻繁に呼び出され、現在の状況を返します。
起動時などに必ず実行されます。
**Set**はステータスを変化させる際に呼ばれます。

その次の引数はデバイスの名前です。あまり気にしなくても良いかと。

三番目のOnについてですが、ここでは必ずOnになっています。
`Set My_PS4 on` `Set My_PS4 off`とした方が分かりやすいのにこれでは冗長です。
ここの値は**characteristic**と呼ばれていて、今回はPS4の電源を切るかつけるかの二つしかないのでこうなりましたが、例えば明るさを変更できる照明のコントロールをする時などは、

```
./light.sh Set My_Dimmable_Light Brightness 40
```
のように、**characteristic**に`Brightness `が与えられてるのがわかると思います。
これを踏まえると、ここに`On`があるのは自然な事であることが分かります。

**Get**された時のコマンドと、**Set**された時のコマンドをONとOFFで２パターン用意して、if文の中にif文入れてつらつら書いていけばいいです。

また、処理に成功したか失敗したかは必ず返すようにしましょう。
ここはちゃんとみられているので、ちゃんと返さないとデバイス上からは応答なしとか言われちゃいます。

さらに、先ほどの明るさを変更できる照明のコントロールをする時

```
./light.sh Set My_Dimmable_Light Brightness 40
```
だと、終了する`exit 0`の前に、`echo 40`をなどを実行して、ちゃんと設定したその値も返してあげないといけません。

#終わりに
PS4を例に取った基本的な概念の解説は以上になります。
ここでようやくインストールした`Stare.js`の解説なのですが、ここにはすべての**characteristic**とその使用法が記述されています。
これを読んで、**state_cmd**で呼び出されるプログラムを書いて実行する、というのが基本です。
また感の良い方や公式のドキュメントに目を通した方は気づいているかもしれませんが、このPS4.shなどは別にシェルスクリプトである必要は全くありません。
`python3 ~/.homebridge/Cmd4Scripts/PS4.py`みたいなんでもOKです。

私が作った冷房をコントロールするためのプログラムを[こちら](https://github.com/nakano57/cmd4_aircon_state_python)に置いとくので、参考になるかは全く分かりませんが、もしよければご活用ください.
改善したらなんかかんか投げつけてください。

本日はお読みいただきありがとうございました。