SORACOM AirをつないだRaspberryPiをlittleBits+Milkcocoaで遠隔OFFするボタンをつくった

この記事はMilkcocoa Advent Calendar 2015 – Qiitaの13日めの投稿です。

先ほどの記事でもお伝えした、SORACOM AirをつないだRaspberryPiをlittleBits+Milkcocoaで遠隔OFFするボタンをつくったネタの詳細です。

今回やりたいこと

すしインタラクティブのワークショップ展示などで、個人IoT/M2Mネタを行っています。

当初はRaspberryPiにリモートデスクトップ(VNCクライアント)を行って、ちょっと遅い操作感で丁寧にシャットダウン操作を行っていましたが、複数台になってしまうとかなり手間を感じていました。

image_20151212_225738_18

ということで、すでにNodeJSでお互いがSocketIOつながっている環境であれば、littleBits+Milkcocoaで遠隔OFFする仕組みなんてどうだろう!というのが今回やりたいことです。

目指す仕組み

image_20151212_231247_21

  • ボタンを押すとOFFしたい対象に「shutdown」という文字列の命令を送る端末を制作する
    • ボタン部分と端末との連携は、littleBitsのボタンモジュールとlittleBitsモジュールを使う
  • 端末同士で連携する部分はNodeJSでMilkcocoaで連携して伝える
  • 遠隔OFFしたい端末はNodeJSで「shutdown」という文字列の命令待っている
    • 命令を受け取るとNodeJS経由でシェルを叩いて「sudo shutdown -h now」する。

といった仕組みで作っていきます。

遠隔OFFしたい端末

image_20151212_232511_24

SORACOM AirとRaspberry Piの接続については、Milkcocoaのブログをご参考ください。

遠隔OFFしたい端末はNodeJSで「shutdown」という文字列の命令待っていて、命令を受け取るとNodeJS経由でシェルを叩いて「sudo shutdown -h now」にします。

ソースコードはこのようになっています。


var MILKCOCOA_APP_ID = "    接続したいAPP_ID    ";
var MILKCOCOA_DATASTORE_ID = "exec";  // execというデータ名を待つ

console.log("MILKCOCOA_APP_ID:" + MILKCOCOA_APP_ID);
console.log("MILKCOCOA_DATASTORE_ID:" + MILKCOCOA_DATASTORE_ID);

// milkcocoa /////////////////////////////////
var MilkCocoa = require("./node_modules/milkcocoa/index.js");
var milkcocoa = new MilkCocoa(MILKCOCOA_APP_ID + ".mlkcca.com");
// dataStore設定
var sampleDataStore = milkcocoa.dataStore(MILKCOCOA_DATASTORE_ID);
// データがsendされたときのイベント通知
sampleDataStore.on("send", function(datum) {
    if( datum.path == "exec" && datum.value.command == "shutdown" ){
        console.log("[exec]");
        console.log("shutdown!!!!!!");
        var exec = require('child_process').exec;
        exec('sudo shutdown -h now', function(err, stdout, stderr){
        });
    }
});

// 起動時にMilkcocoaにメッセージを送っておく
sampleDataStore.push({message:"connected!!!"});

Milkcocoaで接続しexecというデータ名を待ちつつshutdownという文字列が来たらシャットダウンさせます。

NodeJSは require(‘child_process’).exec でシェルが叩けるので、おなじみシャットダウンさせるコマンド「sudo shutdown -h now」をしているシンプルな構造です。

ボタンを押すと「shutdown」という文字列の命令を送る端末

image_20151212_230849_19

こちらはlittleBitsとスティックPCで仕組みをつくりました。実際の実装を見ていきましょう。

littleBitsの実装

image_20151212_232520_25

littleBitsのボタンモジュールを押すとArduinoモジュールがPCに命令を伝えますが、Arduinoモジュールは、こちらの記事のようにルールを決めています。

このArduinoモジュールの動作ですとボタンを押されたとき、2の文字列が送られます。

NodeJSの実装

ボタンを押されたとき2の文字列がPCに送られたあと、NodeJSが「shutdown」の命令をMilkcocoa経由で送るのは以下のようなコードになっています。

var MILKCOCOA_APP_ID = "    接続したいAPP_ID    ";
var MILKCOCOA_DATASTORE_ID = "exec";  // execというデータ名で送る

console.log("MILKCOCOA_APP_ID:" + MILKCOCOA_APP_ID);
console.log("MILKCOCOA_DATASTORE_ID:" + MILKCOCOA_DATASTORE_ID);

// milkcocoa /////////////////////////////////
var MilkCocoa = require("./node_modules/milkcocoa/index.js");
var milkcocoa = new MilkCocoa(MILKCOCOA_APP_ID + ".mlkcca.com");
// dataStore設定
var sampleDataStore = milkcocoa.dataStore(MILKCOCOA_DATASTORE_ID);
// データがsendされたときのイベント通知
sampleDataStore.on("send", function(datum) {
    console.log("[send]");
    console.log(datum);
});

// Serial Port ///////////////////////////////

var serialport = require('serialport');
var portName = 'COM6';  // Mac/Linux/Windowsに合わせてシリアルポート名を決める
var sp = new serialport.SerialPort(portName, {
    baudRate: 9600,
    dataBits: 8,
    parity: 'none',
    stopBits: 1,
    flowControl: false,
    parser: serialport.parsers.readline("\r\n")
});

// シリアルポート入力からのデータ送信
sp.on('data', function(input) {
    var buffer = new Buffer(input, 'utf8');
    try {
        console.log('serialport buffer: ' + buffer);
        if( buffer == 2 ){
            // /input/2
            console.log('/input/2');
            // Milkcocoa経由でshudownの文字列を送る
            sampleDataStore.send({command:'shutdown'});
        }
    } catch(e) {
        return;
    }
});

NodeJSがArduinoと連携するためにserialportを使っています。あとはMilkcocoa経由でshudownの文字列を送るというシンプルな構造です。

こちらでプログラム部分は出来上がりです!

ボタン部分を仕込んでみる

ボタン部分を仕込んでみます。まず、箱にざくざくっと入れていきます。

image_20151212_233259_26

箱を閉じます。雰囲気出てきました。

image_20151212_233303_27

危険度を上げる

これですと、一発シャットダウンをするボタンなのに、うっかり押してしまいそうなので、より危険度を上げてわかりやすくします。

マスキングテープにマジックでシマシマを書いて、

image_20151212_233315_28

ペタペタと装飾したらだいぶデンジャー感が上りました!

image_20151212_233329_29

(・・・私の個人的なこだわりでした!)

それでは動かしてみる

さて動かしてみましょう。

遠隔OFFしたい端末もlittleBitsで電源が入っている限りは、ずっと点滅しています。実際は温度センサーや照度センサーなど、遠隔で記録を取り続けている何かとなるものです。

いざ、ON!!!

無事、動きました!

おわりに

その後、SORACOM AirでつないだRaspberry PiはLTE/3Gネットワークでつながっているので、家の外や別の部屋に持って行っても、ちゃんと遠隔OFFされました。すごい。Wifiよりも場所を気にせずにいろいろな遠隔デバイスを置けそうです。

また、この遠隔OFFができると個人でIoT/M2Mネタをするときの撤収がスムーズになりますし、仮に複数台でセンサーネットワークを作っている時も、いちいちリモートデスクトップ(VNCクライアント)で対応せずに、一斉に出来そうなのでかなり楽しそうです。ボタン化するとワクワクしますね!

この仕組みはMilkcocoaで作りましたが、遠隔を担当するSocketサーバー周りの連絡処理をまるまる任せることができるのは、発想からすぐに作ることが出来て作る気持ちがしぼむまえに、スッと寄り添ってくれる感じが良いですね。

それでは、よき Milkcocoa Lifeを!