あっ、もうお迎えの時間だ!!
育休から復帰し時短で働いているのですが、
仕事に集中しているとあっという間に終業時間になってしまいます。
在宅時でも出社時でも、お迎えの時間をお知らせしてくれる機能ほしい~
でもワーママ、そんなに作りこむ時間はない。
ということで、簡単に作れるものでお悩み解決してみましょう。
作ってみた~出社時編~
会社から保育園が遠いので、電車に乗り遅れるわけにはいかない。
終業時間になったら、乗り遅れないよう何度も急かしてほしい。
こんな感じになったよ
使ったもの
- IFTTT
- Google Apps Script (以後、GASと記述)
- LINE Notify
参考(ほぼほぼコピペ):
薬の飲み忘れ防止!?1日3回「お薬飲んだ?」とLINEで確認してくれる
機能説明
簡単に作りたいので、IFTTTを使います。レッツノーコード!
- 「IF」はWebhooksを使用。
- 「Then」はLINEを使用。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F3569867%2Fce41fae4-9beb-b48c-10c4-33e0e072a658.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=090cdcce7ffe38042a0ca860961383d2)
Webhooks設定
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F3569867%2F3fbc99bd-462d-b76a-707c-013837188898.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=21fc7d8d5a9710c621610aa9ddc7d94f)
- 「Receive a web request」を設定
- Event Nameの「timer」は後述するGASで設定するイベント名
これでトリガーの設定は完了。はや。
LINEの通知を設定
IFTTTと連携させたLINE Notifyを使用。
「会社出る時間だよ」というグループLINEを作り、自分とLINE Notifyを招待しておく。そして送るメッセージを設定。
- 「Value」の中身は後述のGASで設定。メッセージのレイアウト。
GASを使って通知時間とメッセージの設定
コードは以下。
function line1620() {
var url =
"https://maker.ifttt.com/trigger/timer/with/key/取得したキー?value1=16:20だよ!&value2=そろそろ会社出よう!"
UrlFetchApp.fetch(url);
}
設定したイベント名「timer」やIFTTTで取得したwebhookキーの設定を行う。
LINEで送るメッセージも通知ごとに変えたいのでここで設定!
これを、16:20~16:35までの5分ごとのバージョンを作り、それぞれにトリガーを設定してLINEに通知するように設定。
「特定の時間」選択がなく、「特定の日時」なので、日付時刻までいちいち設定しなければならない。
それで、最初の画像のようにLINEメッセージが5分ごとに通知される。
※自分が乗りたい電車に間に合うように急かすため、今回5分毎の設定にしてます。
作ってみた~在宅時編~
こちらです
仕事に集中してると保育園のお迎え時刻にいつの間にかなるので、「蛍の光」でお知らせしてみた
— そってぃ (@sotan115) December 4, 2023
⚠️音出ます#protoout #obniz #保育園お迎え pic.twitter.com/TjS5ZDnvPb
終業時刻になると「蛍の光」が流れ、LEDが点滅します。
あぁ。。終わりの時間だ。。って気分になりますね~。
使ったもの
- enebular
- Node-RED
- obniz Board 1Y
- スピーカー
- LED(抵抗内蔵)
作ったものはこちら
在宅時は集中してスマホを気にしないことがあるので、
視覚的・聴覚的に分かるように obnizで作りました。
内容説明
Node-REDのフローがこちら。(今回はenebularで作ったよ!)
JSON形式のコードはこちら
[{"id":"322dca747679dad5","type":"tab","label":"フロー 1","disabled":false,"info":"","env":[]},{"id":"cb1d6d3a.017e1","type":"debug","z":"322dca747679dad5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":490,"y":60,"wires":[]},{"id":"11a346f0.5a4c19","type":"obniz-function","z":"322dca747679dad5","obniz":"d2c14997c96ad5c0","name":"","code":"msg.payload = \"finish\";\nawait obniz.wait(1000); \nobniz.close();\n\nreturn msg;","x":320,"y":60,"wires":[["cb1d6d3a.017e1"]]},{"id":"76e43759.3dff68","type":"inject","z":"322dca747679dad5","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":60,"wires":[["11a346f0.5a4c19"]]},{"id":"e4ca22ab.554c7","type":"obniz-function","z":"322dca747679dad5","obniz":"d2c14997c96ad5c0","name":"","code":"const sp1 = 2000 // 全音符・全休符\nconst sp2 = sp1 / 2 // 2分音符・2分休符\nconst sp4 = sp1 / 4 // 4分音符・4分休符\nconst sp8 = sp1 / 8 // 8分音符・8分休符\nconst sp16 = sp1 / 16 // 16分音符・16分休符\nconst sp2_34 = sp2 + sp4 // 付点2分音符・付点2分休符 \nconst sp4_34 = sp4 + sp8 // 付点4分音符・付点4分休符\nconst sp8_34 = sp8 + sp16 // 付点8分音符・付点8分休符\nconst sp16_34 = sp16 + (sp16 / 2) // 付点16分音符・付点16分休符\n\n//任意の秒数待つことができる関数\n// 参考: https://qiita.com/suin/items/99aa8641d06b5f819656\nconst sleep = (msec) => new Promise(res => setTimeout(res, msec));\n\nobniz.display.clear(); // 画面を消去\n\n// ド\nobnizParts.Speaker.play(130.813); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// ふぁ\nobnizParts.Speaker.play(174.614); await sleep(sp4_34); obnizParts.Speaker.stop(); await sleep(sp4_34);\n// ふぁ\nobnizParts.Speaker.play(174.614); await sleep(sp8); obnizParts.Speaker.stop(); await sleep(sp8);\n// ふぁ\nobnizParts.Speaker.play(174.614); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// ら\nobnizParts.Speaker.play(220.000); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// そ\nobnizParts.Speaker.play(195.998); await sleep(sp4_34); obnizParts.Speaker.stop(); await sleep(sp4_34);\n// ふぁ\nobnizParts.Speaker.play(174.614); await sleep(sp8); obnizParts.Speaker.stop(); await sleep(sp8);\n// そ\nobnizParts.Speaker.play(195.998); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// ら\nobnizParts.Speaker.play(220.000); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// ふぁ\nobnizParts.Speaker.play(174.614); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// ふぁ\nobnizParts.Speaker.play(174.614); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// ら\nobnizParts.Speaker.play(220.000); await sleep(sp4); obnizParts.Speaker.stop(); await sleep(sp4);\n// ど\nobnizParts.Speaker.play(261.626); await sleep(300); obnizParts.Speaker.stop(); await sleep(700);\n// れ\nobnizParts.Speaker.play(293.665); await sleep(1000); obnizParts.Speaker.stop();\n","x":400,"y":140,"wires":[[]]},{"id":"2bcc39b304890674","type":"obniz-function","z":"322dca747679dad5","obniz":"d2c14997c96ad5c0","name":"","code":"// 任意の秒数待つことができる関数\n// 参考: https://qiita.com/suin/items/99aa8641d06b5f819656\nconst sleep = (msec) => new Promise(res => setTimeout(res, msec));\n\nobniz.display.clear(); // 画面を消去\n\nobnizParts.led.on(); await sleep(3000);\nobnizParts.led.off(); await sleep(1000);\nobnizParts.led.on(); await sleep(3000);\nobnizParts.led.off(); await sleep(1000);\nobnizParts.led.on(); await sleep(3000);\nobnizParts.led.off(); await sleep(1000);\nobnizParts.led.on(); await sleep(3000);\nobnizParts.led.off(); await sleep(1000);","x":400,"y":220,"wires":[[]]},{"id":"4c93f0b7f6201e39","type":"inject","z":"322dca747679dad5","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"20 07 * * 1,2,3,4,5","once":false,"onceDelay":"0.1","topic":"","payload":"お迎えの時間だよ","payloadType":"str","x":150,"y":180,"wires":[["e4ca22ab.554c7","2bcc39b304890674"]]},{"id":"d2c14997c96ad5c0","type":"obniz","obnizId":"xxxx-xxxx","deviceType":"obnizboard1y","name":"","accessToken":"","code":"obniz.display.clear(); // 画面を消去\r\nobnizParts.Speaker = obniz.wired(\"Speaker\", { signal: 0, gnd: 1 });\r\nobnizParts.led = obniz.wired('LED', { anode: 10, cathode: 11 });\r\n//obnizParts.WS2811 = obniz.wired('WS2811', { gnd: 0, vcc: 1, din: 2 });"}]
①injectノードで特定の時間を指定
injectノードで、指定した日時に処理を開始するように設定しました。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F3569867%2F63e0b192-d367-71af-8cf7-c00b9879d957.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=ebda34174b4e886c373eec67f42cc3ec)
時間設定が「UTC協定世界時」なので「JST日本標準時」に当てはめて設定する必要がある。
今回はJST「16:20」開始にしたかったのでUTC「7:20」に設定
②スピーカーとLED点滅を実行
スピーカーのfunctionには、「蛍の光」の音符を探して、音符の長さとともに設定。
閉店間際のスーパーとかでこの曲が流れてるイメージなので「蛍の光」を採用。
LEDのfunctionには音楽とともにLEDが点滅するように設定。
複雑なコードは使わず、簡単に作れたよ~
使ってみた感想
我ながら便利なものが出来たと思う。
出社時はいつでも保育園の連絡に対応できるようスマホは常に携帯しているので、
どこにいても通知してくれるのはありがたい。
ただ、出社時にいちいち設定しなければならないのはネック・・・。
在宅時は逆に、自宅が保育園に近いため、あまりスマホの連絡を頻繁に気にすることがない。視覚的・聴覚的に分かるのでありがたい。
在宅なので周りに迷惑もかけないしね!
今回は「簡単に」作りたかったのであえて作りこまなかったが、
蛍の光をフルバージョンで流してもよいしLEDの点滅の仕方を工夫してもいいな。
さいごに
簡単に、課題解決できるの最高っす
やっぱり、出来ることは限られるので、カスタマイズしたい気持ちになるものの、
そんな時間も惜しいときは欲しい機能だけでもノーコードローコードでちゃちゃっと作れるの、とっても良いですね!
そもそも、コード書くの苦手な私にうってつけ!(職業:システムエンジニア)
ちなみに
出社時保育園に迎えに行くとき夫に毎度連絡するのが面倒なので
ノーコードで解決した記事がこちら↓ あわせて使うとまぁ便利!