チュートリアル - 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 前提条件
-
Android端末の動作環境
- Android 8.0(APIレベル26)以上であること
- Android版の SINETStreamライブラリ は、足回りのメッセージングシステムとして MQTT(Eclipse Mosquitto) に対応しています。
- MQTTのAndroid版の実装である Paho Android Service ライブラリを利用しており、この動作条件(Android8.0以上)の影響です。
- Android 8.0(APIレベル26)以上であること
-
バックエンドシステムの事前準備
- 本チュートリアルでは、MQTTの
Broker
に後処理を組み合わせます。 - バックエンド側のホストサーバにて、
docker run
コマンドにより本チュートリアル用のコンテナイメージの導入とサーバプログラム群の起動を実施します。 Android側の作業着手前にこちらを済ませてください。 - 手順詳細は、前項に戻り 3.1 バックエンド側の作業 (その1) を参照ください。
- 本チュートリアルでは、MQTTの
-
ネットワーク環境
- 本アプリを実行するAndroid端末と
Broker
とはIP(Internet Protocol)ネットワークで接続されます。 携帯電話網やWi-Fiを介して両者のIP疎通を確保してください。
- 本アプリを実行するAndroid端末と
2. センサー情報収集アプリの導入
現状では、本アプリはGooglePlayからではなくNII管理サーバから配布します。
別紙 Androidサンプルアプリケーションの導入 を参照して所用のものを導入してください。アプリ更新時も同様の手順です。
3. センサー情報収集アプリの操作
3.1 画面遷移
<凡例>
- Androidのホーム画面(a)にて、アイコン
Sensor
を押下して本アプリを起動する。 - 起動画面(b)にて、アイコンと著作者を一瞬表示して初期画面(c)に遷移 する。
- 初期画面(c)にて、ボタン
Settings
押下により設定画面(d)に遷移する。 - 設定画面(d)にて、ボタン
BACK
押下により初期画面(c)に戻る。 - 初期画面(c)にて、ボタン
Run
押下により主画面(e)に遷移する。 - 主画面(e)にて、ボタン
BACK
押下により初期画面(c)に戻る。 - 初期画面(c)にて、ボタン
BACK
押下によりホーム画面(a)に戻る。
各画面の構成および操作詳細は後述します。
3.2 初期画面
本アプリの起動直後に表示される初期画面です。
Run
ボタン- 本アプリの主画面
Main
を起動する - 主画面の処理が終わると、この初期画面に戻る
- 本アプリの主画面
Settings
ボタン- 本アプリの設定画面
Settings
を起動する - 設定画面の処理が終わると、この初期画面に戻る
- 本アプリの設定画面
- メニューボタン
- 画面上部のタイトル右端の「縦3つの点」を押下すると、メニューが展開される
Help
:ヘルプ表示About
:このアプリについて
- 画面上部のタイトル右端の「縦3つの点」を押下すると、メニューが展開される
本アプリ導入直後のように、
SINETStream設定ファイル
が存在していない、あるいは現在の設定内容が必須項目を満足していない場合、
Run
ボタンが無効化(灰色表示)され、画面下部にはユーザに対応を促すメッセージが表示されます。
このような場合、まずはSettings
ボタンを押下してSINETStreamの動作環境設定操作を実行してください。
3.3 設定画面
設定画面はセンサー情報配信用、SINETStream動作設定用に分割されており、 それぞれ階層的に展開されます。
3.3.1 センサー情報配信用
Android端末で収集したセンサー情報は、別紙 SINETStreamHelper#JSONデータ形式 で定義されたJSONデータ形式に成形されます。
上記JSONを構成するデバイス情報のうち、User Info
とLocation
(いずれも任意)は外部から指定する必要があります。
- User Info
- 本アプリを実行する複数のAndroid端末群が同じトピック名で
Broker
に接続する場合、送信者の識別情報があると便利。 - 子要素の
Publisher
に送信者情報、Notes
に補足情報をそれぞれ指定する。
- 本アプリを実行する複数のAndroid端末群が同じトピック名で
- Location
- 本アプリを実行するAndroid端末の位置情報(緯度、経度)を指定する。
- v1.5では初期値の手動設定を想定する。自動設定と更新には未対応。
また、ネットワーク送出間隔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つの事象の時間関係を示しています。
- Androidシステム側からセンサー読取値(例としてA/Bの2種類)が
SINETStreamHelper
に通知される契機「o/x」 - 実際に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
と接続するため、以下の項目を必ず設定してください。
他の項目は放置で構いません。プログラム既定値が使われます。
- サービス名:
Service -> Service Name
- トピック名:
Service -> Topic Name
Broker
接続情報(アドレス、ポート)Brokers -> IP Address (or FQDN)
Brokers -> Port Number
このチュートリアルで例示した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 主画面の画面構成
画面中央がセンサー種別のリスト表示欄、画面下部の黒帯が統計情報表示パネル、 最下部の青帯が操作パネルという構成です。
<凡例>
- センサー稼動状態表示
- 星のアイコンは、
SINETStreamHelperライブラリ
内部の
SensorService
が稼働中であることを示す。
- 星のアイコンは、
SINETStreamHelperライブラリ
内部の
- センサー種別一覧
- 当該Android端末で実装されているセンサーデバイスの種別一覧が列挙される。
- チェックボックスで操作対象のものを選択すると、画面下部の配信動作ボタンが操作可能になる。
- 配信動作(RUN/STOP)切換ボタン
- 初期状態で無効。センサー種別が選択されると有効となる。
RUN
ボタンを押下すると、実際にセンサー情報の取得および対向Broker
への周期的なメッセージ送信が開始される。- 誤操作を避けるため、配信動作中はセンサー種別の追加的な選択/解除操作が抑止される。
STOP
ボタン押下によりセンサー情報の配信が停止するとともに、センサー種別を再び選択/解除できるようになる。
- 統計情報表示欄
- センサー情報の配信中は「送信時刻、送信メッセージ数」が随時更新される。
- 統計情報のリセットボタン
- センサー情報の配信中は無効となる。
3.4.2 センサー情報の配信処理
センサー情報の配信処理は以下のように制御されます。
<凡例>
- 主画面を起動後にセンサー種別を指定(a)し、RUNボタン押下で実行開始。
- 実行中(b)は統計情報が随時更新される。STOP後も値は保持。
- 待機中(c)はリセットボタン押下により統計情報を再初期化できる。
- 前回実行時の統計情報を維持したまま、次の実行を開始しても良い。
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 既知の問題
-
情報セキュリティ機能の実装状況
機能項目 実装状況 ユーザ認証 済み SSL/TLS通信 済み データ暗号化 開発中 -
GUIの設定画面とSINETStream設定ファイルの対応
- 実装の都合上、GUIの設定画面での対応項目は SINETStream設定ファイル を網羅しておらず、サブセットとなります。