CCCMKホールディングス TECH Labの Tech Blog

TECH Labスタッフによる格闘記録やマーケティング界隈についての記事など

AzureでIoT機器を管理する仕組みを作っている話

こんにちは。データベースマーケティング研究所の高橋です。

技術書典応援祭、盛り上がってますね。私たちの会社でも「IoTを使ったスマートストアの作り方」という同人誌で参加してみました!

IoTを使ったスマートストアの作り方:CCCマーケティング株式会社技術書典部

この記事はその中で私が担当した二章を抜粋したものになります。よろしくおねがいします。


研究所では最近、Raspberry PiやJetson Nanoを用いたIoT開発に挑戦しています。

IoT開発においては、デバイス自体の開発以外にも、デバイスからのデータ収集や死活監視、デバイスの管理の仕組みが必要になることがあります。そのような仕組みを構築するにあたり、各クラウドベンダーが提供しているサービスを利用すると便利です。今回は、Microsoft Azureを利用した簡易的なIoTデバイス管理システムの概要を説明します。

Azure Iot Hubを用いたデータ収集

デバイスからの情報をクラウド環境に取り込むにあたり、非構造化データを大量に扱いたい場合があります。そのような場合に利用できるAzureのサービスにAzure Iot Hubがあります。Iot HubはIotに特化したメッセージング処理システムです。Iot Hubを用いることで、そのようなデバイスのエンドポイントをスクラッチで組み上げることなく、認証や接続数の担保などをAzure側にオフロードし、デバイスからのデータ収集基盤を構築することができます。

なおIot HubはMQTTと呼ばれるプロトコルに対応しており、双方向通信が可能です。今回は実装しませんでしたが、MQTTを利用することで、デバイスからデータを取得するだけではなく、デバイスの遠隔制御も行うことができます。また、MQTTはHTTPと異なり非同期通信のプロトコルです。これによって、クライアントはサーバーの応答を気にせずにデータを送信可能です。

今回構築したシステムでは、Iot Hubをデバイスのエンドポイントとして利用し、Azure内の各サービスにデータを送信する仕組みとしました。全体のデータの流れとしては、デバイス(Rasberry Pi等) -> Iot Hub -> Stream Analytics -> Cosmos DBとなります。これによって、センサーデータやログをクラウド側に蓄積することができます。

f:id:takahashii:20200218105257p:plain

Stream Analytics は、大規模ストリーミングデータの処理(抽出・集計等)や、他のAzureサービスへのデータ送信を行うサービスです。今回はIot Hubから送られたデータをCosmos DBに送信するためのグルーとして利用しました。

Cosmos DBはMicrosoftが提供しているスキーマレスのマネージドデータベースサービスです。SQLやMongoDB APIに対応しています。Cosmos DBのAPIをインターネット経由で直接デバイスから接続することもできますが、今回はIot Hub経由での接続としました。

Cosmos DBはスキーマレスであるため、RDBで必要なデータ投入前のスキーマの設定が不要です。コンテナ(RDBでのテーブル相当)作成時にユニークキー制約を設定可能なため、データの一部のカラムだけは一意性を担保したい、という場合も対応できます。ただし、Cosmos DBのサポートしていない制約が欲しい場合は、アプリケーションとデータの整合性を取るため、アプリケーション側で別途データバリデーション等が必要になるでしょう。

f:id:takahashii:20200218105323p:plain

これらを利用することで、データ収集部分については全てマネージドサービスのみで構築できました。自らVirtual Machine等を用意してアプリケーションを用意するよりも、インフラの管理が易しくなることが期待されます。

デバイス管理画面

Iot Hubにもデバイス管理機能は存在しますが、今回はより細かい機能の実装も可能なようにwebアプリとしてデバイス管理システムを作成しました。

構成は以下となります。

  • フロントエンド: vue.js
  • バックエンド: Python(FastAPI)
  • DB: Cosmos DB

機能は以下のようなものを実装しました。

  • デバイス登録機能
  • センサー登録機能
  • ドキュメント登録機能

f:id:takahashii:20200218105827p:plain

Vue.jsは軽量なJavaScript Frameworkで、テンプレートとロジックをモジュール化して記述することができます。Angular等の大規模なフレームワークの場合、webpack等を用いてバンドルする仕組みを整える必要がありますが、Vueの場合は(小さいアプリケーションならば)cdnを用いて手軽に利用することもでき、便利です。(将来的にVuexやVue routerを利用する場合は、各ライブラリの管理のためにnpmやwebpackの利用が必要になるでしょう。)

FastAPIはPython製のwebフレームワークです。非同期処理をベースとした実装になっており、軽量で高速です。また、定義したAPIを自動でswagger(API ドキュメントのためのツール)化する機能もついています。今回はCosmos DBへ接続するAPIを手軽に作成したかったのでFastAPIを採用しました。

FastAPIの面白い点として、Pythonの型ヒントを利用してデータバリデーションが行える点があります。

class Device(BaseModel):
    id: str = None
    name: str
    storecode: str = None
    device_type: str = None
    ins_date: str = None
    sensors: List = None
    apis: List = None

型ヒントはPython3.5から入った機能です。これによって、mypyなどのツールを用いることで型チェックを行うことができます。FastAPIはこれをバリデーションに利用することで、独自の記法を用いずにデータバリデーションを記述することができます。

今回データべースにCosmos DBを利用したため、(RDBでのチェック制約のような)データベースでのバリデーションができません。したがって、必要なバリデーションはアプリ側で行う必要があります。ビジネスロジックの無いスキーマのチェックならば、(Pythonの型ヒントで表現できるものは)FastAPIで担保することができます。

死活監視

Azure Monitorはアプリケーションやインフラの監視を行うことができるサービスです。このサービスは内部でLog Analyticsというログの蓄積や取得を行うサービスと統合されており、今回はこちらを利用して以下のような流れで簡易的なログの監視を行います。

  1. データ(Azureのドキュメントではテレメトリと呼称することが多いです)の受信
  2. 蓄積データの取得
  3. アラート

データの受信にはAzure Monitorの機能であるApplication InsightsのCustom Eventsを使います。

今回は先ほど説明したIotHub経由で呼び出したAzure Function上でAzure Monitorにログを送信しています。

ログの取得には、以下のようなKustoというクエリ用の言語を用います。

customEvents | sort by timestamp 

Kustoでは、上記のようにパイプを用いて条件を繋げていきます。

取得したデータに対して、Azureポータル上でアラートルールを設定することができます。

f:id:takahashii:20200218105644p:plain

このようにして、webhookやメールに対して通知を飛ばすことができます。

おわりに

本記事では一部Microsoft Azureの機能を利用して簡易的なIotデバイス管理システムを構築しました。AzureにはAzure Iot Edge、Azure Iot Center、Azure solution acceleratorsなどのIot関連の他のサービスも存在しますが、こちらについてはまだ追い切れていないため、今後も調査を続けていきたいです。

参考