RaspberryPi＋ADRSIRを用いた赤外線機器操作

ADRSIRは赤外線リモコンを簡単に作るためのアイテムです。→[商品ページ](https://www.amazon.co.jp/Bit-Trade-One-ADRSIR-%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%BC%E3%83%BB%E3%83%91%E3%82%A4%E5%B0%82%E7%94%A8-%E5%AD%A6%E7%BF%92%E3%83%AA%E3%83%A2%E3%82%B3%E3%83%B3%E5%9F%BA%E6%9D%BF/dp/B077ZNDW79)

今回はエアコンと照明のリモコンの赤外線を学習してGoogleHomeから操作できるようにする。

# 構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/b6da4c3d-9683-2537-490f-14c8adbca34e.png)


## 1. ADRSIRから家電操作

ADRSIRの構成は以下の通り。

<img width="633" alt="adrsir_struc.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/cff1fe8c-ea28-4edc-bcb9-68cd4d0d4792.jpeg">

なお、基板上の表記ではスイッチは1〜10であるが、内部的には0〜9に対応するため以降コマンド等でスイッチを指定する際には注意。

学習手順
1. スイッチをlearnに切り替える。→ 学習モードになると青いランプがつく。
2. 覚えさせたいボタン（ここでは1番）を押す。
3. 受光部に向けて学習対象のリモコンのボタン（ここでは照明ON）を押す。→ ランプが一瞬だけ緑に点灯。
4. スイッチをcontrolに切り替える。

### テスト
先ほど覚えさせたボタン（1番）を押す。
対象の家電が操作できていれば成功。（電気ついたー）

※エアコンのリモコンは物によっては学習できないものもある。→[参考]()
明るさ変更可能な照明もリモコンに記憶するから「点灯」ボタンは学習できない気がする。実際数十回試したが操作できなかった。→ここに関しては後述。
※一度不可でも何度かリトライし続けるとたまに学習・操作できる。エアコンに関しては8回くらい試行して動かせた。（リモコンの表示状態に依存すると思うのでOFFからつけた時、すでについてる時の信号をそれぞれとってみるといい。）

## 2. ラズパイの設定

[販売元のサイト](http://bit-trade-one.co.jp/blog/2017121302/)から必要なライブラリをPCに落としてくる。
`unzip`してから`scp`でラズパイのホームディレクトリへ追加。

### 赤外線信号をdatファイルに保存
ADRSIRで読み込んだ赤外線信号を読み込む。ここではTurnOnLight.datファイルとして保存しておく。
基板上の1番は内部では0番に対応していることに注意。

```
$ python3 I2C0x52-IR/IR-remocon02-commandline.py r 0 > TurnOnLight.dat
$ cat TurnOnLight.dat
86004100130010001200310014000F0013001000120032001300310012001000120011001200320013000F001200320013000F0013003100130010001200100014000F001300310013000F001300310014000F00120011001200100013001000130010001200320013000F00130032001200310013000F001200330012001000120010001300100013001000120011001200310014000F001200320013000F001300100013004205
```

### テスト
このファイルを利用してコマンドから家電を操作しに行く。

```
$ python3 I2C0x52-IR/IR-remocon02-commandline.py t `cat TurnOnLight.dat`
```

OK。電気ついた。

## 3. Beebotteの設定

### MQTTブローカー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/ccc2804b-7e02-1f84-d8b9-066accdc6570.png)

(1) 左サイドバーから`Channel`を選択し、`Create New`。チャンネル名と、リソース名を指定する。→トークンが発行される。
(2) 左サイドバーから`AccountSetting`を選択し、シークレットキーをコピーする。
(3) コンソールに戻り、シークレットキーを埋め、サブスクライブしたいチャンネルとリソースを指定し、`Subscribe`を押す。
(4) メッセージとかかれたコンソール上に以下が青字で表示される。

```
{ "channel": "xxxxx", "resource": "xxxxx", "data": { "userinfo": { "username": "", "userid": "uid-xxxxxxxxxxxx" }, "id": "xxxxxxxxxxxx", "event": "join" } }
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/ea9041da-efcb-f51a-bbe0-7c58d600ad50.png)

### テスト

`curl`コマンドからAPIをコールする。

```sh
$ curl -i -H "Content-Type: application/json" -X POST -d '{"data":[{"device":"switchbot","action":"TurnOn"}]}' <APIのURL>
```

zshにエラー`zsh: no matches`を返されたら次のコマンドをうってから実行するといける。
参考:https://shirusu-ni-tarazu.hatenablog.jp/entry/2013/01/18/034233

```
$ setopt nonomatch
```

## 4. IFTTTの設定

* this→google assistantを指定して、トリガーとなる言葉/言語を設定。
* that→webhooksを指定し、URLはbeebotteのURLを指定（下記参考）。形式はPOST、aplication/jsonを指定。中に送りたいJSONを書く。今回は以下。

```
//URL
https://api.beebotte.com/v1/data/publish/チャンネル名/トピック名?token=トークン

//メッセージ
{"data":[{"device":"Light","action":"TurnOn"}]}
```

### テスト

googleアシスタントにIFTTTで登録した言葉を話してみる。→beebotteのコンソールのメッセージに設定したJSONが表示されることを確認。

# 5. Node-REDの設定

ラズパイにNode-REDをいれます。この辺りは他の方の記事を参考に・・（忘れました）。

`$ node-red`で起動。起動後はブラウザから`https://raspberrypi.local:1880`へアクセス。

たまに

>このサイトは安全に接続できません 
>raspberrypi.local から無効な応答が送信されました。
>ERR_SSL_PROTOCOL_ERROR

といわれる。原因と助け方は調査中。

### 構成

最終的にはこうしたい。
![struc2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/d5febb58-2bdb-a1db-fe6a-268aaec3ad1d.png)

まだmqttブローカーを用意していないのでサブスクライブできない。とりあえず入力は「input」を選んで直接jsonを流し込むことでこのルートのテストまで行う。

各設定は以下の通り。

* mqtt

![mqtt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/a7b1b458-022c-f3b9-aa3a-23ff272c68f6.png)

| 設定対象 | 内容 |
|:-----------|:------------|
| トピック      | Beebotteで設定したChannel/Resource（今回はgoogleHome/voice） | 
| ●接続タブ    |       |
| サーバ      | mqtt.beebotte.com   |
| ポート番号    | 8883    |
| ●セキュリティタブ   |    |
| ユーザ名    | Beebotteで発行したtoken（今回はtoken_AbcdeFGHijKLmno0）    |
| パスワード  |  空欄  |

* JSON

そのまま繋ぐだけ。

* Switch

![switch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/96bcd7d3-869f-ef15-9ac5-b30e1ca9d291.png)
設定で、「表示名」、「条件式」が書ける。
今回の判定対象となる'device'のメッセージの取得は、`payload.data[0].device`とする。('action'でも同様に設定)

* Exec

![exec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/59f0a87a-5893-d74d-79e2-615787b03503.png)

同じく表示名をつけておける。
実行するコマンドは先ほどの

```
python3 I2C0x52-IR/IR-remocon02-commandline.py t `cat TurnOnLight.dat`
```

また、引数にデフォルトでmsg.payloadが乗ってしまうようチェックが入ってるので必ず外す。動かないから。

### テスト

適度に`msg.payload`ノードをつなぎ、右サイドバーからデバッグ画面を開くと流れてくるメッセージたちを見ることができる。googleアシスタントに話しかけた時にここに期待したJSONメッセージが流れてきたら成功。
さらに全てがうまく繋がっていれば、ADRSIRから赤外線が放射され、期待した動作がおこるはず。（赤外線が何かに遮断されないように注意。）

## 6. 最後に （Optional）

この状態で「クーラーつけて」とかというとGoogleHomeから「デバイスが設定されておりません。云々・・・」といわれることがある。
（エアコンは100％これだがTVは時々言われるくらいの割合でよくわからない・・・）

この場合。スマートフォンのGoogleHomeアプリからショートカットを作成することで回避できる。

「ルーティン」→「ルーティンを管理」と移動して右下のプラスアイコンをタップすれば設定画面が出てくるので「クーラーつけて」と言ったら「〇〇（IFTTTで設定したどれかの音声コマンド）」を実行するという風に登録しておこう。

## トラブルシューティング（赤外線が反応しない）

* 発射時にADRSIRの光は点灯するのに、肝心の対象に赤外線が反応しない！というケース。

うちの電灯のリモコンはDAIKOというメーカー(?)のものなのですが、`点灯`ボタンの赤外線を読み込んでADRSIRから発射させても反応なし・・・。ただ`全灯`ボタンは反応するので、`全灯`の赤外線発射後に数秒間、`暗くする`の赤外線を連射するシェルを書いて任意の明るさを維持することにしています。`点灯`の信号はステートフルな何かでその時の明るさに依存していたりするのだろうか？？

### 参考
[SwitchBotを繋いだ記事](https://qiita.com/Kept1994/items/dc38446e2fd0db917af0)