「せばな」は言わない

綱の上を歩いたり、壁を登ったりする田舎のプログラマーのおはなし

【Raspberry Pi】IoT入門 Azure+Noderedで環境データを見える化作戦 Part2

f:id:tk_thunder:20180213184914p:plain

はじめに

さてさて、前回は本当に疲れましたね。
tk-thunder.hateblo.jp

今回でケリをつけてやりましょう。今回やることはこんな感じです。

  • Noderedのフロー構築
  • Noderedで環境データを定期的に取得
  • AzureのDBに環境データをアップする
  • AzureのDBにアクセスして環境データをグラフ化する

Nodered起動(ようやく登場だよチクショウ!)

まずは、ラズパイ上のNoderedを起動します。
僕はOS Stretchをインスコしているので、Noderedは最初から存在しています。
もしNoderedが入っていなかったらインストールしておきましょう。

参考
qiita.com

まずはNoderedをアップデート。

$ sudo update-nodejs-and-nodered

アップデートが完了したらNoderedを起動。
Noderedを自動起動にしたい場合は下記のコマンドで設定。僕は自動起動にしておきます。

$ sudo systemctl enable nodered.service

それではNodered起動です。

$ sudo node-red-start

実行ログ

Start Node-RED

Once Node-RED has started, point a browser at http://192.168.xx.xx:1880
On Pi Node-RED works better with the Firefox or Chrome browser

Use sudo systemctl enable nodered.service to autostart Node-RED at every boot
Use sudo systemctl disable nodered.service to disable autostart on boot

To find more nodes and example flows - go to http://flows.nodered.org
12 Feb 20:36:15 - [info]

Welcome to Node-RED

ノード追加

Dashboard

表示されているIPにアクセスするとNoderedのフロー編集画面が表示されます。
次にNoderedにノード追加していきましょう。
右上のメニューを表示して[パレットの管理]。
f:id:tk_thunder:20180212210751p:plain

最初に追加するのはグラフなどUIを提供してくれる[dashboard]
[ノードを追加]に[dashboard]と入力して画像のノードを追加。
f:id:tk_thunder:20180212210756p:plain

はいエラー!!!
だ、大丈夫だ、落ち着いて…(震え声

module.js:471
throw err;
^

Error: Cannot find module '/root/.node-red/node_modules/node-red-dashboard/fixfa.js'
(以下略)

まずはこの記事で足りないモジュールをインストールして、ラズパイを再起動。
qiita.com

もっかいノードの追加にトライ!
オッケーですね。追加されると左のノード一覧にこんな感じに表示されます。

f:id:tk_thunder:20180212210801p:plain

MSSQL

続いてMSSQLに接続するためのノードを追加します。
[パレットの管理]から[ノードを追加]で[MSSQL]と検索。
画像のノードを追加します。
f:id:tk_thunder:20180212210802p:plain

追加されるとこんな感じです。
f:id:tk_thunder:20180212210805p:plain

フロー構築

さて、準備が整ったらNoderedのフローを構築していきましょう。
ノードの一覧から画像のようにフローを作成しました。

やっていることはこんな感じです。

  1. 10分毎に処理を実行
  2. 各センサーからデータを取得してデータベースに書き込む
  3. データベースからデータを取得する
  4. データをチャートに表示するように整形する
  5. チャートに渡して表示する

f:id:tk_thunder:20180213190003p:plain

クリップボード(コピーしてNoderedに貼り付けると同じのができます)
コピー:右上のドロワーをクリック→[読み込み]→[クリップボード]→下のJSONを貼り付ける

[{"id":"e810a0b3.f3ec38","type":"function","z":"fe3fcd41.22fef","name":"温度・湿度","func":"var temp = [];\nvar hum = [];\n\nfor(var i = 0; i < msg.payload.length; i++)\n{\n    var n = msg.payload[i];\n    \n    var time = n.register_at;\n    // y軸とx軸の設定 それぞれ取得したデータを設定\n    temp.push({\"y\":n.temperature, \"x\":time.toString()});\n    hum.push({\"y\":n.humidity, \"x\":time.toString()});\n}\nmsg.payload = [{\"series\":[\"温度[℃]\",\"湿度[%]\"],\"data\":[temp,hum], \"labels\":[\"test\"]}];\nreturn msg;","outputs":1,"noerr":0,"x":611,"y":322,"wires":[["f2018d3a.5014b8","358a5d7c.9ce102"]]},{"id":"c740f89b.d467f8","type":"inject","z":"fe3fcd41.22fef","name":"定期実行","topic":"","payload":"","payloadType":"date","repeat":"600","crontab":"","once":true,"onceDelay":"10","x":128,"y":179,"wires":[["baa536f8.a514b","ef91a84.a68eed8"]]},{"id":"baa536f8.a514b","type":"exec","z":"fe3fcd41.22fef","command":"(例)sudo python3 /home/pi/python/bme280db/bme280db.py","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"環境データ取得","x":429,"y":169.5,"wires":[["4c0b3340.37224c"],[],[]]},{"id":"4c0b3340.37224c","type":"debug","z":"fe3fcd41.22fef","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":691,"y":155,"wires":[]},{"id":"ef91a84.a68eed8","type":"MSSQL","z":"fe3fcd41.22fef","mssqlCN":"2d4a26c3.ec7902","name":"Azure接続","query":"(クエリを記述)\nSelect *\nFrom **********","outField":"payload","x":379,"y":282,"wires":[["e810a0b3.f3ec38","2796d5ef.8f52aa"]],"inputLabels":["msg.payload"]},{"id":"358a5d7c.9ce102","type":"debug","z":"fe3fcd41.22fef","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":817,"y":370,"wires":[]},{"id":"f2018d3a.5014b8","type":"ui_chart","z":"fe3fcd41.22fef","name":"","group":"e9bee9b8.1c9bd","order":0,"width":0,"height":0,"label":"Labo 温度/湿度","chartType":"line","legend":"true","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#D62728","#1F77B4","#FF7F0E","#2CA02C","#98DF8A","#D62728","#FF9896","#9467BD","#C5B0D5"],"useOldStyle":false,"x":833,"y":294,"wires":[[],[]],"inputLabels":["msg.payload"]},{"id":"2796d5ef.8f52aa","type":"function","z":"fe3fcd41.22fef","name":"気圧","func":"var pres = [];\n\nfor(var i = 0; i < msg.payload.length; i++) \n{\n    var n = msg.payload[i];\n    var time = n.register_at;\n    // y軸とx軸の設定 それぞれ取得したデータを設定\n    pres.push({\"y\": n.pressure, \"x\": time.toString()});\n}\nmsg.payload = [{\"series\": [\"気圧[hPa]\"], \"data\": [pres], \"labels\": [\"test\"]}];\nreturn msg;","outputs":1,"noerr":0,"x":580,"y":455,"wires":[["96de0c0d.83b22","97548ee1.546e5"]]},{"id":"96de0c0d.83b22","type":"ui_chart","z":"fe3fcd41.22fef","name":"","group":"e9bee9b8.1c9bd","order":0,"width":0,"height":0,"label":"Labo 気圧","chartType":"line","legend":"true","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#FF7F0E","#AEC7E8","#FF7F0E","#2CA02C","#98DF8A","#D62728","#FF9896","#9467BD","#C5B0D5"],"useOldStyle":false,"x":769,"y":431,"wires":[[],[]],"inputLabels":["msg.payload"]},{"id":"97548ee1.546e5","type":"debug","z":"fe3fcd41.22fef","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":769.5,"y":495,"wires":[]},{"id":"2d4a26c3.ec7902","type":"MSSQL-CN","z":"","name":"任意の名前","server":"***********.database.windows.net","encyption":true,"database":"データベース名"},{"id":"e9bee9b8.1c9bd","type":"ui_group","z":"","name":"Labo","tab":"af51bbaf.922318","disp":true,"width":"12","collapse":false},{"id":"af51bbaf.922318","type":"ui_tab","z":"","name":"Labo環境データ","icon":"dashboard"}]
Injectノードの設定

フローの最初のノードです。実行タイミングなどを指定します。
今回はNoderedがスタートして10秒後に1回実行。その後は10分間隔で実行するように設定しました。

f:id:tk_thunder:20180213213002p:plain

MSSQLノードの設定

ノードをダブルクリックすると編集画面が開きます。
ここでは取得したいデータのクエリを記述しましょう。

f:id:tk_thunder:20180213211840p:plain

クエリ編集画面でペンマークをクリックすると、接続設定の画面が開くのでデータベースの情報を入力します。

f:id:tk_thunder:20180213211627p:plain

execノードの設定

このノードで環境データを取得するPythonを実行するコマンドを記述します。
例えばこんな感じです。

f:id:tk_thunder:20180213211917p:plain

チャートの設定

チャートはこんな感じです。てきとーでいいよ

f:id:tk_thunder:20180213211929p:plain

設定を開いて受け取るデータを記述しましょう。[msg.payload]

f:id:tk_thunder:20180213211614p:plain

さて、これで完璧ですね。
10分待たずとも、Injectノードの左端をクリックするとタイミング関係なく実行してくれます。
チャートを確認してみましょう。右端の[ダッシュボード]タブをクリックし、その下のよくわからないボタンをクリックします。

f:id:tk_thunder:20180213213440p:plain

問題なくデータが取れればチャートにはこんな感じに表示されます。
f:id:tk_thunder:20180213213542p:plain

いい感じです!
ここまで来るのに死ぬほど手間がかかりましたけど、形になると達成感が半端ないです。
手順も分かったので、次は今回の半分以下の時間で実現できますね。
さーて、お次は照度センサーを搭載して明るさの測定とかやってみたいですね!!!