この記事は、SORACOM Advent Calendar 2018 の12月7日にエントリーしてます。
SORACOM UG Hiroshima #2 の LT で話したやつの裏側で地味に悩んでしまった経験を書いてみました。
背景
SORACOM Beam を使った MQTTS の通信には IMSI 付与という設定があり、これを使うと簡単にどの SIM から来た情報かを判定することができます。普段から使っている人は当たり前すぎて説明無しの事が多いのですが、AWS IoT Core で判定しようと思った時にうまくググれなかったのでまとめておきます。
構成
- WioLTE
- SORACOM Beam
- AWS Iot Core
- AWS Lambda
WioLTE側
今回、Things 側は WioLTE を使って Arduino IDE でスケッチを作成しました。今回はスケッチ例にある mqtt-client をそのまま使います。
スケッチ
サンプルから MQTT_SERVER_HOST と TOPIC を変えただけです。
#include <WioLTEforArduino.h>
#include <WioLTEClient.h>
#include <PubSubClient.h> // https://github.com/SeeedJP/pubsubclient
#include <stdio.h>
#define APN "soracom.io"
#define USERNAME "sora"
#define PASSWORD "sora"
#define MQTT_SERVER_HOST "beam.soracom.io"
#define MQTT_SERVER_PORT (1883)
#define ID "WioLTE"
#define OUT_TOPIC "device/post"
#define IN_TOPIC "device/post"
// 以下省略(サンプルと同じ)
SORACOM Beam 設定
SORACOM Beam については有名なハンズオンの資料にある手順で設定します。MQTTSの転送先の部分は、後述する AWS IoT Core の設定に変更します。
https://github.com/soracom/handson/wiki/Wio-LTE-%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3#step5
ポイントは「IMSI 付与: ON」です。こうする事で Arduino IDE 側には何も書かなくても SORACOM Beam に送るだけで自動的に IMSI が設定されます。
今回の例では
#define OUT_TOPIC "device/post"
と書いているので、MQTT ブローカーに届く時に下記のように TOPIC が変更されます。
/* 123456789012345 の部分が IMSI */
device/post/123456789012345
プログラム側に何も書かなくても処理されるので便利ですが、SORACOM 初心者の私は気がつくまでしばらくかかりました。
AWS IoT Core
AWS IoT の設定は SORACOM 公式の記事に従います。
https://dev.soracom.io/jp/docs/aws_iot_guide_console/
SORCOM Beam への MQTTS の転送先設定は上記の記事を参考にしてください。
本題
さて、準備が終わったところで本題です。
ここまでの設定で基本的には問題なく処理されますが、AWS IoT Core のルールクエリをうまく設定する事でその先の Lambda で IMSI を使った判定ができるようになります。
設定するところ
ルールクエリのところに、下記の AWS IoT SQL を設定します。
SELECT uptime, topic() as topic FROM 'device/post/#'
SELECT 句
uptime というのは、サンプルに元から設定されている JSON のキーです。コードでいうと下記の部分です。
char data[100];
sprintf(data, "{\"uptime\":%lu}", millis() / 1000);
SerialUSB.print("Publish:");
SerialUSB.print(data);
SerialUSB.println("");
MqttClient.publish(OUT_TOPIC, data);
topic() as topic の部分は MQTT トピックの全文を取得するために使います。AWS のリファレンスを参考にしてください。
ここがこのエントリでもっとも重要な箇所です。
FROM 句
'device/post/#' の一番後ろにある # がワイルドカードを意味します。こちらもリファレンスを読むとひっそりと書いてあります。
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-sql-from.html
コンソール画面の様子
Lambda
あとは、Lambda に送られてきた値をうまく判定する事で IMSI による処理をすることができるようになります。
Lambda のイベントにはこんなペイロードが送られてきます。
{ uptime: 19, topic: 'device/post/123456789012345' }
Arduino IDE のシリアルモニターはこんな表示です。
--- START ---------------------------------------------------
### I/O Initialize.
### Power supply ON.
### Turn on or reset.
### Connecting to "soracom.io".
### Connecting to MQTT server "beam.soracom.io"
### Setup completed.
Publish:{"uptime":19}
Arduino IDE 側は送信したい情報だけを JSON に設定して送り、SORACOM Beam で IMSI を付与して転送します。それを AWS IoT Core のルールクエリで再変換することで Lambda 側で IMSI を処理できるようになりました。
SIM の IMSI を確認する方法
SORACOM の API を使って IMSI を取得することができます。
https://dev.soracom.io/jp/docs/subscriber_status/#api
コンソールからも「SIM管理」の「詳細」ボタンで確認できます。
まとめ
知っていれば非常に簡単な話なのですが、初回つまづいたので思い出して記録を残してみました!
2018年もあと1ヶ月を切りました。体調管理にお気をつけて来年からのイベントに備えてください!
NT広島2019 はこちら
唐突ですが、2019年の2月2日に広島で #NT広島 というイベントが開催されます。
SORACOM を使った作品とともに、ぜひ広島に遊びにきてください!
今回初開催となるNT広島ですが、すでにNT界隈の人から好反応をいただいております。
http://wiki.nicotech.jp/nico_tech/index.php?NT%E5%BA%83%E5%B3%B62019
牡蠣の美味しい季節の広島をぜひご堪能ください!