投稿

10月, 2021の投稿を表示しています

Functionノードを使う(その5)

イメージ
前回 まででFunctionノードのサンプルをひと通り見て満足していたのですが、そういえば、1箇所だけ触っていない設定があったことを思い出しました。設定プロパティの「 モジュール 」です。 Functionノードの ドキュメント によると、 functionExternalModules オプションを使うとsettings.js上でいちいちrequire()しなくても外部モジュールが使えるとのこと。settings.jsを確認したところデフォルトで有効化されていました。それを先に言えよ。 /** Allow the Function node to load additional npm modules directly */ functionExternalModules: true, というわけで、早速動作確認します。 その3の記事 で使ったaxiosで試してみます。前提条件として「 npm install axios 」コマンドでaxiosをインストールしておきます。続いて設定タブでモジュールにaxiosを追加します。 この設定は「 const axios = require("axios") 」みたいなことをやってくれているということなのだと思います。続いて、コードタブに以下のように書きます。いきなりaxios.get()を呼び出せるのがポイントです。 フローを実行するとresponseが出力されます。 まとめ 今回利用した方法だと特定のFunctionノードでのみ外部モジュールが利用可能になりますが、 その3の記事 で確認したsettings.jsファイルの functionGlobalContext でrequire()する方法だと全Functionノードで外部モジュールが利用可能になるということなのでしょう。状況によって使い分けすれば良さそうです。Functionノードについてはこんなもんですかね。  

Functionノードを使う(その4)

イメージ
今回も、 前回 に引き続きFunctionノードのサンプルフローを見つつざっとその機能を把握してみます。第四回目です。 初期化処理と終了処理 最初のサンプルは「 09 - Setup and close 」です。Functionノードはフロー実行時だけでなく、Node-RED起動時と終了時にもコードを実行できます。いつも通りFunctionノードのプロパティを見ていきます。 初期化処理タブではglobalコンテキストの変数を0で初期化しています。 続いてコードタブではglobalコンテキストの変数値をインクリメントしてmsg.playloadに格納しています。 最後に終了処理タブではglobalコンテキストの変数値をコンソールに出力しています。 このフローを何度か実行すると、インクリメントされた値がログに出力されます。この出力はコードタブに記載した内容の実行結果です。 終了処理が実行されることを確認するため、コンソール上でNode-REDを停止すると、以下のように最新のglobalコンテキスト内の変数値が出力されます。通常、この手の機能はログ出力が目的ではなく、リソースの解放処理のような後始末をするのに利用するのが一般的だと思います。 28 Oct 22:33:19 - [info] フローを開始します 28 Oct 22:33:19 - [info] フローを開始しました ^C28 Oct 22:34:57 - [info] フローを停止します count: 4 28 Oct 22:34:57 - [info] フローを停止しましたつ さらに再びNode-REDを起動してフローを実行すると、出力される値がリセットされて1、2、3、、、と増えていくのが確認できると思います。初期化処理タブに記載した内容がNode-RED起動時に実行されて変数値がリセットされたんですね。 というわけで、初期化処理と終了処理の動作が確認できました。パッと使いどころは思いつきませんが、フロー実行のたびに実行するにはコストの高い処理をNode-RED起動時に実行して、終了時に止める、みたいな感じでしょうか。ありがちなパターンかと思います。 非同期初期化 ラストのサンプルは「 10 - Asyncronous setup 」です。デプロイすると1秒後にログが出力されます。初期化処理でも非同

Functionノードを使う(その3)

イメージ
今回も、 前回 に引き続きFunctionノードのサンプルフローを見つつざっとその機能を把握してみます。第三回です。 コンテキストにデータを保存 最初のサンプルは「 06 - Storing data in context 」です。コンテキストにデータを保存するらしいです。この時点でだいたい予想はついたので中身は見なくてもいいかと思いましたが、さすがに雑だと思ったので一応見ますです。Functionノードのプロパティはこんな感じ。 何回か実行すると、ログ上で数値がインクリメントされて出力されます。context上の'count'という名前の変数を使って、実行のたびに値を読み出し、インクリメント、値を保存しています。通常、フローは一回実行したら実行結果は消えてしまいますが、contextに保存して次回実行時に参照しているということですね。ステートフルな作りになってしまうので、バグの温床になりかねませんが、きっと必要な場面もあるはずです。コンテキストについてのドキュメントは こちら 。コンテキストはデフォルトでメモリ上に保存されるので、Node-REDを再起動したら消えるってことですね。 ステータスの表示 次のサンプルは「 07 - Showing status information 」です。フローはこんな感じ。 injectノードではmsg.playloadに「 red 」という文字列を設定しています。 Functionノードではmsg.payloadの値でswitchして、node.status()関数でステータスを更新しているようです。あとは この辺 読んで感じ取れってことですね。 外部モジュールの利用 次のサンプルは「 08 - Using external modules 」です。このままフローを実行してもエラーが出て動きません。commentノードの詳細を見ろとあるので確認してみます。 setting.jsに以下のように書いて「os」モジュールを読み込めば良いようです。 functionGlobalContext: { os: require("os"), } ~/.node-red/settings.jsを確認するとちょうどこれと同じ記述がコメントアウトされているので、コメント部分を外して有効化します。Node

Functionノードを使う(その2)

イメージ
前回 に引き続きFunctionノードのサンプルフローを見つつざっとその機能を把握してみます。 非同期メッセージの送信 最初のサンプルは「 03 - Send message asynchronously 」です。Functionノードのプロパティはこんな感じです。 実行すると、2秒遅れてログが出力されます。setTimeout()で遅延を発生させて、node.send(msg)することで次のノードにメッセージを送信しているようです。普通に非同期処理がかけるってことですね。なるほど。 ログ出力とログレベル 次のサンプルは「 04 - Logging events 」です。Functionノードからデバッグウィンドウにログ出力ができます。 ログ出力関数 は、log()、warn()、error()と3種類あって、出力時に色分けされるようです。これは、見やすいですね。 エラーハンドリング 次のサンプルは「 05 - Handling errors 」です。 実行すると 、catchノードの先に繋がっているdebugノードがログを1件出力します。 Functionノードのコードはこんな感じでnode.error()関数を呼び出しています。こうすると、それ以上先にフローは進まず、catchノードで例外をキャッチできるようです。 第二引数にmsgを設定しているのが興味深かったので、試しにnullを渡してみたところ、node.error()の実行エラーになりました。よくわかりませんが、msgを渡すことに意味があるようです。 とりあえずまとめ いろいろできるようです。続く。

Functionノードを使う(その1)

イメージ
今回は Function ノードを使ってみます。ローコードプログラミング環境のNode-REDをハイコード化する本末転倒感が漂っていますが、JavaScriptを書ける人であればむしろこっちの方が学習コストが低くて使い勝手が良いのではないかと思います。何でもできる分、奥が深くてサンプルもたくさん提供されています。少々時間はかかりますが、一個ずつ見ていきたいと思います。 msgの加工 最初のサンプルは「 flows > node-red > function > function > 01 - Send message to output port 」です。 functionノードのプロパティは以下のような感じです。 暗黙的に入力値としてmsgオブジェクトを受け取っている msg.payloadの値を加工している returnしたmsgオブジェクトが次のノードに渡される 複数msgの出力 次のサンプルは「 flows > node-red > function > function > 02 - Send multiple messages 」です。functionノードから出力が2つ出ています。 プロパティを確認すると、配列がネストしており、それぞれがpayloadプロパティをもっています。 出力数の指定は「 設定 」タブでできるようです。 デプロイして実行するとログが4件出力されます。「 〜out of output 1 」は1つ目の出力から出た内容です。debugノードが受け取ったmsg1〜msg3を含む配列内のmsg.payloadを出力しているということでしょうか。ログが2件で前者が配列で出力されるのであれば直感的に理解できそうですが、ちょっと謎な動きです。 とりあえずまとめ まだまだサンプルはたくさんあるので続きます。

サブフローを作ってみる

イメージ
 今回はサブフローを作ってみます。ドキュメントは こちら 。サブフローは自前でノードを定義してパレットに登録する機能です。フローを再利用する際に使います。一般的なプログラミングで言えば、関数を作るイメージですね。同じ処理が複数箇所に出てきたらサブフロー化を考えると良さそうです。 サブフローの追加 まずはメニューからサブフローを追加します。サブフローを編集するためのエディタが表示されます。 サブフローの編集 今回作成するフローの仕様は以下のとおりです。 入力はmsg.payload1つ(数値) 出力もmsg.payload1つ(数値) 入力値に環境変数Xをかけた値を出力する 出力値と同じ値をステータスに設定する まずは、エディタ上部で入力と出力をそれぞれ「1」に、ステータスノードのチェックを「ON」にします。エディタ上には「input」、「output」、「status」というノードのようなものが追加されます。これらの間に処理を挟んであげればサブフローの完成です。 続いて、画面左上の「 プロパティを編集 」を選択します。この画面はサブフローに設定可能なプロパティを定義します。画面左下の「 +追加 」ボタンからプロパティ(環境変数)を追加して名前を「 X 」にした上で「 数値型 」に変更します。デフォルト値はとりあえず2としておきます。最後に「 完了 」を選択して保存します。 続いて計算部分を実装します。今回はFunctionノードを使ってみます。フローエディタ上にFunctionノードを追加してプロパティを開きます。「コード」に以下のような内容を記述します。先ほど追加したプロパティには環境変数としてアクセスできるようです。 最後に、冒頭の画面のようにFunctionノードをinput、output、statusの間に挟み込んで編集完了です。 サブフローを使う 本体のフローエディタのパレット上に作成したサブフローがノードとして追加されるので、これをエディタ上にドラッグ&ドロップして使います。 フローエディタ上にはinjectノードとdebugノード、作成したサブフローノードを2つ追加指定可のように繋げます。 injectノードのプロパティはこんな感じにします。 サブフローノードのプロパティはこんな感じにします(デフォルトのまま)。 debugノードはmsgオブジェクト全

パレットにノードを追加する

イメージ
 Node-REDでは、標準状態でパレットにさまざまなノードが表示されています。ここには誰かが作成したサードパーティ製のノードや自分で開発したノードを追加できます。ノードの開発方法についてはいずれ掘るとして、今回は誰かが作成したノードを追加してみます。 パレットにノードを追加する やり方は ドキュメント に全部書いてあります、以上。だとアウトプットにならないので、ドキュメントどおりにやってみます。公開ノードは こちら で検索できます。 画面から追加する メニューから「 パレットの管理 」を選択します。 「 ノードを追加 」を選択して、それっぽい名前を入力して検索します。お目当てのノードが見つかったら「 ノードを追加 」を選択して設定画面を閉じます。 なんかごちゃごちゃ言ってくるので、適当に受け流して「追加」を選択します。 追加完了のメッセージが表示されます。 パレットに新しいノードが追加されました。詳しい使い方はヘルプを参照します。 コマンドラインから追加する 続いてコマンドラインから追加する方法です。今回は「 node-red-node-mysql 」というノードを追加してみます。画面に書いてある手順に従ってインストールします。 $ cd ~/.node-red $ npm i node-red-node-mysql added 14 packages, and audited 57 packages in 3s 8 packages are looking for funding run `npm fund` for details found 0 vulnerabilities インストールが完了したらNode-REDを再起動後に画面をリロードします。パレットにノードが追加されます。 まとめ コマンドラインからインストールした場合、Node-REDサーバの再起動が必要なのがポイントですね。ノードの検索サイトを見ると公開されているものが3500以上あります。数が多すぎてよくわかりませんが、便利そうなものを見つけたらまた何か書いてみます。

フロー上の認証情報の扱いについて確認してみる

イメージ
以前書いた記事 で、Node-RED起動時に「 フローのクレデンシャルファイルはシステム生成キーで暗号化されています。 」なるメッセージが出力されることを確認しました。このメッセージからは「 システム生成キー 」や「 暗号化されたフローのクレデンシャルファイル 」がどこに保存されているのかは読み取れません。今回は、フロー内の認証情報がどのように保存されるか確認してみます。 確認用フロー 今回使うフローはこんな感じです。 http requestノードではBasic認証を有効化してユーザ名とパスワードを設定済みです。 http requestノードを書き出すとこんな感じになります。 [ { "id": "5a89ce70.db6d5", "type": "http request", "z": "cad6f983ee9de5e2", "name": "", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://localhost:1880/hello", "tls": "", "persist": false, "proxy": "", "authType": "basic", "credentials": {}, "x": 350, "y": 100, "wires": [

Node-RED UG Hacktoberfest 2021説明会に参加してみました

2021年10月5日に開催された「 Node-RED UG Hacktoberfest 2021説明会 」を聴講してみました。今回はそのメモです。 モチベーション Hacktoberfest自体は今年で8年目 らしいです。このイベント、以前SendGridの公式ライブラリをチェックしていた際、毎年10月になるとリポジトリにPull RequestやIssueが大量に送られてきてメンテナーがしんどそうだったイメージがあります。単にウォッチしているこっちも毎日通知メールが死ぬほど来るので辟易していました。 今のところNode-REDのリポジトリはそこまで過酷な状態でもなさそうなので、学習目的で参加してみようと思います。手に負えなければあきらめますが。 やること 説明 によると、対象リポジトリに対して10月中に4件Pull Requestを送ってマージされると記念品がもらえるとのこと(他にもいくつか細かい条件はありますが)。 正直、Node-RED本体はそんなに使い込んでいないので、プログラム的な修正をかけるのは無理かなと思っています(今のところ不具合に出くわしたこともないので)。一方で、画面上のラベルやヘルプなどのリソースの翻訳はわりと気軽に手を付けられそうです。手順も細かく説明していただき、特に難しいことはなさそうです。 それにしても、Node-REDは翻訳しやすいファイル構成になっているのが素晴らしいです。こういうキレイな作りを見ているだけでグッとモチベーションが上がるものです。 まとめ あとは手を動かすだけです。

Link outとLink inノードを使う

イメージ
共通ノードシリーズ最終回は「 Link out 」と「 Link in 」ノードです。ノードのヘルプには以下のようにあります。 フロー間に仮想的なリンクを作成する 任意のタブ上に存在するlink out(link in)ノードに接続できる この接続はあたかも直接リンクしたかのように動作する linkノード間のリンクはlinkノードを選択した場合にのみ表示する 他のタブへのリンクがある場合は、仮想的なノードを表示する 仮想的ノードをクリックすると対応するタブに移動できる サブフロー内外へのリンク作成は不可 「仮想的ってなんだよ」って感じはしますが、要は他のタブにリンクできるのが最大の特徴のようです。サブフローはまだ使ったことがないのでよくわかりませんが、そのうち深堀りしてみます。 タブ内でリンクするサンプル なにごとも基本から、ということで最初に読み込むサンプルは「 サンプル > flows > node-red > common > link > 01 - Link within a tab 」です。タブ内でリンクするらしいです。デプロイしてフローを動かすといつものパターンで「 Hello, World! 」のログが出力されます。 Link outとLink inノードは一見繋がってなさそうに見えますが、選択してみると点線のリンクが現れます。 試しに、新たにLink inノードを配置して、既存のLink outノードとつなげてみます。「 Link outノードを選択しないと出力ポートが現れない 」以外は普通のノードと一緒です。 挙動的には以前紹介したCompleteノードと同じ感じがしますが、ノードを選択するとリンク点線で表示されるため、より視覚的にわかりやすい感じでしょうか。 タブ間でリンクするサンプル 次はタブ間をリンクするサンプル「 02 - Link across tabs 」です。サンプルは2つのタブから構成されます。「 TAB: 1st 」にあるLink outノードが「 TAB: 2nd 」にあるLink inノードと繋がっています。 Link outノードを選択した際にうっすら表示される仮想ノード「 TAB: 2nd 」を選択すると、画面はリンク先のタブに切り替わります。なるほど、タブがたくさんある場合は便利そうです。