是否可以将子流的引用更改为 Node-RED 上的不同子流?
Is it possible to change the referrence of a subflow to a different subflow on Node-RED?
我通常使用不同的 Node-RED 实例,我喜欢创建子流来封装代码。然而,我总是以这样的方式结束我的节点调色板:
我读过 this thread on the official 论坛,那里说在导入子流时复制子流的行为是 Node-RED 当时的工作方式。然而,这个帖子是从 2019 年 9 月开始的,这种行为仍然是真的吗?如果是,是否有解决此问题的“非官方”方法?我的猜测是进入一个文件,我在其中找到所有“exec node (2)”和“exec node (3)”并将其替换为“exec node”,这样当我重新启动 node-red 时,所有这些子流都将变为“exec节点”,我将能够擦除其他节点,因为它们不再在任何地方使用。可能吗?
手动解决
在查看 Node-RED 文件夹中的 flow_server.json
文件一段时间后,我找到了解决此问题的方法。基本上,您需要执行以下操作:
- 在您的 .
node-red
文件夹中找到文件 flow_server.json
(如果启用了项目功能,它就在文件夹项目中)
- 使用不同的名称之一备份此文件,以免在出现问题时不小心弄乱所有流程
- 获取两个节点的id:你想保留的那个和复制的那个
- 搜索并将所有 subflow:idSubflowToSubstitute 替换为 subflow:idSubflowToKeep。在我的例子中是:subflow:9e7f93e5.544bc8 到 subflow:caeb9890.9cdb18
- 重新启动 运行 Node-RED
的服务
PS:此解决方案假定复制的节点相同。我真的不知道使用不同的子流程执行此过程的后果。
子流解决方案
我还创建了一个子流程,它对我来说更简单。它依赖于为 Node-RED 激活 fs
库。在试验之前备份您的 flow_server.json
文件...
[{"id":"b8749b41.f740e","type":"subflow","name":"fix duplication (2)","info":"","category":"essencial","in":[{"x":520,"y":460,"wires":[{"id":"948937d8.1051a8"}]}],"out":[],"env":[{"name":"flowFile","type":"str","value":"/home/user/.node-red/flow_server.json"},{"name":"subflowToKeep","type":"str","value":""},{"name":"subflowToSubstitute","type":"str","value":""}],"color":"#A6D2FF","icon":"node-red/swap.svg"},{"id":"948937d8.1051a8","type":"function","z":"b8749b41.f740e","name":"fix duplication","func":"const fs = global.get('fs');\n\nconst flowFile = env.get(\"flowFile\");\nconst subflowToKeep = env.get(\"subflowToKeep\")\nconst subflowToSubstitute = env.get(\"subflowToSubstitute\");\n\nlet flowString;\nlet flowObject;\n\ntry {\n flowString = fs.readFileSync(flowFile, 'utf8');\n flowObject = JSON.parse(flowString);\n\n if (checkIfSubflowExists(subflowToKeep) && checkIfSubflowExists(subflowToSubstitute)) {\n let subflowToKeepString = \"\";\n let subflowToSubstituteString = \"\";\n flowObject.forEach(({ type, name, id }) => {\n if ( type === 'subflow'){\n switch(name) {\n case subflowToKeep:\n subflowToKeepString = `subflow:${id}`\n node.warn(name + \"- \" + subflowToKeepString);\n break;\n case subflowToSubstitute:\n subflowToSubstituteString = `subflow:${id}`\n node.warn(name + \"- \" + subflowToSubstituteString);\n break;\n }\n }\n });\n\n if ( subflowToSubstituteString !== \"\" && subflowToKeepString !== \"\" ){\n var regex = new RegExp(subflowToSubstituteString, \"g\");\n if ( flowString.search(regex) >= 0 ){\n flowString = flowString.replace(regex, subflowToKeepString);\n fs.writeFileSync(flowFile, flowString );\n node.warn(\"nodes updated! restart node-red.\")\n return msg;\n }\n }\n }\n node.warn(\"Nothing to do. Check the input parameters correctly...\");\n return msg;\n} catch(err){\n node.warn(err)\n return msg;\n}\n\n// auxiliary functions\nfunction checkIfSubflowExists(key){\n let hasKey = false;\n flowObject.forEach(({ type, name }) => {\n if ( type === 'subflow'){\n if ( name === key ){\n hasKey = true;\n }\n }\n });\n return hasKey;\n}\n","outputs":0,"noerr":0,"x":860,"y":460,"wires":[]},{"id":"a437e02b.0f67d8","type":"subflow:b8749b41.f740e","z":"26278f81.44628","name":"","env":[],"x":1190,"y":380,"wires":[]}]
我通常使用不同的 Node-RED 实例,我喜欢创建子流来封装代码。然而,我总是以这样的方式结束我的节点调色板:
我读过 this thread on the official 论坛,那里说在导入子流时复制子流的行为是 Node-RED 当时的工作方式。然而,这个帖子是从 2019 年 9 月开始的,这种行为仍然是真的吗?如果是,是否有解决此问题的“非官方”方法?我的猜测是进入一个文件,我在其中找到所有“exec node (2)”和“exec node (3)”并将其替换为“exec node”,这样当我重新启动 node-red 时,所有这些子流都将变为“exec节点”,我将能够擦除其他节点,因为它们不再在任何地方使用。可能吗?
手动解决
在查看 Node-RED 文件夹中的 flow_server.json
文件一段时间后,我找到了解决此问题的方法。基本上,您需要执行以下操作:
- 在您的 .
node-red
文件夹中找到文件flow_server.json
(如果启用了项目功能,它就在文件夹项目中) - 使用不同的名称之一备份此文件,以免在出现问题时不小心弄乱所有流程
- 获取两个节点的id:你想保留的那个和复制的那个
- 搜索并将所有 subflow:idSubflowToSubstitute 替换为 subflow:idSubflowToKeep。在我的例子中是:subflow:9e7f93e5.544bc8 到 subflow:caeb9890.9cdb18
- 重新启动 运行 Node-RED 的服务
PS:此解决方案假定复制的节点相同。我真的不知道使用不同的子流程执行此过程的后果。
子流解决方案
我还创建了一个子流程,它对我来说更简单。它依赖于为 Node-RED 激活 fs
库。在试验之前备份您的 flow_server.json
文件...
[{"id":"b8749b41.f740e","type":"subflow","name":"fix duplication (2)","info":"","category":"essencial","in":[{"x":520,"y":460,"wires":[{"id":"948937d8.1051a8"}]}],"out":[],"env":[{"name":"flowFile","type":"str","value":"/home/user/.node-red/flow_server.json"},{"name":"subflowToKeep","type":"str","value":""},{"name":"subflowToSubstitute","type":"str","value":""}],"color":"#A6D2FF","icon":"node-red/swap.svg"},{"id":"948937d8.1051a8","type":"function","z":"b8749b41.f740e","name":"fix duplication","func":"const fs = global.get('fs');\n\nconst flowFile = env.get(\"flowFile\");\nconst subflowToKeep = env.get(\"subflowToKeep\")\nconst subflowToSubstitute = env.get(\"subflowToSubstitute\");\n\nlet flowString;\nlet flowObject;\n\ntry {\n flowString = fs.readFileSync(flowFile, 'utf8');\n flowObject = JSON.parse(flowString);\n\n if (checkIfSubflowExists(subflowToKeep) && checkIfSubflowExists(subflowToSubstitute)) {\n let subflowToKeepString = \"\";\n let subflowToSubstituteString = \"\";\n flowObject.forEach(({ type, name, id }) => {\n if ( type === 'subflow'){\n switch(name) {\n case subflowToKeep:\n subflowToKeepString = `subflow:${id}`\n node.warn(name + \"- \" + subflowToKeepString);\n break;\n case subflowToSubstitute:\n subflowToSubstituteString = `subflow:${id}`\n node.warn(name + \"- \" + subflowToSubstituteString);\n break;\n }\n }\n });\n\n if ( subflowToSubstituteString !== \"\" && subflowToKeepString !== \"\" ){\n var regex = new RegExp(subflowToSubstituteString, \"g\");\n if ( flowString.search(regex) >= 0 ){\n flowString = flowString.replace(regex, subflowToKeepString);\n fs.writeFileSync(flowFile, flowString );\n node.warn(\"nodes updated! restart node-red.\")\n return msg;\n }\n }\n }\n node.warn(\"Nothing to do. Check the input parameters correctly...\");\n return msg;\n} catch(err){\n node.warn(err)\n return msg;\n}\n\n// auxiliary functions\nfunction checkIfSubflowExists(key){\n let hasKey = false;\n flowObject.forEach(({ type, name }) => {\n if ( type === 'subflow'){\n if ( name === key ){\n hasKey = true;\n }\n }\n });\n return hasKey;\n}\n","outputs":0,"noerr":0,"x":860,"y":460,"wires":[]},{"id":"a437e02b.0f67d8","type":"subflow:b8749b41.f740e","z":"26278f81.44628","name":"","env":[],"x":1190,"y":380,"wires":[]}]