LoginSignup
1
0

[#Node-RED]:flows.jsonのノード一覧(固有URL対応版)

Posted at

使えるぞ!Node-RED3.10の固有URL

正式版が待ち遠しいNode-RED3.10。ノードやグループに固有のURLに対応しました。
これまでだと、フロー中のコメントノードなどに手順を書く際に「XXタブの上から3つ目の[実行]と書かれたインジェクトノードのボタンを押下してください。」と場所を説明する必要がありましたがが、3.10だと「ここのインジェクトノードのボタンを押してください」とリンク付きで説明できます。これができるとコードと同時にドキュメントを管理でき、ドキュメントとコードの不一致も少なくなると期待できます。
この固有のURLはNode-RED3.10では情報サイドバーの「要素のURLをコピー」ボタンで取得できますが、リンクをコメントノードに貼ろうとすると、編集中にエディタ内を行ったり来たりすることになります。そこで、以前作成したノード一覧フローをノード、グループ、タブに固有のURLを付加しました。いくつかの不具合修正のほか、一覧作成フローのタブを表示しない、タブごとに見出しを追加する、などの機能追加もしています。
NodeList202308a.png

使い方は2種類

コードを下につけていますので、Node-REDで読み込んで使ってください。ブラウザでNode-REDのURLの下のlist-localまたはlist-jsonを参照してください。list-localは~/.node-red/flows.jsonを、list-jsonはテンプレートノードにペーストしたflows.jsonを参照します。なお、flows.jsonは少なくとも一つのタブが必要です。
3.10の正式版はこの記事作成時点でまだ出てません。なかなか出てこないのでベータ4版で開発しました。利用される場合は、@nextをつけてインストールしてください。
   $ sudo npm install -g --unsafe-perm node-red@next

参考文献

[#Node-RED]flows.jsonのフォーマットを見てみる
[#Node-RED]flows.jsonからノード一覧を作成する

コード


[{"id":"970e4ed7b944a9b6","type":"tab","label":"__NodeList__","disabled":false,"info":"flows.jsonのノード一覧を作成します。","env":[]},{"id":"86f312d94d774b20","type":"junction","z":"970e4ed7b944a9b6","x":580,"y":220,"wires":[["ac03cf7426581af1"]]},{"id":"d47fc116556c1d98","type":"debug","z":"970e4ed7b944a9b6","name":"HTML","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":430,"y":660,"wires":[]},{"id":"fdbe3d70e31de3c9","type":"file in","z":"970e4ed7b944a9b6","name":"","filename":"filename","filenameType":"msg","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":480,"y":220,"wires":[["86f312d94d774b20"]]},{"id":"89278eb590ee4d16","type":"function","z":"970e4ed7b944a9b6","name":"~/.node-red/flows.json","func":"msg.filename = msg.payload + '/.node-red/flows.json'\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":220,"wires":[["fdbe3d70e31de3c9"]]},{"id":"ac03cf7426581af1","type":"json","z":"970e4ed7b944a9b6","name":"","property":"payload","action":"","pretty":false,"x":170,"y":340,"wires":[["db8d0c075506ec6b"]]},{"id":"db8d0c075506ec6b","type":"function","z":"970e4ed7b944a9b6","name":"タブ一覧)(__NodeList__削除)","func":"msg.objs = msg.payload;\nmsg.payload = msg.objs.filter(elm => elm.type === 'tab');\n// msg.payload = msg.objs.filter(elm => (elm.type === 'tab') && (elm.label !='__NodeList__'));\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":340,"wires":[["9deebe2b3a79aefe"]]},{"id":"9deebe2b3a79aefe","type":"split","z":"970e4ed7b944a9b6","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":230,"y":440,"wires":[["3bea992d98e4d4d5"]]},{"id":"a24f81853c9f22b8","type":"join","z":"970e4ed7b944a9b6","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":230,"y":500,"wires":[["d8cbbdc08d6d18d5"]]},{"id":"3bea992d98e4d4d5","type":"function","z":"970e4ed7b944a9b6","name":"解析とマークダウン作成","func":"const tab_path = '/#flow/'\nconst node_path = '/#node/'\nconst group_path = '/#group/'\n// settings.jsのhttpAdminRootを'/admin'に修正した場合\n// const tab_path = '/admin/#flow/'\n// const node_path = '/admin/#node/'\n// const group_path = '/admin/#group/'\n\n// 表が壊れるので説明のマークダウンをHTMLにする\nfunction conv(str) {\n    // if (!str) return '';\n    let md = markdownIt({ html: true, linkify: true, typographer: true });\n    return (md.render(str).trim().replace(/\\n/g, ''));\n}\n\n// 説明欄の文字列作成 disabled mode infoの結合(見たいプロパティはここに追記)\nfunction mkRem(obj) {\n    return (obj.disabled ? 'disabled ' : '')+\n        (obj.d ? 'disabled ' : '') +\n        (obj.mode ? ('mode:'+obj.mode+' ') : '')+\n        (obj.info ? conv(obj.info) : '');\n}\n\nlet tab = msg.payload;\n\n// タブ内のオブジェクト抽出\nlet objs = msg.objs.filter(elm => elm.z === tab.id);\n\n// 抽出するノードの「種類を限定する場合はさらにフィルタする\n// objs = objs.filter(elm => elm.type === 'comment');\n\n// オブジェクトの位置ソート\nobjs.sort((a, b) => {\n    if (a.y == b.y) return a.x - b.x;\n    else return a.y - b.y;\n});\n\n/// グループのMAP作成(リンクノード分析は全体に対して行う)\nlet groups = objs.filter(elm => elm.type === 'group');\nlet groupName = {};\ngroups.forEach(group => { groupName[group.id] = group.name ? group.name : '-'+group.id+'-'});\n\nmsg.payload = '';\n\n\n// タブマークダウン\nmsg.payload += '\\n| **[```' + tab.label +'```]('+tab_path+tab.id+')** | **' +tab.type+'** |  | '+mkRem(tab)+' |';\n\n// オブジェクトマークダウン\nobjs.forEach(obj => {\n    msg.payload += '\\n| [```' + (obj.name === '' || !obj.name ? '-' + obj.id + '-' : obj.name) + \n        '```](' + (obj.type === 'group' ? group_path : node_path) + obj.id + ') | ' + obj.type + ' | ' + \n        (obj.g ? groupName[obj.g] : '') + ' | ' + mkRem(obj) + ' |';\n});\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[{"var":"markdownIt","module":"markdown-it"}],"x":430,"y":440,"wires":[["a24f81853c9f22b8"]]},{"id":"5c8d3dd566715bc3","type":"comment","z":"970e4ed7b944a9b6","name":"タブごとの情報の作成","info":"**split**+**join**を用いてタブ単位で並行処理しています。","x":140,"y":400,"wires":[]},{"id":"134559eded4d1e6c","type":"template","z":"970e4ed7b944a9b6","name":"ここにJSONをペーストする","field":"payload","fieldType":"msg","format":"json","syntax":"plain","template":"","output":"str","x":380,"y":100,"wires":[["86f312d94d774b20"]]},{"id":"d8cbbdc08d6d18d5","type":"function","z":"970e4ed7b944a9b6","name":"表をまとめる","func":"// ヘッダマークダウン追加\n// msg.payload.unshift(`| 名前 | 種類 |  グループ | 説明 |\\n| ---- | ---- | ---- | ---- |`);\n\n// 表の結合\nmsg.payload = `| Name | Type | Group | Detail |\\n| ---- | ---- | ---- | ---- |` +\n        msg.payload.join('\\n| **Name** | **Type** | **Group** | **Detail** |');\n// msg.payload = `| 名前 | 種類 |  グループ | 説明 |\\n| ---- | ---- | ---- | ---- |` +\n//         msg.payload.join('\\n| **名前** | **種類** | **グループ** | **説明** |');\n// msg.payload = msg.payload.join('');\n\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":600,"wires":[["62a050f4f4e791b1","b1c87663ee56f99b"]]},{"id":"b1c87663ee56f99b","type":"markdown","z":"970e4ed7b944a9b6","name":"","x":230,"y":700,"wires":[["d47fc116556c1d98","69031c4cfc3d0fb5"]]},{"id":"49d8107f50af82f0","type":"http in","z":"970e4ed7b944a9b6","name":"","url":"/list-local","method":"get","upload":false,"swaggerDoc":"","x":150,"y":160,"wires":[["eb2cac95ebbde58a"]]},{"id":"eb2cac95ebbde58a","type":"change","z":"970e4ed7b944a9b6","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"HOME","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":160,"wires":[["89278eb590ee4d16"]]},{"id":"d7af628eac5c00e4","type":"http in","z":"970e4ed7b944a9b6","name":"","url":"/list-json","method":"get","upload":false,"swaggerDoc":"","x":150,"y":100,"wires":[["134559eded4d1e6c"]]},{"id":"29a1f1043ae1c1ea","type":"http response","z":"970e4ed7b944a9b6","name":"","statusCode":"","headers":{},"x":590,"y":700,"wires":[]},{"id":"69031c4cfc3d0fb5","type":"function","z":"970e4ed7b944a9b6","name":"ヘッダー追加","func":"msg.payload = msg.payload.replace('', '');\n\nmsg.payload =\n    `\n\n    Node List\n    \n\n\nNode List\n\n  \n     ` +\n    msg.payload +\n    `   \n  \n\n\n`\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":700,"wires":[["29a1f1043ae1c1ea"]]},{"id":"62a050f4f4e791b1","type":"debug","z":"970e4ed7b944a9b6","name":"マークダウン","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":540,"y":600,"wires":[]},{"id":"94a234e2bbab804e","type":"comment","z":"970e4ed7b944a9b6","name":"データ入力","info":"ブラウザから以下のいずれかをを参照してください。\n- http(s)://ホスト:ポート/list-json\n- http(s)://ホスト:ポート/list-local","x":100,"y":60,"wires":[]},{"id":"4994573e34e9ede4","type":"comment","z":"970e4ed7b944a9b6","name":"全体で使う情報の作成","info":"","x":140,"y":280,"wires":[]},{"id":"793d31ab83d60a8b","type":"comment","z":"970e4ed7b944a9b6","name":"全てのタブ情報の結合","info":"","x":140,"y":560,"wires":[]},{"id":"5dc2829793d8a062","type":"comment","z":"970e4ed7b944a9b6","name":"HTML作成","info":"","x":100,"y":660,"wires":[]},{"id":"37890012798eda13","type":"comment","z":"970e4ed7b944a9b6","name":"要修正:httpAdminRoot設定時","info":"","x":590,"y":400,"wires":[]}]

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0