LoginSignup
6
2

エアコン嫌いの家族を熱中症から守りたい

Last updated at Posted at 2024-06-05

どうしてクーラーつけないの?!

ある夏の日に実家に帰った時のこと。
うだるような暑さの中、リビングでクーラーもつけずにテレビを見る父がいた。
かろうじてシーリングファンは回っていたものの、父の隣で寝そべっている猫もぐったりしている。驚いて「どうしてクーラーつけないの?!」と聞いたら、「窓開けてれば、涼しいよ」と、ニコニコしながら父は言った。

人は老化が進むにつれ、温度に対する感覚が弱くなる

人は老化が進むと熱放射能力が低くなり、深部体温が上昇しやすい。また、温度に対する感覚も弱くなり「暑い」と感じにくくなったり、喉の渇きを感じにくくなったりすることで、熱中症にかかりやすいと言われている。
【参考文献】
・熱中症ゼロへ
 熱中症、こんな人は特に注意!

熱中症の約4割は室内で発生している

消防庁の統計によると、熱中症の約4割が室内で発生しており、熱中症死亡者数で見ると65歳以上の高齢者が8割を占めている。
屋内で熱中症により亡くなった高齢者の約9割は、エアコンがあるのに使用していなかったとのことだ。
【参考文献】
・weathernews
 15年で3倍以上 死者数の8割を占める高齢者の熱中症対策
・消防庁
 全国の熱中症による救急搬送状況 令和5年7月24日~7月30日(速報値)

LINE Botを活用して家族を守る仕組みを考える

どうしたら離れて暮らす家族を守ることができるのか考えてみた。
考えた仕組みは以下2点である。
LINEのあて先 : 両親、離れて暮らしている家族を想定

・温度センサー
 一定の時間ごとに自動で室内の温度を測り、LINE Botでお知らせして注意喚起する
・超音波距離センサー
 一定の時間ごとに室内で人の動きがあるか検知し、LINE Botでお知らせする
 人の動きがない場合は家族に安否確認するよう促す

活用ツール

・obniz(OSのひとつで、瞬時に動作が始まるIoTを実現)
 ・温度センサー(LM60)
 ・超音波距離センサー(HCSR04)

・Node-RED
・JavaScript
・LINEmessagingAPI

フロー

・上段・・処理停止用ノード(説明は省略)
・下段・・処理実行用ノード
スクリーンショット 2024-06-04 18.17.38.png

ソースコード(処理実行用ノード)

[{"id":"c61534fcfc6e08b2","type":"obniz-repeat","z":"19f26d722b829ed2","obniz":"2a612d9a43b88fcd","name":"センサーデータ取得","interval":"3600000","code":"const LM60Value = await obnizParts.LM60.getWait();\nconst HCSR04Value = await obnizParts.HCSR04.measureWait();\nmsg.payload = { temperature: LM60Value, distance: HCSR04Value };\nreturn msg;","x":270,"y":200,"wires":[["c7e273cea974653f"]]},{"id":"c7e273cea974653f","type":"function","z":"19f26d722b829ed2","name":"メッセージ生成","func":"let temperature = msg.payload.temperature;\nlet distance = msg.payload.distance;\n\nif (temperature < 28) {\n    msg.payload = '【熱中症注意!窓を開けて!】現在の気温は' + temperature + '度です。';\n} else {\n    msg.payload = '【熱中症警告!エアコンをつけて!】現在の気温は' + temperature + '度です。';\n}\n\nif (distance >= 1000) {\n    msg.payload += '\\n【安否確認】動きが検出されませんでした。確認してください。';\n} else {\n    msg.payload += '\\n動きが検出されました。';\n}\n\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":460,"y":200,"wires":[["be193680201d4aae"]]},{"id":"be193680201d4aae","type":"BloadcastMessage","z":"19f26d722b829ed2","name":"LINEメッセージ送信","x":660,"y":200,"wires":[[]]},{"id":"2a612d9a43b88fcd","type":"obniz","obnizId":"****-****","deviceType":"obnizboard1y","name":"","accessToken":"","autoConnectOnDeploy":true,"code":"// 画面を消去\r\nobniz.display.clear();\r\n\r\n// LM60温度センサーの設定\r\nobnizParts.LM60 = obniz.wired(\"LM60\", {\r\n    gnd: 0,      // GNDピンの接続\r\n    output: 1,   // アナログ出力ピンの接続\r\n    vcc: 2       // VCCピンの接続\r\n});\r\n\r\n// HC-SR04超音波センサーの設定\r\nobnizParts.HCSR04 = obniz.wired(\"HC-SR04\", {\r\n    gnd: 3,      // GNDピンの接続\r\n    echo: 4,     // Echoピンの接続\r\n    trigger: 5,  // Triggerピンの接続\r\n    vcc: 6       // VCCピンの接続\r\n});\r\n"}]

①センサーデータ取得

・温度センサー(LM60)と、超音波距離センサー(HCSR04)のデータを取得し、msg.payloadに"temperature"と"distance"を代入する
・"interval":"3600000"=1時間ごとに稼働するよう設定

②メッセージ生成

msg.payloadに代入されたそれぞれのデータを呼び出し、メッセージを生成する
 ・温度(temperature)
  28℃未満だった場合
  ・・【熱中症注意!窓を開けて!】現在の気温は⚫︎度です。
  その他(28℃以上)だった場合
  ・・【熱中症警告!エアコンをつけて!】現在の気温は⚫︎度です。

 ・距離(distance)
  1m以内で動きがあるか確認
  動きなし・・【安否確認】動きが検出されませんでした。確認してください。
  動きあり・・動きが検出されました。

③Broadcastノード

LINE Botにメッセージを送信する

結果

 警告バージョンと注意喚起バージョンが無事送信された。
IMG_8953.jpg

考察

今回はobniz1台で粘ったので、稼働時間を分けることが出来なかった。
できれば動きの検出については、6時間に1回などに回数を減らしたい。
メッセージを受け取る対象を誰にするかによっても、稼働のタイミングは変えた方が良さそうだ。
取得したデータを活かして、自動でエアコンをON、OFFする仕組みも作ることができそう。
家族が離れて暮らしていても、見守り・フォローする体制ができていれば、安心して過ごせるのではないだろうか。親世代はとにかくクーラーをつけたがらない。それを認識しておくだけでも防げる事故があるはずだ。

おまけ

前回作成したLINE Botに部屋の温度を測る機能をプラスした。
これでいつでも温度を確認することができる。
全体フローを紹介
スクリーンショット 2024-06-05 2.48.57.png

[{"id":"97811561ee3a6b19","type":"Webhook","z":"9ef9e62fc4a4dae4","name":"","url":"/webhook","x":120,"y":340,"wires":[["bc574decf74c8274"]]},{"id":"2fb4f5b04158148f","type":"ReplyMessage","z":"9ef9e62fc4a4dae4","name":"","replyMessage":"","x":800,"y":340,"wires":[]},{"id":"bc574decf74c8274","type":"switch","z":"9ef9e62fc4a4dae4","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"朝食","vt":"str"},{"t":"eq","v":"朝ごはん","vt":"str"},{"t":"eq","v":"昼食","vt":"str"},{"t":"eq","v":"ランチ","vt":"str"},{"t":"eq","v":"昼ごはん","vt":"str"},{"t":"eq","v":"気温教えて","vt":"str"},{"t":"eq","v":"温度教えて","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":8,"x":290,"y":340,"wires":[["2a93e82fe561e35d"],["2a93e82fe561e35d"],["9f0c3636c6dc4d9a"],["9f0c3636c6dc4d9a"],["9f0c3636c6dc4d9a"],["be0cd555c1d96a7e"],["be0cd555c1d96a7e"],["117eda19e0f3da20"]]},{"id":"2a93e82fe561e35d","type":"function","z":"9ef9e62fc4a4dae4","name":"朝食","func":"function getRandomElement(array) {\n    return array[Math.floor(Math.random() * array.length)];\n}\n\nconst categories = {\n    onigiri: [\"鮭おにぎり\", \"梅おにぎり\", \"昆布おにぎり\"],\n    sandwich: [\"ハムサンド\", \"卵サンド\", \"ツナサンド\"],\n    salad: [\"チキンサラダ\", \"ツナサラダ\", \"シーザーサラダ\"],\n    yogurt: [\"プレーンヨーグルト\", \"フルーツ入りヨーグルト\", \"ギリシャヨーグルト\"],\n    fruit: [\"カットフルーツ(メロン、パイナップルなど)\", \"バナナ\", \"りんご\"],\n    smoothie: [\"野菜スムージー\", \"フルーツスムージー\", \"プロテインスムージー\"],\n    cerealBar: [\"グラノーラバー\", \"ナッツ&シードバー\", \"フルーツバー\"],\n    hotMenu: [\"おでん\", \"中華まん\", \"焼き芋\"],\n    bread: [\"クロワッサン\", \"ベーグル\", \"ブランパン\"],\n    others: [\"サバの塩焼き\", \"枝豆\", \"ゆで卵\"],\n    drink: [\"豆乳\", \"プロテインドリンク\", \"ミルク\"]\n};\n\nconst randomSelection = {\n    onigiri: getRandomElement(categories.onigiri),\n    sandwich: getRandomElement(categories.sandwich),\n    salad: getRandomElement(categories.salad),\n    yogurt: getRandomElement(categories.yogurt),\n    fruit: getRandomElement(categories.fruit),\n    smoothie: getRandomElement(categories.smoothie),\n    cerealBar: getRandomElement(categories.cerealBar),\n    hotMenu: getRandomElement(categories.hotMenu),\n    bread: getRandomElement(categories.bread),\n    others: getRandomElement(categories.others),\n    drink: getRandomElement(categories.drink)\n};\n\n// 結果を整形してメッセージとして設定\nmsg.payload = `\n今日のおすすめ朝食メニュー:\nおにぎり: ${randomSelection.onigiri}\nサンドイッチ: ${randomSelection.sandwich}\nサラダ: ${randomSelection.salad}\nヨーグルト: ${randomSelection.yogurt}\nフルーツ: ${randomSelection.fruit}\nスムージー: ${randomSelection.smoothie}\nシリアルバー: ${randomSelection.cerealBar}\nホットメニュー: ${randomSelection.hotMenu}\nパン: ${randomSelection.bread}\nその他: ${randomSelection.others}\n飲み物: ${randomSelection.drink}\n`;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":300,"wires":[["2fb4f5b04158148f"]]},{"id":"9f0c3636c6dc4d9a","type":"function","z":"9ef9e62fc4a4dae4","name":"昼食","func":"function getRandomElement(array) {\n    return array[Math.floor(Math.random() * array.length)];\n}\n\nconst categories = {\n    bento: [\"チキン南蛮弁当\", \"焼肉弁当\", \"鮭弁当\", \"鯖の塩焼き弁当\", \"牛丼弁当\"],\n    sandwich: [\"ローストビーフサンドイッチ\", \"クラブハウスサンドイッチ\", \"カツサンド\", \"エッグサラダサンドイッチ\", \"ツナサラダサンドイッチ\"],\n    salad: [\"シーザーサラダ\", \"チキンサラダ\", \"豆腐サラダ\", \"海藻サラダ\", \"ミックスサラダ(チーズ、ナッツ入り)\"],\n    pasta: [\"ペペロンチーノ\", \"カルボナーラ\", \"ミートソーススパゲッティ\", \"バジルソースパスタ\", \"シーフードパスタ\"],\n    donburi: [\"親子丼\", \"牛丼\", \"海鮮丼\", \"豚丼\", \"天丼\"],\n    soup: [\"ミネストローネ\", \"コーンスープ\", \"わかめスープ\", \"チキンスープ\", \"野菜たっぷりスープ\"]\n};\n\nconst randomSelection = {\n    bento: getRandomElement(categories.bento),\n    sandwich: getRandomElement(categories.sandwich),\n    salad: getRandomElement(categories.salad),\n    pasta: getRandomElement(categories.pasta),\n    donburi: getRandomElement(categories.donburi),\n    soup: getRandomElement(categories.soup)\n};\n\n// 結果を整形してメッセージとして設定\nmsg.payload = `\n今日のおすすめ昼食メニュー:\nお弁当: ${randomSelection.bento}\nサンドイッチ: ${randomSelection.sandwich}\nサラダ: ${randomSelection.salad}\nパスタ: ${randomSelection.pasta}\n丼もの: ${randomSelection.donburi}\nスープ: ${randomSelection.soup}\n`;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":340,"wires":[["2fb4f5b04158148f"]]},{"id":"117eda19e0f3da20","type":"template","z":"9ef9e62fc4a4dae4","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"朝食・朝ごはん\n昼食・昼ごはん・ランチ\nと入力してね!\n\n栄養バランスのポイント\n【たんぱく質】 肉、魚、豆腐、卵などのたんぱく質が豊富な食材を選びましょう。\n【野菜】 サラダやスープに野菜を取り入れて、ビタミンやミネラルを摂取しましょう。\n【炭水化物】 主食としてご飯やパン、パスタなどをバランスよく摂取します。\n【健康的な脂肪】 ドレッシングやナッツ、魚の脂など、健康的な脂肪を適量取り入れます。\n\nおすすめメニューは、栄養バランスを考慮して選んでおり、コンビニや食堂で手軽に手に入るものを中心にしています。","output":"str","x":480,"y":420,"wires":[["2fb4f5b04158148f"]]},{"id":"16f127f2c22e4a7b","type":"template","z":"9ef9e62fc4a4dae4","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"今の温度は {{payload}} 度です!","output":"str","x":680,"y":420,"wires":[["2fb4f5b04158148f"]]},{"id":"be0cd555c1d96a7e","type":"obniz-function","z":"9ef9e62fc4a4dae4","obniz":"2a612d9a43b88fcd","name":"","code":"msg.payload = await obnizParts.LM60.getWait();\nreturn msg;","x":500,"y":380,"wires":[["16f127f2c22e4a7b"]]},{"id":"2a612d9a43b88fcd","type":"obniz","obnizId":"****-****","deviceType":"obnizboard1y","name":"","accessToken":"","autoConnectOnDeploy":true,"code":"// 画面を消去\r\nobniz.display.clear();\r\n\r\n// LM60温度センサーの設定\r\nobnizParts.LM60 = obniz.wired(\"LM60\", {\r\n    gnd: 0,      // GNDピンの接続\r\n    output: 1,   // アナログ出力ピンの接続\r\n    vcc: 2       // VCCピンの接続\r\n});\r\n\r\n// HC-SR04超音波センサーの設定\r\nobnizParts.HCSR04 = obniz.wired(\"HC-SR04\", {\r\n    gnd: 3,      // GNDピンの接続\r\n    echo: 4,     // Echoピンの接続\r\n    trigger: 5,  // Triggerピンの接続\r\n    vcc: 6       // VCCピンの接続\r\n});\r\n"}]

IMG_8968.jpg

・参考(過去の記事)
 栄養を気にしてくれる人(Bot)を作りました!

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2