既存の時系列データをAzure Time Series Insightsでデータ分析

Smart Citizen Kitの時系列データをAzure Time Series Insightsに入れて、グラフこねこねが快適になるという話です。

# 動機

Seeedは、温度、湿度、気圧など環境情報を手軽にセンシングできるデバイス「**Smart Citizen Kit**」を販売しています。

> 2021年10月現在、工事認証（いわゆる技適）を取得したSmart Citizen Kitは、一般販売していません。
> 「欲しいぞ！」という方は、Seeedへご相談ください。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/5aac93f8-717f-1445-9dc6-9a0102225b6b.png">
こちらの製品は単なるデバイスだけでなく、情報を収集するプラットフォームが用意されていて、かっこいいWebサイトで各地に設置されたSmart Citizen Kitが測定した環境情報を表示できます。しかも、（Public設定されているデータであれば）誰でも、世界各地に設置されたSmart Citizen Kitのデータにアクセスすることができます。

https://smartcitizen.me/kits/

> このビデオも興味深いです。
> [Documentary: Citizen Science Revolution - Making Sense](https://youtu.be/hvn5LyACUYw)
> SeeedとSmart Citizen Kitの内情は、こちらにちょっとだけ書かれています。
> https://lab.seeed.co.jp/entry/2019/10/15/120000

次の図は、Seeed株式会社に設置しているSmart Citizen Kitの情報です。lightやnoiseなどの現在値や、過去データをグラフ表示することができます。
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/b1237ba9-970e-d3a6-e5e1-9ccc5660271b.png">

世界でSmart Citizen Kitを買えるようにして、ファームウェアもあらかじめ入っていて、パパっとセットアップするだけでWebのどこかにデータが蓄積されて、それをかっこいいWebサイトで見れるなんて、自分でやろうと思うと頭クラクラするほどの凄いことが実現されています。いやはや凄い。

しかしながら、データを分析しはじめてみると、このWebサイトでは「ウーン」といった感情が湧き出てきます。
たとえば、2箇所のSmart Citizen Kitの温度変化を並べようとすると、、、Webブラウザを2画面立ち上げなければいけません。:sweat_smile:
日付をスライドして見ようとすると、、、えぇ、2画面を別々に操作しないと（略）。:sweat:

そこで、Smart Citizen Kitのデータを、時系列データのデータ分析に強い「**Azure Time Series Insights**」に入れて分析が可能か試してみました。

# 結果

下図のようにシステムを構築しました。
Smart Citizen KitからAzure Time Series Insightsへの繋ぎは、それらしいツールは見当たらなかったので、.NET5(C#) Console Applicationを自作しました。（Azureへの書き込みが簡単そうだし、わたしがC#erなので。）Smart Citizen Kitのデータは、[Smart Citizen Websiteに用意されているREST API](https://developer.smartcitizen.me/#get-historical-readings)で取ることができました。Azure Time Series Insightsへデータを直接書き込むことはできません。Azure Time Series Insightsは、Azure Event HubもしくはAzure IoT Hubからしか取り込むことができないのです。そこで、自作アプリからはAzure Event Hubに書き込むようにして、Azure Time Series InsightsはAzure Event Hubから取り込むようにセットアップしました。（後記）

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/0668c750-09fb-9dc8-cc65-0e5bfd7cdd8b.png">

Smart Citizen Kitの全データをAzure Time Series Insightsへ転送するなんて無理ゲーなので（課金コワイ）、ベルギーの屋外に設定されている2台｛"VDK09","VDK05"｝の3ヶ月分のデータに絞って転送しました。（Event Hubへのメッセージは170万件でした。）
この2台にした理由は、、、1台は道路脇で、もう1台は道路から離れているので、比べてみてなにか分かるのでは？と思ったからです。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/14283170-853b-ace6-437d-521602cc7f69.png">

## 2台のnoiseを比較

2台のnoiseを比べてみました。ピンク色が道路脇、青色が道路奥のSmart Citizen Kitです。
予想に反して、道路奥のnoise値が低くないですね。センサー絶対値の誤差なのか、それとも設置している周辺がうるさいのか。
道路脇は、日中、noiseが高くなっています。マーカーを置いてみると、7:00-22:00ぐらいに高いことがわかります。

> 当初は、ベルギーと日本は時差7時間なので目盛の日時を脳内変換していたのですが、右上の日時が表示されているところをクリックして表示のタイムゾーンを変更することができました。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/6f0418f0-c51f-d16f-297d-a7d2bb6576a9.png">

## 長期間をグラフ表示

"VDK09"のtemperatureとhumidityを1ヶ月間グラフ表示しました。
長期間をグラフ化すると、一般的に（色んな事情から）一定期間の平均値で表示されるため突発的な変化に気づきにくいのですが、Max/Minが薄く表示されているので、「ここでなにか異常あったのかな？」ということに気づけます。なにげに便利。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/ec69d897-4ac0-47e4-88db-18ab40d8d939.png">

そして、クイッと範囲指定して拡大表示できます。しかも結果が表示されるのが速い！（下の動画は、早送りしていません。）

<img width="800" alt="image.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/9cade11f-d0c4-917c-8c63-1f27b71cae8b.gif">

## 過去との比較

"VDK09"のnoiseを、前日と比べてみました。
noiseをグラフに2つ追加して、片方のX軸を+1日ズラすことで、前日と見比べることができます。このように表示することで、直感的に赤枠部分が前日よりもnoiseが大きいことが分かります。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/18699047-cd16-6f99-7ec7-02fa70552ce5.png">

# でもお高いんでしょ？

Azure Time Series Insightsを初めて聞いたのは、たしかbuild2017のとき。デモでは時系列データ処理爆速で、とても気になっていたのですが、たしか2万円/月ぐらいかかるので指くわえて見ているだけでした。

しかし、2021年10月現在は、Gen2が出て価格が下がったようです。
これは4000円ちょっと/ユニット/月に、＋αのようです。1日あたり200円弱。

https://azure.microsoft.com/ja-jp/pricing/details/time-series-insights/#pricing

# まとめ

* Smart Citizen Kitの時系列データをAzure Time Series Inisightsに入れることができた。
* 系列の比較、X軸のズラしなど、時系列データを操作してグラフ表示できた。
* とにかく、グラフ表示が速くて快適。
* とはいえ、複雑な分析機能は無い。（そういうときはデータをダウンロードしてお好きなツールで分析）
* 費用は200円弱/日。

---

# 作り方

それでは、構築手順です。

Smart Citizen WebsiteとAzure Time Series Insightsのデータ渡しは、「sck2eventhub」（.NET5 Console Application）で行います。このアプリは、Smart Citizen WebsiteのREST APIを呼び出して対象データを抜き出し、データを日時ソートして、Event Hubへ送信します。日時ソートは、Azure Time Series Insightsが時系列にデータを投入しないとパフォーマンスが低下するためです。

Azure内のデータの流れは、Event Hub -> Event Source -> Time Series Insights Environmentという流れです。Event HubはEvent Hubs Namespace内に作成することができます。Event SourceはTime Series Insights Environmentから作成操作できます。Time Series Insights Environmentはデータ保持にStorage Accountが必須です。

以上から、

* （Event Hubs Namespaceと）Event Hubを作る
* Time Series Insights Environment（とStorage Account）を作る
* （Time Series Insights Environment内で）Event Sourceを作る
* sck2eventhubを実行する

というステップになります。

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/e5428a0c-b196-ec52-2c28-cb923fd09d6d.png">

## Resource Group

Azureなので、先ずはResource Groupを作ります。
Time Series Insightsを設置できるリージョンに制限があるので、リージョンの指定には注意してください。

* Project details
  * Subscription ... あなたの所有するサブスク
  * Resource group ... 「tsi」（適当に）
* Resource details
  * Region ... 「Southeast Asia」（[TSIを設置できるリージョン](https://azure.microsoft.com/ja-jp/pricing/details/time-series-insights/#pricing)を選ぶ）

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/4f78280a-d2ae-15ad-8253-dd8adb80b670.png">

## Event Hub

Event Hubs Namespaceを作ります。
今回は書き込みが1台（sck2eventhub）、読み出しが1台（Event Source）なので、BasicでOKです。

* Project Details
  * Subscription ... 作成したResource Groupのサブスク
  * Resource group ... 「tsi」（作成したResource Group）
* Instance Details
  * Namespace name ... 「mjtsievent」（適切に）
  * Location ... 「Southeast Asia」（作成したResource GroupのRegion）
  * Pricing tier ... 「Basic」（最小でOK）

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/5aa52ff0-7c05-41b3-cb9e-4efe078fb1ae.png">

Event Hubを作ります。

* Name ... 「sc」（適切に）

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/53c568fb-c40e-6eee-4e5f-2a2425d5c565.png">

外部（sck2eventhub）からEvent Hubへ接続があるので、念のためにそれ用のポリシーを作ります。

* Policy name ... 「sc」（適切に）
* Send ... チェック

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/edbc0f6e-4ca2-d5c8-e2b9-efa72730b65d.png">

## Time Series Insights (+ Storage Account)

Time Series Insights Environmentを作ります。同時に、Storage Accountも作られます。
特に、Time series IDの設定は重要です。デバイスから送られてくるメッセージ（JSON）に含まれている、Series（系列）を一意にするプロパティ名を入力します。あとから修正できないので慎重に入力してください。
今回は過去データの投入なので、Warm storeはNoにします。

* Project details
  * Subscription ... 作成したResource Groupのサブスク
  * Resource group ... 「tsi」（作成したResource Group）
* Instance details
  * Environment name ... 「mjtsi」（適切に）
  * Location ... 「Southeast Asia」（作成したResource GroupのRegion）
* Time series ID
  * Property name ... 「deviceId」（系列を一意にするプロパティ名）
* Cold store
  * Storage account name ... 「mjtsistorage」（適切に）
* Warm store
  * Enable warm store ... No

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/7ad1f057-9aeb-8d30-2e6a-e9c9a796ba2a.png"> <img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/6308aa54-ab52-8aab-5002-212d11aa5533.png">

Time Series Insights Environment作成時に、同時にEvent Sourceも作成できますが、、、今回はNoにして、後ほど手作業で作成します。

* Create an event source? ... No

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/4efef467-1646-806c-b12b-329fc1f0282d.png">

## Event Source

Event Sourceを作ります。
Timestamp property nameに、デバイスから送られてくるメッセージ（JSON）に含まれている、時刻を示すプロパティ名を入力します。

* Event source name ... 「sc」（適切に）
* Source ... 「Event Hub」
* Event Hub namespace ... 「mjtsievent」（作成したEvent Hub名前空間）
* Event Hub name ... 「sc」（作成したEvent Hub）
* Event Hub policy value ... 「RootManageSharedAccessKey」
* Event Hub consumer group ... 「$Default」
* Timestamp property name ... 「timestamp」（データの日時を示すプロパティ名）

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/f02c8741-98f9-dc02-8117-90f07bbdaddf.png"> <img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/885c6612-1299-abd1-1c72-f31d1cf47d84.png">

## 確認

Resource Groupに4つ作成できていることを確認します。

|Name|Type|
|:--|:--|
|mjtsievent|Event Hubs Namespace|
|mjtsi|Time Series Insights environment|
|mjtsistorage|Storage account|
|sc (mjtsi/sc)|Time Series Insights event source|

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/027a67cf-46bc-bfa1-cda1-8e0f170c8b89.png">

この時点でTime Series Insights EnvironmentのTSI Explorerを開くと、データがカラのページが表示されます。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/19a6674e-c7e9-e805-4ba7-3a6af6f86107.png">

## sck2eventhub

sck2eventhubのソースコードはこちらです。

https://github.com/matsujirushi/sck2eventhub

ローカルにクローンして、Visual Studioで開きます。
Event Hubへの接続情報をAZURE_EVENT_HUB_CONNECTION_STRINGとAZURE_EVENT_HUB_NAMEに記入します。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/801994db-abb1-6bdb-507e-a03ebfca927e.png">

## 実行

sck2eventhubを実行すると、Smart Citizen Kitからデータを抜き出して、Event Hubへ送信します。
"VDK09"と"VDK05"のセンサー値7種類、2021/7/1から3ヶ月分で、約170万メッセージでした。転送に要した時間は29分でした。

Event HubのIncoming MessagesとOutgoing Messagesが上がれば正常に実行できています。（赤枠部分）

> なお、赤枠の左の、青グラフだけ上がっているのは、Event Sourceの設定をミスっていてうまく転送できなかったときのものです。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/45c44d9c-b2d2-e333-f771-16f3a221bb6d.png">

Time Series Insights Environmentでは、Number of messages receivedとNumber of events storedがバタバタすれば正常です。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/11e94df5-4e68-3bea-72d7-1155fbc5c3ee.png">

## TSI Explorer

データが取り込まれると、TSI Explorer上部の時間軸指定グラフが表示されます。
しかし、左側のインスタンスが表示されません。:sweat:

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/6342732e-5e9e-a5a6-56ff-aaa813e7d298.png">

上部の「Refresh」をクリックすると、左側のインスタンスが表示されます。わーい。
が、しかし、インスタンスの系列が「EventCount」しか表示されません。むむむ。:sweat:

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/32b8ce24-70a7-85e8-00ff-f210a108ead6.png">

Webブラウザのリロードで、インスタンスの系列が正しく表示されました。わーいわーい。:innocent:

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/70fb6a2a-47e9-2b27-b62e-b43dded45def.png">