EnOcean

obnizとLineとEnOcean環境センサー&スイッチを使った高齢者見守り&連絡システム

この記事はobniz Advent Calendar 2020の18日目の記事です。

ほんと、早いもので12月も半分が過ぎ来ました。激動の2020年も残り2週間を切りました。

で、今年のobnizアドベントカレンダーでは、調べ物をしながら書いたのですでに4つの記事を上げることができました。

今回はこれまでの記事の内容を全部盛り込んだ、「遠隔地に住む高齢の親のゆるい見守り&連絡システム」についてご紹介いたします。

実行の様子

システムの概要

Thume 1217

故郷の実家に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のフロー

12 17
[{"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環境センサーとスイッチ

12 17

フロー上のEnOcean環境センサーとスイッチからのデータをNode-REDで受信する方法は下記の記事を参照ください。

12 17

今回は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を開け締めする

12 17

EnOcean環境センサーは1分置きに温度、湿度、照度、ドアの開閉状態、充電池残量をNode-REDに送っています。

そのままLineでメッセージとして送ると、Line Message APIの無料枠(1000通/月)を超えてしまうので、この”gate”というノードを使ってLineに送るか止めるかをコントロールしています。

この方法について解説します。

12 17

まずは”obniz repeat”ノードのところから。

12 17

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;
    
}
12 17

同じメッセージが何度も送られないように、”delayノード”を使って流量制限しています。

simple gate

12 17

フローを任意で閉じたり開いたりできるnode-red-contrib-simple-gate (node)を利用しました。

12 17

このノードは、payloadに”open,close,status”, topicに”control”を入れることで、ゲートを操作してくれます。

obnizにgateの状態を表示

12 17

“status”ノードを使って”gate”ノードに変更があったことを取得、”obniz function”でobnizのディスプレイにgateの状態が表示されるようにしています。

12 17 12 17

“status”ノードからは、msg.status.textでくるのでfunctionノードはそれを msg.payloadにうつしているだけです。そして、”obniz function”でobnizの画面に表示します。

Line Message

12 17

EnOcean環境センサーからの情報はgateの状態によって送信をコントロール、EnOceanスイッチからのデータはそのままLine Messageに送ってます。

Node-REDからLineにメッセージを送る方法は、こちらの記事をご覧ください。

  • obnizのジョグダイヤルを操作するとNode-REDを通してLineにメッセージが送れる仕組み|デジタルライト(Digital-light.jp)
  • obniz 画面クリア

    12 17

    こちらにて、obnizの画面をクリアにする処理をしてます。でもこれって、Node-REDを立ち上げたときに起動するので、あまり意味ないです。

    この仕組のポイント

    ポイント1

    環境センサーからは、照度、湿度、温度、ドアの開閉状態(マグネットコンタクトを利用)を取得することができるので、その変化の様子から、いつもどおりに生活しているのか?そうでないのか?といった判断をする情報を入手できます。

    ポイント2

    スマートフォンなどを使うのが難しい高齢者にも、スイッチを押せばメッセージが送ることができるので、ちょっとさみしいときや、連絡がほしいときなど、気軽にスイッチを押して連絡をとる手段を提供できます。

    ポイント3

    EnOceanの環境センサーやスイッチはエナジーハーベスティングといって、太陽電池やボタンを押すときの電力を利用するので、バッテリーの交換が必要ありません。

    なので、遠く離れた実家でも、一度設置すれば数年間そのまま利用することができます。

    まとめ

    obnizアドベントカレンダー2020がきっかけでいろいろ試したことを集約した記事をかきました。

    親もかなりの年齢になってきたので、いろいろ心配になるようなこともあります。

    実家の環境センサーからの情報を、気になったときはLineでみれるようにすることで、いつもどおり生活しているなとか、部屋の温度がずっと低いままで怪しいけどドアの開閉は頻繁にしているみたいだから問題なさそうだなとか、事実に基づいて判断ができるような手段をもっていると、便利なのではないかなと思います。

    ちなみに、EnOceanのBLEセンサーとスイッチはスイッチサイエンスさんで入手できますので、ぜひ、チェックしてみてください。

    ABOUT ME
    中畑 隆拓
    スマートライト㈱ 代表取締役。IoTソリューションの開発、スマートホーム&オフィスのコンサルティング、DALI,KNX,EnOceanなどのインテグレーションを行っています。

    COMMENT

    メールアドレスが公開されることはありません。 が付いている欄は必須項目です