郵便物が届いたらLINEにお知らせ
コンテンツ
今回やること
LINE NotifyのAPIを使って、郵便物が届いたらLINEで通知するシステムを作ります。
関連記事:IoT x 郵便物の通知
システムの流れは以下の通りです。
-
- 郵便受けの天井に取り付けた距離センサーが、郵便受けの床までの距離を常時計測しています。
- 郵便物が郵便受けに入れられると、その距離が縮まるため、郵便物が届いたことを検知することができます。
- 郵便物が届いたことを検知すると、LINE NotifyのAPIを叩いて、LINEに通知します。
- 郵便物が届いたことが手元でわかり、ハッピーになります!
(この実装では、郵便物を取り出すときも距離が変わるため反応してしまいますが、郵便受けの前にいないときに通知を受け取るために動かす想定としています。)
用意するもの
- obniz Board
- 赤外線距離センサー GP2Y0A21YK0F
- 電源 (モバイルバッテリーなど)
- LINEアカウント
組み立て方
赤外線距離センサーのライブラリを参考に、下の表や図のようにobnizに赤外線距離センサーGP2Y0A21YK0Fを配線します。
obniz | 赤外線距離センサー GP2Y0A21YK0F |
---|---|
0 | Vcc |
1 | GND |
2 | signal |
プログラム
郵便受けの天井から床までの距離を300ミリ秒おきに計測し、その変化量が一定値を超えたらLINE Notifyで通知をする仕組みになっています。
LINE Notifyのページにアクセスしログインした後、マイページを開きます(要LINEアカウント)。
マイページをスクロールすると、 アクセストークンの発行(開発者向け) という項目があるので、こちらの トークンを発行する をクリックします。
通知の際に表示するトークン名を入力し、 1:1でLINE Notifyから通知を受け取る を選択します(トークン名はここでは posted としました)。
発行する をクリックすると以下のようにトークンが表示されるので、紛失しないように控えておきましょう。このページを離れてしまうとトークンを確認することができなくなってしまいます。
7行目 LINE_NOTIFY_TOKEN_HERE
の部分を、ここで控えたトークンにかきかえてください。
最後に、LINEのアプリケーションからLINE Notifyのアカウントを忘れずに友達登録しておきましょう。
完成したプログラム
Node.jsでかかれたコードです。
const fs = require("fs"),
request = require("request"),
Obniz = require("obniz"),
{ createCanvas } = require("canvas");
const LINE_NOTIFY_URL = "https://notify-api.line.me/api/notify";
const TOKEN = "LINE_NOTIFY_TOKEN_HERE";
const POSTED_THOREHOLD = 2.0;
const MESSAGE = "郵便物が投函されました。";
const HEADERS = {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Bearer " + TOKEN
};
const OPTIONS = {
url: LINE_NOTIFY_URL,
method: "POST",
headers: HEADERS,
json: true,
form: {
message: MESSAGE
}
}
let distanceVals = [];
let passCount = 8;
let passFlag = false;
let obniz = new Obniz("OBNIZ_ID_HERE");
let connected = await obniz.connectWait({timeout:10});
if(connected){
obniz.display.clear();
const canvas = createCanvas(128, 64);
const ctx = canvas.getContext("2d");
ctx.fillStyle = "white";
ctx.font = "20px Avenir";
let disSensor = obniz.wired("GP2Y0A21YK0F", {vcc:0, gnd:1, signal:2});
let rawDistance = 0;
let changeDiffAbs = 0;
rawDistance = await disSensor.getWait();
await obniz.wait(500);
rawDistance = await disSensor.getWait();
await arrangeArray(distanceVals, rawDistance);
obniz.repeat(async () => {
rawDistance = await disSensor.getWait();
changeDiffAbs = await calChangeDiffAbs(distanceVals, rawDistance);
await console.log(changeDiffAbs);
if(passFlag){
await passCount--;
if(passCount <= 0){
passCount = 8;
passFlag = false;
obniz.display.clear();
}
return;
}
if(changeDiffAbs < POSTED_THOREHOLD || Number.isNaN(changeDiffAbs)){
return;
}
await request(OPTIONS, async(error, response, body) => {
console.log(body);
ctx.fillText("郵便物が", 0, 26);
ctx.fillText("届いています",0,56);
obniz.display.draw(ctx);
passFlag = true;
if(error){
console.log(error);
}
});
}, 300);
}
async function arrangeArray(arr, val){
const ARR_LIMIT_NUM = 20;
await arr.push(val);
if(arr.length > ARR_LIMIT_NUM){
await arr.shift();
}
}
async function calPrevChangeAve(arr){
let prevChanges = [];
for(let i=0; i < arr.length-1; i++){
await prevChanges.push((arr[i+1]-arr[i])/300 * 10);
}
let denoNum = prevChanges.length;
let total = await prevChanges.reduce((sum, data) => {return sum + data}, 0);
return total / denoNum;
}
async function calChangeDiffAbs(arr, val){
let prevVal = arr[arr.length-1];
let currentChange = (prevVal - val)/300 * 10;
let prevChangeAve = await calPrevChangeAve(arr);
let diff = await Math.abs(prevChangeAve - currentChange);
await arrangeArray(arr, val);
return diff;
}
うごかす
プログラムを実行すると、郵便物が届くごとに、LINE Notifyから通知が来るようになります。 (うまく反応しない時は、9行目の POSTED_THOREHOLD
の値を調整してみてください。)
おわりに
このように、obnizとLINE Notifyを使うことによって、センサーの値に応じて簡単にLINEへ通知を送ることができます。 ぜひ活用してみてください。