ポキオ(@pokiiio)です。
Node-RED Advent Calendar 2018の12日目を担当させていただきます。ゆるいネタでよろしくおねがいします。
TL;DR
- Node-RED is すごい
- 困ったらFunction NodeにJSでつらつら書けばいい
- JSと親和性が低い処理はExec Nodeでやってしまえばいい
- ちょっとダサいけど、なんでもできます
最高のプロトタイピングツール
ノンプログラミングで、ノードとノードをつなぐだけのフローで処理がデザインできるツールということで、Node-REDを一度知ってからは、ちょいちょい使わせていただいております。個人的にお気に入り(?)な使い方をシェアさせてください。
Function Nodeの凄み
Node-REDは、その豊富なNodeのおかげで簡単に処理をデザインできることに強みがあると思います。ただ、あまりにもマニアックな処理ができるNodeは準備されていないことが多いですが、そんなときに役立つのがFunction Nodeです。
たとえば、私は京急が好きで、京急の運行情報ページから運行情報をしばしばパースするのですが、そんなノードなければFunction Nodeで書いちゃえばよいのです。
普段ArduinoなどのCっぽい言語に慣れている身からすると、JavaScriptはHTTP-GETなどが簡単にできるしrequireも使えるので、最高に便利です。
例:
[{"id":"3ad520c3.545e78","type":"tab","label":"フロー 1","disabled":false,"info":""},{"id":"80cbf517.c17cc8","type":"twitter-credentials","z":"","screen_name":"@pokiiiwo"},{"id":"3eb4297b.7362fe","type":"twitter in","z":"3ad520c3.545e78","twitter":"80cbf517.c17cc8","tags":"@keikyu_official","user":"user","name":"京急公式Twitterに新しい投稿","topic":"tweets","inputs":0,"x":180,"y":100,"wires":[["60533152.38f37"]]},{"id":"22429d61.35d622","type":"inject","z":"3ad520c3.545e78","name":"京急 + 山手線","topic":"","payload":"","payloadType":"date","repeat":"600","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":140,"wires":[["60533152.38f37"]]},{"id":"60533152.38f37","type":"http request","z":"3ad520c3.545e78","name":"京急運行情報取得","method":"GET","ret":"txt","url":"http://unkou.keikyu.co.jp","tls":"","x":150,"y":180,"wires":[["77d3de0e.446b9"]]},{"id":"77d3de0e.446b9","type":"function","z":"3ad520c3.545e78","name":"京急運行情報パース","func":"msg.payload = msg.payload.split(\"<div class=unko-panel>\")[1];\nmsg.payload = msg.payload.split(\"</div>\")[0];\nmsg.payload = msg.payload.replace(/\\r?\\n/g,\"\");\nmsg.keikyu = msg.payload;\nmsg.payload = null;\nreturn msg;","outputs":1,"noerr":0,"x":160,"y":220,"wires":[["49eb60e7.4544c"]]},{"id":"49eb60e7.4544c","type":"http request","z":"3ad520c3.545e78","name":"JR運行情報取得","method":"GET","ret":"txt","url":"https://transit.yahoo.co.jp/traininfo/detail/21/0/","tls":"","x":140,"y":260,"wires":[["8119d93e.e43388"]]},{"id":"8119d93e.e43388","type":"function","z":"3ad520c3.545e78","name":"JR運行情報パース","func":"msg.payload = msg.payload.split(\"\\\"og:description\\\" content=\\\"\")[1];\nmsg.payload = msg.payload.split(\"(\")[0];\nmsg.payload = msg.payload.replace(/\\r?\\n/g,\"\");\nmsg.yamanote = msg.payload;\nmsg.payload = null;\nreturn msg;","outputs":1,"noerr":0,"x":150,"y":300,"wires":[["1fbe8bb5.87f034"]]},{"id":"6f00e56f.8150ec","type":"exec","z":"3ad520c3.545e78","command":"python /home/pi/GitHub/TextToEPaper/text_to_e_paper.py","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"電子ペーパーに表示","x":480,"y":280,"wires":[[],[],[]]},{"id":"1fbe8bb5.87f034","type":"function","z":"3ad520c3.545e78","name":"keikyu, yamanote -> payload","func":"msg.payload = \"京浜急行 \\\"\" + msg.keikyu + \"\\\" 山手線 \\\"\" + msg.yamanote + \"\\\"\";\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":140,"wires":[["71e04a63.eb8114"]]},{"id":"7dac4a68.ffcf04","type":"inject","z":"3ad520c3.545e78","name":"","topic":"起動時","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"5","x":150,"y":60,"wires":[["60533152.38f37"]]},{"id":"71e04a63.eb8114","type":"switch","z":"3ad520c3.545e78","name":"差分があった場合だけ更新","property":"payload","propertyType":"msg","rules":[{"t":"neq","v":"info","vt":"global"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":500,"y":180,"wires":[["b6900e34.b64bb"],[]]},{"id":"b6900e34.b64bb","type":"function","z":"3ad520c3.545e78","name":"globalにセット","func":"global.set(\"info\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":460,"y":220,"wires":[["6f00e56f.8150ec"]]}]
何でもできるExec Node
Function Nodeだけでも最強なんですが、それを遥かに凌駕するのがExec Nodeです(個人の感想です)。
というのも以前、[Raspberry Pi用の電子ペーパーハットを買って、そこに天気予報を表示するガジェットを作ったんですが・・・](。
電子ペーパーといっても仕組みは単純で、ちょうどいいサイズの画像をプログラム上で作成して、それを特別なコマンドで電子ペーパーに貼り付けるだけ。コマンドは、いわゆるコマンドラインから叩くようなもので、また画像作成にはJavaScriptではなくPythonのPillowを使ってました(画像処理はPythonのほうが楽)。
定期的な処理をさせるのは、Node-REDで簡単に設計できるが、Pythonとかコマンドラインツールとはあまり親和性が高く感じられないかもしれません。そこでExec Nodeです。
結論から言っちゃえば、Node-REDだろうがPythonのスクリプトやらコマンドラインツールは簡単に叩けて、
cd ~/GitHub/WeatherDisplayForEPapers;python create_weather_image.py;papirus-draw image.png
例えばこんなようなコマンドをExec Nodeで実行するだけ。そのNodeが、よしなに定期的に実行されるように仕込んでしまえば、常に最新の天気予報が電子ペーパーに表示できるというわけです。
その他、電子ペーパーハット上のハードスイッチのイベントもNode-REDで簡単に拾えるので、ボタンが押されたら表示内容を変えたりするなどの処理も簡単にかけます。
それ、Node-REDじゃなくてよくね?
って言われたら最後ですが、別にプロダクトのコードではなく、サンデープログラマのクソコードなので、なんと言われても強い気持ちで生きていきます。