Armadillo-IoTを使い、データをクラウド上のサーバーにアップロードするサンプルアプリケーションを動かし、IoTの基本部分を体験してみましょう。
サンプルアプリケーションは、Armadillo-IoT上で動作するクライアントサイドアプリケーションとクラウドプラットフォーム上で動作するサーバーサイドWebアプリケーションの2つのアプリケーションから構成されています。サンプルアプリケーションは、Armadillo-IoT(クライアント)からデータをサーバーにアップロードする機能と、サーバーからクライアントに対して操作指示(Push通知)を行う機能の二つを備えています。
クライアントからサーバーへのデータアップロードの例として、Armadillo-IoTが本体の状態監視用に内蔵している温度センサの値をアップロードします[]。また、サーバーからのPush通知の例として、ブラウザに表示されたボタンをクリックすると、その状態(ONまたはOFF)をArmadillo-IoTに通知します。
クライアントサイドアプリケーションは、Rubyのコンソール(CLI)アプリケーションとして実装されています。実装を簡単にするために、Ruby用ライブラリの一般的な配布形式である、gem[]をいくつか使用しています。データのアップロードはREST API(HTTP POST)で行うため、rest-clientを使用します。また、サーバーからのPush通知にはPusher[]を使用しているため、pusher-clientを使用します。
サーバーサイドWebアプリケーションは、クラウドアプリケーション開発プラットフォームのHeroku上で動作しています。Node.jsで実装されており、クライアントサイドアプリケーションからのデータを受信するとデータベース(PostgreSQL)に格納します。格納したデータは、Webブラウザからリアルタイムに変化を確認できるようになっています。また、ブラウザ上に表示されたボタンをクリックすると、それがクライアント(Armadillo-IoT)への操作指示として、Push通知されるようになっています。
| REST API |
---|
REST(REpresentational State Transfer)は、WebアプリケーションのAPIに関するアーキテクチャスタイル(設計思想)の一つです。
ネットワーク上のリソースに対し一意のURIを割り当て、リソースに対する操作をHTTP GET(取得)/POST(新規作成)/PUT(更新)/DELETE(削除)で行います。RESTの原則に従いAPIを設計すると、クライアントからのリクエストをステートレスにできるため、サーバー側の実装をスケールアウトしやすいと言われています。サンプルアプリケーションでは、時々刻々と変化する温度センサデータのアップロードは、常にリソース(温度データの時系列情報)の新規作成となるためHTTP POSTで行っています。
なお、厳密にはREST原則に従っていないAPIもREST APIと称することが多くなっているため、原則に忠実に従って設計されたAPIのことを、RESTful APIということもあります。
|
| Heroku |
---|
Heroku(ヘロク)は、Webアプリケーションの開発、公開が簡単に行えるクラウド上のプラットフォームです。
一昔前のWebアプリケーション開発現場では、まず開発環境にLinuxやApache、MySQL、PHP(LAMP)をインストールして開発を行い、開発がうまくいったら公開用のサーバーを購入するなり、レンタルサーバーを借りるなりして、また色々インストールして、一般公開するためにドメインを購入して、というようにアプリケーションの実装以外に多くの付随する作業が必要でした。
Herokuを使うと、1. Herokuアカウントを作成する、2. アプリケーションを実装する(アプリケーションの実行に必要なサーバーやデータベースの設定は、Herokuのツールが面倒を見てくれるので、開発者は何を使うか指定するだけです)、3. サーバーに「push」する、という単純なステップで、アプリケーションを一般公開できます。また、サーバーで使用するCPUの数やメモリサイズ、データベース容量を動的に変更できるなど、急にアクセスが増えた場合でも、簡単にスケールアウトできるような仕掛けがなされています。
また、Webアプリケーションを開発する際に必要となる様々な機能が「アドオン」として用意されており、それらを活用することで、アプリケーションの本質的な部分に開発リソースを集中することができます。サンプルアプリケーションでは、データベースとしてPostgreSQLを、Push通知を行うためにPusherのアドオンを使用しています。
課金体系としてフリーミアムモデルを採用しており、一定時間までは無料で使用することができます。このことも、利用の敷居を下げる一因になっています。サンプルプログラムも無料枠の範囲内で運用しています。
|
| Node.js |
---|
Node.jsは、javascriptで構成されたサーバーサイドアプリケーションの開発フレームワークです。わざわざサーバーサイドと謳っているのは、Node.js登場以前は、javascriptはクライアント(ここではWebブラウザのことを意味します)上で動作するプログラムに使用することが一般的であったためです。
Node.jsが登場した背景には、10,000台のクライアントが一斉にWebアプリケーションにアクセスすると急激に性能が劣化する、いわゆるC10K問題と呼ばれる課題がありました。これは、それまでのWebアプリケーション開発フレームワークが、クライアントからのリクエストがあるたびに、プロセス(ないしはスレッド)を生成する構成になっていたため、接続が重複すると、サーバーのメモリを使い切ってしまう事が一因です[]。
Node.jsでは、非同期I/Oを活用し一つのプロセスで全てのリクエストを処理することで、この課題の解決を試みています。Webアプリケーションのサーバーサイドロジックが単純な場合、サーバーサイドアプリケーションはほとんどの時間、I/O待ちをしていることになります(CPU boundではなく、I/O boundな状態)。非同期I/Oを使うと、その間も他の処理ができるため、一つのプロセスで複数のリクエストを捌くことができるようになります。
例えば、APIをRESTfulにしておくと、HTTP POST(新規作成)リクエストは、クライアントから受けとったデータを(ほとんど何も処理せずに)DBに書き込むだけになり、HTTP GET(取得)はDBからデータを取得してレスポンスを返すだけになるため、I/O boundな状態となります。このようなアプリケーションの場合、Node.jsのアプローチは非常にうまくスケールします。サンプルアプリケーションはまさにこのような状況なため、Node.jsを使って実装しています。
反対に、Node.jsでは数値計算などが必要でCPU処理が長くなるアプリケーションには適しません。また、非同期I/Oを活用することで、必然的にイベント駆動型のプログラミングスタイルが強制されるため、複雑なロジックが必要なアプリケーションでは、それに応じてコードも複雑化しがちです。どのようなアプリケーションにも適しているわけではない点には注意が必要です。
|
クライアントから https://armadillo-iot-sample.herokuapp.com/api/series というURIに対して、下記の内容でHTTP POSTリクエストを発行すると、データが格納されます。
表4.1 POST時のQUERYパラメータ
パラメータ名 | 値 | 型 |
---|
uid | UID | character varing(制限付き可変長文字列) 255文字 |
latitude | 緯度 | double precision(8byte 浮動小数点) |
longitude | 経度 | double precision(8byte 浮動小数点) |
value | 摂氏温度 | real(4byte 浮動小数点) |
created_at | 温度取得時刻 | timestamp without time zone(日付と時刻両方、時間帯なし) |
token | トークンID("12345") | 文字列 |
uidは、重複しない値であれば何でも構いません。クライアントサイドサンプルアプリケーションでは、MACアドレスから「:」を抜いた文字列を使用します。サンプルアプリケーションは、実装の簡単な例を示すことを目的としているため、誰でもデータをアップロードし、閲覧することができます。tokenは、Armadillo-IoTのことを全く知らない人が、簡単にデータをアップロードできないようするための簡易的な仕掛けとして使用します。
データアップロードは単純なHTTP POSTリクエストですので、例えばcurlコマンドを使用し、下記のように実行することでも、データをアップロードすることができます[]。自分でクライアントアプリを実装する際の参考としてください。
サーバーからのPush通知は、下記のパラメータで行われます。
表4.2 Push通知パラメータ
パラメータ名 | 型 | 値 |
---|
チャンネル | 文字列 | UID |
イベント | 文字列 | "button" |
データ | JSON文字列 | {"value": "on"} か {"value": "off"} |
Armadillo-IoTに電源を投入する前に、USBシリアル変換アダプタのスライドスイッチを次のように外側になるようにしてください。[]
Armadillo-IoTに電源を接続すると、シリアル通信ソフトウェアには次のように表示されます。
Linuxシステムを起動するには、次のように "boot"コマンドを実行してください。コマンドを実行するとブートローダーがLinuxシステムを起動させます。シリアル通信ソフトウェアにはLinuxの起動ログが表示されます。
| |
---|
Linuxシステムの起動後に表示される次のメッセージは、エラーメッセージではありません。
このメッセージは、/dev/urandom が内部的に使用するプール領域の初期化完了を示します。
|
ここでは、rootユーザーでログインします。デフォルトのパスワードは、"root"となっています。
クライアントサイドサンプルアプリケーションを動作させるためには、次の項目を設定する必要があります。
Armadillo-IoTは、WAN用インターフェースとして、LAN、無線LAN、及びモバイル通信(3G)を備えています。ここでは、LANを使ってネットワークに接続する設定方法について説明します。無線LAN、3Gの設定方法や、LANの設定方法の詳細については、製品マニュアルを参照してください。
Armadillo-IoTでは、通常のLinuxシステムと同様、ネットワークインターフェースの設定は/etc/network/interfaces
に記述します。Armadillo-IoTの出荷時の設定では、eth0(LANのネットワークインターフェース)が自動でupし、DHCPでネットワーク設定を取得するようになっています。
もし、固定IPに設定したい場合など、ネットワーク設定を変更したい場合、一度ネットワークインターフェースをdownしてから、設定を変更してください。
固定IP(IPアドレス: 192.0.2.100、デフォルトゲートウェイ: 192.0.2.1、サブネットマスク: 255.255.255.0)に設定する場合の記述例を下記に示します。
変更した設定は、ifupコマンドで反映されます。
DNSサーバーの指定は/etc/resolv.conf
に記述します。DNSサーバーのIPアドレスを192.0.2.2に設定する場合の記述例を下記に示します。
| |
---|
DHCP を利用している場合には、DHCP サーバーが DNS サーバーを通知する場合があります。この場合、/etc/resolv.conf は自動的に更新されます。
|
なお、この設定は再起動すると消えてしまいます 。これに限らず、Armadillo-IoTではルートファイルシステムのファイルに加えた変更は再起動すると全て元通りとなります。これは、Armadillo-IoTのユーザーランドがRAMDISK上にあるためです。これは、再起動すると必ず同じ状態で起動するという意味で組み込み機器としては必要な機能なのですが、毎回起動するたびに設定するのも面倒です。そのため、設定ファイル類だけはフラッシュメモリに永続的に保存できるようになっています。
それを行うためのコマンドが、flatfsdです。flatfsd -sと-sオプションを付けて実行することで、/etc/config
ディレクトリにあるファイルを、フラッシュメモリに保存します。実は/etc/network/interfaces
や/etc/resolv.conf
は、/etc/config
以下のファイルへのシンボリックリンクとなっています。そのため、/etc/network/interfaces
などに対して行った変更は、flatfsd -sコマンドを実行することで、フラッシュメモリに保存されます。保存されたファイルは起動時に自動で復元されるようになっているため、次回起動時は変更したネットワーク設定が行われるようになります。変更を消したくない場合は、flatfsd -sコマンドを実行することを忘れないでください。
サンプルアプリケーションで使用するデータの取得時刻には、クライアント側のシステムタイムを利用します。時刻が大幅にずれている場合には混乱を招く場合があるため、時刻を設定します。
ここでは、NTPクライアントを利用してシステムタイムをタイムサーバー[]と同期させます。ntpclientコマンドで時刻を設定し、dateコマンドで時刻が設定されたことを確認してください。
| 起動時に自動で時刻設定を行う |
---|
時刻設定のように起動するたびに毎回行う操作は、起動時に自動で行うように設定できます。Armadillo-IoTでは、/etc/config/rc.local がinitスクリプトの最後に実行されるようになっていますので、これを編集しntpclientコマンドを実行するように記述することで、起動時に自動で時刻設定されるようになります。
/etc/config/rc.local ファイルに対する変更も、そのままでは再起動すると消えてしまいますのでflatfsd -sコマンドでフラッシュメモリに保存するのを忘れないでください。
|
| 時刻の保持 |
---|
Armadillo-IoTでは、システムタイムをリアルタイムクロック(カレンダー時計)に保持することができます。リアルタイムクロックのバックアップ用電池を取り付けることで、電源を切っても時刻を保持し続けるようになります。この場合、起動するたびに時刻設定をする必要は無くなります。詳しくは、製品マニュアルを参照してください。
|
クライアントサイドサンプルアプリケーションを実行すると、デフォルトで設定されたURIに対してデータをアップロードし、サーバーからのPush通知に応じてコマンドを実行します。表4.1「POST時のQUERYパラメータ」で示したQUERYパラメータのうち、「latitude」、「longitude」については、東京周辺を指すようにランダムに生成されます。
クライアントサイドのサンプルアプリケーションと設定ファイルは、それぞれ http://armadillo-iot-sample.herokuapp.com/client/sample.rb と http://armadillo-iot-sample.herokuapp.com/client/config.json から取得します。
デフォルトでは、5秒間隔で10回データ送信を行います。--interval
オプションを指定することで送信間隔を、--times
オプションを指定することで送信回数を指定できます。(-1を指定すると、無制限にデータをアップロードし続けます。)
その他のオプションについては、helpを参照してください。
アップロードしたデータが反映されているか、Webブラウザで確認してみましょう。確認用URLは、クライアントサイドサンプルアプリケーション実行時のログに表示されています。
「top page」と表示されている行のURL (http://armadillo-iot-sample.herokuapp.com) にアクセスすると、地図アプリケーションが表示されます。Basic認証が掛かっていますので、ユーザー名「username」、パスワード「password」でログインしてください。
データが存在する場所には、ピンが立っています。ピンをクリックすると、UIDが表示されますので、自分のUIDと一致していたら「こちら」をクリックし、パーソナルページに移動してください。もし、自分のUIDを持つピンが見当たらなかったら、地図を広域表示にして探してください。詳細ページはクライアントサイドサンプルアプリケーションの実行ログの「personal page」と表示されている行のURLから直接アクセスすることもできます。
| ピンが見つからない |
---|
地図上のピンは、最新のデータがある位置を示しています。後から他の人がアップロードしたデータがたまたま同じ位置になってしまった場合、上書きされてしまいます。その場合は、再度クライアントサイドアプリケーションを実行して別の位置にピンを立てるか、パーソナルページに直接アクセスしてください。
|
パーソナルページには、現在の温度データを表示するメーター(左上)と、Armadillo-IoTへの操作指示を行うボタン(右上)、時系列を表示するグラフ領域(下)があります。
クライアントから温度データがアップロードされると、メーターの表示がリアルタイムに変化することを確認してください。また、グラフ領域上の日付ボックスでデータを表示したい日を選択すると、その日の温度変化が時系列グラフとして表示されます。
また、ボタンをクリックすると、クライアントにPush通知を行います。クライアントサイドサンプルアプリケーションのデフォルト設定では、シリアル通信ソフトウェアに"on"または"off"と表示するだけです。--command
でPush通知を受けたときに実行するコマンドを指定できます。value変数に"on"または"off"が格納されてコマンドが実行されます。ボタンの状態に応じてLED[]を点灯/消灯する場合の実行例を下記に示します。