Node-RED オンラインリアクションシステムのシンプル版を作ったメモ

Node-RED リアクションシステムのシンプル版を作ったメモです。

背景

2020年の東海大学組込みソフトウェア開発特別講義をオンラインでしてきました

最近、大学の講義などオンラインではリアクションが分かりにくいという課題感を感じていて、Node-REDで参加者のスマホからリアクションを集めるシステムを作りました。

こちらでも、IoT機器と結び付けて、結構面白いシステムにできているなということで、データベースで記録する機能を外したり、他の人が使う上では分かりにくい構造を見直したりとシンプルに組みなおして、他の人でも使いやすいように整えてみます。

今回はウォームアップということで、

  • ユーザーからリアクション(いいね!)をもらう機能
  • リアクション(いいね!)をリセットするまで合計して表示する機能
  • 5秒ごとのリアクション(いいね!)をグラフに表示する機能

という最低限の機能に絞り込んでみます。

image

実際にこのように動きます。

Node-REDのフロー

image

フローはこのようになっております。

実際のフローJSONです。そのまま、以下のフローをインポートすると使えます。

[{"id":"9a083219.2940d","type":"change","z":"97e7ed62.9283","name":"全体の反応カウント = 0","rules":[{"t":"set","p":"countAllReaction","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":40,"wires":[["ce1ebf4.66f1d4"]]},{"id":"758aca36.9b9064","type":"change","z":"97e7ed62.9283","name":"定期的な反応カウント = 0","rules":[{"t":"set","p":"countConstantReaction","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":120,"wires":[[]]},{"id":"45503112.bd4bd","type":"comment","z":"97e7ed62.9283","name":"カウントリセット","info":"","x":130,"y":40,"wires":[]},{"id":"ff549c36.34979","type":"inject","z":"97e7ed62.9283","name":"リセット","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":80,"wires":[["c66bb9be.a6d818"]]},{"id":"c66bb9be.a6d818","type":"function","z":"97e7ed62.9283","name":"<HUB>","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":80,"wires":[["9a083219.2940d","758aca36.9b9064"]]},{"id":"dcb0a2c3.0639f","type":"comment","z":"97e7ed62.9283","name":"ユーザーいいねボタン","info":"","x":140,"y":220,"wires":[]},{"id":"3bd8828b.da863e","type":"comment","z":"97e7ed62.9283","name":"定期的な反応カウント","info":"","x":140,"y":360,"wires":[]},{"id":"6b4d0f69.2b019","type":"ui_button","z":"97e7ed62.9283","name":"","group":"a7682b4e.aa5fd8","order":3,"width":"6","height":"3","passthru":false,"label":"いいね!","tooltip":"","color":"","bgcolor":"","icon":"thumb_up","payload":"","payloadType":"str","topic":"","x":100,"y":260,"wires":[["bf6fed5c.6386c"]]},{"id":"a9552932.f92e88","type":"change","z":"97e7ed62.9283","name":"全体の反応カウント 加算","rules":[{"t":"set","p":"countAllReaction","pt":"flow","to":"$flowContext(\"countAllReaction\") + 1\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":260,"wires":[["ce1ebf4.66f1d4"]]},{"id":"ae2edaee.b16ae8","type":"change","z":"97e7ed62.9283","name":"定期的な反応カウント 加算","rules":[{"t":"set","p":"countConstantReaction","pt":"flow","to":"$flowContext(\"countConstantReaction\") + 1\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":300,"wires":[[]]},{"id":"23e0b238.736a1e","type":"inject","z":"97e7ed62.9283","name":"定期実行","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":400,"wires":[["a8093ca.fa7f3c"]]},{"id":"cf17624d.915ce","type":"change","z":"97e7ed62.9283","name":"定期的な反応カウント リセット","rules":[{"t":"set","p":"countConstantReaction","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1030,"y":400,"wires":[[]]},{"id":"57ded5fa.fca0cc","type":"ui_chart","z":"97e7ed62.9283","name":"いいね!カウント グラフ","group":"a7682b4e.aa5fd8","order":2,"width":0,"height":0,"label":"5秒ごとの経過","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"100","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":770,"y":400,"wires":[["cf17624d.915ce"]]},{"id":"a8093ca.fa7f3c","type":"change","z":"97e7ed62.9283","name":"定期的な反応カウント -> msg.payload","rules":[{"t":"set","p":"payload","pt":"msg","to":"countConstantReaction","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":400,"wires":[["57ded5fa.fca0cc"]]},{"id":"ce1ebf4.66f1d4","type":"change","z":"97e7ed62.9283","name":"全体の反応カウント -> msg.payload","rules":[{"t":"set","p":"payload","pt":"msg","to":"countAllReaction","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":830,"y":260,"wires":[["e108a1c9.92952"]]},{"id":"e108a1c9.92952","type":"ui_template","z":"97e7ed62.9283","group":"a7682b4e.aa5fd8","name":"いいねカウント","order":1,"width":"6","height":"3","format":"<div\n    class=\"md-display-1\"\n    layout=\"row\"\n    layout-align=\"center center\">いいねカウント</div>\n<div\n    class=\"md-display-3\"\n    layout=\"row\"\n    layout-align=\"center center\"\n    ng-bind-html=\"msg.payload\"></div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":1120,"y":260,"wires":[[]]},{"id":"751c9fab.d7252","type":"inject","z":"97e7ed62.9283","name":"グラフリセット","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[]","payloadType":"json","x":540,"y":460,"wires":[["57ded5fa.fca0cc"]]},{"id":"bf6fed5c.6386c","type":"function","z":"97e7ed62.9283","name":"<HUB>","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":320,"y":260,"wires":[["a9552932.f92e88","ae2edaee.b16ae8"]]},{"id":"d922bf46.0d1d6","type":"inject","z":"97e7ed62.9283","name":"テスト用いいね!","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":300,"wires":[["bf6fed5c.6386c"]]},{"id":"2b58a103.ecc4ee","type":"inject","z":"97e7ed62.9283","name":"リセット","repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":580,"wires":[["70f6bdaf.50a604"]]},{"id":"70f6bdaf.50a604","type":"function","z":"97e7ed62.9283","name":"<HUB>","func":"\nreturn msg;","outputs":1,"noerr":0,"x":300,"y":580,"wires":[["9b3f0936.057668","9bac55f5.112c88"]]},{"id":"fb2a532b.4bb25","type":"change","z":"97e7ed62.9283","name":"全体の反応カウント = 0","rules":[{"t":"set","p":"countAllReaction","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":950,"y":540,"wires":[[]]},{"id":"fac5006f.652a4","type":"change","z":"97e7ed62.9283","name":"定期的な反応カウント = 0","rules":[{"t":"set","p":"countConstantReaction","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":960,"y":600,"wires":[[]]},{"id":"9b3f0936.057668","type":"switch","z":"97e7ed62.9283","name":"countAllReaction check","property":"countAllReaction","propertyType":"flow","rules":[{"t":"null"}],"checkall":"true","repair":false,"outputs":1,"x":590,"y":540,"wires":[["fb2a532b.4bb25"]]},{"id":"9bac55f5.112c88","type":"switch","z":"97e7ed62.9283","name":"countConstantReaction check","property":"countConstantReaction","propertyType":"flow","rules":[{"t":"null"}],"checkall":"true","repair":false,"outputs":1,"x":610,"y":600,"wires":[["fac5006f.652a4"]]},{"id":"a7480b50.0f67b8","type":"comment","z":"97e7ed62.9283","name":"初期値設定","info":"","x":100,"y":520,"wires":[]},{"id":"a7682b4e.aa5fd8","type":"ui_group","z":"","name":"Reaction System","tab":"c700a7c8.2b7498","order":1,"disp":false,"width":"6","collapse":false},{"id":"c700a7c8.2b7498","type":"ui_tab","z":"","name":"ホーム","icon":"dashboard","order":2,"disabled":false,"hidden":false}]
  • 8/31 はじめてのフロー
  • 9/3 初期値の設定の処理を調整

使い方

Node-REDのバージョンは 1.0.4 で話を進めます。

image

こちらのページを参考に上記のフローJSONをインポートして、デプロイをします。

image

デプロイ出来たら仕組みは完了です。ダッシュボードタブからダッシュボードを表示してみます。

image

このように表示されたら準備完了です。あとは、このURLを参加者に配布していいね!をクリックしてもらいましょう。

image

カウントリセットはこちらの inject ノードで行えます。

image

グラフの表示もリセットしたい場合は、こちらのグラフリセットと書いてある inject ノードをクリックするとクリアされます。