先日、myThings + milkcocoaで高齢者見守りデバイスを作ってみたという記事を投稿したのですが
その過程で、扉の開閉をチェックしつつmilkcocoaを使ってデータを送信する部分がうまく動かなくて困ったので、問題と解決案をメモしておきます。
#問題があったプログラム
問題があったのはwhile(1)の中で特定の条件(今回は扉の開閉というイベント)があった時にpushするプログラムです。
プログラムの内容としてはシンプルで、扉の状態をリードスイッチの値によって判断し、状態に変化があった時にデータを送信するというものです。
var fs = require('fs');
var MilkCocoa = require('milkcocoa');
var milkcocoa = new MilkCocoa('*********.mlkcca.com');
var ds = milkcocoa.dataStore('door');
fs.writeFileSync('/sys/class/gpio/export', 21);
fs.writeFileSync('/sys/class/gpio/gpio21/direction', 'in');
var value = 0;
var pre_value = 0;
while( 1 ) {
value = fs.readFileSync('/sys/class/gpio/gpio21/value', 'ascii');
if ( value != pre_value ) {
console.log(value);
if (value == 1) {
ds.push({DoorOpenFlag:'1'});
pre_value = 1;
}
else{
ds.push({DoorOpenFlag:'0'});
pre_value = 0;
};
}
}
今回はこのwhileの中でpushが行われず、エラーも出ないという状態でした。
(ドキュメントには120回/分までの制限があると書いてありますが、今回は一つもデータが送信されないという状態になっていました。)
予想される原因としては、whileのループが早すぎてjsの処理のタイミングや通信のタイミングあたりが追いついてないとか…?
普段jsを触らないのでよくわかりませんでした。
#解決案
milkcocoaを提供している株式会社Technical Rockstarsの方に相談した結果、最終的な解決案としては下記のようになりました。
根本的な原因の究明には至っていませんが、データ送信後に待機時間を置くことでなんとか送信がうまくできました。
var fs = require('fs');
var MilkCocoa = require('milkcocoa');
var milkcocoa = new MilkCocoa('*******.mlkcca.com');
var ds = milkcocoa.dataStore('door');
fs.writeFileSync('/sys/class/gpio/export', 21);
fs.writeFileSync('/sys/class/gpio/gpio21/direction', 'in');
var pre_value = 1;
loop();
function loop() {
var value = parseInt(fs.readFileSync('/sys/class/gpio/gpio21/value', 'ascii'));
if ( value != pre_value ) {
console.log(value);
ds.push({DoorOpenFlag:value});
pre_value = value;
}
setTimeout(loop, 1000/10);
}