Raspberry Pi3で集めた無線温度センサーのデータを、MQTT brokerのBeebotteに送信して表示する


# はじめに

[オススメ！1600円の無線(BLE)温度センサーをRaspberry Pi3 + node-redで活用する](https://qiita.com/tinoue@github/items/be50b80c7d6bb107a00c) という投稿で書きましたが、自宅の各部屋に無線の温度・湿度センサーを設置し、Raspberry Pi3で値を取得しています。
取得したデータの処理・表示ですが、IoTがはやりなのでBeebotteというMQTTブローカーを使ってみました。

BeebotteのDashboardでこんな感じで温度・湿度のグラフ表示が可能です。

![スクリーンショット 2018-08-17 午後2.31.58.png](https://qiita-image-store.s3.amazonaws.com/0/12960/21c73b32-d7f2-a6d3-9d25-6f5c9209d870.png)

正直、Beebotteのグラフ表示は見た目が今一つなのですが、無料アカウントでも一日5000件という比較的多めのデータを扱え、履歴が3ヶ月分保存できるのが魅力で選びました。

# Beebotte側の初期設定

## チャンネル`linking`の作成

- https://beebotte.com でアカウント作成
- Beebotteにログイン後、左側のメニューで`Channels`を選ぶ
- 右上の`Create New`を選ぶ
 - `Channel Name`に`linking`を設定。`Channel Description`は適当に入力
 - `Resource Name`には`{デバイス名}_{センサー名}`を登録。データの種類は
`temperature`や`humidity`などを設定。
 - たとえばTukeru THの場合、`Tukeru_th012345_temperature`と`Tukeru_th012345_humidity`の2つのリソースを登録することになります。
- `Create channel`を押して終了 

<img width="977" alt="スクリーンショット 2018-08-25 午前11.27.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/97f90e03-66b8-f677-b45e-28f8dde81c26.png">

## Channel Tokenの確認

- Beebotteの左側のメニューで、`Channels`を選ぶ
- `linking`を選択
- 画面の上のほうに`Channel Token:token_xxxxxxx`と表示されるので、赤色で表示されている"Token_xxxxxx"の部分をメモ。これは後でnode-redの設定に必要です。

# Node-RED側の設定

## node-red-contrib-linking-device のインストール

以下を参考にインストールします：
[オススメ！1600円の無線(BLE)温度センサーをRaspberry Pi3 + node-redで活用する](https://qiita.com/tinoue@github/items/be50b80c7d6bb107a00c)

## linking-scannerノードを設置

ダブルクリックして設定ダイアログを開き、以下の設定を行います
- `起動時に自動で開始する`をチェック
- `出力間隔`は `30 * Beebotteのリソース数` かそれ以上の値にします。Tukeru THを1つ使う場合は60秒、2つなら120秒が目安となります。後で書きますがBeebotte側のデータ書き込み総数制限を超えないようにするためです。

## Changeノートで、msgの内容をMQTT書き込み用に加工

そのままMQTT outノードにセンサーデータを送ると、データは揮発性のPublish扱いとなり、履歴がBeebotteサーバーに記録されません。履歴を記録するには、msg.payload.write = true を追加する必要があります。
また、payloadにはdata, write以外の情報は不要なので削除します。

Changeノードを設置して、以下の設定を行います。

<img width="515" alt="スクリーンショット 2018-08-27 午後8.32.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/9c6e156f-4b14-b2b8-aa8a-fd6aca0514d4.png">


## MQTT outノードを設置

まず最初の画面を設定。QoSは0か1にします（画面は1ですが、0で十分です)。BeebotteはQoS 2に対応していないので、2を設定するとデプロイ時にMQTTノードが正常終了しない現象が出ます。
最期に、`サーバー`の右端にある鉛筆アイコンをクリックします。

<img width="509" alt="スクリーンショット 2018-08-25 午前11.11.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/afa7f299-3519-4302-6d3c-c94db6cf8e6a.png">

`接続`タブを以下のように設定

<img width="642" alt="スクリーンショット 2018-08-25 午前11.07.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/b07696cc-65a0-e6e8-1dbe-97b7561bc72b.png">

`セキュリティ`タブでは、ユーザー名としてBeebotteのChannel Tokenを設定します。

<img width="644" alt="スクリーンショット 2018-08-25 午前11.07.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/3942a3b9-a074-dda1-046b-a8a5d1d62571.png">

# 各ノードを接続

以下のようにノードを接続します。最初は動作確認のために、debugノードも入れておくのをおすすめします。

<img width="698" alt="スクリーンショット 2018-08-25 午前11.21.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/53b961b2-a299-9f5e-1a37-eb85d2daa387.png">

# デプロイ後、Beebotteにデータが来ていることを確認

- まずNode-REDのフローでlinking-scannerのステータスが`scanning. found: 1`などとなっていればデバイスをスキャンできています。
- Beebotteの左側のメニューで、`Channels`を選ぶ
- `linking`を選択
- 各リソースの値の内容と、それがいつ設定されたかが以下のように表示されます。データが来ていなければ、これまでの設定内容を再度確認。

<img width="781" alt="スクリーンショット 2018-08-25 午前11.22.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/43150bbd-9e4c-441e-c7a2-863767d3ea63.png">

# Beebotteのグラフ表示の設定

Beebotte側でグラフを表示してくれるDashboardの設定を行います。

- Beebotteにログイン後、左側のメニューで`Dashboards`を選ぶ
- 右上の`Create Dashboard`を選ぶ
- `New Dashboard`と表示されている文字を、適当なタイトルに置き換え。`Description`も適当に入力
- 後は`Add Widget`で好きな表示パーツを追加していきます。`Gauge Meter`でメータ表示。複数のセンサーの温度などを一緒に表示する場合は`Multi Line Chart`がお勧めです
- 設定後、右上の`Save Changes`を忘れずに押します。これを忘れると、せっかくの設定が消えてしまいます。

<img width="915" alt="スクリーンショット 2018-08-25 午後4.59.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/35012332-6fbc-1cdf-c863-8922073d8793.png">

# データ書き込みの頻度に注意

Beebotteの無料アカウントだと、データ書き込みは一日5000件までの制限があります。

自分の場合、センサーが温度・湿度 ☓ 4個 + 気圧 ☓ 1個 なので計9種類のデータ。したがって、各データあたり3分おきぐらいの書き込み頻度が限界となります。linking-scanner や linking-sensor の`出力間隔`設定をその値にしておきます（ちなみに設定は秒単位です)。

BeebotteのAccount Usage画面で、データ書き込み状況が以下のように表示されるので、赤い制限ラインを超えない利用状況なのを確認します。ちなみに見てわかるように、出力間隔の設定を忘れてて一回盛大に超過してしまいました。

<img width="816" alt="スクリーンショット 2018-08-25 午前11.57.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/9dd4fd49-11ed-3458-3a5a-c8cfe1bd8673.png">

# しばらくグラフを眺めて思ったこと

家の各部屋の温度・湿度を取り始めて思ったのが、冷房をつけるとしばらくして湿度がどんどん上がっていく点。今ひとつ快適さが足りないのはこのせいかと、エアコンを除湿モードで動かしてみましたが、ほとんど変化なし。

調べてみると、安いエアコンの除湿モードは飾りのようなもので、中高級機種でないと期待するような除湿はできないらしい。今度エアコン買い換えるときは、日立の「カラッと除湿」対応機種にしようと決意しました。

# 体感温度・不快指数の表示

温度だけでは快適さの指標にならないことがわかったので、体感温度・不快指数を表示してみることにしました。

計算はCASIOのサイトを参考：

- [体感温度 (sensible temperature)](https://keisan.casio.jp/exec/system/1257417058)
- [不快指数 (THI: Temperature-Humidity-Index)](https://keisan.casio.jp/exec/system/1202883065)

作成したfunctionノードをエクスポートしたものがこちら。linking-scannerと上記Changeノードの間にはさみます。

```
[{"id":"6810a45f.b628ec","type":"function","z":"2b09d8bf.0e4648","name":" Sensible temperature and THI","func":"const device = msg.payload.device;\n\nif (msg.payload.service === 'humidity') {\n    context.set(device + '_humidity', msg.payload.data);\n} else if (msg.payload.service === 'temperature') {\n    const humidity = context.get(device + '_humidity');\n    if (humidity != null) {\n        // context.set(device + '_humidity', null);\n\n        const temperature = msg.payload.data;\n        \n        const thi = 0.81 * temperature + 0.01 * humidity * (0.99 * temperature - 14.3) + 46.3;\n\n        node.send({\n            topic: 'linking/' + device + '_thi',\n            payload : {\n                data: thi\n            }\n        });\n\n        // Missenard\n        const sensitivetemp = temperature - 1 / 2.3 * (temperature - 10) * (0.8 - humidity / 100);\n\n        node.send({\n            topic: 'linking/' + device + '_sensitivetemp',\n            payload: {\n                data: sensitivetemp\n            }\n        });\n    }\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":260,"wires":[["89df693f.9a7a38"]]}]
```

Beebotteでの表示はこんな感じです。見たところ不快指数が快適さの目安としてわかりやすい値に思えました。扇風機も併用すれば、不快指数「やや暑い」の限界に近い80弱でもなんとか。エアコンだけだと不快指数75以上はきついです。

<img width="1115" alt="スクリーンショット 2018-08-27 午後8.46.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/93e1793e-8745-e14f-7107-5a00c91f2842.png">

ただ、ここまで項目数が多くなると、Beebotteの書き込み上限を考慮して10分おきの更新となります。これはちょっと間隔長すぎるので、Beebotte以外でいいのがないか検討中です。