こちらはSORACOM Arc ブログコンテストへの応募記事です。
はじめに
探し物は何ですか?
見つけにくいものですか?
自部署エリア内も、
他部署で使ってそうなところも、
共用設備を管理してる場所も、
いろんな実験室も、
工場のラインも、
普段行かない謎の倉庫も、
探し回ったけれど見つからない。
いったいどうすればいいんだ。
どうすれば。。
ということで今回のテーマは会社における設備捜索です。
ビジネスにおいて何かを探している時間というのはけっこう大きいらしく、年間150時間程度という話もあります。(リズ・ダベンポート『気がつくと机がぐちゃぐちゃになっているあなたへ』より)150時間といえば一ヶ月くらいの時間(8時間×18.75日)なので、なかなか馬鹿にならないですよね。
特に共用で使っている設備はいろんな人が使う関係上、いつの間にかどこかへ行ってしまっている、ということはないでしょうか。そしていざ使う時や、固定資産棚卸しの際になかなか見つからなくて苦労します。使う可能性がある人が多いと探すのも大変なんですよね。
もちろんそうならないように設備管理システムに入力するとか、貸出帳に記録するとか、又貸し禁止するとか、色々対策はするんですが、使ってる間に設備の置き場所が変わったり異動で管理者変わったりとかで、確実に追えるようにするのは意外と難しいものです。
欲を言えば、レーダーみたいな感じで設備の場所を表示したいものです。そうすれば人が管理しなくても、場所を追うことができます。イメージとしてはこんな感じで、設備の現在位置がマッピングされてて、探したいものを指定するとハイライトされるというものです。
そのためには設備自体に自分の場所を発信してもらわなければなりません。たとえばGPSの位置情報を定期的にクラウドに反映させる、という方法が考えられますが、GPSは建物の中ではうまく位置が取れず、また高さ方向を正しく把握するのは難しいです。電力消費量も気になりますし。
こういう場合、AirTag(あれって企業利用可能なのかな?)やビーコンなどのアイテムを使うのが一般的な解決策かと思いますが、SORACOM Arcを使ったネットワーク構成を作ることで、そこそこ近いところまでいけるのではないかと思いつきました。
具体的には、「SORACOM ArcのVPNルーターが複数設置されているネットワークにおいて、デバイスがSORACOMプラットフォームに接続した場合、ネットワーク的に一番近い≒物理的に一番近いVPNルーターのIMSIが結びつく」ということを利用します。
デバイスは自分の識別情報(設備番号や製造番号など)をSORACOMプラットフォームに送信するだけで、その識別情報と一番近いルーター≒設置場所と結びつく、というわけです。
まあフロアレベルのざっくりとした位置しかわかりませんが、何か探し物をしている時には、「少なくともそのものが存在していて」「だいたいの場所が分かっている」だけでもありがたいものです。探しても見つからない時には、そもそもそんなものが本当に存在していたのか?ということまで疑いますからね。
ではいってみましょう。
システム構成
システム構成はこんな感じです。
最終的には位置報告器が最後に接続したルーターの識別情報をDynamoDBに保存されます。そのルーターの周辺に探したい設備があることが確認できます。
まずWireGuardに対応したVPNルーターを各フロアに設置します。
VPNルーターに対してSORACOM Arc接続情報(VSIM)を発行し、SORACOM Arcに接続します。
そして位置報告器を各設備にくっつけます。これは適当な小型マイコンボードで、WiFiで近くのルーターに接続し、自身の識別情報をSORACOM Funnelに送るだけのものです。
SORACOM FunnelはAWS IoT Coreと連携させており、AWS IoT Coreは設定されたルールに基づいてFunnelから送られてきた位置報告器の識別情報、VSIMのIMSI、およびタイムスタンプをDynamoDBに保存します。
SORACOMから先の連携はいくつかパターンがありますが、ノーコードで手がかからないSaaSの組み合わせであるSORACOM Funnel + AWS IoT Core + Amazon DynamoDBを採用しました。もうちょっと複雑なこと、たとえば場所をVSIMのIMSIじゃなくてそれに紐づいた場所で保存したい、という場合は、SORACOM Funk + AWS Lambda + Amazon DynamoDBといった組み合わせや、間にSORACOM Orbitを入れる方法なども考えられますね。このあたりは要件に応じて考えましょう。
DynamoDBに保存されたデータの可視化なんかも考える必要があるのですが、今回は省きました。たぶん可視化するWebアプリなんかを作った方がいいんだろうなとは思ってます。
ルーターの設定
WireGuardクライアント機能があるルーターを用意します。
今回は、こちらのブログ記事「すべてが S になる (SORACOM Arc をルーターで使う)」にて紹介されている「Microuter-N300」にて動作確認しました。
こういう感じのものですね。安価で小さくあまり邪魔になりません。
ではルーターにSORACOM Arc接続の設定をしていきましょう。
まずルーターにWiFiで接続します。初期のSSIDとパスワードはルーターの裏に記載されています。
接続できたら、管理画面である http://192.168.8.1/ にアクセスします。
初回設定として、言語とパスワードを設定して管理画面に入ったら、まずやることは**「ファームウェアをアップデート」**です。これを抜かしていたためずいぶんハマってしまいました。購入時に新しいファームウェアが入っている可能性もありますが、念の為やっておいた方が良いでしょう。
私が購入した時点では、WireGuardのクライアントの設定をするとAllow IPの設定に関わらず全ての通信がVPN経由になってしまう、という問題がありました。しかもAllow IPの設定によって100.127.0.0/16以外はブロックされるので、実質SORACOMプラットフォームしかアクセスできなくなります。最新のファームウェアでは修正されているようなので、必ずアップデート後に設定してください。
また、次のマイコンからの接続を考えるとSSIDとパスワードはルーターで共通のものとした方が良いかと思います。(このように設定することの弊害は申し訳ありませんが未調査です)ついでにWiFiのチャネルなども必要に応じて変更しておいてもよいでしょう。
SSIDを設定するといったん接続切れますので、再度SSIDを指定して接続しなおしましょう。
次に本題のWireGuardの接続を設定します。ちょっと日本語がアレなのが気になる人は英語の方がいいかもしれません。
ここでSORACOMコンソールにアクセスします。(要ログイン)
https://console.soracom.io/#/sims
SIM登録をします。なお、ここでサブスクリプションコンテナに対応した新しいSIM管理画面ではない場合は切り替えておきましょう。この先の操作はその画面であることが必要です。
ルーターの管理画面に切り替え、コピーした設定を貼り付けます。
警告の内容を確認して、確定します。(100.127.0.0/16の通信しかVPNを通さない、それ以外はWANに流れるけどいいですか?という内容です)
接続できているかどうかは、pong.soracom.ioへのpingなどを試すと良いでしょう。pingが通ればOKです。
なお、既設のルーターを利用する場合は、100.127.0.0/16あての通信をSORACOM Arc接続したサーバーに静的ルーティングする、といった方法を取ることもできます。この方法は、こちらの記事が参考になります。
SORACOM Arcで自宅ネットワークをSORACOMプラットフォームに接続する
なお、この方法の場合もちゃんとルーターごとに違うSORACOM Arc接続になるようにする必要があることに注意しましょう。そうしないと、接続元が特定できません。
デバイス(位置報告器)のプログラム
位置を報告するデバイスに求められるのは、以下のような要素です。
- Wifi接続可
- 小型
- 省電力・電池駆動
- プログラムの書き込みが可能
設備にくっつけて違和感を感じにくいサイズと、電池で1年程度持つ省電力が求められます。
使い方を考えるとそれほど頻繁に位置を報告する必要はないので、基本的にはスリープ状態にしておいて、1時間に1回程度起動して、WiFi接続後識別情報を送信してすぐにスリープする、という使い方になるでしょう。動作中よりスリープ時の待機電力が重要になります。
移動中などはWiFi接続できないことも考えられるため、接続できなければ適当なところでタイムアウトさせる必要もありますね。
やることは非常に少ないです。
ひとまず今回はM5StickCを使いました。WiFi接続できてまあまあ小型な、こういうものです。(単体だとサイズ感がよくわからなかったのでSIMカードと一緒に撮影)
消費電力は検証の必要がありそうですが、今回はそこまではしません。(正直そこまで消費電力は小さくないだろうな、とは思ってます)ある程度ちゃんと使いたい場合は、マイコン + 電源だけ、といったハードの方が良いかもしれません。(最近出てきたM5Stamp Pico Mateとか良さげな気がします。ディープスリープ時の消費電流が仕様に記載されていますし。そのうち試したいですね)
Arduinoを使ってコードを書き、書き込みをします。開発環境の準備などは説明を省略いたします。詳しくは公式のドキュメントをご参照ください。
https://docs.m5stack.com/en/arduino/arduino_development
コードは以下のようになります。
#include <M5StickC.h>
#include <WiFi.h>
#include <WiFiUDP.h>
const char* ssid = "arc-router";
const char* password = "goodlife"; // N300初期パスワード
WiFiUDP wifiUdp;
const char *soracomEndpoint = "uni.soracom.io"; // SORACOM サービス
const int soracomPort = 23080; // SORACOMサービスのポート
const int senderPort = 50000; // 自身のポート
const uint64_t sleepInterval = 3600LL * 1000000LL; // 1時間ごとに復帰
void setup() {
M5.begin();
WiFi.mode(WIFI_STA);
M5.Axp.SetLDO2(true);
M5.Lcd.setTextSize(1);
WiFi.begin(ssid, password);
int loopCount = 0;
while (WiFi.status() != WL_CONNECTED) {
// 1分以上接続できなければ諦める
if (loopCount++ >= 60){
sleepDeep();
}
delay(1000);
M5.Lcd.print(".");
}
M5.Lcd.println("connected");
char macAddressBuffer[20];
WiFi.macAddress().toCharArray(macAddressBuffer, sizeof(macAddressBuffer));
wifiUdp.begin(senderPort);
wifiUdp.beginPacket(soracomEndpoint, soracomPort);
wifiUdp.write((const uint8_t *)macAddressBuffer, strlen(macAddressBuffer));
wifiUdp.endPacket();
M5.Lcd.println("sent.");
M5.Lcd.fillScreen(BLACK);
sleepDeep();
}
void loop() {
// 使わない
}
void sleepDeep(){
WiFi.mode(WIFI_OFF);
M5.Axp.SetLDO2(false);
esp_sleep_enable_timer_wakeup(sleepInterval); // wakeup after 1hour
esp_deep_sleep_start();
}
起動したらWiFiに接続して、Unified EndpointにUDPでMACアドレスを送信するだけの簡単なプログラムです。以下のような点を考慮しています。
- 識別子をMACアドレスにしたのは、デバイス固有の設定なく取得できそうなのがこれくらいしか思いつかなかったからです。MACアドレスは偽装の可能性もありますが、この用途で偽装されることはあまり考えなくてもよいでしょう。
- WiFiのSSID、パスワードは固定にしています。これができるよう、ルーターには同じSSID、パスワードをかけています。セキュリティ的にどうなんだという懸念はあるでしょうが、MACアドレス制限で対処することになるかと思います。
- setupが終わり次第ディープスリープに入るため、loopには入りません。ディープスリープはsetupからやり直すためです。
- 動作確認のため、動作している間は液晶に進捗を表示しています。本番も何らかの方法で動作確認できる方法はあった方がいいと考えます。
- スリープ中のWiFiやLCDは明示的にOFFにしています。おそらく他にも色々周辺回路をOFFにした方が良いと思われますが、このあたりは実際に電力計で測定しながら試したいところです。
- 利用するのはFunnelと言っておきながら、送信先はUnified Endpointです。特にデバッグ中はHarvestでデータを確認できた方が何かと便利なのですよね。Funnelの設定すると自動的にFunnelに連携されますし、あとでやっぱりFunk連携にしたい、となった場合も簡単に対処できます。Unified Endpont素晴らしいですね。
マイコンのプログラムはこれで完了です。あとはモバイルバッテリなどに接続しておくだけで、近くのルーターに接続してSORACOMにデータを送ってくれます。
AWSの設定
AWSに用意するのはデータを保存するAmazon DynamoDBと、データをDynamoDBに注解するAWS IoT Coreです。この組み合わせはサーバーレスであるため、使った分しか課金されません。素晴らしいですね。
また、SORACOM FunnelからAWS IoT Coreを利用するために、IAM Userを作成する必要があります。こちらは次節「SORACOMの設定」で説明します。
Amazon DynamoDB
DynamoDBのテーブルは2つ作成します。
デバイスごとに最新の場所を保存する「placeLatest」と、デバイスの場所の履歴を保存する「placeHistory」です。もちろんplaceHistoryでタイムスタンプが一番新しいアイテムを取得すればplaceLatestになるのですが、楽に探すため分けることにしました。どちらでも良いと思います。
デバイスID(今回の場合はMACアドレス)とアイテムが1:1で結びつくため、キーはパーティションキーのみです。
こちらはデバイスIDごとにタイムスタンプで場所を追えるようにしたいので、ソートキーとしてタイムスタンプを利用します。
キャパシティモードは、読み書きともに頻度が少ないと見てオンデマンドとします。暗号化は必要に応じて実施しましょう。
DynamoDBについては以上です。
AWS IoT Core
AWS IoT Coreではデバイスからのデータを受け付け、各種AWSサービスに連携することができます。今回は、SORACOM FunnelからのデータをDynamoDBに保存してみましょう。
どのようなデータが届いたら、どのサービスに連携するのか、を決めるのは、AWS IoTの「ルール」という要素です。以下のページにて、「ルール」を作成します。
https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/create/rule
まず名前を入力します。命名規則が妙に厳しく、半角英数と_(アンダースコア)しか使えないことに注意しましょう。
次にクエリステートメントを入力します。これはどこ(トピック)に送信された、どのデータを送信するのかを、SQLに似たテキストで指定するものです。
以下のように入力します。
SELECT payloads AS deviceId, imsi AS place, timestamp FROM 'place'
次にアクションを指定します。これは取り出したデータをどのサービスに送信するのかを指定するものです。各種AWSサービスの他、いくつかのサードパーティのサービスや任意のHTTPSのURLとも連携可能です。
同様に、「placeHistory」テーブルと連携するアクションも作成します。ロールはこのアクション専用のロールを作成した方が、同じ手順で作成できますし、管理もしやすいです。同じデータを送信していますが、DynamoDBのキーの設定が違うため、placeLatestはデバイスIDに対して場所とタイムスタンプが上書きされ、placeHistoryはデバイスIDに対する場所とタイムスタンプが蓄積されます。
最後にSORACOM Funnelと連携するためのエンドポイントを確認しておきましょう。以下のページにアクセスします。
https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/settings
「デバイスデータエンドポイント」をコピーして保存しておきます。SORACOM Funnelの設定の際に使用します。
AWS IoTの設定はこれで終了です。
SORACOMの設定
SORACOM FunnelとAWS IoTとの連携については、こちらのドキュメントに記載されています。
https://users.soracom.io/ja-jp/docs/funnel/aws-iot/
こちらを参考に設定していきましょう。
IAMユーザーの作成
IAMユーザー作成画面にアクセスします。
https://console.aws.amazon.com/iam/home#/users$new?step=details
ポリシードキュメントは以下のようになります。AWSアカウントIDの部分には自分のアカウントIDを入力します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": "arn:aws:iot:ap-northeast-1:{AWSアカウントID}:topic/place"
}
]
}
「タグを追加 (オプション)」はそのまま「次のステップ」に進みます。
IAMユーザーの画面に戻り、更新ボタンを押して新しく作成したポリシーを選択します。
「タグを追加 (オプション)」はそのまま「次のステップ」に進みます。
「ユーザーを追加」画面で内容を確認し、「ユーザーの作成」に進みます。
作成されたユーザーの「アクセスキーID」「シークレットアクセスキー」をそれぞれコピーしてメモしておくか、CSVファイルをダウンロードします。
これでAWS側の設定は終わりです。
認証情報の登録
SORACOM FunnelからAWS IoTにアクセスするための認証情報を登録します。
以下の認証情報管理ページにアクセスします。
https://console.soracom.io/#/security/credentials?coverage_type=jp
先ほど作成したIAMユーザーの「アクセスキーID」「シークレットアクセスキー」を入力し、登録します。
これで認証情報の登録は完了です。
SIMグループの設定
以下のSIM管理画面にアクセスします。
https://console.soracom.io/#/sims?coverage_type=jp
対象にするVSIMにチェックを入れ、所属グループを変更します。
SORACOM Funnelの設定をします。転送先URLは、メモしておいたAWS IoTのエンドポイントの前に「https://」、後ろに「/place」をつけたものです。また、送信データ形式は「テキスト」を選びます。マイコンからはデバイスID(MACアドレス)のみを送るため、JSON形式にしていないためです。他の情報も送りたい場合はJSON形式で送信するか、バイナリパーサー、SORACOM Orbitを併用することを考えても良いでしょう。
これでSORACOM側の設定は完了です。
AWS IoTのコンソールで確認すると、以下のようなデータが送信されていることが確認できます。
では試してみましょう!
結果
会社のネットワークを勝手にいじるわけにもいかないのでひとまず自宅で試してみました。
ルーターはこんな感じで配置します。(間取りは抽象化してます)
なお、デバイスからの報告時間が1時間に1回だと確認に時間がかかるので、確認中は1分に1回報告させています。
まずは以下のように、部屋1にデバイス1を、部屋2にデバイス2を置いてみましょう。
しばらく待ってから、placeLatestテーブルを確認します。
https://ap-northeast-1.console.aws.amazon.com/dynamodb/home?region=ap-northeast-1#tables:selected=placeLatest;tab=items
デバイス1はルーター1(部屋1)、デバイス2はルーター2(部屋2)にある、ということがわかりますね。
またしばらく待ってから、placeLatestテーブルを確認すると、場所を変えたのがちゃんと反映されていますね。
どのように変わったのかをplaceHistoryで確認してみます。
https://ap-northeast-1.console.aws.amazon.com/dynamodb/home?region=ap-northeast-1#tables:selected=placeHistory;tab=items
デバイスID、タイムスタンプ、場所がそれぞれ直感的ではないのは今後の課題ですね。やはり可視化のためのWebアプリも作るべきだったかもしれません。
改善項目
- 結果が直感的に可視化できないのがちょっと苦しいですね。デバイスIDと設備名、IMSIと場所名を結びつけて保存する、もしくは表示時に変換する、などは必要になりそうです。最初に示したイメージみたいに表示できればいいのですが、間取りとルーターの対応付けとか設定させるの色々大変そうです。Webアプリの修行が足りないですね。
- デバイスはもっと省電力を目指した方が良さそうですね。というか電力測定できてないのでどれくらい持ちそうかもわからない状態です。設備の棚卸し時期などを考えると、乾電池で1年動作する、というのが最低限の要求事項になりそうなので、それができるハードウェアが必要ですかね。
- 部屋レベルでのざっくりした位置がわかるのはとてもいいんですが、そこからさらに絞りこむ方法は欲しいところです。探したい機器を指定したら音が鳴る、とかできればよさそうですかね。Funkの応答とかをうまく使えばいけるかな、と思ってます。(反映に最大1時間かかりますが)
- とはいえ、こういうWiFi + VPNルーターを会社内に配置させてくれるか、というのが一番問題になりそうではあります。コストは大したことなくても、ネットワーク・セキュリティポリシーの懸念が高そうです。いっそこの用途専用にして、Unified Endpoint以外の全ての通信を塞いだ方がいいかもしれないですね。
応用できそうなこと
- 一つの社屋や事業所だけでなく、複数の建物でも同じ設定がされたルーターが置ければ、同じようにトラッキングできると思います。設備見当たらないと思ったらいつの間にか他の工場に行ってたりとか、なんかデモ装置に組み込まれてたりしてますからね。。
- 配送所が決まってる車や荷物などの到着判断とかにも使えそうですね。このWiFiに繋がったということは到着してる、という考えです。とはいえこの辺りはすでにGPSなどでトラッキングする仕組みが導入されてそうなものではありますが。
- テザリング + SORACOM Arc接続のスマホを持っている人がいれば、その人と一緒にあることのトラッキングもできそうです。これはスマホの状態がトラッキングできない大きな原因になりそうなのが課題ですね。テザリング切れるとかは考えられます。
おわりに
見つからないものを探し続けるのは結構苦しいもので、これ本当にこの世界に存在してるのか?すでに異世界に旅立ったりしてない?みたいに考えることさえありますよね。
探し物は割と普遍的な課題であり、すでにさまざまなソリューションがあります。iPhoneを探す、とかすごいですよね。今回は自分のできる範囲で何か考えてみようと思いこのような形になりました。
このブログが探し物に悩む人の一助となれば幸いです。