23: Intel Edison実践編 (3) 〜 XDKで開発したプログラムからiotkit-agentにデータを送る

よく訓練されたアップル信者、都元です。昨日のエントリーはこちらです。今回いよいよ、実際にセンサーから取得した値をIoT Analyticsに送ってみようと思います。

Edison上で動かすnodeアプリケーションから直接IoT Analyticsに接続しても良いのでしょうけど、送信部分を担ってくれるiotkit-agentというものが存在します。Treasure Dataに直接データを流すのではなく、td-agentを介してデータを上げる、というのと同じような考え方でしょう。

iotkit-agent

まず、iotkit-adminで、デバイスのアクティベートが必要ですので、まだの場合は以前の記事を参照して済ませておきましょう。

次に、iotkit-agentはデフォルトでインストール済みではありますが、無効になっていますので、下記コマンドで有効化しておきます。

# systemctl enable iotkit-agent
# systemctl start iotkit-agent

下記ログの通りプロセスが上がり、7070/tcp及び41234/udpでポートが開いた *1ようです。

# systemctl status iotkit-agent  -l
● iotkit-agent.service - iotkit-agent
   Loaded: loaded (/lib/systemd/system/iotkit-agent.service; enabled)
   Active: active (running) since Mon 2014-12-22 05:20:25 UTC; 13min ago
 Main PID: 1257 (node)
   CGroup: /system.slice/iotkit-agent.service
           └─1257 node /usr/bin/iotkit-agent

Dec 22 05:20:25 edison systemd[1]: Started iotkit-agent.
Dec 22 05:20:28 edison iotkit-agent[1257]: 2014-12-22T05:20:28.479Z - info: Sending attributes...
Dec 22 05:20:38 edison iotkit-agent[1257]: 2014-12-22T05:20:38.724Z - info: Starting listeners...
Dec 22 05:20:38 edison iotkit-agent[1257]: 2014-12-22T05:20:38.733Z - info: TCP listener started on port:   7070
Dec 22 05:20:38 edison iotkit-agent[1257]: 2014-12-22T05:20:38.755Z - info: UDP listener started on port:  41234

ここでは60秒ごとにセンサー値をIoT Analyticsに送ってみようと思います。TCPできっちり送信するのも良いのですが、ここはオーバーヘッドの軽いUDPで通信してみましょう。ちなみに、各プロトコルでのiotkit-agentとの通信方法は、GitHub上にサンプルコードが上がっています。

コーディング

前半はUDPクライアントを作って、iotkit-agentに対してデータを送信するメソッドsendObservationを定義しています。

コード後半は、以前ご紹介したコードとほぼ同じです。ログ出力するのに加えて、sendObservationメソッドを呼んでいるだけです。また、繰り返し実行周期は60秒としました。

var dgram = require('dgram');
var client = dgram.createSocket('udp4');
var udpOptions = {
    host : '127.0.0.1',
    port : 41234
};

function sendObservation(name, value, on){
    var msg = JSON.stringify({
        n: name,
        v: value,
        on: on
    });

    var sentMsg = new Buffer(msg);
    console.log("Sending observation: " + sentMsg);
    client.send(sentMsg, 0, sentMsg.length, udpOptions.port, udpOptions.host);
}

var groveSensor = require('jsupm_grove'); 
var tempPin = new groveSensor.GroveTemp(0);
var lightPin = new groveSensor.GroveLight(1);

setInterval(function () {
    var date = new Date();
    console.log("==== " + date + " ====");
    var temp = tempPin.value();
    var light = lightPin.value();
    
    console.log(tempPin.name() + ": " + temp);
    sendObservation('temp', temp, date.getTime());

    console.log(lightPin.name() + ": " + light);
    sendObservation('light', light, date.getTime());
}, 60000);

結果

さて、このままEdisonにはこの状態のまま、オフィスで一晩越して頂きました。どうなっているでしょうか?

2014-12-23_1221

横軸が時間(UTC)です。13:30(22:30 JST)〜22:00(7:30 JST)の間、残念ながら何らかの影響で光センサーの値が取れていませんでした。その他のタイミングでも、50〜60件に1回くらいの頻度で値の抜けがありました。まぁその辺りはUDPならではの特徴かもしれません。

採れたデータについて、温度・光ともに概ね想定通りの動きをしていますね。オフィスは冬場の明け方だと18度くらいまで下がるんですね。明るさに見られる7:50 JST頃のピークは、多分センサーに窓からの直射日光が直撃するタイミングだったのではないでしょうか。

明日のエントリーはこちらです。

脚注

  1. 本当は、1884/tcpでMQTTのポート対応もあるようなのですが、設定の方法が分かりませんでした…。