Node-REDを使ってみる その3(ui-tableノード、emailノード)

はじめに

 今回はNode-REDのui-tableノードとemailノードを使ってみました。

 デスクトップPCの作業を自動化して、遠隔でも状態を確認するためにdashboard画面を確認したり、メールで通知したりするのに使おうと思っています。

 ui-tableノードのデータ構造が少し分かりづらい気もしますが、ChatGPTに相談しつつ便利に使うことができました。

▼以前の記事はこちら

Node-REDを使ってみる その1(execノード、Pythonプログラム実行)

はじめに  今回はNode-REDのexecノードを使ってみました。コマンドを実行できるノードです。  私はNode-RED MCUを先に使い始めたので、Node-RED自体はあまり使っていま…

Node-REDを使ってみる その2(Googleフォーム、Googleスプレッドシート)

はじめに  今回はNode-REDとGoogleフォーム、Googleスプレッドシートを連携させてみました。  Googleフォームで入力した内容をGoogleスプレッドシートにリンクし、Node-…

ui-tableノードを使ってみる

▼以下のノードを利用しました。

https://flows.nodered.org/node/node-red-node-ui-table

▼dashboardノードも一緒に利用します。

https://flows.nodered.org/node/node-red-dashboard

 Node-RED Advent Calender 2024の人気ノードランキングで紹介されていたノードで、気になったので使ってみました。

▼以下の記事です。

https://qiita.com/taiponrock/items/537ccc1798c895c5e9a7

 ノードのhelpに書かれていたのですが、配列に格納して使うようですね。splitノードで分割後、joinノードで配列として結合すれば、ui-tableノードで表示させることができそうです。

▼ノードの設定とhelp画面は以下のようになっています。

 今回はキュー型のデータ構造でデータを管理したかったので、ChatGPTに相談しながらそのためのプログラムをfunctionノードに記述しました。

▼動作を確認するために、以下のフローを作成しました。

[{"id":"26e45d3ec99880d1","type":"function","z":"22eb2b8f4786695c","name":"function 4","func":"let queue = flow.get(\"queue\") || [];\n\nmsg.payload = queue.map((item, index) => ({ index: index + 1, value: item }));\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":3700,"wires":[["ae894b4b865108e6"]]},{"id":"0d79642cd4e5e406","type":"function","z":"22eb2b8f4786695c","name":"Queue","func":"let queue = flow.get(\"queue\") || [];\nmsg.dequeued = ''\n\n// 操作の種類をチェック(msg.topicを使用)\nswitch (msg.topic) {\n    case \"enqueue\": // データを追加\n        queue.push(msg.payload);\n        break;\n\n    case \"dequeue\": // データを削除\n        if (queue.length > 0) {\n            let dequeuedItem = queue.shift(); // 先頭を削除\n            msg.dequeued = dequeuedItem;     // 削除した要素を返す\n        }\n        break;\n\n    case \"clear\": // キューをクリア\n        queue = [];\n        break;\n\n    default:\n        node.warn(\"サポートされていない操作です: \" + msg.topic);\n}\n\n// キューを更新\nflow.set(\"queue\", queue);\n\n// 現在のキューを出力\nmsg.queue = queue;\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":3700,"wires":[["26e45d3ec99880d1"]]},{"id":"0b519e8e17bdc5d2","type":"inject","z":"22eb2b8f4786695c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"enqueue","payload":"","payloadType":"date","x":530,"y":3640,"wires":[["0d79642cd4e5e406"]]},{"id":"857b0f66ba530fb6","type":"inject","z":"22eb2b8f4786695c","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dequeue","x":500,"y":3680,"wires":[["0d79642cd4e5e406"]]},{"id":"b0c2d470f6f29bf7","type":"inject","z":"22eb2b8f4786695c","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"clear","x":490,"y":3720,"wires":[["0d79642cd4e5e406"]]},{"id":"ae894b4b865108e6","type":"ui_table","z":"22eb2b8f4786695c","group":"824d75e0b288451b","name":"","order":0,"width":0,"height":0,"columns":[],"outputs":0,"cts":false,"x":990,"y":3700,"wires":[]},{"id":"824d75e0b288451b","type":"ui_group","name":"Default","tab":"e3d29ad0e240b35c","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"e3d29ad0e240b35c","type":"ui_tab","name":"Test","icon":"dashboard","disabled":false,"hidden":false}]

 一つ目のfunctionノードでは、msg.topicがenqueue、dequeue、clearの場合で処理を分岐しています。enqueueの場合データを追加し、dequeueの場合はデータを一つ取り出します。clearの場合はデータを削除します。このデータはflow.queueに保存されます。

let queue = flow.get("queue") || [];
msg.dequeued = ''

// 操作の種類をチェック(msg.topicを使用)
switch (msg.topic) {
    case "enqueue": // データを追加
        queue.push(msg.payload);
        break;

    case "dequeue": // データを削除
        if (queue.length > 0) {
            let dequeuedItem = queue.shift(); // 先頭を削除
            msg.dequeued = dequeuedItem;     // 削除した要素を返す
        }
        break;

    case "clear": // キューをクリア
        queue = [];
        break;

    default:
        node.warn("サポートされていない操作です: " + msg.topic);
}

// キューを更新
flow.set("queue", queue);

// 現在のキューを出力
msg.queue = queue;
return msg;

 二つ目のfunctionノードでは、キューからデータを取り出しています。

let queue = flow.get("queue") || [];

msg.payload = queue.map((item, index) => ({ index: index + 1, value: item }));

return msg;

 injectノードでデータの追加や取り出し、削除を試してみました。

▼表示はできたのですが、高さを調整しないと4行分しか表示されていませんでした。

▼ui-tableノードのSizeを変更しました。

▼下まで表示されるようになりました。

 キュー型のデータ構造として扱うことができているのかを確認してみました。

▼先入れ先出しになっています。clearも機能しています。

 キュー型のデータ構造を扱うノードとして新しく開発しておくと便利に使えそうですね。

emailノードを使ってみる

▼以下のノードを利用しました。

https://flows.nodered.org/node/node-red-node-email

▼インストールすると、以下のノードが追加されます。

 今回は一番下のメールを送信するノードで、自分宛に自分のメールアドレスで送信します。

▼以前ハッカソンのときに使ったことがあります。

Node-REDでマイコンと、SNSやメールを連携させる(ヒーローズリーグ ハイブリット・ハッカソンにて)

はじめに  ヒーローズリーグのハッカソンにて二日間製作していたのですが、今回はその技術的なまとめです。短い期間でしたが、Node-RED経由でLINE、Slack、Discord、Gmai…

▼以前利用したときは以下のenebularの記事を参考にしたのですが、Googleのアプリパスワードの場所が変わっているようでした。

https://blog.enebular.com/nodes/letsuse-emailnode

 Googleのアカウント画面でアプリパスワードを発行します。

▼セキュリティの欄の2段階認証プロセスで、2段階認証を有効にしておきます。

▼検索欄で「アプリパスワード」を検索しました。

▼アプリ名を入力して、作成を選択しました。

 アプリパスワードが表示されるので、コピーしておきます。

▼後から表示できないのでご注意ください。

▼一度追加した後は、2段階認証プロセスの欄でアプリパスワードが表示されるようです。

 先程作成したアプリパスワードをemailノードに入力します。

▼injectノードと接続しました。

▼Auth typeはBasic、送信先とUseridは自分のメールアドレス、Passwordはアプリパスワードで発行したものです。

 injectノードを実行して、メールを送信してみました。

▼msg.payloadの値が送信されています。

応用例:機械学習の自動化

 具体的な実装例についてここでは詳説しないのですが、最近YOLOを使った物体検出に取り組んでいます。

▼以下の記事でも利用しています。

YOLOで物体検出 その2(Python、Node-RED)

はじめに  今回はYOLOをPythonで実行してみました。  以前の記事でYOLOを試したときは簡単なコマンドしか試していませんでしたが、実際にロボットに搭載して処理を行う…

 検出したい物体のモデルが無い場合は自分でデータセットを作成して、学習させる必要があります。このとき、データセットが大きいと学習に時間がかかります。

 コマンドで学習を開始させることができるのですが、CPUの使用率が90%近くなるので、一気に複数のデータセットを学習させることができません。そこで、学習させたいデータセットをキューに格納して順次に学習させ、その様子をダッシュボード画面で管理できるようにしてみました。学習終了後はメールで通知が来ます。

▼画面はこんな感じ。YOLOのモデルの選択や、データセットの結合もできます。

 学習時間も把握したかったので、時間を計算するようになっています。

▼データセットはプルダウンメニューで選択できます。

▼学習させるものとして追加すると、ui-tableに追加されます。CLEARを選択するとキューに追加されたものはすべて削除されます。

 これで順次に学習が行われるようになりました。あとは放置しておけば、自動的に学習が終了します。

最後に

 作業を自動化するためのフローの作成は、うまくいくと楽になっていいですね。空いている時間で他の作業をしています。

 YOLOの場合、学習中にデプロイすると途中でプロセスが終了してしまうので、その間はプログラムの変更を試すことができないという問題はあります。Expressでポートを変えて起動したNode-REDの環境がいくつかあると便利です。

▼ノードの検証を行う場合やソフトウェアに組み込む場合は、Expressで起動したNode-REDを利用しています。

Node-REDをアプリケーションに組み込む(Electron、Express)

はじめに  今回はElectronで作成しているアプリケーションに、Node-REDを組み込んでみました。  Node-REDのユーザーガイドに、Expressアプリケーションへの組み込みのサ…

コメントを残す

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