IRISは、データベース技術をはじめとして幅広い範囲の機能を持っています。IRISを理解してもらうためには、その機能を一つひとつ順番に説明していく方法もあるでしょう。しかし、限られた字数ではお伝えできないこともたくさん出てきてしまいます。また、全体像を捉えることが難しくなるおそれもあります。そこでこの連載では、簡単なアプリケーションを題材にしてIRISを使った開発の流れを体験する形で進めていきます。
その1回目となる今回のテーマは、ズバリ、「まずは動かしてみよう」です。
題材
本連載で作成するのは車載器のデータ(車の速度、エンジン回転数、位置情報など)を扱うIoTアプリケーションです。車載器のデータは、株式会社ビズベース様のご好意によりサンプルを用意しています。
アプリケーションの画面は図のとおりです。
画面は3つの部分に分かれており、一番上にはGoogle Map上に車の現在位置をプロットしています。真ん中には、それぞれの車の速度やエンジンの回転数、ブレーキを踏んでいるかなどを一覧表で示しています。一番下には、大きな加速度がかかるなどのイベントが表示されます。
必要なソフトウェア
アプリケーションを動作させるためには以下のものが必要です。
- Git
- Docker
- Webブラウザ
- Maps JavaScript APIのキー (Google Cloud Platform)
今回のアプリケーションのソースコードやデータはGitHubで公開しています。お持ちの環境でGitのコマンドが実行できるよう準備してください。
CodeZineの読者の皆さまの中にはDockerをご存知の方は多いと思います。Dockerはコンテナと呼ばれる仮想化技術で、ソフトウェア実行環境の可搬性を高めるものです。今回のアプリケーションでもDockerイメージを利用し、設定などを行わずにアプリケーションを実行できます。また、IRISもDocker版を提供しています。Windows、Linux、macOS各OS用にDockerのエンジンがあるのでインストールしてください。また、複数のコンテナを制御するためにdocker-composeコマンドも使用するので、そちらもインストールしてください。
Webブラウザは、Chrome、Firefox、Safariで動作確認しています。
最後に、Google Cloud Platform(GCP)のMaps JavaScript APIのキーです。今回のアプリケーションでは、車の位置情報を元にGoogle Map上にプロットを行なっています。プロットを行うためには、GCPでキーを取得する必要があります。本原稿の執筆時点では月$200の無料クレジットがあり、本アプリケーションが利用するDynamic Mapsは無料枠内で最大28000回の読み込みが可能とのことです。地図へのプロットなしでもアプリケーションは動作しますが、ぜひキーを取得して試していただければと思います。
詳細は、GCPのページを参照してください。
アプリケーションの構成
アプリケーションの全体構成を図に示します。
4つのDockerイメージでアプリケーションが構成されています。各イメージから1つずつコンテナを生成して動作します。
IRIS Data Platform
IRISの基本イメージに今回のアプリケーションコードを組み込んだものです。
MQTT Broker mosquito
MQTTブローカ には、Eclipse Mosquittoを使用します。MQTTはIoTやM2M(machine-to-machine)で活用される軽量プロトコルです。MQTTではセンサーなどからの情報をPub/Subメッセージングモデルで交換します。センサーなどは「トピック」と呼ばれるデータとともに情報を発信(Publish)します。データの受け取り側は処理したい「トピック」を購読(Subscribe)し、必要なデータのみを受信します。その仲立ちをするのがブローカです。
Data Generator
実際には車載器からの情報はリアルタイムに送信されますが、今回のアプリケーションではデータをCSVファイルの形で保持し、それを1秒に1回MQTTでPublishするプログラムを用意しました。それをData Generatorと呼ぶことにします。プログラムはPythonで記述しました。
node
Node.jsはJavaScriptの実行環境として開発者の方にはおなじみのものと思います。今回は、Webブラウザへのコンテンツを提供するためだけに使用します。本格的なアプリケーションを書く場合には、nodeとAngularを組み合わせるといった発展が考えられます。
実行手順
それでは実行手順を説明します。
まず、作業ディレクトリを決めてください。本稿では、仮にDriveDemoとします。
GitHubからアプリケーションのPull
DriveDemoディレクトリでGitの初期化を行います。
>git init
次にGitHubからソースコードなどをpullします。
>git pull https://github.com/mhoritaisj/DriveDemo.git
そうすると、DriveDemoディレクトリにアプリケーションが展開されます。ディレクトリ構造は以下のようになっています。
DataGenerator
- Python環境をビルドするためのDockerfile
- CSVファイルからMQTTメッセージをPublishするPythonプログラム
- CSVファイル(14台分)
- Pythonプログラムを実行するスクリプト
が含まれています
├── DataGenerator │ ├── Dockerfile │ ├── code │ │ └── gen_drivedata.py │ ├── data │ │ ├── drivedata1.csv … │ ├── run.bat │ └── run.sh
IRIS-MQTT
- InterSystems IRIS Data Platform, Community Edition上で作成した今回のアプリケーションが含まれるイメージをビルドするためのDockerfile
- IRISで定義されたクラス定義
などが含まれます。
├── IRIS-MQTT │ ├── Dockerfile │ └── projects …
MQTTBroker
Eclipse Mosquittoのconfファイルがあります。
├── MQTTBroker │ └── conf │ └── mosquitto.conf
WebServer
- Node.jsのイメージを元に、今回のアプリケーションの画面を生成するhttpサーバをビルドするためのDockerfileとJavaScriptファイル(server.js)
- アプリケーションのテンプレートとなるHTMLファイル
などがあります。
├── WebServer │ ├── Dockerfile │ ├── main.html │ ├── package.json │ └── server.js ├
GitHubのルートには、
- アプリケーション全体をビルドするためのymlファイル
- アプリケーションを実行するためのスクリプト
があります。
── docker-compose-demo.yml ├── docker-compose.yml ├── rundemo.bat └── rundemo.sh
Maps JavaScript APIキーの設定
GCPのMaps JavaScript APIキーを取得した方は、キーを「WebServer/apikey.txt」にテキストファイルとして保存してください。WebServerのDockerイメージビルドの際に、このファイルの内容を読み込んでHTMLファイルを生成します。
アプリケーションの起動
Linux, macOSの場合 >./rundemo.sh Windowsの場合 >rundemo.bat
を実行します。このスクリプトでは、各Dockerイメージをビルドし、起動してコンテナを生成します。初回の実行の際は、手元にないDockerイメージのダウンロードやビルドが実行されます。
最後に、
Creating network "drivedemonw" with driver "bridge" Creating webserver ... done Creating iris-drive-demo ... done Creating mosquitto ... done
と出力されれば成功です。
>docker-compose ps
でコンテナの稼働状況が確認できます。以下のとおり表示されれば正常です。
Name Command State Ports -------------------------------------------------------------------------------------------------------------------- iris-drive-demo /iris-main Up (healthy) 0.0.0.0:51003->51773/tcp, 0.0.0.0:52003->52773/tcp mosquitto /docker-entrypoint.sh /usr ... Up 0.0.0.0:1883->1883/tcp, 0.0.0.0:9001->9001/tcp webserver node server.js Up 49160/tcp, 0.0.0.0:49160->8080/tcp
Webページの表示
起動に成功したらWebページを開きます。Webブラウザで「http://localhost:49160」を開くと上に示した画面が表示されます。
データの生成
車載器のデータを1秒ごとにMQTTにPublishするプログラムを動かします。
>cd DataGenerator Linux, macOSの場合 >./run.sh Windowsの場合 >run.bat
以下のように表示されれば、正常にデータがPublishされています。
Connected : code: 0 Connected : code: 0 Connected : code: 0 Connected : code: 0 Connected : code: 0 Connected : code: 0 Connected : code: 0 Connected : code: 0 Published: 1 Published: 1 Published: 1 Published: 1 Published: 1 Published: 1 Published: 1 Published: 1 …
データは長いもので90分以上あります。途中で止めたい場合はCtrl-Cで中断してください。再度はじめから実行する場合は、もう一度コマンドを実行してください。
Web画面
先ほど起動したWebブラウザの中央にあるグリッドに、14台の車の情報が1秒おきに更新される様子を見ることができます。
ここでいくつかのデータ項目について簡単に説明します。
方位は真北を0°とし時計回りに359.9°までの範囲で車が向いている方角を表しています。また、前後、左右、上下の加速度は単位mG(=0.001G: 1G=9.880665m/s^2)で、車にかかる加速度を表します。
- 前後は加速時に+、減速時-
- 左右は左折時+、右折時-
- 上下は重力方向が+、車がはねた場合-
となります。上下加速度は、常に重力加速度がかかっているため、+1000前後の値となっています。
車のスタート時にはGPSからの情報が取れないため、地図へのプロットが行われません。スタートして十数秒後から、順次車の情報が地図上にプロットされます。また、途中トンネルなどでGPS情報が取れない場合、一時的にプロットがなされないことがあります。
元の車載器データには、燃料の噴射量など興味深いデータが他にもあるのですが、今回は簡単のため以上のデータ項目のみを取り上げています。
画面の一番下には、車に発生したさまざまな「イベント」が表示されます。ここでいう「イベント」とは次の事象を言います。
- 直近5秒間の平均速度が100km/hを超える場合
- 直近のエンジン回転数が3000rpmを超える場合
- 直近の前後加速度の絶対値が300mGを超える場合
- 直近の左右加速度の絶対値が200mGを超える場合
これらのイベントが発生したら、その車のIDとともに表示されます。これらの閾値はあくまでも簡易的なものですが、IRISがこれらのイベントをリアルタイムに検知し、それをMQTTでPublishする機能を持っている点が重要です。
IRIS内で実行されていること
アプリケーションが動くところを見て、とても面白いと思っていただけたでしょうか? しかし、そう思った方も、IRISが一体何をどう処理しているのだろうという疑問を持たれるのではないでしょうか。
この連載を通して、その疑問に答え、IRISによるアプリケーション開発を体験していただく訳ですが、今回はポイントとなる部分をいくつか紹介したいと思います。
IRIS管理ポータル
IRISには、さまざまなツールが付属しています。その一つが、ここで紹介する管理ポータルと呼ばれるWebベースのツールです。
Webブラウザから「http://localhost:52003/csp/sys/UtilHome.csp」を開いてください。ユーザ名とパスワードを聞かれるので、ここでは、それぞれ「SuperUser」「driveuser」と入力してください。
そうすると次のような画面が表示されます。
管理ポータルは、IRISの設定を行ったり、状態のモニターを行ったりするツールです。この連載でも度々使用するので、管理ポータルのアクセス方法はぜひ覚えておいてください。
インターオペラビリティ
IRISにはインターオペラビリティ(interoperability:相互運用性)の機能が内包されています。
複数のシステムが連携して動作する仕組みにおいて、あるシステムで発生したデータを、どのように変換・収集し、一貫性のあるデータベースを構築するか、またそのようなデータを他のシステムに変換・送信するかは非常に重要な機能です。そのような機能を一般にインターオペラビリティと呼びます。IRISは、さまざまなデータ形式やネットワークプロトコルに対応するアダプタを装備し、また、処理されるデータをメッセージとしてトレースする機能を持つなど、インターオペラビリティを必要とするアプリケーションの開発を強力にサポートします。
今回取り上げている車載器のデータをMQTTで受信する仕組みも、IRISのインターオペラビリティ機能を活用しています。ここでは、その一端をご覧いただきたいと思います。
管理ポータルで、[Interoperability]-[表示]-[メッセージ]の順にクリックしてください。そうすると、次のような画面が表示されます。
ここには、MQTTで受信した車載器のデータをメッセージとして処理した記録が一覧表示されています。例えば、セッションと書かれたカラムの数字を1つクリックしてみると次のような画面が表示されます。その際、右側ペインの「内容」タブを選択してください。
この画面の例では、左上の矢印に「EDI.XMLDocument」というメッセージが処理された時刻が表示され、右ペインにその内容が示されています。内容には、車載器の情報の各項目がXMLタグ形式で記録されています。
メッセージの流れの中ほど(「CarUpdateRequest」と書かれたメッセージ)には、車載器のデータをもとにデータベースを更新する処理が示されています。
そして、メッセージの流れ右下部分には、このデータで示される運転状況が、上で説明したイベント発生条件に該当しないかを確認する処理の流れが記録されています。次の図のように、この車載器情報でイベントは発生していないことが表示されています。
ここで、メッセージの内容には、
<hasEvent>false</hasEvent>
と記録されていることをご確認ください。
メッセージ一覧画面から分かるように多くのメッセージが記録されており、この中から条件を指定してメッセージを検索する機能もあります。
では、イベントが発生したデータのメッセージを検索し、確認してみましょう。
次の図に示すように、メッセージ一覧の画面左側、「基本条件」の「タイプ」で「すべて」を選択し、「追加条件」で「条件の追加」をクリック、ダイアログにおいて、
- 「条件タイプ」:「ボディ・プロパティ」
- 「クラス」:「DriveDemo.Response.CheckDriveResponse」
- 「IF」:hasEvent = 1
をセットし「OK」を押します。一覧に戻ったところで、上にある「検索」をクリックします。
そうすると、先ほどと同様、メッセージの一覧が表示されますが、これらは指定した条件にマッチするメッセージです。セッションカラムから数字を1つクリックしてみてください。
先ほどのように、「CheckDriveResponse」とラベルの付いたメッセージを確認すると今回は、
<hasEvent>true</hasEvent>
となっており、MessageTextタグに平均速度が100km/hを超えていることが表示されています(次図)。また、イベントが発生した場合は、その後にメッセージが送信されていることも分かります。これは、MQTTにイベント発生をPublishしている部分で、このメッセージ送信によってアプリケーションの画面下側にイベントが表示される仕組みになっています。
まとめ
今回は「まずは動かしてみよう」をテーマに、IRISで開発したIoTアプリケーションについてご紹介しました。
車載器のデータをMQTTプロトコルで受信し、車の位置をWeb画面の地図にリアルタイムでプロットしたり、発生したイベントを表示したりする様子をご覧いただきました。
アプリケーションは複数のDockerコンテナが連携して動作し、簡単なコマンドで皆様のお手元のPCで実行できることを体験していただけたと思います。
また、このアプリケーションを実現するために、IRISのインターオペラビリティ機能を活用している点を説明しました。一見すると発生したデータを単に表示させているように見えますが、その裏側ではリアルタイムのデータがメッセージ形式で流れ、データベースへの記録やイベントの検出などの処理がトレース可能な形で実行されていることが確認できました。
次回以降、このアプリケーションを開発する手順について説明しながら、IRISによる開発を体験していただく予定です。