NodeRedとHomekit de つくる自宅IoT

# はじめに
## なぜHomekit？
一般的なIoTというと、Amazon製のAlexaを頭に浮かべると思われます。次点でGoogleHomeです。
IoTを謳う製品はたいてい、この2つに対応しています。開発要件が比較的ゆるいのも一因になっているのかなと予想してます。
しかし、これらの製品は以下の不満(個人的な)を抱えてます。

- 各IoT製品のアプリからGUIで操作できるが、アプリを起動するのが面倒である。

>声を出せない環境(テレワーク時)などではGUIが必要になる

- 多くの家電はスマート赤外線リモコンで操作できるが、そうでないものを操作できない

>例えば、PS4を操作したいが、赤外線では不可。個別にアプリを開発する必要がある

- IoT製品がサービス停止になったときのことが気になる。

>これを気にするとキリがないが


つまるところ、家電を一カ所でまとめて管理したいが、AlexaやGoogleHomeだとカスタマイズ性に欠ける。AlexaやGoogleHomeのアプリを開発すればいいが、コストが大きすぎるし、大変

そこで、**Homekit**がでてくる

### 参考資料
- [HomeKit入門](https://zenn.dev/tokorom/books/homekit-framework)

### 概要
> Appleが定めるプロトコル。家電オブジェクトを定義し、家電オブジェクトができること(ボタンが押せる、そのボタンが3段階であるなど)を肉付けしてやると、同一ネットワーク上のiPhoneが認識し、音声操作をよしなに解釈して操作してくれる。Homepod(=appleのスマートスピーカー)やiPadがあるとそれがゲートウェイになり、ネットワーク外からでも操作できる

# Let's do it
## 実現方法
Homekitの仕様をベースに有志のライブラリが[Github](https://github.com/homebridge/HAP-NodeJS)に上がっているが、新しい家電を買うごとにコーディングするのはちょっと大変。
そこで、ビジュアルコーディングが可能な[NodeRed](https://nodered.org/)にHomekitの[プラグイン](https://www.npmjs.com/package/node-red-contrib-homekit-bridged)があるとのこと。採用

## 手順
### Dockerで起動
NodeRedのDockerイメージを皆さんお持ちの自宅サーバで起動します。
Docker上でNodeRedを立ててHomekitを動かす場合Dockerをホストネットワークモードで起動させる。（Homekitの仕様のせい？）

```
docker run -it -p 1880:1880 --network host -v myNodeREDdata:/data --name mynodered nodered/node-red
```

### NodeRedにインストール

localhost:1880へアクセスしてNodeRedにログイン。
パレットの管理を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/0f1ad49a-d139-7ccf-660c-8b4b4802e30b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/f8869df6-5064-0865-1bbb-3733e1fd3483.png)

```
node-red-contrib-homekit-bridged
```
をインストール。

### Homekitを定義しよう
インストールすると、左のパレットに新しくHomekitパレットが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/0ff3a4da-dcf5-3aa6-569b-a5625c500088.png)

Homekitパレットをドラッグして画面に配置します。
次に、そのパレットをダブルクリックして家電をて定義します。
今回はLightbulb(電球)です。
>ServiceHierarchyは一部家電は子家電を定義できます。
テレビとテレビのスピーカーとか(詳細略)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/7ba4dff1-824d-3e8c-c5cd-e5e883c7e0e4.png)

CharacteristicPropertiesで家電の詳細なふるまいを定義します。
ここでは、明るさが4段階に変化するライト(minStep=25:明るさが25/100ごとに変化する)を定義しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/9eb69249-dd54-2968-c548-69b7b2b72ef1.png)

ここでは、厳密にいうと、Brightness機能(=Characteristic)を有効にしminStepオプション(=Characteristic Property)を設定しています。

```json
{
    "Brightness": {
        "minStep": 33
    }
}
```

ほかにも、[Hue](https://www.philips-hue.com/ja-jp/product-overview)のようなフルカラースマート電灯などかなり幅広い機能に対応できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/e04d8d63-c13c-5a5d-a84b-b6bc524c590f.png)

### スマホで確認
NodeRedにデプロイして、iOSで認識していることを確認。
(その前に作成したHomekitを[スマホに連携させる](https://chasuke.com/alexa_homekit/#rtoc-4)必要があります。)

するとiPhoneのHomekitアプリor下から上にスワイプすると家電が確認できます。
Siriで”電気をつけて”(今回のLightbulbの家電名が電気)というと、ステータスがOnになります。
![image0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/16a6b771-893c-f48c-46fd-3e7aca4e7eb2.png)

### 操作時の動作の定義
NodeRedはScratchのようなビジュアルプログラミングインターフェースを持っているので、
Homekitパレットの出力先に任意の操作を追加してください。ここから先は各環境に合わせた操作をしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123667/e9d1f6e6-8a29-50f8-9441-36e56a295dc8.png)

NodeRedはNatureRemo(スマート赤外線リモコン)のプラグインなどもサポートされているので、お手軽に拡張できます。

# おわり
テレビのOn/Offなどは厳密に実装すると難しい。電源をOnとOffする赤外線が同じで、冪等性がないので、もし障害物などでテレビにOnを送信するのを失敗すると、以降Homekit側ではOn、実際にはOffといった逆転現象が起きてしまう。
私のケースではテレビはPS4しか使わないので、起動時はPS4を起動→テレビは自動的に起動(入力があると起動するタイプ)、終了時はOffを送信、として運用している。あんまりいけてない