鳴らない、通知
全国のお父さんお母さん、お疲れ様です。寝れてますか?
私が小学生の頃は、小一時間かけて石をけりけり、人通りの少ない道をテクテクと通学していた記憶があります。子供を見守るのは地域の目オンリー、そんな時代でした。
今や時は令和、ちびっこが防犯ブザーやGPS端末を持つのが当たり前になりました。
コドモにGPS?いらなくない?と思っていた私ですが、我が子(かわいい)の入学に合わせてGPS端末を買ってしまいました。(なにかと不安なご時世だし・・・)
購入したのはソフトバンクの「どこかなGPS」という製品で、スマホアプリで位置情報がわかる・最短1分半の位置情報トラッキングができる・指定エリアへのin/outをメールで通知してくれる、というなかなかのスグレモノです。
が、若干の難点として、通知が「メール」一択なんですね。
朝の通学は「ちゃんと通ってるかな?」「ついたかな?」をスマホアプリで追えるんですが、学校が終わった後の帰宅時が厳しい。
下校時間(13時~)に直帰するのか、放課後の子ども教室で遊んで帰ってくるのか(~17時)によって、受け入れ側の準備に支障が出るわけです。
どうせ通知してくれるなら、「帰るぞ~!」を盛大に教えてほしい。
では、作りましょう。
作ったやつ
・Node-RED v3.0.2
・obniz Board 1Y(+ 圧電スピーカー)
"童の帰還"
— ディー | 𝕕𝕜𝕠𝕓𝕒𝕪𝕒𝕤𝕙𝕚 (@mitoreterusuki) May 8, 2023
子(のランドセルのGPS端末)が学校を離れたらリビングにチャイムが鳴るやつ
撮れてないけど、GPS端末から飛ぶ通知メールでキックしてます。 pic.twitter.com/jVCkPXGv0l
つくりかた
0.構成の概要
GPS端末のサービスから通知メールが来たら、Node-REDで検知してobnizに刺した圧電スピーカーを鳴らします。
<フローをJSON形式でExportしたもの>
[{"id":"f7257f0590e1f909","type":"e-mail in","z":"63251b116131104f","name":"","protocol":"IMAP","server":"imap.gmail.com","useSSL":true,"autotls":"required","port":"666","authtype":"BASIC","saslformat":true,"token":"oauth2Response.access_token","box":"INBOX","disposition":"Read","criteria":"UNSEEN","repeat":"30","fetch":"auto","inputs":0,"credentials":{"userid":"dummy@mail.com","password":"ppp"},"x":90,"y":120,"wires":[["77eb48ece28073ad"]]},{"id":"77eb48ece28073ad","type":"switch","z":"63251b116131104f","name":"本文チェック","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"通過しました","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":280,"y":120,"wires":[["6be0778f79389a35"],["3f20c18490d08a05"]]},{"id":"3f20c18490d08a05","type":"debug","z":"63251b116131104f","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":480,"y":200,"wires":[]},{"id":"6be0778f79389a35","type":"obniz-function","z":"63251b116131104f","obniz":"96f2843488d5ae52","name":"chime","code":"msg.payload = await obniz.switch.getWait();\n\nif (msg.payload === 'push') {\n // 押されたとき\n obniz.display.clear(); // 画面を消去\n obniz.display.print('beep!'); // beep! と画面に表示\n obnizParts.Speaker.stop(); // 音をとめる\n} else {\n // 何も押していない\n obniz.display.clear(); // 画面を消去\n obniz.display.print('GPSAlert'); // GPSAlert と画面に表示\n obnizParts.Speaker.play(783.991); // C5 ソ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(987.767); // C5 シ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(880.000); // C5 ラ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(587.330); // C5 レ\n obniz.wait(2000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(1000);\n\n obnizParts.Speaker.play(587.330); // C5 レ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(880.000); // C5 ラ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(987.767); // C5 シ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(783.991); // C5 ソ\n obniz.wait(3000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(500);\n\n obnizParts.Speaker.play(987.767); // C5 シ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(783.991); // C5 ソ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(880.000); // C5 ラ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(587.330); // C5 レ\n obniz.wait(2000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(1000);\n obnizParts.Speaker.play(587.330); // C5 レ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(880.000); // C5 ラ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(987.767); // C5 シ\n obniz.wait(1000);\n obnizParts.Speaker.stop(); // 音をとめる\n obniz.wait(200);\n\n obnizParts.Speaker.play(783.991); // C5 ソ\n obniz.wait(3000);\n\n\n obnizParts.Speaker.stop(); // 音をとめる\n obnizParts.WS2811.rgb(0, 0, 255); // 青\n\n\n}\n\nreturn msg;","x":470,"y":100,"wires":[["22e3b0ddad64583f"]]},{"id":"22e3b0ddad64583f","type":"debug","z":"63251b116131104f","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":660,"y":100,"wires":[]},{"id":"96f2843488d5ae52","type":"obniz","obnizId":"1234-1234","deviceType":"obnizboard1y","name":"obniz_man","accessToken":"","code":"obniz.display.clear(); // 画面を消去\nobnizParts.Speaker = obniz.wired(\"Speaker\", { signal: 0, gnd: 1 });\nobnizParts.WS2811 = obniz.wired('WS2811', { gnd: 7, vcc: 8, din: 9 });"}]
1.通知メールの検知
通知メールの検知は、Node-REDの「node-red-node-email
」を使用します。
対象となるメールボックスを定期的に監視し、未読メールがあったら条件分岐で「本文に"指定エリアを離れた"文言が入っているか」をチェックします。(この場合、学校の半径〇mから離れたか)
2.obnizを鳴らす
Functionノードで、obnizに刺したスピーカーを鳴らします。
音を鳴らすにもいろいろありますが、今回はシンプルな圧電スピーカーを使いました。
3.メロディを決める
圧電スピーカーだと、ザ・Beep音!って感じのサウンドが想起されるんですが、それだとあまり楽しくないですね。
可愛い子の帰宅を知らせるのですから、チャイムくらい鳴らしましょう。
obnizParts.Speaker.play(783.991); // C5 ソ
obniz.wait(1000);
obnizParts.Speaker.stop(); // 音をとめる
obniz.wait(200);
obnizParts.Speaker.play(987.767); // C5 シ
obniz.wait(1000);
obnizParts.Speaker.stop(); // 音をとめる
obniz.wait(200);
obnizParts.Speaker.play(880.000); // C5 ラ
obniz.wait(1000);
obnizParts.Speaker.stop(); // 音をとめる
obniz.wait(200);
obnizParts.Speaker.play(587.330); // C5 レ
obniz.wait(2000);
obnizParts.Speaker.stop(); // 音をとめる
obniz.wait(1000);
シンプル!
こちらのメロディは下記のリンクを参考に作成しました。
スピーカーのサイズ感どおり音も小さいので、そこはご愛敬です。
どうだったか
実際動かしてみて、「リビングにチャイムが鳴る」ギミックはスマホから離れていても帰宅のタイミングがわかるので家族にも好評でした。
次は紙コップ工作で「スピーカーの音量をブーストする」に着手します!