やりたいこと
- Node-REDからPythonを実行する。
特徴
- (Python実行環境を容易にするため)Anacondaを使用する
- (初学者のハードルを低くするため)可能な限り入手可能なNode-REDノードを活用する
やりたいことイメージ
1. Node-REDからpostgreSQLに接続してcsvファイルを作成する 2. Node-REDからbatファイルを実行する 3. batファイルにてconda環境を有効にしてPythonプログラムを実行する 4. PythonプログラムへのI/Fファイルを指定する実行環境
- OS:windows 10
- postgreSQL:9.6
- ANACONDA NAVIGATOR:1.9.12
- Python(Anaconda仮想環境上):3.7.7
- Node-RED:v1.0.4
ゴール
1. Node-REDからpostgreSQLに接続してcsvファイルを作成する
必要なノードは5つ。下記ノードを下記の順番で結合する。
- 【機能】function ノード
- 目的:SQL文を組み立てる
- 使用方法:msg.payloadにSQL文を直接記述
functionノードへの記述イメージ
msg.select = "SELECT val"
msg.from = "FROM public.sensordata "
msg.where = "where sensor ='湿度センサー'"
msg.orderBy = "order by datetime desc"
msg.limit = "limit 1000"
msg.payload = msg.select
msg.payload += " " + msg.from
msg.payload += " " + msg.where
msg.payload += " " + msg.orderBy
msg.payload += " " + msg.limit
return msg;
- 【ストレージ】postgres ノード
- 目的:postgreSQLに接続して、SQLを実行する
- 使用方法:標準的な使い方 - 【機能】json to csv converter ノード
- 目的:postgre ノードがjson形式で返すのでcsv形式に変換する
- 使用方法:標準的な使い方 - 【機能】function ノード
- 目的:ファイル名を指定する
- 使用方法:msg.filenameにcsvファイルのフルパスを指定する
functionノードへの記述イメージ
// 例)msg.rootpath = "C:\\temp\\conda"
// 例)msg.timestampはinjectノードから取得
msg.filename = msg.rootpath + "\\indata\\" + msg.timestamp + ".csv";
return msg;
- 【ストレージ】file ノード
- 目的:csvファイルを作成する
- 使用方法:ファイル名には空白を指定(空白の場合、msg.filenameへの設定値でファイルを作成)
2. Node-REDからbatファイルを実行する
必要なノードは2つ。下記ノードを下記の順番で結合する。
ポイント
- 実行コマンドを任意に指定できるようにmsg.payloadにコマンド+引数を指定する(通常はexecノードにコマンドを直接指定するが、その場合可変に出来ない)
※execノードのコマンドへの設定値+空白+msg.payloadでコマンド実行していると思われる
- 【機能】function ノード
- 目的:実行コマンドを組み立てる
- 使用方法:msg.payloadに実行するコマンドを設定
functionノードへの記述イメージ
// 実行するbatファイルのフルパス 例)"C:\\temp\\conda\\ExecPython.bat" ※指定したPythonプログラムを実行するbatファイルの
msg.command = msg.execPythonCmd
// 第1引数 例)"test.py" ※実行するPythonプログラムのファイル名
msg.arg_1 = msg.execPythonNm
// 第2引数 例)実行するPythonプログラムへのI/F(入力ファイル)
msg.arg_2 = "indata\\" + msg.timestamp + ".csv"
// 第3引数 例)実行するPythonプログラムへのI/F(出力ファイル)
msg.arg_3 = "outdata\\" + msg.timestamp + ".csv"
msg.payload = msg.command + " " + msg.arg_1 + " " + msg.arg_2 + " " + msg.arg_3
return msg;
- 【機能】exec ノード
- 目的:コマンドを実行する
- 使用方法:コマンドには空白を指定。msg.payloadのチェックボックスはオン。
3. batファイルにてconda環境を有効にしてPythonプログラムを実行する
ExecPython.bat
rem 実行フォルダに移動
rem 例)C:\temp\conda 配下に実行環境が整備済の場合
cd /d C:\temp\conda
rem condaを有効にする
call activateConda.bat
rem Pythonを実行する
rem %1:実行するPythonのファイル名
rem %1~7:実行するPythonへの引数
python %1 %2 %3 %4 %5 %6 %7
activateConda.bat
conda activate [有効にしたい環境名 例)base]
4. PythonプログラムへのI/Fファイルを指定する
test.py
import sys
# 引数を取得する
args = sys.argv
import pandas as pd
sensordata = pd.read_csv(args[1])
print(sensordata.describe())
sensordata.describe().to_csv(args[2], index=True)
実行
準備1)実行ファイル用意
準備2)フロー作成
1,2に記載のフローを準備する。
下記のように、実行に必要な情報をfunctionノードに記載すると管理が楽かも。
※「injectノード→実行条件設定→1→2」の順番で実行するフローを作成
実行条件設定
msg.timestamp = msg.payload
msg.rootpath = "C:\\temp\\conda"
msg.execPythonCmd = "C:\\temp\\conda\\ExecPython.bat"
msg.execPythonNm = "test.py"
return msg;
実行結果
indataフォルダに格納されたcsvファイルを読み取り、簡単な統計情報をoutdataフォルダに出力
おわりに
IoTのプラットフォームとしては「Node-RED」、データサイエンスのプラットフォームとしては「Anaconda+Python+JupyterNotebook」
が挙げられるかと思いますが、これらがシームレスにつながるとDXが進むんじゃないかと期待してます。