0%

Johnny-Fiveを使いLM35の温度データをArduinoからMeshbluのMongoDBに保存する

先日構築したMeshbluコンテナのデータストアはNeDBのままでした。センシングデータをMongoDBに保存するように変更します。引き続きArduinoはFirmataとJohnny-Fiveを使いホストマシンから操作します。LM35を搭載した温度センサーモジュールを用意してArduinoから温度データを取得します。取得したデータはWebSocket over SSLでMeshbluにPOSTしてMongoDBに保存します。

MongoDBをデータストアに使う

Dockerコンテナの起動

MeshbluのリポジトリforkしてDockerfileなど修正しました。forkしたリポジトリをcloneします。

$ git clone https://github.com/masato/meshblu
$ cd meshblu
$ docker build -t meshblu .

Dockerコンテナにカレントディレクトリをマウントして使うためnode_modulesのシムリンクを作成します。

$ ln -s /dist/node_modules ./node_modules

今回のMongoDBはMeshbluのコンテナ内で起動しています。環境変数MONGODB_URIにURLを指定します。

$ docker run -d --name meshblu \
-p 3000:3000 \
-p 4443:4443 \
-p 5683:5683 \
-p 1883:1883 \
-e PORT=3000 \
-e MQTT_PORT=1883 \
-e MQTT_PASSWORD=skynetpass \
-e MONGODB_URI=mongodb://localhost:27017/skynet \
-e SSL_PORT=4443 \
-e SSL_CERT=/opt/meshblu/certs/server.crt \
-e SSL_KEY=/opt/meshblu/certs/server.key \
-v $PWD:/var/www \
-v $PWD/docker:/etc/supervisor/conf.d \
-v $HOME/docker_apps/certs/meshblu:/opt/meshblu/certs \
meshblu

Meshbluが起動しました。

$ docker logs meshblu
...
Meshblu (formerly skynet.im) development environment loaded...
...
Starting HTTP/HTTPS... done.
Starting MQTT... done.
CoAP listening at coap://localhost:5683
HTTP listening at http://0.0.0.0:3000
HTTPS listening at https://0.0.0.0:4443
...
MQTT listening at mqtt://0.0.0.0:1883

任意のuuid/tokenでデバイスの登録

statusを取得してMeshbluが起動していることを確認します。

$ export MESHBLU_URL=https://xxxx
$ curl --insecure "$MESHBLU_URL/status"
{"meshblu":"online"}

センシングデータデバイスを登録します。普通に登録すると以下のようにuuidとtokenが取得できますがとても長いので扱いずらいです。

$ curl -X POST \
--insecure \
-d "name=osx" \
"$MESHBLU_URL/devices"
{"geo":null,"ipAddress":"172.17.42.1","name":"osx","online":false,"timestamp":"2015-03-24T07:34:12.997Z","uuid":"2aa8fd10-d1f8-11e4-a109-7b68e78fda3b","token":"b4f6c6df56b82f747444b891e133ddd8c34992b6"}

POSTするメッセージに任意のuuidtokenを指定することができます。

$ curl -X POST \
--insecure \
-d "name=johnny-five-test&uuid=johnny&token=five" \
"$MESHBLU_URL/devices"
{"geo":null,"ipAddress":"172.17.42.1","name":"johnny-five-test","online":false,"timestamp":"2015-03-25T04:50:17.949Z","uuid":"johnny","token":"five"}

今回はArduinoのホストマシンにOSXを使います。さきほど取得したuuidとtoken、MeshbluのURLを~/.bash_profileに記述して再読込します。

~/.bash_profile
$ export MESHBLU_URL=https://xxx
$ export OSX_UUID=johnny
$ export OSX_TOKEN=five

環境変数を指定して登録したデバイスを表示してみます。

$ source ~/.bash_profile
$ curl -X GET \
"$MESHBLU_URL/devices" \
--insecure \
--header "meshblu_auth_uuid: $OSX_UUID" \
--header "meshblu_auth_token: $OSX_TOKEN"
{"devices":[{"geo":null,"ipAddress":"172.17.42.1","name":"johnny-five-test","online":false,"timestamp":"2015-03-25T04:50:17.949Z","uuid":"johnny"}]}

MongoDBのコレクションの確認

Dockerコンテナに入りMongoDBのコレクションを表示してみます。

$ docker exec -it  meshblu bash

データベース名は環境変数MONGODB_URIに指定したskynetです。

$ mongo skynet
MongoDB shell version: 2.4.13
connecting to: skynet
> show collections;
devices
system.indexes

先ほど登録したデバイスのコレクションが作成されています。

> db.devices.find();
{ "_id" : ObjectId("55123e89a90c660a00775d53"), "geo" : null, "ipAddress" : "172.17.42.1", "name" : "johnny-five-test", "online" : false, "timestamp" : ISODate("2015-03-25T04:50:17.949Z"), "token" : "$2a$08$O3hl4gnoTHG0zj/rcIACieEqzB5zHsnktZwNDdFldrJqdVcBidVe6", "uuid" : "johnny" }

センシングデータをPOSTする

OSXをホストマシンとしてFirmataプロトコルでArduinoに接続します。Johnny-FiveからArduinoを操作してセンシングデータを取得します。取得したデータはmeshblu-npmを使ってMeshbluにPOSTしてMongoDBに保存します。

LM35 温度センサモジュール

温度センサモジュールはaitendoからM35DZ-3Pを購入しました。Jonny-Fiveから操作できるLM35を搭載しています。回路図を参考にしてArduinoと接続します。

temperature-lm35.png

サンプルプロジェクト

OSX上にサンプルプロジェクトを作成します。

$ mkdir -p ~/node_apps/johnny-five-meshblu-lm35
$ cd !$

package.jsonにインストールするパッケージを記述します。

~/node_apps/johnny-five-meshblu-lm35/package.json
{
"name": "johnny-five-meshblu-lm35",
"version": "0.0.1",
"private": true,
"dependencies": {
"johnny-five": "0.8.49",
"meshblu": "1.19.0"
},
"scripts": {"start": "node app.js"}
}

app.jsにメインプログラムを書きます。Meshbluの接続情報は~/.bash_profileに記述した環境変数を使います。Meshbluに接続したあとJohnny-FiveからLM35の温度データを取得します。freq: 5000として5秒間隔にします。温度データが取得できたらJSONにフォーマットしてMesubluにPOSTします。

~/node_apps/johnny-five-meshblu-lm35/app.js
var five = require("johnny-five"),
meshblu = require('meshblu');

var conn = meshblu.createConnection({
"uuid": process.env.OSX_UUID,
"token": process.env.OSX_TOKEN,
"protocol": "websocket",
"server": process.env.MESHBLU_URL
});

conn.on('notReady', function(data){
console.log('UUID FAILED AUTHENTICATION!');
console.log(data);
});

conn.on('ready', function(data){
console.log('UUID AUTHENTICATED!');
console.log(data);

five.Board().on("ready", function() {
console.log("Ready...");
var temperature = new five.Temperature({
controller: "LM35",
pin: "A0",
freq: 5000
});

temperature.on("data", function(err, data) {
console.log(data.celsius);
conn.data({
"temperature":data.celsius
});
});
});
});

必要なパッケージをインストールしてNode.jsプログラムを起動します。標準出力には摂氏の温度が5秒間隔で表示されます。

$ npm install
$ npm start
...
25.390625
25.390625
25.87890625
25.87890625
25.390625

MongoDBのデータ確認

Meshbluコンテナを起動しているDockerホストにログインします。Meshbluコンテナに入りMongoDBのdataコレクションをリストします。Arduinoに接続したLM35モジュールから取得した温度データが、OSXで動作しているJohnny-Fiveを通してクラウド上のMongoDBに保存されました。

$ docker exec -it meshblu bash
mongo skynet
MongoDB shell version: 2.4.13
connecting to: skynet
> db.data.find();
{ "timestamp" : "2015-03-25T03:53:08.179Z", "temperature" : "25.390625", "_id" : ObjectId("55123124c2eede05005958f2") }
{ "timestamp" : "2015-03-25T03:53:13.176Z", "temperature" : "25.87890625", "_id" : ObjectId("55123129c2eede05005958f3") }
{ "timestamp" : "2015-03-25T03:53:18.251Z", "temperature" : "25.87890625", "_id" : ObjectId("5512312ec2eede05005958f4") }