はじめに
新型コロナウイルス対策として密集した場所を回避したいと思う方も多いと思われますが、その場所にどのくらい人がいるのか、遠隔からわかる仕組みには試行錯誤が続いています。
今回は、人の混雑度を間接的に測定する方法として、BLE(Bluetooth Low Energy)のアドバタイズメントパケットの仕組みを応用する方法を考えます。また、測定するアプリの作成を通して、RedMobileというAndroidOS上でNode-REDの使用方法についてもお伝えします。
密集度を測定するアイディア
BLEは、様々な機器どうしが通信するために使われる通信プロトコルです。自分の存在を周囲に伝えるためにアドバタイズメントパケットという信号を送り続けています。つまり、スマホを持った人間が増えれば、このBLEのアドバタイズメントパケットが増えるという想定です。しかし、BLEはスマホ以外にも様々な機器に使われています。そこで、今回は接触確認アプリで使われているアドバタイズメントパケットの数を数えることにより、その周辺に何人の人々がいるのかという推定に使うことにします。測定のイメージは以下の通りです。
パケットの判定方法は、 プロトコルデータユニット内のデータの先頭から7バイト(下図の赤枠部分)を比較してアプリが発信するパケットかどうかをチェックして行います。
「Exposure Notification Bluetooth Specification」より引用
接触確認アプリのパケットはプロトコルデータユニット内のアドレスが動的に生成される乱数アドレスになっており、個人を特定することはできません。密集度だけを知りたい場合は好都合です。
密集度を捉える実験アプリの作り方
今回は実験なので、自分のスマホで捉えられる範囲で密集度を測定するアプリケーションを作成します。Node-REDで作ってみたいと思います。
Node-REDのフローをダウンロードする
今回使用するフローは以下の通りです。デスクトップにフローが定義されたjsonファイルをダウンロードしておいてください。フローの解説は本記事の最後に記載していますのでそちらをご覧ください。
RedMobileを設定する
- AndroidのスマホにRedMobileをインストールします。※無料版のRedMobile LiteにはBLEのノードがありません今回は有料版のRedMobileが必要です。
- インストールが終わりましたら、RedMobileアプリを起動します。
- UsernameとPasswordを設定する。設定しない場合、ログイン画面無しでアクセスできてしまうので必ず設定してください。
- KeeepAwakeをONにするとバックグラウンドでも動作できるようになります。
Ambientのチャンネルを作る
可視化のために今回はAmbientというサービスを使用します。アカウントをお持ちでない方は作成してください。
- Ambientにログインします。
- Ambientのチャンネルを作ります。
- WriteKeyとChannel IDを控えておきます。
Ambientでチャートを作る
チャンネルを作成したら、チャンネルにチャートを追加します。
- グラフ名:Exposures Notification(任意)
- グラフ種類:折れ線グラフ
- グラフサイズ:mediur(任意)
- 軸
- d1:左軸(アプリのパケット数)
- d2:右軸(全てのアドバタイジングパケット数)
- 最大最小値や表示件数は任意で設定してください。
RedMobileでNode-REDを起動する
- Startボタンを押します。
- 表示されたURLをクリックします。
- RedMobileからブラウザに遷移し、Node-RED画面にアクセスします。
フロー編集画面でWrite KeyとChannel IDを書き換える
控えておいたライトキーとチャンネルIDをNode-REDフローに入力します。
- Changeノード「Ambient用データ生成」の[writeKey]をAmbient側にあわせて編集します。
- HTTPノード「AmbientへPOST」の[channelId]の部分をAmbient側にあわせて編集します。
スマホを横画面にするか、HDMI経由モニタに接続して作業した方が楽だと思います。
RedMobileのDashboardで閲覧する
RedMobileアプリに戻り、左上のメニューからDashboardを選択します。
測定を開始するには、トグルボタンのscanをONにします。暫くすると、測定結果が反映されます。
以上で、密集度を測定するためのモバイルアプリの完成です!
RedMobileを活用すると、思った以上に簡単にアプリができますね。
測定
実際に街に出て測定してみました。パケット数はAmbientにもデータを送信しているので、データをダウンロードすることも可能です。
赤グラフは全てのアドバタイズメントパケット数(右縦軸)青グラフはアプリのパケット数(左縦軸)を表します。
都内オフィス
10時前後に出社する人が多いのかパケット数が増えているのがわかります。
アプリのパケット数と全てのアドバタイズメントパケット数の比率は1:10程度でした。
某飲食店
12時ごろから人が増えていることがわかります。
アプリのパケット数と全てのアドバタイズメントパケット数の比率は1:5程度でした。
某カフェ
8:50ごろに4人グループと2人グループの客が帰っていた様子が見て取れます。
アプリのパケット数と全てのアドバタイズメントパケット数の比率は1:4程度でした。
考察
人数の増減に比例してアプリパケット数が増減していることがわかるので、密集度の参考指標にはできそうと思われます。しかし、アプリの普及率が100%にならない限り絶対的な密度は測定できないことは制約として理解しておく必要がありそうです。
アプリのパケット数と全てのアドバタイズメントパケットの比が場所により異なるので、場所による普及率に偏りが少ない場合Aの場所よりBの場所のほうが人の密度が高いなどの相対的な情報は得られる可能性があり、その場所の密集に関する特徴を捉えることにも応用できそうです。
おわりに
今回は、スマホをセンサに見立てて、BLEのパケット数を測定し、密集度測定ができそうかにチャレンジしました。同じ仕組みが増えれば、遠隔から密集度がわかる日が来るかも知れません。
Node-REDを使えば簡単にアプリを作って、自分のアイディアを確かめることができます。今回はRedMobileというスマホでNode-REDを使う方法をご紹介しました。enebularでもNode-REDアプリを簡単に作ることができますので、ご興味を持った方はぜひチャレンジしてみてください。
フローの解説
ここでは、ノード全ての解説は割愛しますが、パケット数をカウントする部分について説明します。
Changeノード「set msg.allpackets」は全てのパケット数をmsg.allpacketsプロパティに追加しています。 | |
パケットはmsg.payload[]に配列型で格納されています。
Node-REDはJSONata式をサポートしており、$countは配列の要素数を返す関数です。その値をそのままmsg.allpacketsプロパティに追加しています。 |
|
Changeノード「set msg.enspackets」はアプリのパケット数をmsg.enspacketsプロパティに追加しています。 | |
パケットのプロトコルデータユニット内のデータはmsg.payload[].advertisementに文字列型で格納されています。
$substringは第二引数の位置(先頭は0)から第三引数の分を第一引数から返す関数です。先頭から7文字を比較して該当するmsg.payload[]の数を$count関数でカウントしてmsg.enspacketsプロパティに追加しています。 Node-REDではついfunctionノードを使いがちですがJSONata式で済ませることができることも多いと思いますので、参考になればと思います。 |