この記事はobniz Advent Calendar 2020の18日目の記事です。
ほんと、早いもので12月も半分が過ぎ来ました。激動の2020年も残り2週間を切りました。
で、今年のobnizアドベントカレンダーでは、調べ物をしながら書いたのですでに4つの記事を上げることができました。
今回はこれまでの記事の内容を全部盛り込んだ、「遠隔地に住む高齢の親のゆるい見守り&連絡システム」についてご紹介いたします。
実行の様子
システムの概要
故郷の実家にEnOcean環境センサーとEnOceanスイッチとラズパイを設置し、スイッチを押すとLineにメッセージを送信、obnizのジョグダイヤルを押すと環境センサーの情報がLineに通知される仕組みです。
EnOcean環境センサー&スイッチからRaspberry PIまではBLEで通信、ラズパイ上のNode-REDで受信して、Line Message APIを利用したnode-red-contrib-line-messaging-apiノードを使ってLineのチャンネルに送信します。
EnOcean 環境センサーSTM 550Bは、初期設定で1分置きにデータを送信します。
しかし、Line Message APIの無料利用枠は、メッセージの送信回数が月1000回なので、obnizのジョグダイヤルを使ってメッセージ送信許可&停止の切り替えを行います。
また、EnOceanスイッチには、スイッチに応じて4種類のメッセージを設定し、スイッチが押されるとLineにメッセージが送られる仕組みです。
使う機器は下記の通り
Node-REDのフロー
[{"id":"845452ca.ebe95","type":"BLE Beacon Scanner","z":"2d251ac3.0545a6","name":"BLE Scanner","x":130,"y":260,"wires":[["83f79504.55e718"]]},{"id":"83f79504.55e718","type":"switch","z":"2d251ac3.0545a6","name":"フィルター","property":"payload.id","propertyType":"msg","rules":[{"t":"eq","v":"e50010000efb","vt":"str"},{"t":"eq","v":"e21500015886","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":230,"y":320,"wires":[["a21d1c80.faaf7"],["15b9e06a.1083"]]},{"id":"15b9e06a.1083","type":"delay","z":"2d251ac3.0545a6","name":"流量制限","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"0.1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":400,"y":380,"wires":[["a87368c4.938668"]]},{"id":"a87368c4.938668","type":"function","z":"2d251ac3.0545a6","name":"電文デコード","func":"var Packet = msg.payload.other;\nvar data = Packet[6];\nmsg.payload = data;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":560,"y":380,"wires":[["3f839a04.2a31a6"]]},{"id":"3f839a04.2a31a6","type":"function","z":"2d251ac3.0545a6","name":"メッセージ処理","func":"var value = msg.payload;\nvar message = \"na\";\n\nif ( value == \"3\") {\n message = \"元気だ心配するな\"; \n} else if ( value == \"5\") {\n message = \"ちょっとしんどい\";\n} else if (value == \"9\" ) {\n message = \"お前は元気か?\";\n} else if ( value ==\"17\" ) {\n message = \"連絡よこせ\";\n}\n\nif ( message != \"na\" ) {\n msg.payload = message;\n return msg;\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":660,"y":420,"wires":[["76002df3.bba914","a291475a.9149b8"]]},{"id":"76002df3.bba914","type":"debug","z":"2d251ac3.0545a6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1030,"y":660,"wires":[]},{"id":"eb9a7c42.ffe4f","type":"function","z":"2d251ac3.0545a6","name":"電文デコード","func":"var Packet = msg.payload.other\nvar Temp = (Packet[8]*256+Packet[7])/100\nvar Humid = Packet[10]/2\nvar Lux = Packet[13]*256+Packet[12]\nvar Energy = Packet[22]/2\nvar contact = Packet[20]\nif ( contact == 2 ) { contact = \"Close\" } else { contact = \"Open\" } \n \nvar data = {\n \"Temp\": Temp,\n \"Humid\": Humid+'%',\n \"Lux\": Lux+'lux',\n \"Contact\": contact,\n \"Energy\": Energy+'%'\n}\nmsg.payload = data\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":560,"y":260,"wires":[["ae68f3b1.80ec6"]]},{"id":"a21d1c80.faaf7","type":"delay","z":"2d251ac3.0545a6","name":"流量制限","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"0.1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":400,"y":260,"wires":[["eb9a7c42.ffe4f"]]},{"id":"a291475a.9149b8","type":"PushMessage","z":"2d251ac3.0545a6","name":"","channelSecret":"6597e38e39f03dcee1b2799275f1b608","channelAccessToken":"vjGkB+FUGJo0EU6fnbz0W/LRhsgoQc3YiHE/2AUKqco2h6UC5gU3oWC676x27tIfhA3pIC0kWsicESySx7yBr7B3xz70pUQaIlcwsAnjWEPlGSJ3pWIDPxG2hWwuEIRbNmvOg1mUWqn0NSlj0OhJto9PbdgDzCFqoOLOYbqAITQ=","targetId":"U93a6837671a1518d9d9df7a08eef437d","x":1100,"y":440,"wires":[]},{"id":"ae68f3b1.80ec6","type":"function","z":"2d251ac3.0545a6","name":"メッセージ処理","func":"var data = msg.payload;\nvar message = \"温度:\"+data['Temp']+\"\\n湿度:\"+data['Humid']+\"\\n照度:\"+data['Lux']+\"\\nドア:\"+data['Contact']+\"\\n電池残量:\"+data['Energy'];\nmsg.payload = message;\nreturn msg\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":660,"y":300,"wires":[["6d345f29.71d4e"]]},{"id":"6d345f29.71d4e","type":"gate","z":"2d251ac3.0545a6","name":"","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","statusCmd":"status","persist":false,"x":850,"y":360,"wires":[["76002df3.bba914","a291475a.9149b8"]]},{"id":"60a2c23.759553c","type":"inject","z":"2d251ac3.0545a6","name":"open","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"control","payload":"open","payloadType":"str","x":830,"y":120,"wires":[["6d345f29.71d4e"]]},{"id":"d568f44f.b72858","type":"inject","z":"2d251ac3.0545a6","name":"close","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"control","payload":"close","payloadType":"str","x":830,"y":160,"wires":[["6d345f29.71d4e"]]},{"id":"dff1b7d3.d89d88","type":"inject","z":"2d251ac3.0545a6","name":"status","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"control","payload":"status","payloadType":"str","x":830,"y":200,"wires":[["6d345f29.71d4e"]]},{"id":"e5afd8a0.953c88","type":"status","z":"2d251ac3.0545a6","name":"gate status","scope":["6d345f29.71d4e"],"x":360,"y":620,"wires":[["4be0b6b1.6f6368"]]},{"id":"4be0b6b1.6f6368","type":"function","z":"2d251ac3.0545a6","name":"","func":"var status = msg.status.text;\n\nmsg.payload = status;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":520,"y":620,"wires":[["2ec7bd52.c2f7b2"]]},{"id":"c62f3017.c31b2","type":"obniz-repeat","z":"2d251ac3.0545a6","obniz":"dd3656da.037ea8","name":"","interval":100,"code":"var state = await obniz.switch.getWait();\nvar gate;\n\nmsg.topic = \"control\";\n\nif ( state != \"none\"){\n \n if ( state == \"left\" ) {\n gate = \"open\";\n } else if ( state == \"right\") {\n gate = \"close\";\n } else {\n gate = \"status\";\n }\n \n msg.payload = gate;\n \n return msg;\n \n}","x":370,"y":500,"wires":[["6978b34c.df5bec"]]},{"id":"1f2320e9.eea82f","type":"debug","z":"2d251ac3.0545a6","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1010,"y":620,"wires":[]},{"id":"7d7133bf.a8229c","type":"comment","z":"2d251ac3.0545a6","name":"環境センサー","info":"","x":410,"y":220,"wires":[]},{"id":"54b5c5c9.97026c","type":"comment","z":"2d251ac3.0545a6","name":"スイッチ","info":"","x":400,"y":340,"wires":[]},{"id":"2ec7bd52.c2f7b2","type":"obniz-function","z":"2d251ac3.0545a6","obniz":"dd3656da.037ea8","name":"","code":"var state = msg.payload;\n\n\nobniz.display.clear();\n\nobniz.display.print(state);","x":700,"y":620,"wires":[[]]},{"id":"6978b34c.df5bec","type":"delay","z":"2d251ac3.0545a6","name":"流量制限","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":540,"y":500,"wires":[["1f2320e9.eea82f","6d345f29.71d4e"]]},{"id":"9bd2b34d.8b41f","type":"comment","z":"2d251ac3.0545a6","name":"gate テスト","info":"","x":810,"y":80,"wires":[]},{"id":"1d75a6e6.c5da29","type":"comment","z":"2d251ac3.0545a6","name":"obniz 操作","info":"","x":360,"y":460,"wires":[]},{"id":"167ffadf.f339a5","type":"comment","z":"2d251ac3.0545a6","name":"gate状態","info":"","x":360,"y":580,"wires":[]},{"id":"aa76d823.ed5718","type":"inject","z":"2d251ac3.0545a6","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":380,"y":700,"wires":[["76aa574.03a2fa8"]]},{"id":"76aa574.03a2fa8","type":"obniz-function","z":"2d251ac3.0545a6","obniz":"dd3656da.037ea8","name":"","code":"obniz.display.clear();","x":600,"y":700,"wires":[[]]},{"id":"f6428eb7.0796b","type":"comment","z":"2d251ac3.0545a6","name":"obniz 画面クリア","info":"","x":380,"y":660,"wires":[]},{"id":"dd3656da.037ea8","type":"obniz","z":"","obnizId":"40930779","deviceType":"obnizboard","name":"","accessToken":"","code":""}]
Node-REDのフローはこのようになります。
EnOcean環境センサーとスイッチ
フロー上のEnOcean環境センサーとスイッチからのデータをNode-REDで受信する方法は下記の記事を参照ください。
① EnOcean 環境センサーのデータをNode-REDで受信する方法
高齢者のゆるい見守りに!EnOcean環境センサとobnizを使った見守りシステム
② EnOceanスイッチのデータをNode-REDで受信する方法
obnizとEnOceanスイッチを使って故郷の親が軽くメッセージを送れるシステム|デジタルライト(Digital-light.jp)
今回はLineに送るので日本語でも大丈夫です。なので、上記のようにLineに送るメッセージを設定しました。
var value = msg.payload; var message = "na"; if ( value == "3") { message = "元気だ心配するな"; } else if ( value == "5") { message = "ちょっとしんどい"; } else if (value == "9" ) { message = "お前は元気か?"; } else if ( value =="17" ) { message = "連絡よこせ"; } if ( message != "na" ) { msg.payload = message; return msg; }
obnizのジョグスイッチでgateを開け締めする
EnOcean環境センサーは1分置きに温度、湿度、照度、ドアの開閉状態、充電池残量をNode-REDに送っています。
そのままLineでメッセージとして送ると、Line Message APIの無料枠(1000通/月)を超えてしまうので、この”gate”というノードを使ってLineに送るか止めるかをコントロールしています。
この方法について解説します。
まずは”obniz repeat”ノードのところから。
obniz.switch.getWait()でジョグダイヤルの状態を取得し、gateノードに送るデータ形式にこちらで変換しています。
var state = await obniz.switch.getWait(); var gate; msg.topic = "control"; if ( state != "none"){ if ( state == "left" ) { gate = "open"; } else if ( state == "right") { gate = "close"; } else { gate = "status"; } msg.payload = gate; return msg; }
同じメッセージが何度も送られないように、”delayノード”を使って流量制限しています。
simple gate
フローを任意で閉じたり開いたりできるnode-red-contrib-simple-gate (node)を利用しました。
このノードは、payloadに”open,close,status”, topicに”control”を入れることで、ゲートを操作してくれます。
obnizにgateの状態を表示
“status”ノードを使って”gate”ノードに変更があったことを取得、”obniz function”でobnizのディスプレイにgateの状態が表示されるようにしています。
“status”ノードからは、msg.status.textでくるのでfunctionノードはそれを msg.payloadにうつしているだけです。そして、”obniz function”でobnizの画面に表示します。
Line Message
EnOcean環境センサーからの情報はgateの状態によって送信をコントロール、EnOceanスイッチからのデータはそのままLine Messageに送ってます。
Node-REDからLineにメッセージを送る方法は、こちらの記事をご覧ください。
obniz 画面クリア
こちらにて、obnizの画面をクリアにする処理をしてます。でもこれって、Node-REDを立ち上げたときに起動するので、あまり意味ないです。
この仕組のポイント
ポイント1
環境センサーからは、照度、湿度、温度、ドアの開閉状態(マグネットコンタクトを利用)を取得することができるので、その変化の様子から、いつもどおりに生活しているのか?そうでないのか?といった判断をする情報を入手できます。
ポイント2
スマートフォンなどを使うのが難しい高齢者にも、スイッチを押せばメッセージが送ることができるので、ちょっとさみしいときや、連絡がほしいときなど、気軽にスイッチを押して連絡をとる手段を提供できます。
ポイント3
EnOceanの環境センサーやスイッチはエナジーハーベスティングといって、太陽電池やボタンを押すときの電力を利用するので、バッテリーの交換が必要ありません。
なので、遠く離れた実家でも、一度設置すれば数年間そのまま利用することができます。
まとめ
obnizアドベントカレンダー2020がきっかけでいろいろ試したことを集約した記事をかきました。
親もかなりの年齢になってきたので、いろいろ心配になるようなこともあります。
実家の環境センサーからの情報を、気になったときはLineでみれるようにすることで、いつもどおり生活しているなとか、部屋の温度がずっと低いままで怪しいけどドアの開閉は頻繁にしているみたいだから問題なさそうだなとか、事実に基づいて判断ができるような手段をもっていると、便利なのではないかなと思います。
ちなみに、EnOceanのBLEセンサーとスイッチはスイッチサイエンスさんで入手できますので、ぜひ、チェックしてみてください。