siroitori0413 が 2021年05月05日13時41分42秒 に編集
プログラムの修正とその説明を追記
本文の変更
# お風呂の消し忘れお知らせ装置 我が家では私と夫と子供の家族3人暮らし。全員気ままに生活しており、毎日家族がお風呂に入る順番はまちまち。 お風呂は自動で沸かしてますが次に入る人がいたりいなかったりで、自動保温のまま何時間も放置されることがしばしばです。 『これではガス代がもったいない!』 ということで、これを重大な問題と捉えた私はobnizで消し忘れをお知らせする装置を作成することにしました。 ## 実現したいこと 夜11時になったらその後お風呂に入る人はいないとみなし、その時点でついたままになっていた場合に、音と光でお知らせする。 - 夜11時になったら稼働 → スリープ機能を活用して電池による給電(obniz Board 1Yの機能を有効活用) - お風呂のついたまま判定 → 台所の壁に設置されているお風呂リモコンの電源ランプの点灯状態を光センサーで検知して判定してみる - 音と光でお知らせ → obniz Board 1Yに直接接続したSpeakerとLEDを制御する ![台所の壁にあるお風呂リモコンに仕込んだ装置](https://camo.elchika.com/6347d6a86f6eaa64828f739fa74951777bb891df/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30613439623061322d303637642d343831662d616535342d6662376130303834316537342f31336332393161302d633836392d343338352d613665302d653864343266383635343065/) # 材料 - obniz Board 1Y × 1個 - 単三電池× 3個 - [Grove 光センサー](https://www.switch-science.com/catalog/2854/)× 1個 - [圧電ブザー(Speaker)](https://amzn.to/3xah6zU) × 1個 - [抵抗入りLED](https://www.switch-science.com/catalog/5199/) × 1個 # 作り方 以下のように接続します。 ![配線図](https://camo.elchika.com/6937dccda19ce852b04c1e3ce9340eed007897f4/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30613439623061322d303637642d343831662d616535342d6662376130303834316537342f64656632653331382d633139302d346133312d626265382d656538393239613139303063/) ケースは3Dプリンターで設計・出力しました。フィラメントはPETGです。 # プログラム(script箇所抜粋) ```html: <script> // 以下は、30秒(20000)待ってもonConnect内の処理が最後まで終了しなかった場合に稼働する。エラー時のために必ず書く //Timeout 30s var tid = setTimeout(() => { console.log('30Seconds timeout!'); //23時間後に起動 obniz.sleepMinute(23 * 60); }, 30000); // OBNIZ_ID_HERE will be replaced at run. // インストールされたデバイス情報に書き換わる var obniz = new Obniz("OBNIZ_ID_HERE"); var sensor; // Called on Online // 接続時に呼ばれる。 obniz.onconnect = async function () { console.log('24 時間で起動テスト'); // 光センサーをobnizに接続 sensor = obniz.wired("Grove_LightSensor", {gnd:0, vcc:1, signal: 3}); // 光センサーで明るさを取得 var value = await sensor.getWait(); console.log('value:' + value); if (value > 0.2){ // 閾値:0.2 を超える値の時は電気の消し忘れ判定 console.log('消し忘れ警報発令'); // LED点灯 var led = obniz.wired("LED", {anode:5, cathode:6}); led.on(); // 音を鳴らして通知する await melodyOn(); // LED点灯 led.off(); } // 次の日の23時に起動する(日付は後で変えるので適当) var nextTimeDate = new Date('2019/01/01 23:00'); var nowDate = new Date();
// 次回起動日時に最初に今日を設定する
// 【修正】例えばお昼にプログラムを修正するなどしてテスト起動した時にもその日の夜にも実行してほしいため // 以下ロジックとしたが、日時指定のobniz.sleepでは誤差が生じてしまい実際には23時前に起動してしまい、 // 23時前であるため、もう一度実行されてしまう。(例えば同じ日の22:48と23:00に二度起動される) // このため必ず次の日の23時に動作するように修正した。(誤差は無視) // // 次回起動日時に最初に今日を設定する // nextTimeDate.setYear(nowDate.getYear() + 1900); // nextTimeDate.setMonth(nowDate.getMonth()); // nextTimeDate.setDate(nowDate.getDate()); // // 今日の起動時刻が現在より後かどうか確認 // if (nowDate >= nextTimeDate){ // // 今日の起動時刻を過ぎてしまっている場合は1日未来に設定 // nextTimeDate.setDate(nowDate.getDate() + 1 ); // } // 次回起動日時に最初に明日を設定する
nextTimeDate.setYear(nowDate.getYear() + 1900); nextTimeDate.setMonth(nowDate.getMonth());
nextTimeDate.setDate(nowDate.getDate());
nextTimeDate.setDate(nowDate.getDate() + 1);
// 今日の起動時刻が現在より後かどうか確認 if (nowDate >= nextTimeDate){ // 今日の起動時刻を過ぎてしまっている場合は1日未来に設定 nextTimeDate.setDate(nowDate.getDate() + 1 ); }
console.log('次回起動日時:' + nextTimeDate); // sleep obniz.sleep(nextTimeDate); //program finish wait... await obniz.wait(1000); clearTimeout(tid); if (typeof done === "function") { done(); } } // Called on Offline // 切断時に呼ばれる obniz.onclose = async function () { //tempsens = null; sensor = null; } // Speakerからメロディーを鳴らす async function melodyOn(){ var speaker = obniz.wired("Speaker", {signal:11, gnd:8}); //for(var i=0; i<=2; i++){ speaker.play(880); //880hz:ラ await obniz.wait(300); speaker.stop(); await obniz.wait(100); speaker.play(880); //880hz:ラ await obniz.wait(300); speaker.stop(); await obniz.wait(100); speaker.play(784); //784hz:ソ await obniz.wait(300); speaker.stop(); await obniz.wait(100); speaker.play(880); //880hz:ラ await obniz.wait(300); speaker.stop(); await obniz.wait(100); speaker.play(784); //784hz:ソ await obniz.wait(200); speaker.stop(); speaker.play(698); //698hz:ファ await obniz.wait(200); speaker.stop(); speaker.play(659); //659hz:ミ await obniz.wait(200); speaker.stop(); speaker.play(587); //587hz:レ await obniz.wait(200); speaker.stop(); speaker.play(523); //523hz:ド await obniz.wait(400); speaker.stop(); } </script> ``` ## プログラム設定方法 ①「管理者コンソール」の レガシー > リポジトリ に上記プログラムを登録。 ②レガシー > サーバーレスイベント に トリガーを「obniz Hardware Event」、実行するアプリケーションに①を設定して作成。 プログラム内にスリープのロジックを書いているので定期的にスリープから目覚めます。上記設定をしていることで目覚めたタイミングでサーバーレスイベントが走ります。 サーバーレスイベントの画面の作成したイベント名をクリックすることでいつ起動したかを確認することができ、そのときのログも確認することができるので便利です。あとで確認したくなりそうな項目はconsole.logで出力しておくと良いです。 ![サーバーレスイベントの画面のログ](https://camo.elchika.com/19b776e671d55e4cbc9a29f84368b41aeafe675e/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30613439623061322d303637642d343831662d616535342d6662376130303834316537342f35626163363138352d303030352d346165352d396631302d616264633266336430666339/) ## 解説 - 閾値について 電気の消し忘れ判定に、光センサーの値を0.2以上かどうか(0.2以上の時は消し忘れと判定)で設定しました。 周囲の光も入ってしまうため、周囲の照明をつけてみたりいろいろなパターンで計測して決めました。 **実はお風呂の電源をオフっているときでも以下の時は0.2以上の値が取得されてしまいます。** **・お昼間** **・台所の換気扇のところの照明点灯時** 今回は夜限定で通知を行いたいのでお昼間の測定はしないためOKとし、換気扇のところの照明点灯時にお知らせしてしまう件については夜にその換気扇照明が点いているのも消したいから教えてほしいので通知も結果オーライとしました。 - 最初のtimeoutについて var tid = setTimeout(() => { ~~ }, 30000); の部分は、30秒待ってもプログラムがエラーなどで最後まで終わらなかったときに発動します。 何かのはずみでエラーになったりしてプログラムが最後まで終わらなかったときに電源がつきっぱなしになるので気が付いたら電池が切れていたということにならないための対策です。 - メロディについて 圧電ブザーを鳴らすのにせっかくなのでメロディにしてみました(メロディはアマリリスの一節より)。 メロディにしないほうが電池の持ちは良いだろうなとは思います。 ついでにLEDも特に必要ないと思いますがせっかく抵抗付きLEDを購入したのでつけてみた感じです。
++【2021/5/5 追記】次回起動時間について(プログラムを修正しています)++ 連続稼働していたところ問題が発生して気が付きました。 例えばお昼にプログラムを修正するなどしてテスト起動した時にもその日の夜にも実行してほしいため、「PM11時より前であればその日に実行、PM11時より後であれば次の日に実行」というプログラムとしていました。 ですが、**日時指定のobniz.sleepでは誤差が生じてしまい実際には23時前に起動**してしまっていました。 そして23時前であるため、もう一度実行されてしまいます。(例えば同じ日の22:48と23:00に二度起動されます) このため、**必ず「次の日」の23時に動作するように修正**しました。(**実際には誤差があるので23時より前に起動**します)
## 参考情報(obniz公式情報) ■ Grove光センサのobniz使用方法 https://obniz.com/ja/sdk/parts/Grove_LightSensor/README.md ■ LEDのobniz使用方法 https://obniz.com/ja/sdk/parts/LED/README.md ■ 圧電ブザー(Speaker)のobniz使用方法 https://obniz.com/ja/sdk/parts/Speaker/README.md ■ スリープ仕様 https://obniz.com/ja/doc/reference/common/sleep # 完成 (動画33秒) @[youtube](https://youtu.be/Q15y-0KfysI) # おわりに - LINE通知 最初はLINE通知をしようとしてましたが、それが実装できるのはNode.jsのときのみでした。(クラウドのHTML+CSSではCORSの関係でLINE通知のAPIは動作しないということを身をもって体験しました。) Node.jsでは実装できる([公式情報を参考](https://blog.obniz.com/make/notify-line-mail-arrives))ということだったので、いったんはNode.jsで作って動作するところまで確認しましたが、 ・Node.jsを稼働させるサーバーが必要 ・そもそもスマホへの通知はあまり気が付かない(LINEは通知がありすぎてあまり確認しない…) という理由から、物理音で通知させるように変更してやっぱりクラウド実行するようにしました。 サーバーレスで簡単に動かせ、スリープ機能で電池起動できるobniz Board 1Yの機能を味わいました。 ハード初心者にも使いやすい良いデバイスだと思いました。 まだまだたくさんのできることがあり、これからもたくさん作っていきたいと思います。