【新機能】SORACOM Beamを使ってLoRaゲートウェイからのデータをKibanaで可視化する #scd2016 #soracom

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、せーのです。今日はSORACOM Conference "Discovery"というSORACOMさんのイベント会場に来ております。こちらからご紹介するのはSORACOM BeamがLoRaに対応した、というお話です。

LoRaって何

"LoRa"とはLPWA(Low Power Wide Area Networkと呼ばれる 無線通信規格の1つです。Bluetoothとか赤外線通信とかの仲間ですね。特徴としてはなんといっても「長距離(最大15km)」というところです。LoRaはモジュールとゲートウェイからなるのですが、ゲートウェイが5〜6個あれば町ひとつをまるまるカバーする、ということも可能なレベルです。

その他LoRaの説明、SORACOMとLoRaの関連はこちらを参考にして下さい。

SORACOMのSIMとLoRaデバイスが一つのコンソールで同じように管理出来る、というのは非常に便利ですね。
今回はプレビュー版をいち早く触る機会がありましたので早速使ってみました。

やってみた

さて今回はLoRaモジュールにPIRセンサーのデータを送り、そこからSORACOM Beamを使ってAPI Gatewayに渡し、Lambdaを使ってAmazon ES Serviceに投入してKIBANAで表示、というソリューションを作ってみました。

lora_funnel8

右側にある長四角いモジュールがLoRaモジュールです。Arduinoに刺さっています。Arduinoを使ってLoRaモジュールにデータを送るスケッチに関してはこちらを参考にして下さい。

さて、次はBeamの設定です。これは本来のBeamの設定とそう変わりません。LoRaの場合はβ版の現時点ではLoRaモジュール => HTTP/HTTPSのみサポートしています。ではグループを開きます。新規グループを作成し、API GatewayのURLとパスを設定します。

lora_beam6

現在はカスタムヘッダが使えないのでAPI Gatewayはオープンにしておきます(近々つくそうです)。これでBeam部分ができました。

lora_beam5

後は対象となるLoRaデバイスにこのグループをつければLoRaゲートウェイからのデータがBeamを通してAPI Gatewayに送られます。

lora_beam7

lora_beam8

どうでしょう。SIMの時とほぼ変わりませんね。

AWS側構築

ついでにAWS側の設定もご紹介します。AWS側はAPI GatewayでBeamからのデータを受け、Lambdaに渡してES Serviceに登録、Kibanaで表示、という形になります。まずはLambdaから。新規にLambda Funcitonを作ります。RoleはES Serviceが操作でき、Cloudwatch Logsに登録できる権限があればOKです。

lora_beam9

コードは特にローカルでダウンロードしなければいけない外部ライブラリをつかわなかったので、エディタ上で書きました。

lora_beam10

console.log('Loading function');


/**
 * Provide an event that contains the following keys:
 *
 *   - operation: one of the operations in the switch statement below
 *   - tableName: required for operations that interact with DynamoDB
 *   - payload: a parameter to pass to the operation being performed
 */
var AWS = require('aws-sdk');
var path = require('path');
var creds = new AWS.EnvironmentCredentials('AWS');

var esDomain = {
    endpoint: 'search-soracomdiscovery2016-XXXXXXXXXXXXXXXXXXXXXX.ap-northeast-1.es.amazonaws.com',
    region: 'ap-northeast-1',
    index: 'lora',
    doctype: 'data'
};
var endpoint =  new AWS.Endpoint(esDomain.endpoint);
 
exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    var countdata = Number(event.message.moduleData.data.slice(-2));
    console.log('count: ', countdata);
    
    var dt = event.message.moduleData.date;
    
    var result = {
		count:countdata,
		dt:dt
	};
    
    postDocumentToES(JSON.stringify(result), function(ret){
        if (ret == "success"){
            context.succeed("success");
        } else {
            context.fail("failed.");  
        }
    });
    
    
};

function postDocumentToES(doc, callback) {
    var req = new AWS.HttpRequest(endpoint);

    req.method = 'POST';
    req.path = path.join('/', esDomain.index, esDomain.doctype);
    req.region = esDomain.region;
    req.body = doc;
    req.headers['presigned-expires'] = false;
    req.headers['Host'] = endpoint.host;

    // Sign the request (Sigv4)
    var signer = new AWS.Signers.V4(req, 'es');
    signer.addAuthorization(creds, new Date());

 
    var send = new AWS.NodeHttpClient();
    send.handleRequest(req, null, function(httpResp) {
        var body = '';
        httpResp.on('data', function (chunk) {
            body += chunk;
        });
        httpResp.on('end', function (chunk) {
        	//console.log("es ok chunk:"+body);
            callback("success");
        });
    }, function(err) {
    	console.log("es error"+err);
        callback("fail");
    });
}

LoRaデータのJSONの内PIRセンサーのカウントデータが入っている部分を切り出して数値化、日時データと一緒に新たなJSONとしてHTTPリクエストを投げる、という感じですね。次にAPI Gateway。

lora_beam11

lora_beam12

パスを適当に設定してPOSTメソッドを作成します。Lambdaにはそのまんま渡すだけなのでLambdaに渡す権限をRoleにつけてあげればあとはデフォルトのままでOKです。一応content typeとしてapplication/jsonを付与するようにしました。最後にES Service。

lora_beam13

クラスタ自体はテストなので1つのみ、オープンで立てました。UTCで日時データが飛んで来るのでLambdaのログが入っているCloudwatch LogsにES Serviceに送るデータを吐いてコピペし、1件だけ登録すれば自動的にdate型(日時)とint型(カウントデータ)でマッピングされます。

curl -XPOST search-soracomdiscovery2016-XXXXXXXXXXXXXXXXXXXXX.ap-northeast-1.es.amazonaws.com/lora/data -d '{"count":0,"dt":"2016-07-12T06:26:00.000Z"}'

最後はKibanaです。これは好きな様にグラフ化したら良いかと思います。私の場合は棒グラフでカウントデータを日時順に表示し、全体の合計カウントをMetricsとして数値で表示しました。

lora_beam14

こんな感じで構築完了です。AWS側も慣れれば数時間でできると思います。

まとめ

いかがでしたでしょうか。LoRa部分はArduinoのスケッチが書ければ後の流れは通常のIoTとそう変わらないことがわかるかと思います。データが通った時には結構な快感がありますので、是非LoRa+SORACOM、お試し下さい!

参考リンク