1600円の無線(BLE)温度センサーをRaspberry Pi3 + node-redで活用する

<img width="500" alt="Raspberry Pi3とLinkingデバイス" src="https://qiita-image-store.s3.amazonaws.com/0/12960/8a078cb8-bf65-2286-a5e1-34558bc018cc.jpeg">

:::note warn
残念ながら、ここで使用しているLinkingデバイスは販売終了し、2023年8月でサイトもクローズされる模様。
:::

# はじめに

Raspberry Piで温度センサーを使う際の選択肢はいっぱいあります。USBモジュールを使うもよし、Raspberry PiらしくGPIOにセンサーモジュールを接続するもよし。

でも、できれば無線の温度センサーをあちこちにおいて各部屋の温度を計りたい。と思ってたら、Qiitaのトレンドに出てた [しいたけを自動栽培してみた結果（前編）](https://qiita.com/kojira/items/eadc9956139150990651) という投稿で、スマホ用に売られている [Linkingデバイス](https://linkingiot.com/devices.html) というのを知りました。これをRaspberry Pi3 + node-redで誰でも簡単に使えるようにしてみます。

どのくらい簡単かというと、このようにノード配置しただけでセンサーのデータを取れます。

<img width="414" alt="スクリーンショット 2018-08-23 午後5.56.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/cf7a3a3f-9075-3e3d-65e1-83787fddc43e.png">

無線なので家の各部屋にセンサー置いて、温度・湿度を取得したりできます。照度センサーやワイヤレススイッチもあります。

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

# Linkingデバイスとは

DocomoがいわゆるIoT関連で主導してるっぽい [Project Linking](https://linkingiot.com/) 用のデバイスです: [Linkingデバイス一覧](https://linkingiot.com/devices.html)

- BLE(Bluetooth Low Energy)対応で、ボタン電池で動作。100日単位の電池寿命
- 温度・湿度だけでなく、いろんなセンサーやボタンがある。しかも、ほとんどのセンサーに点灯制御できるLEDがついてる。
- コンシューマー製品なので、基盤むき出しとかではないちゃんとした見た目
- 低価格。たとえば、温度センサー[Tukeru](https://ssl.braveridge.com/store/html/products/detail.php?product_id=34)は1600円。これは、Zigbee対応の中国製品 [Xiaomi temperature and humidity sensor](https://www.gearbest.com/living-appliances/pp_344665.html) とほぼ同じ値段。技適マークつくだけで下手すりゃ数倍の値段になる製品とか多い中、これはすばらしい。

と、結構いい事ずくめなんですが、Docomo主導なので当然のようにiOSとAndroidのみ対応 (SDK有り)。
Raspberry PiでもAndroid thingsのせれば使えるけど、なんとかLinuxで使えないかと思って念の為検索したらありました！

- Linkingデバイスにアクセスできるnode.js用モジュール [node-linking](https://github.com/futomi/node-linking/blob/master/README_ja.md)

ドキュメントもすごく丁寧で最高です。Bluetoothまわりに詳しくなくてもこれなら使える。

これはもうRaspberry pi + node-redでやって見るしかないと、温度・湿度センサーのTukeruと、開閉センサーのOshieruを早速注文。大体3営業日ぐらいで届きました。

ちなみに、Linkingデバイスはほとんどが [株式会社Braveridge](https://ssl.braveridge.com/) の製品のようです。検索すると、[「九州・福岡から、日本のIoT業界をけん引！ブレイブリッジ 小橋氏」](https://www.ipros.jp/technote/tmc-braveridge/)とかの記事があって、個人的にもちょっと応援したい感じです。

# 購入前の注意事項：対応デバイスは要チェック

注文後に[node-linkingのドキュメント](https://github.com/futomi/node-linking/blob/master/README_ja.md#%E9%96%8B%E9%96%89%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E6%83%85%E5%A0%B1%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9-serviceid-6)を全部読んだら、なんと

>開閉センサー情報サービス (serviceId: 6)
今のところ、Oshieru だけがこのサービスをサポートしています。しかし、ビーコンデータが暗号化されているようです。
どうやら、我々、サードパーティの開発者には、直接的にこのビーコンデータを扱うことは許されていないようです。

と書いてあり、購入した開閉センサーOshieruは、node-linkingでは使えないことが判明。しかしこれ、node-linkingだけでなく、たぶん公開されてるスマホ用SDKでも使えませんね。もったいない...

気を取り直して、まずは温度センサーを試します。

なお、この後に対応デバイスの詳細を書いてますが、実際に動作を確認したデバイスは限られています。購入の際はお気をつけください。

# node-redカスタムノード node-red-contrib-linking-device を作る

はじめてのカスタムノード作成にチャレンジし、[node-red-contrib-linking-device](https://github.com/tinoue/node-red-contrib-linking-device/blob/master/README.ja.md)を作成しました。

## 対応Linkingデバイス

まずはデバイスの対応状況です。

### 対応を確認：
- 温度・湿度センサー: Tukeru TH
- 温度・湿度・大気圧センサー: Sizuku THA
- 照度センサー: Sizuku Lux (linking-sensorは非対応)
- ボタン: Pochiru(eco)

### 多分対応している (動作未確認)
- LED: Tomoru / Tomoruフルカラー
- LED: Sizuku LED
- ボタン: Pochiru
- 6軸センサー: Sizuku 6X (linking-scannerは非対応)

### 対応していない
- バイブレーション: Furueru
- 開閉センサー: Oshieru
- 振動センサー: Kizuku
- BLEAD-TSH-LK

## node-redで使えるLinkingデバイス用ノード

Linkingデバイス用ノードは以下の3つです

- linking-scanner

Linkingデバイスをスキャンし、ビーコンデータを出力します。Linkingデバイスが定期的に発信しているビーコンデータにはセンサーの情報が含まれているので、このノードを使うだけでセンサー情報の収集が可能です（ただし、接続が必要なデバイスもあります）。

また、接続できないぐらいデバイスが離れている場合は、このノードを使うしかないです。

- linking-sensor

Linkingデバイスに接続して、センサー情報を取得します。比較的近くにデバスがある場合には、これを使って接続状態でセンサデータを取得すると、電池が長持ちする模様です。

- linking-led

Linkingデバイスに接続して、LEDの点灯リクエストを出します。接続が必須のため、比較的近くにデバイスがある場合に利用できます。

# node-redでのLinkingデバイス用ノードの使い方

例として、温度センサ Tukeru THを使用して温度と湿度のデータを取得し、それをnode-redのデバッグタブに表示してみます。

## インストール

Raspberry Pi3でのインストールを前提として解説します。

なお、Raspberry Pi3自体の新規セットアップから行う場合はこちらをご参考: [Raspberry Pi 3 (Stretch) 設定覚え書き: node-redでスマートホーム用](https://qiita.com/tinoue@github/items/7831849e6a9560159fa5)

### Bluooth関連ライブラリのインストール

ターミナルで以下を実行

```
sudo apt-get -y install bluetooth libbluetooth-dev libudev-dev
```

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

ターミナルで以下を実行。node-redのWeb画面からインストールもできます。

```
cd ~/.node-red
npm install node-red-contrib-linking-device
```

node-redを再起動

```
node-red-stop && node-red-start
```

## linking-scannerでセンサーデータを収集する

1.インストールすると、Node-REDのパレットの linking device カテゴリーにノードが追加されます。

<img width="178" alt="スクリーンショット 2018-08-23 午後5.55.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/9abc86fd-80d6-997c-7f06-08da62847f92.png">

2.まず、linking-scannerノードをワークスペースにドラッグ＆ドロップし、ダブルクリックして設定を開きます。

- `Start automatically at startup` をチェック
- Intervalを60(秒)に設定

<img width="500" alt="スクリーンショット 2018-08-23 午後5.58.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/ec7a0d07-a3cc-7445-2706-c3440d9788d4.png">

3.次に、debugノードをワークスペースにドラッグ＆ドロップして、linking-scannerと接続します。

<img width="414" alt="スクリーンショット 2018-08-23 午後5.56.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/cf7a3a3f-9075-3e3d-65e1-83787fddc43e.png">

4.デプロイします。デバッグタブにLinkingデバイスからのビーコンデータが表示されれば正常動作してます。

上記設定だと、だいたい1分間隔で各センサからの以下のようなデータが表示されます。

```javascript
msg: {
  advertisement: object,
  payload: {
    device: "Sizuku_tha0141790",
    service: "temperature",
    data: 25.625
  },
  topic: "Sizuku_tha0141790_temperature"
}
```

advertisementはnode-linkingの [LinkingAdvertisement](https://github.com/futomi/node-linking/blob/master/README_ja.md#LinkingAdvertisement-object)オブジェクトそのままです。rssiやdistanceなどの詳細情報を取りたいときに参照します。 

## linking-sensorでセンサーデータを収集する

このノードを使う場合、安定して接続できるぐらいデバイスが近くにある必要があります。取れる情報は原則linking-scannerとほぼ同じですが、電池の持ちが良くなるのが利点です。

1.まず、linking-sensorノードをワークスペースにドラッグ＆ドロップし、ダブルクリックして設定を開きます。

- デバイスを選択
- しばらく時間がかかりますが、センサーの対応状況が読み込まれ、battery以外はデフォルトでチェックされます
- `Start automatically at startup` をチェック
- Intervalを60(秒)に設定

<img width="502" alt="スクリーンショット 2018-08-23 午後5.59.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/1bb5ec5d-7d01-ece7-334e-412848bfe0cf.png">

2.次に、debugノードをワークスペースにドラッグ＆ドロップして、linking-scannerと接続します。

<img width="440" alt="スクリーンショット 2018-08-23 午後5.59.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/f8cad626-e13f-dea6-ae04-be231b975ce6.png">

3.デプロイします。デバッグタブにLinkingデバイスからのセンサーデータが表示されれば正常動作してます。

上記設定だと、だいたい1分間隔で各センサからの以下のようなデータが表示されます。advertisementがない意外は、linking-scannerと同じ内容です。

```javascript
msg: {
  payload: {
    device: "Sizuku_tha0141790",
    service: "temperature",
    data: 25.625
  },
  topic: "Sizuku_tha0141790_temperature"
}
```

なお、linking-sensorでデータ収集を行う場合でも、接続がうまくいかない場合を考慮して、linking-scannerをバックアップとして併用するのをおすすめします。デバイスが接続中の場合はlinking-sensorが、接続できない場合はlinking-scannerがデータを収集します。

## linking-ledでLEDを点灯する

このノードを使う場合、安定して接続できるぐらいデバイスが近くにある必要があります。

1.まず、linking-ledノードをワークスペースにドラッグ＆ドロップし、ダブルクリックして設定を開きます。

- デバイスを選択
- しばらく時間がかかりますが、対応しているLEDの色・点灯パターンが読み込まれ、リストに表示されます。表示されない場合はリフレッシュボタンを押してください。
- ここでTestボタンを押してLEDを点灯させてみることもできます。

<img width="496" alt="スクリーンショット 2018-08-23 午後6.01.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/414377b7-b6f2-d9fc-3d79-9012ebb20729.png">

2.Injectノードをワークスペースにドラッグ＆ドロップし、trueを出力するように設定して、linking-ledとつなげます。

<img width="403" alt="スクリーンショット 2018-08-23 午後6.00.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/8cdbedf3-8e93-d08c-bdf5-ecb7f8e5d50d.png">

3.Injectノードの左側をクリックすると、LEDが点灯します。

注意点：デバイスが接続されていない状態だと、点灯リクエストを出して実際にLEDが点灯するまで10〜20秒程度かかります。すぐに点灯させたい場合は、"Keep connection"オプションをチェックしておく必要があります。ただし、接続中はlinking-scannerでのセンサーデータの収集はできません。代わりにlinking-sensorを使う必要があります。

# Beebotteで温度や湿度をグラフ表示

[node-red-dashboard](https://flows.nodered.org/node/node-red-dashboard) でセンサーデータを表示するのもありですが、ここではMQTTブローカーのBeebotteにデータを送ってクラウドで管理する方法を試してみました。このやり方だと、複数台のRaspberry Piで収集したデータを一括管理できるので、スケールしやすいというメリットがあります。

詳細は別記事にて：[Raspberry Pi3で集めた無線温度センサーのデータを、MQTT brokerのBeebotteに送信して表示する](https://qiita.com/tinoue@github/items/3fbceea9a42329c3cc49)

# 使ってみての感想・Tips

## linking-scannerでスキャン結果を受け取れる範囲は最大で5m程度

距離が離れると、scannerでbeaconを取得する頻度ががっくり下がります。間にさえぎるものが何も無くてもだいたい5m以上になるときつくなってくるので、それ以上はなれた場所を計測する際は複数のRaspberry Pi3が必要になりそうです。その場合も考慮して、Beebotteなどを使ってクラウドでデータを集中管理するのがよさそうです。

linking-scannerの編集ダイアログで、各デバイスの信号強度(RSSI)を表示しているので参考にしてください。自分の環境だと-80dBm台だと接続も安定。-95dBm以下はスキャンも含めてかなり厳しくなってくる感じです。

## linking-sensor, linking-ledで接続できる距離は、Raspberry Pi3の場合数mまでが無難

距離が離れるととたんに接続が不安定になります。その場合はlinking-sensorは諦めてlinking-scannerでのセンサー値の読み込みに徹したほうがいいですね。

## Raspberry Pi3本体の向きも気をつけたほうがいい

5m程度のシビアな距離になると、Raspberry Piの向きも影響するようです。アンテナは基板上面についるので、そちらがデバイスに向くようにしたほうがいいです。

また、Tukeruなどはボタン電池と金属クリップが本体下面にあるので、こちら側への電波の飛びは多分悪くなると思います。デバイスの向きも要注意です。

## linking-sensor, linking-ledでの接続には時間がかかる

距離が近い場合でも接続時は10〜20秒程度時間がかかります。

## バッテリー残量通知は動いてるのかどうか不明

node-linkingのドキュメントに以下のように書いてあります：

>今のところ、このリクエストに対して通知を返してくれるのは Sizuku 6X だけのようです。しかし、chargeRequired は常に true、chargeLevel は常に 0 になります。このサービスがうまく機能しているか良く分かりません。

確かにバッテリー残量通知はビーコンデータにも入ってないようで、果たして動作してるのかどうかよくわかりません（バッテリーが減ってきたら通知されるのかも）。linking-sensorを使う場合は、batteryのチェックは除外しておくのがおすすめです（そのほうが接続が早くすみます）。

## 温度センサーは、Tukeru THとShizuku THAのどっちがいいか

Shizukuは大気圧センサーもついているかわりに、値段は700円高い2300円。両方使ってみての感想です。

- Sizukuの大気圧センサーは正確ではない？

自分が購入したものは一日中値が1000のままで機能してるように見えません。また値はlinking-scanner経由でしか取れず、linking-sensoで接続して取得することがなぜか出来ません。そもそも気圧は部屋ごとに変わるものでもないので、気圧が知りたければ適当なWebサービスで値を取れば十分な気がしてきました。

- もしかするとSizukuのほうが電波が遠くまで届くかも

はっきり確かめたわけではないですが、自分の利用状況だと一番離れた部屋からはTukeruの電波が届きませんでした。ためしにSizukuに置き換えてみると大丈夫でした。

- Tukeruは設置向きで湿度の値が変わる

Tukeru × 3個、Sizuku × 1個を同じ場所において、値がどの程度そろうかを見てみました。

下のグラフで、オレンジの線がShizukuで、それ以外がTukeru。12時数分すぎに同じ位置においてます。

<img width="549" alt="スクリーンショット 2018-08-18 午後1.03.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/12960/fda5c9f2-6280-79bd-e9e0-4ec025166b9b.png">

温度は4つともなかなかにそろった値をだしてるので問題ないのですが、湿度が若干ばらついてます。なお、使用してるセンサSHT20のスペックを見たら±3%。
最初、Tukeruが3つともSizukuより5%ほど高い湿度の値となってますが、ふと思いついて、Tukeruを穴が開いてる正面を上向きにして置いたら、グラフ右側のように1つを除いて湿度の値が近づきました。どうやらTukeruは上向きに置いたほうがいいようです。筐体の密閉性が高すぎて湿気がこもってる感じです。