![]() |
サランラップ+お湯で柔らかくなるプラスチックによる雑な仕事w |
まず、SMTPサーバを入れてその設定、次にBoneScriptを書く。
SMTPサーバの入れ方はこちら。とても参考になりました、ありがとうございます。
記事との相違点はMacではなくBeagleboneなので「brew/aptitudeの替わりに apt-get を使う」ことと、設定ファイルの中身です。蛇足ですが、fromとuserは同じでOKです。設定したら記事にあるように、テストしてみてください。
で、BoneScriptで書いてみます。Node.jsから直接SMTPを呼び出せるmailなどのモジュールも試してみたのですが、エラーの山を解決することができなかったので、child processとして呼び出す方式にしました。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var b = require('bonescript'); | |
var exec = require('child_process').exec, child; | |
var fs = require('fs'); | |
var filename = '/root/test.msg'; | |
function sendMessage(to, subject, message) { | |
// create message file | |
var msg = 'To: ' + to + '\n' + 'Subject: ' + subject + '\n' + message + '\n'; | |
fs.writeFileSync(filename, msg); | |
// send it | |
child = exec('msmtp -t < ' + filename, function(error, stdout, stderr) { | |
if (stdout != null) console.log('stdout:' + stdout); | |
if (error != null) { | |
if (stderr != null) console.log('stderr:' + stderr); | |
console.log(error); | |
} | |
}); | |
} | |
sendMessage('mail@example.com', 'this is subject', 'たれぱんだはとてつもなくかわいい'); |
![]() |
メール系のテストをするとこうなるよねw |
さて。
この度、玄関にもPIRセンサーを取り付けました。恐ろしいことに15mのワイヤ(余ってた6芯の電話線)による有線接続ですw センサーをほどよくナナメに固定するのは結構難しいのですが、玩具として売られているお湯で柔らかくなるプラスチックを使いました。80度のお湯に3分ほどつけておくと練り消しゴム状態になり、好きな形に成型してから冷します。プラスチックというよりもスーパーゴムのような素材なので、パッキングがわりに使ったり、断線しやすいiPhoneコネクタの補強、壊れた自転車用パーツの補修などに使えると思います。これでまた3Dプリンタの購入が遠ざかってしまいました(笑)。
これだけ入って1080円 |
なお、お湯を保温性のあるカップにいれて作業場所まで持っていくのがコツです。PIRセンサーを覆うように形を作っておき、反対側を冷たいドアに押し付けると丁度いい角度に調整することができます。私は面倒くさいので養生テープで止めちゃいましたが、プラスチックの中に磁石埋め込めばそのまま固定できると思います。電子工作において、「ナナメ固定」は結構鬼門ですが、これはホントに便利です。安いし。
![]() |
養生テーブが泣かせます |
これで留守番中に間違ってドアチェーンをかけてしまって外出中のヨメを締め出してしまっても大丈夫だ(ごめん)。
うちは宅配便ぐらいしか来ない&廊下の端で他の住民が通らないから通知ごとに送るようにしていますが、人通りの多いところでは一度送ったら数分間は検出しても送らない、などの工夫が必要かもしれないですね。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Read PIR, Write csv, Push to ShowSensor | |
// | |
// 2015-02-11 : add function : send email when out door sensor detect a visitor | |
// | |
var b = require('bonescript'); | |
var fs = require('fs'); | |
var http = require('http'); | |
var exec = require('child_process').exec, child; // for mail | |
var mailfile = '/root/sendmail.msg'; // for mail | |
var useLED = true; | |
var LED = 'USR3'; | |
var pirInRoom = 'P8_19'; | |
var pirOutDoor = 'P8_18'; | |
b.pinMode(pirInRoom, b.INPUT); | |
b.pinMode(pirOutDoor, b.INPUT); | |
setInterval(readStatus, 100); // Checks the Sensor Every 0.1 Seconds | |
var limitCurrentHour = 12; | |
var limitPrevHour = limitCurrentHour -1; | |
var filename = null; | |
var isStart = false; | |
var countInRoom = 0; | |
var countOutDoow = 0; | |
var prevMinute = 99; | |
var prevHour = 99; | |
function readStatus() { | |
var outDoor = b.digitalRead(pirOutDoor); | |
var inRoom = b.digitalRead(pirInRoom); | |
var tokei = new Date(); | |
var sec = tokei.getSeconds(); | |
var min = tokei.getMinutes(); | |
var hour = tokei.getHours(); | |
var day = tokei.getHours(); | |
if (min != prevMinute) { | |
if (prevHour == 99) prevHour = hour; | |
if (prevMinute == 99) { | |
if (sec == 0) { | |
prevMinute = min; | |
} | |
} else { | |
if (filename == null) { | |
var tempTokei = tokei; | |
if (hour <= limitPrevHour) { | |
tempTokei.setTime(tokei.getTime() - 24*3600*1000); | |
} | |
filename = getStrFilename(tempTokei); | |
// filename = '/root/' + formatDate(tempTokei, "YYYY-MM-DD") + '.txt'; | |
// console.log("filename=" + filename); | |
} | |
if (prevHour == limitCurrentHour-1 && hour == limitCurrentHour) { | |
filename = getStrFilename(tokei); | |
// filename = '/root/' + formatDate(tokei, "YYYY-MM-DD") + '.txt'; | |
// console.log("filename=" + filename); | |
} | |
var sDate = formatDate(tokei, "YYYY-MM-DD hh:mm"); | |
var sInRoom = Math.round(countInRoom /10); | |
var sOutDoor = Math.round(countOutDoor/10); | |
var s = sDate + "," + sInRoom + "," + sOutDoor; | |
fs.appendFile(filename, s + "\n", function(err) { | |
if (err) console.log(err); | |
}); | |
// http://stackoverflow.com/questions/4505809/how-to-post-to-a-request-using-node-js | |
var body = JSON.stringify({ | |
date: sDate, | |
count: sInRoom, | |
outdoor: sOutDoor, | |
email: "mail@example.com" | |
}); | |
console.log(body); | |
try { | |
pushData(body); | |
if (sOutDoor > 10) { | |
sendMessage('mail@example.com', '来客?', 'カウント=' + sOutDoor); | |
} | |
} catch(e) { | |
console.log(body); | |
} | |
prevMinute = min; | |
} | |
prevHour = hour; | |
countInRoom = countOutDoor = 0; | |
} | |
if (inRoom == 0) { // detected | |
countInRoom ++; | |
} | |
if (outDoor == 1) { | |
countOutDoor ++; | |
} | |
if (useLED) b.digitalWrite(LED, outDoor); | |
} | |
function pushData(inBody) { | |
var request = new http.ClientRequest({ | |
// hostname: "192.168.0.70", | |
hostname: "infinite-reaches-8771.herokuapp.com", | |
port: 80, | |
path: "/receive", | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
"Content-Length": Buffer.byteLength(inBody) | |
} | |
}); | |
request.on('response', function (response) { | |
response.on('data', function (chunk) { | |
}); | |
response.on('error', function (chunk) { | |
console.log('BODY: ' + chunk); | |
}); | |
}); | |
request.write(inBody); | |
request.end(); | |
} | |
function getStrFilename(x) { | |
var str = '/root/' + formatDate(x, "YYYY-MM-DD") + '.txt'; | |
console.log("filename=" + str); | |
return str; | |
} | |
function sendMessage(to, subject, message) { | |
// create message file | |
var msg = 'To: ' + to + '\n' + 'Subject: ' + subject + '\n' + message + '\n'; | |
fs.writeFileSync(mailfile, msg); | |
// send it | |
child = exec('msmtp -t < ' + mailfile, function(error, stdout, stderr) { | |
if (stdout != null) console.log('stdout:' + stdout); | |
if (error != null) { | |
if (stderr != null) console.log('stderr:' + stderr); | |
console.log(error); | |
} | |
}); | |
} | |
// http://qiita.com/osakanafish/items/c64fe8a34e7221e811d0 | |
/** | |
* 日付をフォーマットする | |
* @param {Date} date 日付 | |
* @param {String} [format] フォーマット | |
* @return {String} フォーマット済み日付 | |
*/ | |
var formatDate = function (date, format) { | |
if (!format) format = 'YYYY-MM-DD hh:mm:ss.SSS'; | |
format = format.replace(/YYYY/g, date.getFullYear()); | |
format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2)); | |
format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2)); | |
format = format.replace(/hh/g, ('0' + date.getHours()).slice(-2)); | |
format = format.replace(/mm/g, ('0' + date.getMinutes()).slice(-2)); | |
format = format.replace(/ss/g, ('0' + date.getSeconds()).slice(-2)); | |
if (format.match(/S/g)) { | |
var milliSeconds = ('00' + date.getMilliseconds()).slice(-3); | |
var length = format.match(/S/g).length; | |
for (var i = 0; i < length; i++) format = format.replace(/S/, milliSeconds.substring(i, i + 1)); | |
} | |
return format; | |
}; | |
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。