IoTの注目株！EnOcean対応マルチセンサをクラウドで可視化する

# はじめに
はじめまして，NTTコミュニケーションズの[川戸](https://qiita.com/kawatom)と申します．
同社のIoTチームにて， Things Cloud という IoT プラットフォームを活用したソリューションアーキテクトに携わらせていただいております．

本記事は，[NTTコミュニケーションズ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nttcom)の23日目の記事です．
いよいよクリスマスも目前ですね！このご時世で外出もままなりませんが，適度に楽しんでいきましょう．

さて，早速ですが本記事の概要をご説明します．
今回は，**EnOcean Multisensor STM 550** というセンサデバイスを使用し，クラウドサービス上に設置先の様々な情報を表示する流れをまとめていきます．

センサから取得した情報のアップロード先は，弊社の **Things Cloud** を選択します．

今回使用するセンサ STM 550は，まだ Things Cloud への接続実績がありませんので，こちらの接続検証も兼ねて取り組んでみました．
これからIoTシステムを自分で構築してみたい，という方にとっても何かしらご参考になれば幸いです．
また，記事に不正確な点や事実誤認がありましたら，コメントにてご指摘ください．

# EnOcean とは
ご存知の方も多いかとは思いますが，EnOcean（エンオーシャン）とは，EnOcean社が開発し，基本特許をもつエネルギーハーベスティング無線通信技術のことを指します．

EnOceanは，エネルギーハーベスティング技術により，**無給電で動作**するという大きな特徴があります．あまり高頻度な通信には向きませんが，一般的なIoTシステムのように定頻度で少量のデータ通信を主として行う場合，電池レス，配線レスのEnOceanセンサは非常に有効であると言えます．

大量のデバイスを扱うIoTシステムでは通常，電池交換などのメンテナンスが必要不可欠かつ面倒な部分となっており，この作業が必要なくなることはIoTシステムにとって大きなメリットであるため，EnOceanは今後ますます注目度が高まる技術であると考えられています．

EnOceanの技術仕様など，さらに詳しい情報については下記の記事をご覧いただくとより理解が深まります．

* [IoTの台風の目！？EnOceanについて本気出して語ってみた](https://qiita.com/a-yoshino/items/29c34795c87ad9f21665)


# 使用機器と構成
本記事で使用するデバイス等についてご説明します．

## センサデバイス
データ収集用のセンサとして**EnOcean Multisensor STM 550**を使用します．
以下の図からもわかる通り，かなりコンパクトな造りをしており，配線等は一切ありません．

![MultiSensor.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/f2ab4436-9dcc-b06a-623e-9f8fa32fe733.jpeg)

このセンサ１つで
　- 温度センサ
　- 湿度センサ
　- 照度センサ
　- 3軸加速度センサ
　- マグネットセンサ
の役割を果たすことができます．

どのセンサデータを送信するかは，設定から変更することが可能です．
今回はせっかくなので全てのデータを送信してみましょう．

因みにですが，このセンサは**NFCリーダに対応**しており，NFC対応のスマートフォンに専用のアプリをインストールすることで，スマホから簡単に設定を変更する事ができます．変更できる設定内容も，送信するデータ種別だけでなく，データの送信間隔や閾値など，柔軟性が高いものになっています．ご参考までに，専用アプリの動作画面を以下に載せておきます．
（App Storeにて"EnOcean Tool"でヒットします．iPhone8で問題なく動作することを確認）

![EnOceanTool.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/9dc74388-5a0e-0a70-949c-7bc3229c52c2.png)

## IoTゲートウェイ
センサからのデータをクラウドへアップロードするには，ゲートウェイ（以下，GW）が必要となります．
EnOceanセンサを使用する場合，当然ですがGWもEnOceanに対応している必要があります．
今回は簡単のため，Raspberry Pi 4 に EnOcean対応通信モジュールを接続し，GWとして使用します．

![RaspberryPi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/734b2b36-d805-9580-e1fe-0ef6cab43071.jpeg)

## クラウドサービス
センサだけではIoTシステムとして成立しません．センサデータを蓄積し，管理するプラットフォームが必要です．本記事では，Things Cloud 上にデータをアップロードし，リアルタイムにデータを観察してみましょう．

Things Cloud は，IoTシステムを構築・管理する上で必要となる**様々な機能が全て標準搭載**されているため，特別な知識が無くても非常に扱いやすいクラウドサービスであると言えるでしょう．実際の動作画面は以下の図の様になっています．センサデータの可視化UIもとても見やすいですね．

![ThingsCloud_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/956428e2-ee28-9729-717d-45293da4285f.png)


Things Cloud についての詳細は，[NTTコミュニケーションズ公式サイト](https://www.ntt.com/business/services/iot/iot/iot.html)をご覧ください．

## Node-RED
センサから受信したデータを解析してクラウドへの送信を実行するための，所謂 Agent Software の実装に使用します．このNode-REDを使用してAgent Softwareを実装し，Raspberry Pi 上で動作させます．以下の図の様に，コードブロック形式のプログラミングツールとなっており，今回の様なテスト開発にもうってつけです．

![Node-RED_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/4c727940-98bc-4bab-6791-e53347fbab7c.png)

## 構成
以上の構成要素の関係を簡単にまとめると，以下の様になります．

![System.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/25b61708-9ad8-c05d-da4c-48f3849f2c01.png)


# センサとクラウドサービスとの接続
センサデータを可視化するには，いくつかの工程を踏む必要があり，
使用する機器等にもよりますが，基本的には以下の様な流れになっています．
以降，それぞれの工程について詳しく説明していきます．

1. センサとGWのペアリング（EnOceanの場合はTeachi-in機能による事前登録）
2. センサデータの解析
3. 使用クラウドに応じたデータ整形処理
4. クラウドへのデバイス登録
5. データ可視化画面の構築


> EnOceanはブロードキャストの通信ですので，センサとGWのペアリング機能はなく，GW側でセンサのIDと通信プロファイルの対応づけを行います．このセンサのIDと通信プロファイルの対応づけの作業を行うため，**Teach-In**という仕組み用意されており，データの種別や取りうる値の範囲などのデータ定義をGWに登録できます．（しかし今回は理解を深めるため，Teach-Inを使用せずに実施しています．）

## 1. センサとGWのペアリング（センサの事前登録）
まずはセンサの仕様書を見てみます．

![EEPlist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/31413c16-676b-68cc-600d-9a27ca6bfdaf.png)

今回使用するSTM-550は，冒頭でも述べた通り設定によって送信するデータ種別をカスタマイズできます．そのため，設定によって通信プロファイルも異っていることがわかりました．今回はデフォルト設定ですが，扱えるデータ種の最も多いプロファイルを使用します．
仕様書で確認すると，プロファイル番号は「**D2-14-41**」となっていますね．

EnOceanでは送信される電文の中にプロファイル番号が含まれていないため，EnOceanを利用するアプリケーションは，各センサのIDとプロファイル番号の対応付けを独自に実装する必要があります．

今回は，Node-REDのプログラムから読み込み易いよう，JSON形式で Raspberry Pi 上に保存することで，プロファイル番号とセンサのシリアルIDとの対応づけをGW側で保持します．

```json
{"sensors":[ {"Serial ID": "d21441"} ]}
```

## 2. センサデータの解析

### EnOceanの通信プロトコル
さて，いきなり通信プロファイルの話が飛び出しましたが
その前に，EnOceanの通信プロトコルの基本的な部分から改めてご説明しておきます．

まず，EnOceanセンサから送信される電文は，大別すると次のような構成をしており，
登場するプロトコルは4つです．

![EnOcean_protocol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/94920d98-ee9b-a970-f268-ba5fd682387e.png)

| プロトコル                              | 役割・概要                                                             | 規格             | 
| --------------------------------------- | ---------------------------------------------------------------------- | ---------------- | 
| ESP3（EnOcean Serial Protocol 3）       | データ長，パケット種別，チェックサムなど                               | EnOcean GmbH     | 
| ERP2（EnOcean Radio Protocol 2）        | 送信元ID，電文タイプなど                                               | EnOcean GmbH     | 
| EEP（EnOcean Equipment Profiles 2.6.X） | 各センサにおけるデータモデルの定義<br>（予め登録されているものを扱う） | EnOcean Alliance | 
| GP（Generic Profiles 1.0）              | 各センサにおけるデータモデルの定義<br>（センサのメーカが独自に定義）   | EnOcean Alliance | 

各センサごとのデータモデル定義はEEPもしくはGPで行われており，これらのデータモデルをネットワーク経由でやりとりするためにERP2，ESP3でパケットがカプセル化されます．

> 先ほど登場した**プロファイル番号**とは，EEPにおけるデータフォーマットの識別番号のことでした．（EEPのプロファイルはEnOcean Allianceへの申請によって可能で，200以上ものデータフォーマットが登録されているとのこと）

### ESPとERP
まずはESPとERPの内容を解析する機能を実装する必要があるのですが，
この部分はEnOceanの基本となる部分であり，どのメーカのEnOceanセンサでも共通です．
つまり，**一度実装してしまえばずっと使いまわせる**，という事になります．この辺りは標準化プロトコルの強みと言えますね．

ESP・ERPの説明から始めると，クリスマスが終わってしまいそうなので，本記事では割愛させていただきます．ご興味のある方は，下記の記事をご覧ください．

* [IoTの台風の目！？EnOceanについて本気出して語ってみた](https://qiita.com/a-yoshino/items/29c34795c87ad9f21665)
* [Node-REDのserialノードを使ってEnOceanのスイッチデータを受信してみた](https://digital-light.jp/2017/10/13/received-enocean-data-by-using-serialport-node/)
* [Node-REDでのEnOceanのデータ読み取りをもう少し踏み込んだメモ](https://www.1ft-seabass.jp/memo/2017/09/19/nodered-enocean-data-read-second-step/)

### EEP
さて，大幅に端折ってしまいましたが，ここまでの内容を実施していただくと，受信したセンサデータから以下のような情報を取り出すことができるはずです．（Node-REDのデバッグウィンドウにて確認可能）

![Log1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/5dcfab7e-7e1d-eead-0f54-79698e15cdf8.png)

次に解析すべきは，上記`payload`に含まれる9Byteからなるデータです．
ここで，もう一度STM-550の仕様書を確認しましょう．

![VLD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/96ff8d7f-1b6d-578f-cbe7-2ee25688d4ba.png)

先ほどのpayloadに含まれていた9Byteのデータの読み方が記述されています．
ここから読み取れる内容を図にまとめると，以下の様になりますね．

![VLD_memo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/d480333c-8b5e-ae24-f7a5-d01e6ed5cfcb.png)

ここまで理解できれば，後はpayloadの中身を適切に処理するのみとなります．
具体的には，下記の様な処理をそれぞれのデータに対して行います．

```js
// データの抽出&格納用に初期化
var data = msg.payload;
msg.data = {};

//温度（先頭10bit, -40°C ... 60°C）
var temp = data[0]<<2 | (data[1]&0xC0)>>6;  //必要な部分を連結
temp = temp / 1023.0 * (60 - (-40)) - 40    //表現可能範囲に合わせる
msg.data.Temperature = temp;
```

湿度，照度，加速度，マグネットについても同様の処理を行うと，センサデータの解析は完了です．ここまで解析が進むと，いよいよ人間が読んでも理解できる情報が得られました．
詳しい動作確認は後に行いますが，感覚的には正しくデータが抽出できていると思われます．

![Log2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/933d0820-0129-debd-434c-4f1e9524f08d.png)

## 3. 使用クラウドに応じたデータ整形処理
続いて，抽出したセンサデータをクラウドにアップロードする訳ですが，
その前にクラウド側が理解できる形にデータを整形する必要があります．

Things Cloud の場合，クラウドに送信するセンサデータは**メジャーメント**と呼ばれるフォーマットに従って整形されている必要があります．
メジャーメントへのデータ整形は，具体的に下記の様な処理で実現できます．

```js
// フラグメント格納用オブジェクト
var fragments = {};

//温度
var c8y_TemperatureMeasurement = {};
var T = {};
T.value = msg.data.Temperature;     //計測値
T.unit = "C";                       //単位
c8y_TemperatureMeasurement.T = T;
fragments.c8y_TemperatureMeasurement = c8y_TemperatureMeasurement;
```

整形されたメジャーメントは，下記の様なJSON形式で保存されます．

```JSON
{
    "c8y_TemperatureMeasurement": {
        "T": {"value": "---", "unit": "C" }
    }
}
```

メジャーメント形式に整形すると，後はThings CloudのAPIを利用してデータをPOSTするだけですので，この部分も割愛していきます．
ここまで本記事でご説明した処理をNode-REDのフローで表現すると，次の様になります．

![VLD_Parse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/23af3e3e-9376-c702-0121-8b564016e174.png)

## 4. クラウドへのデバイス登録
ここからは，Things Cloud側から設定を行っていきます．
まずは，今回IoTゲートウェイとして使用する Raspberry Pi をデバイス一覧に登録します．
デバイス登録は，以下の図のように，`デバイス管理` ＞ `デバイス` ＞ `登録` から実施します．

![device_setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/ce794db7-c0e2-0cd5-d454-dfd3cc1bbb68.png)

登録が完了すると，`デバイス一覧`画面にRaspberry Piが表示されます．

![devices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/47e96bbe-bc8b-6f50-8b20-b7f407db4cec.png)

> このように，デバイスの登録・管理が直感的かつ簡単に行えるのもThings Cloudのいいところだと思います．

## 5. データ可視化画面の構築
続いて，クラウドにアップされたデータの可視化画面を構築します．
冒頭で例をお見せしておりましたが，Things Cloudでは`コックピット`と呼ばれるアプリケーションから，デバイスごとまたはグループごとに可視化画面を自由にカスタマイズできます．

本記事の本題ではないので，ここはあまり拘らず，以下のようにウィジェットを配置してみました．これで，マルチセンサで取得した様々なデータが，リアルタイムにかつ一目で把握できるようになりました．

![Cockpit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/74e8ba56-735a-b87d-734c-69e9755721d4.png)

以上で，センサデータをクラウド上で可視化する作業は完了です．お疲れ様でした．


# 動作確認
最後に，センサ本体および今回実装したAgent Softwareが正しく動作しているか，実際にセンサへ刺激を加えながら確認していきます．

## 温度・湿度
まずは基本となる温度と湿度です．
私の部屋には温度計の類がないので正確な値を知ることはできませんが，実際こんなものでしょう．

![TC_TempHumid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/2a580fe8-82ba-d1c0-b76b-37c2eacc6ada.png)

## 照度
続いて，照度を見てみましょう．
めちゃめちゃ暗いですね．こちらも照度計などは置いていないので正解値は不明です．

![TC_Ilumi1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/7df50439-2f32-c101-c713-d8063bfc5531.png)

心配なので，照度センサに直接ライトを当ててみました．

![TC_Ilumi2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/4f844704-db82-381a-fbd6-fc1ba59c753f.png)

無事に明るさの変化に応答してくれていますね．
仕様書によると100000luxまで計測可能とのことでしたが，屋内ではそこまでの明るさは必要なさそうです．

## 加速度
次は加速度です．
EnOceanセンサはデータ送信間隔が長めなので，センサの動きをトラッキングするのではなく，センサの傾きを読みとることがメインの用途になると思われます．

動作確認として，以下のようにセンサ本体の置き方を変えながら，センサ値の変化を観察しました．図より，重力加速度（約1g）の加わり方が置き方に応じて正しく変化していることがわかります．こちらは間違いなく正しく動作しているといえそうです．

![TC_ACC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/b9626cb4-2e09-79dc-edc1-114e287f9d7d.png)

> STM-550は，3軸の加速度センサ値以外に，`AccelerationStatus`というものもセンサデータの1部として送信しています．こちらは，センサが動いている時に`1`を，センサが静止している時に`0`を示します．

## マグネットコンタクト
最後はマグネットセンサです．
マグネットセンサは，その名の通り磁石を近づけたり離したりすることで値が変化します．
こちらも問題なく動作していることが確認できました．

![TC_Magnet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/6703d331-692b-763e-beec-b52f9ece0a58.png)

> マグネットセンサは，磁石が近づいた時，離れた時，それぞれ即座にデータを送信します．
他のセンサも，センサ値に大きな変化が起こった場合，デフォルトのデータ送信頻度によらずデータの送信を行う仕様になっているようです．（加速度の場合は，AccelerationStatusが0→1の時に即座に送信．再び0に戻るまでは通常通りの頻度で送信）

# 考察
今回クラウドへ接続したSTM-550ですが，実際に使用する場合にどのような使用用途があるのか，少し考えてみました．
これまで述べてきたように，STM-550では５種類のデータを扱うことができます．それぞれのセンサで出来ることを考えると，下記のようなところかと思います．（もっとよく考えれば様々な使い方がありそうですが．）

| センサ種         | 基本使用用途                                                       | 応用                                                                  | 
| ---------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------- | 
| 温度センサ       | ・室内状況の監視                                                   | ・空調設備の自動制御システム<br>・食品衛生管理システム                | 
| 湿度センサ       | ・室内状況の監視                                                   | ・空調設備の自動制御システム                                          | 
| 照度センサ       | ・室内状況の監視                                                   | ・照明設備の自動制御システム                                          | 
| 加速度センサ     | ・窓やケージなどの開閉検知<br>・荷物などの転倒検知<br>・稼働率監視 | ・窓などの閉め忘れ防止システム                                        | 
| マグネット<br>センサ | ・扉などの開閉検知                                       | ・空室 / 利用状況管理システム<br>・配達物などの開封検知システム※ | 

上記全てのデータを組み合わせて有効活用することは難しそうですが，
「生き物などを飼育するケージの総合マネジメント」
などはいかがでしょうか．

## 生き物などを飼育するケージの総合マネジメント
動物園や水族館，趣味で生物の飼育を行っている人向けに，ケージの状態監視システムを構築できそうです．温湿度や照度を把握し，必要に応じて手動または自動で設備を調節できます．また，加速度センサやマグネットセンサを利用することで，扉や蓋の閉め忘れ時にアラームで知らせることもできますし，万が一生物が脱走した場合も逸早く気づくことができます．

似たようなサービスは既にありそうですが，STM-550の場合，これ１つで全て完結しますし，配線や電池交換が一切必要ないという点で差別化を図っていけるのではないでしょうか．

> ※先日のニュースにて，極低温で保存する必要のある新型コロナウィルス用ワクチンの運搬には，温度管理用のデバイスが箱に同封されているとの情報を耳にしました。STM-550では-20℃までしか計測できず互換性は全くありませんが，転倒検知や開封検知と組み合わせ，ワクチンのように重要な荷物の安全管理に有効活用できるかもしれません.

# おまけ：作業中に困ったことのメモ
以下の図はSTM-550のVLD Telegramの内容を記したものですが，ここのデータパースで若干詰まる部分があったのでメモしておきます．

![VLD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/1cec5e32-f249-0f9b-531c-c309c6fc5bc4.png)

受信した9byteのデータを，上記の仕様書通りに素直に読み解くと，次のようになります．

![Addition1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/7336132a-ce9b-3254-38ba-01bbbf73a809.png)

ところが，この形式でデータ解析を行うと，加速度だけ狂っているように感じました．
具体的には，センサ本体を動かしていないにもかかわらず，加速度センサの値が一定に定まらない，重力加速度に対して検出される値が明らかにおかしい，などです．
また，Acceleration Status の値も動きにかかわらず1になったり0になったりしていました．

感覚的な部分も含みますが，加速度センサ以外のデータは正常に見えたため，加速度だけ何かがおかしいという予想のもと，試しに以下のようにデータ解析の順序を変更してみました．

![Addition2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866823/fdf22032-0384-0c57-ff25-75fc1575ec0f.png)

その結果，これまで確認してきたような正常な値を読みとることができました．
色々試してみるもんですね．

# おわりに
長らくお付き合いいただきありがとうございました．
また機会がありましたら何かしらまとめていきますので，今後もよろしくお願いいたします．