English

チュートリアル - ANDROID-STEP2

目次

1. 概要
1.1 ネットワーク構成
1.2 前提条件
2. センサー情報収集アプリの導入
3. センサー情報収集アプリの操作
3.1 画面遷移
3.2 初期画面
3.3 設定画面
3.3.1 センサー情報配信用
3.3.2 SINETStream動作設定用
3.4 主画面
3.4.1 主画面の画面構成
3.4.2 センサー情報の配信処理
4. Android端末位置情報の設定
5. 運用ヒント
5.1 不安定な電波状況下でもブローカとの接続状態をなるべく維持する

付録
A.1 ソースコード
A.2 既知の問題

1. 概要

Android版の SINETStreamライブラリ および SINETStreamHelperライブラリ の使用例として、Android端末上の センサーデバイス の読取値をSINETStream経由で送信する「センサー情報収集アプリ」 (以降「本アプリ」と略記)を実装しました。 本書では、本アプリのAndroid端末への導入と設定、操作方法などについて 概説します。

1.1 ネットワーク構成

構成

本アプリは、Writer機能のみを具備します。 当該Android端末上で収集したセンサー値は SINETStreamHelperライブラリ によりJSON形式に成形されて本アプリ制御部に非同期通知されます。 これをSINETStreamメッセージとして対向のBrokerに送信します。

一方、Broker側では同メッセージ内容を解析してサーバ側のデータベースに蓄積するとともに、 Webインタフェースでグラフ化するという動作の流れになります。

またBrokerへの接続情報やSINETStreamの動作パラメータなどの諸元をGUI操作で設定し、その内容に応じてAndroid版の SINETStream設定ファイル を自動生成するための設定画面も用意してあります。

1.2 前提条件

2. センサー情報収集アプリの導入

現状では、本アプリはGooglePlayからではなくNII管理サーバから配布します。

別紙 Androidサンプルアプリケーションの導入 を参照して所用のものを導入してください。アプリ更新時も同様の手順です。

3. センサー情報収集アプリの操作

3.1 画面遷移

画面遷移

<凡例>

  1. Androidのホーム画面(a)にて、アイコンSensorを押下して本アプリを起動する。
  2. 起動画面(b)にて、アイコンと著作者を一瞬表示して初期画面(c)に遷移 する。
  3. 初期画面(c)にて、ボタンSettings押下により設定画面(d)に遷移する。
  4. 設定画面(d)にて、ボタンBACK押下により初期画面(c)に戻る。
  5. 初期画面(c)にて、ボタンRun押下により主画面(e)に遷移する。
  6. 主画面(e)にて、ボタンBACK押下により初期画面(c)に戻る。
  7. 初期画面(c)にて、ボタンBACK押下によりホーム画面(a)に戻る。

各画面の構成および操作詳細は後述します。

3.2 初期画面

初期画面

本アプリの起動直後に表示される初期画面です。

本アプリ導入直後のように、 SINETStream設定ファイル が存在していない、あるいは現在の設定内容が必須項目を満足していない場合、 Runボタンが無効化(灰色表示)され、画面下部にはユーザに対応を促すメッセージが表示されます。 このような場合、まずはSettingsボタンを押下してSINETStreamの動作環境設定操作を実行してください。

3.3 設定画面

設定画面はセンサー情報配信用、SINETStream動作設定用に分割されており、 それぞれ階層的に展開されます。

設定画面

3.3.1 センサー情報配信用

Android端末で収集したセンサー情報は、別紙 SINETStreamHelper#JSONデータ形式 で定義されたJSONデータ形式に成形されます。

上記JSONを構成するデバイス情報のうち、User InfoLocation(いずれも任意)は外部から指定する必要があります。

また、ネットワーク送出間隔Interval timerを指定可能(省略時は10秒)です。 この意図するところは以下の通りです。

動作中のセンサーデバイスの読取値はAndroidの SensorManager から非同期的に通知されますが、その契機はセンサー種別ごとにまちまち(継続的に出力されたり、値の変化時に出力されたりなど)であり、 複数のセンサー種別を同時に観測する場合は高頻度の通知となる可能性があります。 ネットワーク負荷を抑止するため、個々のセンサーデータは SINETStreamHelperライブラリ 内部に最新データとして蓄積しつつ、本アプリの設定画面で指定した標本化間隔を下回らない頻度でJSONデータを生成するようにしています。

    [SensorA] [SensorB]
       |         :
       +-----------------++---------------+
       |         :       ||               |
       |   ......:.......||...............|..
       |   :          :  ||   :    :      | :
       V   V          V  VV   V    V      V V

   ----o---x----------o--xx---x----o------x-x---------> t
       |<-------->|   |            |
       |    T         |<-------->| |
       V              |    T       |<-------->|
      JSON#1          V            |    T
                     JSON#2        V
                                  JSON#3

上図は、以下の2つの事象の時間関係を示しています。

  1. Androidシステム側からセンサー読取値(例としてA/Bの2種類)がSINETStreamHelperに通知される契機「o/x」
  2. 実際にJSONデータが生成される契機「o」

そもそも、個々のセンサー読取値の生起タイミングは一定周期ではありません。

契機「o」でJSONデータが生成されたとき、その時点から指定時間「T」が経過するまでの間に通知された契機「x」時点のセンサー読取値はJSON生成対象とせず、 センサー種別ごとの最新値として蓄積されます。

次にセンサー読取通知が発生した契機「o」の時点が「T」を超えている場合、 各センサー種別ごとの最新値(「o」および最後の「x」時点の値)を集計してJSONデータを生成します。

{
   ...
   "sensors": [
     { # Sensor A with a scalar value
         ...
         "timestamp": "20210101T012312.345+0900",  # Timing 'x'
         "values": 1
     },
     { # Sensor B with vector values
         ...
         "timestamp": "20210101T012345.678+0900",  # Timing 'o'
         "values": [
           1.0,
           -2.3,
           4.5
         ]
     }
   ...
   ]
}

すなわち、本アプリがBrokerに送信するSINETStreamメッセージの最小送信間隔は「T」(設定項目Interval timer)により律速されます。

3.3.2 SINETStream動作設定用

Android版の SINETStreamライブラリ を使うためには、 SINETStream設定ファイル を「対向Brokerとの接続条件に適合するよう」設定する必要があります。

このためGUI操作によるSINETStream設定画面(Settings)を用意しています。 本アプリ起動後の初期画面からボタンSettingsを押下して設定画面に遷移し、 (もろもろの設定操作を経て)初期画面に戻る際にSINETStream設定ファイルが自動生成されます。 既存の設定内容から変更が発生した場合は同設定ファイルが更新されます。

まずはBrokerと接続するため、以下の項目を必ず設定してください。 他の項目は放置で構いません。プログラム既定値が使われます。

このチュートリアルで例示したBrokerであれば以下のように設定することになります。 実際のBrokerのアドレスはお使いの環境に合わせてください。

Service Name Topic Name IP Address (or FQDN) Port Number
service-tutorial-mqtt sensor-data xx.xx.xx.xx 1883

ここでTopic Nameは通信チャネル識別子として使われる文字列です。 任意の値を指定して構わないのですが、特にSTEP2の使い方においては、 バックエンドシステムの都合上、予約語sensor-data指定して ください。 この予約語が後段処理に渡されるフィルターとなっているため、指定の 値と異なるとJSONデータがデータベースに蓄積されず、グラフ表示に 反映できません。

3.4 主画面

初期画面からボタンRunを押下して主画面(Main)を表示し、センサー情報の配信操作を実行します。

3.4.1 主画面の画面構成

画面中央がセンサー種別のリスト表示欄、画面下部の黒帯が統計情報表示パネル、 最下部の青帯が操作パネルという構成です。

主画面の画面構成

<凡例>

  1. センサー稼動状態表示
  2. センサー種別一覧
    • 当該Android端末で実装されているセンサーデバイスの種別一覧が列挙される。
    • チェックボックスで操作対象のものを選択すると、画面下部の配信動作ボタンが操作可能になる。
  3. 配信動作(RUN/STOP)切換ボタン
    • 初期状態で無効。センサー種別が選択されると有効となる。
    • RUNボタンを押下すると、実際にセンサー情報の取得および対向Brokerへの周期的なメッセージ送信が開始される。
    • 誤操作を避けるため、配信動作中はセンサー種別の追加的な選択/解除操作が抑止される。
    • STOPボタン押下によりセンサー情報の配信が停止するとともに、センサー種別を再び選択/解除できるようになる。
  4. 統計情報表示欄
    • センサー情報の配信中は「送信時刻、送信メッセージ数」が随時更新される。
  5. 統計情報のリセットボタン
    • センサー情報の配信中は無効となる。

3.4.2 センサー情報の配信処理

センサー情報の配信処理は以下のように制御されます。

主画面の状態遷移

<凡例>

  1. 主画面を起動後にセンサー種別を指定(a)し、RUNボタン押下で実行開始。
  2. 実行中(b)は統計情報が随時更新される。STOP後も値は保持。
  3. 待機中(c)はリセットボタン押下により統計情報を再初期化できる。
  4. 前回実行時の統計情報を維持したまま、次の実行を開始しても良い。

4. Android端末位置情報の設定

利用者によっては、本アプリで配信するJSONデータにAndroid端末の位置情報を埋め込みたい用途があると思います。 当該Android端末を固定的な場所に設置して運用する場合、既知の位置情報(緯度、経度)を手動で設定できます。 あるいはそのAndroid端末を移動しながら運用する場合、位置情報の自動更新モードを有効にすると便利です。

本件の詳細に関しては別紙 端末位置情報の自動更新 を参照してください。

5. 運用ヒント

5.1 不安定な電波状況下でもブローカとの接続状態をなるべく維持する

移動体通信の宿命として、電波受信状況は時々刻々と変動します。 すなわち、対向ブローカとの接続を確立しても、状況次第でメッセージやりとりが滞ることは有り得ます。さらには相手側無応答により接続が切られるかもしれません。

前述の通り、Android版の SINETStreamライブラリ は、足回りのメッセージングシステムとして MQTT(Eclipse Mosquitto) のAndroid版クライアントライブラリ Paho Android Service を用いています。このMQTTクライアントライブラリの機能の一つとして、対向ブローカとの通信状態の監視があります。

MQTTクライアントライブラリが対向ブローカとの何らかの通信異常を検出した場合、直ちにプログラムを異常終了させることが本アプリの既定動作です。 しかしながら、MQTTクライアントライブラリ使用上の工夫(具体的にはMQTT接続オプション MqttConnectOptions の調整)により、通信路障害に対してある程度の抗堪性を確保することが可能です。 以下の各項目を試してみてください。

項番 手法 期待される効果 設定方法
1 MQTTの自動再接続を有効にする ブローカとの接続断を検出したら、再接続試行を繰り返す Settings -> MQTT -> MQTT Connect -> Enable Automatic Reconnect
2 ブローカ死活監視のタイムアウト値を延長する 一時的な通信路障害に対して鈍感にする Settings -> MQTT -> MQTT Connect -> Keep Alive Interval
3 ブローカ接続完了待ちのタイムアウト値を延長する 同上 Settings -> MQTT -> MQTT Connect -> Connection Timeout
4 MQTTのメッセージ送信待ち行列を有効にする 送信要求に対する応答を待たずに次を送信可能とする Settings -> MQTT -> MQTT Protocol -> MQTT InFlight -> Enable Max InFlight Messages
5 MQTTのメッセージ送信待ち行列の枠を拡張する 一時的な帯域不足による滞留を吸収する Settings -> MQTT -> MQTT Protocol -> MQTT InFlight -> InFlight

なお、上記MQTT接続オプションの工夫によっても救済できない場合は存在します。

また、項番4および5で設定した送信待ち行列の枠を使い切った場合、以降の送信要求は無視されます。この枠に空きが出れば、本アプリはまた送信要求を発行できるようになります。

付録

A.1 ソースコード

本アプリのソースコードは GitHub で公開しています。 もし何か不具合がありましたら連絡いただけると助かります。

ソース修正が必要な方は、Android開発環境 Android Studio をお手元の機材に導入して、上記ソースコードを取り込んでください。

A.2 既知の問題