Commit ff1a29d6 authored by wubi's avatar wubi

优化流程模板添加

parent 44a1d4b3
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
"1277fc352696634b" "1277fc352696634b"
] ]
], ],
"func": "\nvar t = msg.payload; //采集到的数据\nvar type_input = \"number\"//由服务端处理\nvar type = \"number\"//number string send_speed collect_speed list raw location\nif (type_input == \"string\"){\n type = type_input;\n}\nif(type == \"number\" || type == \"collect_speed\"){\n var min_input = \"-100\"//由服务端处理\n var max_input = \"5000\"//由服务端处理\n var min = -20;\n var max = 100;\n\n if (!Number.isNaN(Number(min_input))){\n min = Number(min_input)\n }\n\n if (!Number.isNaN(Number(max_input))) {\n max = Number(max_input)\n }\n\n if (t <= max && t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n if(type == \"collect_speed\" && msg.payload == 1 && global.get(\"timing\")!=0){//达到目标值,计算时间\n var current_time = new Date().getTime();\n var collect_speed = 1000/(current_time - global.get(\"timing\"))\n collect_speed = parseFloat((collect_speed).toFixed(2))//单位Hz\n msg.payload = collect_speed\n global.set(\"timing\",0)\n }\n}else if(type == \"string\"){\n var value_input = \"{{value_input}}\"////由服务端处理\n if(t == value_input){\n msg.payload = 1;\n }else{\n msg.payload = 0;\n }\n}else if(type == \"send_speed\"){\n msg.payload = msg.speed\n}else if(type == \"list\"){//列表值对比\n var list = JSON.parse(\"{{list}}\")//服务器替换list如[\"123\",\"456\"]\n var glist = global.get(\"list\",null)\n if(glist == null){\n global.set(\"list\",list)\n }\n msg.payload=0\n if(list.length >0){\n for (let i = 0; i < list.length; i++) {\n if(list[i] == t){\n msg.payload = t\n break;\n }\n }\n }\n}\n\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n", "func": "\nvar t = msg.payload; //采集到的数据\nvar type_input = \"number\"//由服务端处理\nvar type = \"number\"//number string send_speed collect_speed list raw location\nif (type_input == \"string\"){\n type = type_input;\n}\nif(type == \"number\" || type == \"collect_speed\"){\n var min_input = \"0\"//由服务端处理\n var max_input = \"5000\"//由服务端处理\n var min = -20;\n var max = 100;\n\n if (!Number.isNaN(Number(min_input))){\n min = Number(min_input)\n }\n\n if (!Number.isNaN(Number(max_input))) {\n max = Number(max_input)\n }\n\n if (t <= max && t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n if(type == \"collect_speed\" && msg.payload == 1 && global.get(\"timing\")!=0){//达到目标值,计算时间\n var current_time = new Date().getTime();\n var collect_speed = 1000/(current_time - global.get(\"timing\"))\n collect_speed = parseFloat((collect_speed).toFixed(2))//单位Hz\n msg.payload = collect_speed\n global.set(\"timing\",0)\n }\n}else if(type == \"string\"){\n var value_input = \"{{value_input}}\"////由服务端处理\n if(t == value_input){\n msg.payload = 1;\n }else{\n msg.payload = 0;\n }\n}else if(type == \"send_speed\"){\n msg.payload = msg.speed\n}else if(type == \"list\"){//列表值对比\n var list = JSON.parse(\"{{list}}\")//服务器替换list如[\"123\",\"456\"]\n var glist = global.get(\"list\",null)\n if(glist == null){\n global.set(\"list\",list)\n }\n msg.payload=0\n if(list.length >0){\n for (let i = 0; i < list.length; i++) {\n if(list[i] == t){\n msg.payload = t\n break;\n }\n }\n }\n}\n\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n",
"name": "指标参数判断", "name": "指标参数判断",
"x": 220, "x": 220,
"y": 80, "y": 80,
...@@ -652,7 +652,7 @@ ...@@ -652,7 +652,7 @@
"c8c05d075e4746f9" "c8c05d075e4746f9"
] ]
], ],
"func": "if(msg.payload.is_init){\n var loop_mode_input = \"size\"//由服务端处理\n var loop_size_input = \"8\"//由服务端处理\n var loop_time_input = \"8\"//由服务端处理\n var timeout_input = \"5000\"////由服务端处理\n var device_mode_input = \"{{device_mode}}\"//主动/被动\n\n var loop_size = 10;//默认值,10次 测试次数\n var loop_time = 60 * 1000;//默认值,60秒 测试持续时间\n var timeout = 5000;//默认值,5秒 超时时间\n var loop_mode = \"size\"; //默认值, size 测试次数 time 持续时间\n var device_mode = \"active\"//active 主动 passive 被动\n\n if (!Number.isNaN(Number(loop_size_input))){\n loop_size = Number(loop_size_input)\n }\n\n if (!Number.isNaN(Number(loop_time_input))) {\n loop_time = Number(loop_time_input)*1000\n }\n\n if (!Number.isNaN(Number(timeout_input))) {\n timeout = Number(timeout_input)\n }\n\n var time = loop_time +new Date().getTime();\n\n if (loop_mode_input == \"time\" || loop_mode_input == \"size\"){\n loop_mode = loop_mode_input\n }\n node.warn(`loop_size:${loop_size},loop_time:${loop_time},timeout:${timeout},loop_mode:${loop_mode},device_mode:${device_mode}`);\n global.set(\"loop_size\", loop_size);\n global.set(\"loop_time\",time);\n global.set(\"loop_mode\",loop_mode);\n global.set(\"loop_end\",false);\n global.set(\"result\",[]);//初始化结果\n global.set(\"has_result\",1);\n global.set(\"complete\",false);\n global.set(\"timeout\", timeout);//被测设备超时时间\n global.set(\"device_mode\",device_mode);\n global.set(\"active_start_time\", null);\n \n if(loop_mode == \"size\"){\n msg.loop_info = loop_size;\n }else if(loop_mode == \"time\"){\n msg.loop_info = loop_time;\n }\n msg.delay = 1000 //循环延迟(毫秒)\n msg.payload = {\"msg\":\"流程初始化成功\",\"code\":0};\n return msg;\n}\n", "func": "if(msg.payload.is_init){\n var loop_mode_input = \"size\"//由服务端处理\n var loop_size_input = \"5\"//由服务端处理\n var loop_time_input = \"5\"//由服务端处理\n var timeout_input = \"5000\"////由服务端处理\n var device_mode_input = \"{{device_mode}}\"//主动/被动\n\n var loop_size = 10;//默认值,10次 测试次数\n var loop_time = 60 * 1000;//默认值,60秒 测试持续时间\n var timeout = 5000;//默认值,5秒 超时时间\n var loop_mode = \"size\"; //默认值, size 测试次数 time 持续时间\n var device_mode = \"active\"//active 主动 passive 被动\n\n if (!Number.isNaN(Number(loop_size_input))){\n loop_size = Number(loop_size_input)\n }\n\n if (!Number.isNaN(Number(loop_time_input))) {\n loop_time = Number(loop_time_input)*1000\n }\n\n if (!Number.isNaN(Number(timeout_input))) {\n timeout = Number(timeout_input)\n }\n\n var time = loop_time +new Date().getTime();\n\n if (loop_mode_input == \"time\" || loop_mode_input == \"size\"){\n loop_mode = loop_mode_input\n }\n node.warn(`loop_size:${loop_size},loop_time:${loop_time},timeout:${timeout},loop_mode:${loop_mode},device_mode:${device_mode}`);\n global.set(\"loop_size\", loop_size);\n global.set(\"loop_time\",time);\n global.set(\"loop_mode\",loop_mode);\n global.set(\"loop_end\",false);\n global.set(\"result\",[]);//初始化结果\n global.set(\"has_result\",1);\n global.set(\"complete\",false);\n global.set(\"timeout\", timeout);//被测设备超时时间\n global.set(\"device_mode\",device_mode);\n global.set(\"active_start_time\", null);\n \n if(loop_mode == \"size\"){\n msg.loop_info = loop_size;\n }else if(loop_mode == \"time\"){\n msg.loop_info = loop_time;\n }\n msg.delay = 1000 //循环延迟(毫秒)\n msg.payload = {\"msg\":\"流程初始化成功\",\"code\":0};\n return msg;\n}\n",
"name": "测试策略", "name": "测试策略",
"x": 140, "x": 140,
"y": 140, "y": 140,
...@@ -1053,7 +1053,7 @@ ...@@ -1053,7 +1053,7 @@
"wires": [ "wires": [
[] []
], ],
"func": "msg.payload = msg.payload[0]*1;\nreturn msg;", "func": "msg.payload = msg.payload[0]*0.5;\nreturn msg;",
"name": "数据转换", "name": "数据转换",
"x": 420, "x": 420,
"y": 140, "y": 140,
......
...@@ -1048,13 +1048,12 @@ ...@@ -1048,13 +1048,12 @@
{ {
"outputs": 1, "outputs": 1,
"noerr": 0, "noerr": 0,
"{{factor}}": "0.5",
"type": "function", "type": "function",
"timeout": 0, "timeout": 0,
"wires": [ "wires": [
[] []
], ],
"func": "msg.payload = msg.payload[0]*{{factor}};\nreturn msg;", "func": "msg.payload = msg.payload[0]*0.5;\nreturn msg;",
"name": "数据转换", "name": "数据转换",
"x": 420, "x": 420,
"y": 140, "y": 140,
......
...@@ -436,6 +436,7 @@ var RED = (function() { ...@@ -436,6 +436,7 @@ var RED = (function() {
let load_url = "flows"; let load_url = "flows";
let request_type = "GET"; let request_type = "GET";
const flowId = getId(); const flowId = getId();
RED.nodes.currentNodeId = flowId;
if(flowId!=null){ if(flowId!=null){
//load_url = `http://192.168.0.113:1909/getflows?id=${getId()}` //load_url = `http://192.168.0.113:1909/getflows?id=${getId()}`
...@@ -474,7 +475,7 @@ var RED = (function() { ...@@ -474,7 +475,7 @@ var RED = (function() {
nodes ={ nodes ={
"flows": [ "flows": [
{ {
"id": `${getNewID()}`, "id": `${flowId}`,
"type": "tab", "type": "tab",
"label": `${getFormattedTime()}`, "label": `${getFormattedTime()}`,
"disabled": false, "disabled": false,
...@@ -4581,6 +4582,7 @@ RED.nodes = (function() { ...@@ -4581,6 +4582,7 @@ RED.nodes = (function() {
var dirty = false; var dirty = false;
var templateId; var templateId;
var currentNodeId;
function setDirty(d) { function setDirty(d) {
dirty = d; dirty = d;
...@@ -17083,11 +17085,14 @@ RED.deploy = (function() { ...@@ -17083,11 +17085,14 @@ RED.deploy = (function() {
function init(options) { function init(options) {
options = options || {}; options = options || {};
var type = options.type || "default"; var type = options.type || "default";
$('<button id="saveButton">保存</button>').prependTo(".red-ui-header-toolbar"); var urlId = getId();
if(urlId != null){
$('<button id="saveButton">保存</button>').prependTo(".red-ui-header-toolbar");
$("#saveButton").on('click',function(){ $("#saveButton").on('click',function(){
saveNode() saveNode()
}); });
if (type == "default") { }
if (type == "default" && getId()==null) {
$('<li><span class="red-ui-deploy-button-group button-group">'+ $('<li><span class="red-ui-deploy-button-group button-group">'+
'<a id="red-ui-header-button-deploy" class="red-ui-deploy-button disabled" href="#">'+ '<a id="red-ui-header-button-deploy" class="red-ui-deploy-button disabled" href="#">'+
'<span class="red-ui-deploy-button-content">'+ '<span class="red-ui-deploy-button-content">'+
...@@ -75563,7 +75568,7 @@ const getId=()=>{ ...@@ -75563,7 +75568,7 @@ const getId=()=>{
async function saveNode(){ async function saveNode(){
console.log("save"); console.log("save");
const nns = RED.nodes.createCompleteNodeSet(); const nns = RED.nodes.createCompleteNodeSet();
const data = { id:nns[0].id,label:nns[0].label,flows: nns }; const data = { id:RED.nodes.currentNodeId,label:nns[0].label,flows: nns };
//先查询是否存在 //先查询是否存在
let token = await window.iotAPI.getToken(); let token = await window.iotAPI.getToken();
$.ajax({ $.ajax({
...@@ -75594,7 +75599,7 @@ async function saveNode(){ ...@@ -75594,7 +75599,7 @@ async function saveNode(){
"type": 1, "type": 1,
"templateConfig": JSON.stringify(data), "templateConfig": JSON.stringify(data),
"templateName":`${data.label}`, "templateName":`${data.label}`,
"templateNodeId": `${data.id}`, "templateNodeId": getNewID()//`${data.id}`,
} }
} }
}else{ }else{
...@@ -75630,87 +75635,91 @@ async function saveNode(){ ...@@ -75630,87 +75635,91 @@ async function saveNode(){
tmpId = templateIdMatch[1] tmpId = templateIdMatch[1]
RED.nodes.templateId = tmpId RED.nodes.templateId = tmpId
console.log(`add id:${tmpId}`); console.log(`add id:${tmpId}`);
RED.nodes.dirty(false);
//RED.nodes.version(data.rev);
RED.nodes.originalFlow(nns);
RED.nodes.dirty(false);
const flowsToLock = new Set()
function ensureUnlocked(id) {
const flow = id && (RED.nodes.workspace(id) || RED.nodes.subflow(id) || null);
const isLocked = flow ? flow.locked : false;
if (flow && isLocked) {
flow.locked = false;
flowsToLock.add(flow)
}
}
RED.nodes.eachNode(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
if (node.credentials) {
delete node.credentials;
}
});
RED.nodes.eachGroup(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
})
RED.nodes.eachJunction(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
})
RED.nodes.eachConfig(function (confNode) {
if (confNode.z) {
ensureUnlocked(confNode.z)
}
confNode.changed = false;
if (confNode.credentials) {
delete confNode.credentials;
}
});
RED.nodes.eachSubflow(function (subflow) {
if (subflow.changed) {
subflow.changed = false;
RED.events.emit("subflows:change", subflow);
}
});
RED.nodes.eachWorkspace(function (ws) {
if (ws.changed || ws.added) {
ensureUnlocked(ws.z)
ws.changed = false;
delete ws.added
RED.events.emit("flows:change", ws)
}
});
flowsToLock.forEach(flow => {
flow.locked = true
})
// Once deployed, cannot undo back to a clean state
RED.history.markAllDirty();
RED.view.redraw();
RED.sidebar.config.refresh();
RED.events.emit("deploy");
}else{
var json = JSON.parse(data);
window.alert(json.errorMessage);
} }
RED.nodes.dirty(false);
//RED.nodes.version(data.rev);
RED.nodes.originalFlow(nns);
RED.nodes.dirty(false);
const flowsToLock = new Set()
function ensureUnlocked(id) {
const flow = id && (RED.nodes.workspace(id) || RED.nodes.subflow(id) || null);
const isLocked = flow ? flow.locked : false;
if (flow && isLocked) {
flow.locked = false;
flowsToLock.add(flow)
}
}
RED.nodes.eachNode(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
if (node.credentials) {
delete node.credentials;
}
});
RED.nodes.eachGroup(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
})
RED.nodes.eachJunction(function (node) {
ensureUnlocked(node.z)
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if (node.moved) {
node.dirty = true;
node.moved = false;
}
})
RED.nodes.eachConfig(function (confNode) {
if (confNode.z) {
ensureUnlocked(confNode.z)
}
confNode.changed = false;
if (confNode.credentials) {
delete confNode.credentials;
}
});
RED.nodes.eachSubflow(function (subflow) {
if (subflow.changed) {
subflow.changed = false;
RED.events.emit("subflows:change", subflow);
}
});
RED.nodes.eachWorkspace(function (ws) {
if (ws.changed || ws.added) {
ensureUnlocked(ws.z)
ws.changed = false;
delete ws.added
RED.events.emit("flows:change", ws)
}
});
flowsToLock.forEach(flow => {
flow.locked = true
})
// Once deployed, cannot undo back to a clean state
RED.history.markAllDirty();
RED.view.redraw();
RED.sidebar.config.refresh();
RED.events.emit("deploy");
}) })
}}); }});
{"testTaskId":"1929900489378369536","host":"http://192.168.0.82:8082","token":"Bearer eyJhbGciOiJIUzI1NiJ9.eyJzZXNzaW9uSWQiOiJhZG1pbl80XzU0YmMwN2U0N2NkZTQwNzJhZWQyNWRiOTM1MmEyYzg1IiwiQ3JlYXRlZFRpbWUiOjE3NDg5NTkwNTEzNzIsImV4cCI6MTc0OTU2Mzg1MX0.bU1jeVrCs0kpMNgWvtpSeHuajiKKUlBvrJ9srLxTRGk"} {"testTaskId":"1929900489378369536","host":"http://192.168.0.82:8082","token":"Bearer eyJhbGciOiJIUzI1NiJ9.eyJzZXNzaW9uSWQiOiJhZG1pbl80X2FiYmQ5MWY1N2EyNTRhYTc4NDBmNDAxNjU2MGIwMjJmIiwiQ3JlYXRlZFRpbWUiOjE3NDkwMDY3MTE0NDgsImV4cCI6MTc0OTYxMTUxMX0.S_Y-M7f1r8o0aGclrmKraflXK0VDz05TqL3llCV6dXU"}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"name": "COAP",
"config": [
{
"name": "请求方式",
"key": "method",
"type": "select",
"value": "GET",
"option": [
{ "label": "GET", "value": "GET" },
{ "label": "POST", "value": "POST" },
{ "label": "PUT", "value": "PUT" },
{ "label": "DELETE", "value": "DELETE" },
{ "label": "FETCH", "value": "FETCH" },
{ "label": "PATCH", "value": "PATCH" }
],
"rules": [
{ "required": true, "message": "必须选择CoAP方法", "trigger": "change" }
],
"hint": "CoAP支持的请求方法"
},
{
"name": "URI路径",
"key": "url",
"type": "string",
"value": null,
"rules": [
{ "required": true, "message": "URI路径不能为空", "trigger": "blur" }
],
"width": "500px",
"hint": "不包含协议头的路径,如:/test"
},
{
"name": "读对象",
"key": "read_obj",
"type": "string",
"value": null,
"rules": [
{ "required": true, "message": "读对象不能为空", "trigger": "blur" }
],
"width": "500px",
"hint": "读取接收的消息中的指定对象的数据,如读{obj:100}中obj的值,填:obj;如读取{list:[1,2,3,4]}中的第1个元素,填:list[0"
}
],
"nodes": [
{
"id": "da7a0f42ae981076",
"type": "subflow",
"name": "被测设备",
"info": "",
"category": "",
"in": [
{
"x": 60,
"y": 140,
"wires": []
}
],
"out": [
{
"x": 580,
"y": 140,
"wires": [
{
"id": "d80b7fa87a21f707",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "671138f6e624e466",
"type": "coap in",
"z": "da7a0f42ae981076",
"method": "GET",
"name": "",
"server": "da8be2d43093b320",
"url": "/",
"x": 170,
"y": 280,
"wires": [
[
"d80b7fa87a21f707"
]
]
},
{
"id": "d80b7fa87a21f707",
"type": "function",
"z": "da7a0f42ae981076",
"name": "读对象",
"func": "function findJsonValue(jsonObj, path) {\n node.error(jsonObj);\n // 辅助函数:通过完整路径遍历获取值\n const traverse = (current, parts) => {\n for (let i = 0; i < parts.length; i++) {\n if (typeof current !== 'object' || current === null) {\n return undefined;\n }\n const part = parts[i];\n const isArrayIndex = /^\\d+$/.test(part); // 检查是否为纯数字(数组索引)\n\n if (isArrayIndex && Array.isArray(current)) {\n const index = parseInt(part, 10);\n if (index < current.length) {\n current = current[index];\n } else {\n return undefined; // 索引越界\n }\n } else if (typeof current === 'object' && current !== null && Object.prototype.hasOwnProperty.call(current, part)) {\n current = current[part];\n } else {\n return undefined; // 路径部分不存在\n }\n\n // 如果当前值是字符串,并且不是路径的最后一部分,尝试解析它看是否为JSON字符串\n if (typeof current === 'string' && i < parts.length - 1) {\n try {\n const parsedJson = JSON.parse(current);\n if (typeof parsedJson === 'object' && parsedJson !== null) {\n current = parsedJson; // 如果是合法的JSON对象/数组,则用解析后的结果继续遍历\n }\n } catch (e) {\n // 不是合法的JSON字符串,或者解析失败,则保持 current 不变,下一轮循环可能会因此返回 undefined\n }\n }\n }\n return current;\n };\n\n // 辅助函数:深度优先搜索对象中的键\n // 返回找到的第一个匹配键的值\n const deepSearch = (obj, keyToFind) => {\n if (typeof obj !== 'object' || obj === null) {\n return undefined;\n }\n\n // 直接在当前对象层级查找\n if (Object.prototype.hasOwnProperty.call(obj, keyToFind)) {\n return obj[keyToFind];\n }\n\n // 遍历对象的每个属性/元素\n for (const k in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, k)) {\n const item = obj[k];\n let foundValue;\n\n // 如果属性值是对象或数组,递归搜索\n if (typeof item === 'object' && item !== null) {\n foundValue = deepSearch(item, keyToFind);\n }\n // 如果属性值是字符串,尝试解析为JSON并搜索\n else if (typeof item === 'string') {\n try {\n const parsedJson = JSON.parse(item);\n if (typeof parsedJson === 'object' && parsedJson !== null) {\n // 先检查解析后的JSON顶层是否有该键,然后才考虑深度搜索解析后的内容\n if (Object.prototype.hasOwnProperty.call(parsedJson, keyToFind)) {\n foundValue = parsedJson[keyToFind];\n } else {\n foundValue = deepSearch(parsedJson, keyToFind);\n }\n }\n } catch (e) {\n // 不是可解析的JSON字符串\n }\n }\n\n if (foundValue !== undefined) {\n return foundValue; // 一旦找到,立即返回\n }\n }\n }\n return undefined; // 在当前对象及其子结构中未找到\n };\n\n // 主函数逻辑开始\n if (typeof jsonObj !== 'object' || jsonObj === null || typeof path !== 'string') {\n return undefined;\n }\n\n \n\n // 判断路径是简单键名还是复杂路径\n if (path.includes('.') || path.includes('[')) {\n // 复杂路径:使用路径遍历逻辑\n const parts = path.split(/[.\\[\\]]+/).filter(Boolean); // 分割路径并移除空字符串\n return traverse(jsonObj, parts);\n } else {\n // 简单键名:\n // 1. 首先尝试直接从顶层获取 (更符合直接输入键名的直觉)\n if (Object.prototype.hasOwnProperty.call(jsonObj, path)) {\n return jsonObj[path];\n }\n // 2. 如果顶层没有,则进行深度搜索\n return deepSearch(jsonObj, path);\n }\n}\n\nvar read_input_obj = \"{{read_input}}\"\n//read_input_obj = \"RS_SD\";\nconst val2 = findJsonValue(msg.payload, read_input_obj);\nmsg.payload = val2;\nif (read_input_obj == \"{{read_input}}\"){\n node.error(\"读对象未设置!\");\n}\nnode.warn(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 280,
"wires": [
[
"aa251ad8295edf79"
]
]
},
{
"id": "aa251ad8295edf79",
"type": "coap response",
"z": "da7a0f42ae981076",
"name": "",
"statusCode": "200",
"contentFormat": "application/json",
"x": 530,
"y": 280,
"wires": []
},
{
"id": "da8be2d43093b320",
"type": "coap-server",
"name": "test",
"port": "5683",
"ipv6": false
}
],
"map": {
"interface": [
],
"protocol": [
{"key": "method", "replace": {"id": "671138f6e624e466", "name": "method", "type": "string"}},
{"key": "url", "replace": {"id": "671138f6e624e466", "name": "url", "type": "string"}},
{"key": "read_obj", "replace": {"id": "d80b7fa87a21f707", "name": "{{read_input}}", "type": "content"}}
]
}
}
\ No newline at end of file
{
"name": "HTTP",
"config": [
{
"name": "请求方式",
"key": "method",
"type": "select",
"value": "GET",
"option": [
{ "label": "GET", "value": "get" },
{ "label": "POST", "value": "post" },
{ "label": "PUT", "value": "put" },
{ "label": "DELETE", "value": "delete" }
],
"rules": [
{ "required": true, "message": "必须选择请求方法", "trigger": "change" }
],
"hint": "HTTP请求类型"
},
{
"name": "URL地址",
"key": "url",
"type": "string",
"value": null,
"rules": [
{ "required": true, "message": "URL不能为空", "trigger": "blur" }
],
"width": "500px",
"hint": "不包含协议头的URL,如:/test/path 。 请求地址为:http://本机地址:1955/test/path"
},
{
"name": "读对象",
"key": "read_obj",
"type": "string",
"value": null,
"rules": [
{ "required": true, "message": "读对象不能为空", "trigger": "blur" }
],
"width": "500px",
"hint": "读取接收的消息中的指定对象的数据,如读{obj:100}中obj的值,填:obj;如读取{list:[1,2,3,4]}中的第1个元素,填:list[0"
}
],
"nodes": [
{
"id": "da7a0f42ae981076",
"type": "subflow",
"name": "被测设备",
"info": "",
"category": "",
"in": [
{
"x": 60,
"y": 140,
"wires": []
}
],
"out": [
{
"x": 580,
"y": 140,
"wires": [
{
"id": "d80b7fa87a21f707",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "d80b7fa87a21f707",
"type": "function",
"z": "da7a0f42ae981076",
"name": "读对象",
"func": "function findJsonValue(jsonObj, path) {\n node.error(jsonObj);\n // 辅助函数:通过完整路径遍历获取值\n const traverse = (current, parts) => {\n for (let i = 0; i < parts.length; i++) {\n if (typeof current !== 'object' || current === null) {\n return undefined;\n }\n const part = parts[i];\n const isArrayIndex = /^\\d+$/.test(part); // 检查是否为纯数字(数组索引)\n\n if (isArrayIndex && Array.isArray(current)) {\n const index = parseInt(part, 10);\n if (index < current.length) {\n current = current[index];\n } else {\n return undefined; // 索引越界\n }\n } else if (typeof current === 'object' && current !== null && Object.prototype.hasOwnProperty.call(current, part)) {\n current = current[part];\n } else {\n return undefined; // 路径部分不存在\n }\n\n // 如果当前值是字符串,并且不是路径的最后一部分,尝试解析它看是否为JSON字符串\n if (typeof current === 'string' && i < parts.length - 1) {\n try {\n const parsedJson = JSON.parse(current);\n if (typeof parsedJson === 'object' && parsedJson !== null) {\n current = parsedJson; // 如果是合法的JSON对象/数组,则用解析后的结果继续遍历\n }\n } catch (e) {\n // 不是合法的JSON字符串,或者解析失败,则保持 current 不变,下一轮循环可能会因此返回 undefined\n }\n }\n }\n return current;\n };\n\n // 辅助函数:深度优先搜索对象中的键\n // 返回找到的第一个匹配键的值\n const deepSearch = (obj, keyToFind) => {\n if (typeof obj !== 'object' || obj === null) {\n return undefined;\n }\n\n // 直接在当前对象层级查找\n if (Object.prototype.hasOwnProperty.call(obj, keyToFind)) {\n return obj[keyToFind];\n }\n\n // 遍历对象的每个属性/元素\n for (const k in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, k)) {\n const item = obj[k];\n let foundValue;\n\n // 如果属性值是对象或数组,递归搜索\n if (typeof item === 'object' && item !== null) {\n foundValue = deepSearch(item, keyToFind);\n }\n // 如果属性值是字符串,尝试解析为JSON并搜索\n else if (typeof item === 'string') {\n try {\n const parsedJson = JSON.parse(item);\n if (typeof parsedJson === 'object' && parsedJson !== null) {\n // 先检查解析后的JSON顶层是否有该键,然后才考虑深度搜索解析后的内容\n if (Object.prototype.hasOwnProperty.call(parsedJson, keyToFind)) {\n foundValue = parsedJson[keyToFind];\n } else {\n foundValue = deepSearch(parsedJson, keyToFind);\n }\n }\n } catch (e) {\n // 不是可解析的JSON字符串\n }\n }\n\n if (foundValue !== undefined) {\n return foundValue; // 一旦找到,立即返回\n }\n }\n }\n return undefined; // 在当前对象及其子结构中未找到\n };\n\n // 主函数逻辑开始\n if (typeof jsonObj !== 'object' || jsonObj === null || typeof path !== 'string') {\n return undefined;\n }\n\n \n\n // 判断路径是简单键名还是复杂路径\n if (path.includes('.') || path.includes('[')) {\n // 复杂路径:使用路径遍历逻辑\n const parts = path.split(/[.\\[\\]]+/).filter(Boolean); // 分割路径并移除空字符串\n return traverse(jsonObj, parts);\n } else {\n // 简单键名:\n // 1. 首先尝试直接从顶层获取 (更符合直接输入键名的直觉)\n if (Object.prototype.hasOwnProperty.call(jsonObj, path)) {\n return jsonObj[path];\n }\n // 2. 如果顶层没有,则进行深度搜索\n return deepSearch(jsonObj, path);\n }\n}\n\nvar read_input_obj = \"{{read_input}}\"\n//read_input_obj = \"RS_SD\";\nconst val2 = findJsonValue(msg.payload, read_input_obj);\nmsg.payload = val2;\nif (read_input_obj == \"{{read_input}}\"){\n node.error(\"读对象未设置!\");\n}\nnode.warn(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 390,
"y": 140,
"wires": [
[]
]
},
{
"id": "9e3876add8330aa0",
"type": "http in",
"z": "da7a0f42ae981076",
"name": "",
"url": "/test/url",
"method": "post",
"upload": false,
"swaggerDoc": "",
"x": 210,
"y": 140,
"wires": [
[
"d80b7fa87a21f707",
"5e69cb3392524cff"
]
]
},
{
"id": "5e69cb3392524cff",
"type": "http response",
"z": "da7a0f42ae981076",
"name": "",
"statusCode": "200",
"headers": {},
"x": 400,
"y": 200,
"wires": []
}
],
"map": {
"interface": [
],
"protocol": [
{"key": "method", "replace": {"id": "9e3876add8330aa0", "name": "method", "type": "string"}},
{"key": "url", "replace": {"id": "9e3876add8330aa0", "name": "url", "type": "string"}},
{"key": "read_obj", "replace": {"id": "d80b7fa87a21f707", "name": "{{read_input}}", "type": "content"}}
]
}
}
\ No newline at end of file
{
"name":"Modbus-RTU",
"config":[
{
"name": "从机地址",
"key": "unitid",
"type": "number",
"value": null,
"rules": [
{ "required": true, "message": "从机地址不能为空", "trigger": "blur" }
],
"min": 1,
"max": 247,
"width": "500px",
"hint": "Modbus从机设备地址(1-247)"
},
{
"name": "功能码",
"key": "dataType",
"type": "select",
"value": null,
"option": [
{ "label": "功能码1:读取线圈状态", "value": "Coil" },
{ "label": "功能码2:读取输入状态", "value": "Input" },
{ "label": "功能码3:读取保持寄存器", "value": "HoldingRegister" },
{ "label": "功能码4:读取输入寄存器", "value": "InputRegister" }
],
"rules": [{ "required": true, "message": "功能码不能为空", "trigger": "change" }],
"hint": "选择Modbus功能码类型"
},
{
"name": "地址",
"key": "adr",
"type": "number",
"value": null,
"rules": [
{ "required": true, "message": "寄存器地址不能为空", "trigger": "blur" }
],
"min": 0,
"max": 65535,
"width": "500px",
"hint": "寄存器起始地址(十进制)"
},
{
"name": "数量",
"key": "quantity",
"type": "number",
"value": null,
"rules": [
{ "required": true, "message": "读取数量不能为空", "trigger": "blur" }
],
"min": 1,
"max": 200,
"width": "500px",
"hint": "需要读取的寄存器数量"
},
{
"name": "乘系数",
"key": "factor",
"type": "number",
"value": 1,
"rules": [
{ "required": true, "message": "乘系数不能为空", "trigger": "blur" }
],
"min": -999999,
"max": 999999,
"width": "500px",
"hint": "数据乘系数"
}
],
"nodes": [
{
"id": "da7a0f42ae981076",
"type": "subflow",
"name": "被测设备",
"info": "",
"category": "",
"in": [
{
"x": 60,
"y": 140,
"wires": [
{
"id": "7d08042446ad6297"
}
]
}
],
"out": [
{
"x": 580,
"y": 140,
"wires": [
{
"id": "4f986ed7787cc630",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "7d08042446ad6297",
"type": "modbus-getter",
"z": "da7a0f42ae981076",
"name": "",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"logIOActivities": false,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "1",
"quantity": "2",
"server": "4cd290346f79a501",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 220,
"y": 140,
"wires": [
[
"4f986ed7787cc630"
],
[]
]
},
{
"id": "4f986ed7787cc630",
"type": "function",
"z": "da7a0f42ae981076",
"name": "数据转换",
"func": "msg.payload = msg.payload[0]*{{factor}};\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 420,
"y": 140,
"wires": [
[]
]
},
{
"id": "d2ceed10c706fc5a",
"type": "comment",
"z": "da7a0f42ae981076",
"name": "3.数据采集",
"info": "",
"x": 200,
"y": 100,
"wires": []
},
{
"id": "4cd290346f79a501",
"type": "modbus-client",
"name": "",
"clienttype": "serial",
"bufferCommands": true,
"stateLogEnabled": false,
"queueLogEnabled": false,
"failureLogEnabled": true,
"tcpHost": "127.0.0.1",
"tcpPort": "502",
"tcpType": "DEFAULT",
"serialPort": "/dev/ttyS4",
"serialType": "RTU-BUFFERD",
"serialBaudrate": "9600",
"serialDatabits": "8",
"serialStopbits": "1",
"serialParity": "none",
"serialConnectionDelay": "100",
"serialAsciiResponseStartDelimiter": "0x3A",
"unit_id": "1",
"commandDelay": "1",
"clientTimeout": "1000",
"reconnectOnTimeout": true,
"reconnectTimeout": "2000",
"parallelUnitIdsAllowed": true,
"showErrors": false,
"showWarnings": true,
"showLogs": true
}
],
"map":{
"interface":[
{"key":"dk","replace":{"id":"4cd290346f79a501","name":"serialPort","type":"string"}},
{"key":"bt","replace":{"id":"4cd290346f79a501","name":"serialBaudrate","type":"string"}},
{"key":"sj","replace":{"id":"4cd290346f79a501","name":"serialDatabits","type":"string"}},
{"key":"tz","replace":{"id":"4cd290346f79a501","name":"serialStopbits","type":"string"}},
{"key":"jy","replace":{"id":"4cd290346f79a501","name":"serialParity","type":"string"}}
],
"protocol":[
{"key":"unitid","replace":{"id":"7d08042446ad6297","name":"unitid","type":"string"}},
{"key":"dataType","replace":{"id":"7d08042446ad6297","name":"dataType","type":"string"}},
{"key":"adr","replace":{"id":"7d08042446ad6297","name":"adr","type":"string"}},
{"key":"quantity","replace":{"id":"7d08042446ad6297","name":"adr","type":"string"}},
{"key":"factor","replace":{"id":"4f986ed7787cc630","name":"{{factor}}","type":"content"}}
]
}
}
\ No newline at end of file
{ {
"name":"Modbus-RTU", "name":"Modbus-TCP",
"config":[ "config":[
{ {
"name": "从机地址", "name": "从机地址",
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
"dataType": "HoldingRegister", "dataType": "HoldingRegister",
"adr": "1", "adr": "1",
"quantity": "2", "quantity": "2",
"server": "4cd290346f79a501", "server": "2cd79a42dc42add9",
"useIOFile": false, "useIOFile": false,
"ioFile": "", "ioFile": "",
"useIOForPayload": false, "useIOForPayload": false,
...@@ -137,7 +137,7 @@ ...@@ -137,7 +137,7 @@
"type": "function", "type": "function",
"z": "da7a0f42ae981076", "z": "da7a0f42ae981076",
"name": "数据转换", "name": "数据转换",
"func": "msg.payload = msg.payload[0]*1;\nreturn msg;", "func": "msg.payload = msg.payload[0]*{{factor}};\nreturn msg;",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
...@@ -161,18 +161,19 @@ ...@@ -161,18 +161,19 @@
"wires": [] "wires": []
}, },
{ {
"id": "4cd290346f79a501", "id": "2cd79a42dc42add9",
"type": "modbus-client", "type": "modbus-client",
"z": "da7a0f42ae981076",
"name": "", "name": "",
"clienttype": "serial", "clienttype": "tcp",
"bufferCommands": true, "bufferCommands": true,
"stateLogEnabled": false, "stateLogEnabled": false,
"queueLogEnabled": false, "queueLogEnabled": false,
"failureLogEnabled": true, "failureLogEnabled": true,
"tcpHost": "127.0.0.1", "tcpHost": "127.0.0.1",
"tcpPort": "502", "tcpPort": "10502",
"tcpType": "DEFAULT", "tcpType": "DEFAULT",
"serialPort": "/dev/ttyUSB0", "serialPort": "/dev/ttyUSB",
"serialType": "RTU-BUFFERD", "serialType": "RTU-BUFFERD",
"serialBaudrate": "9600", "serialBaudrate": "9600",
"serialDatabits": "8", "serialDatabits": "8",
...@@ -193,18 +194,15 @@ ...@@ -193,18 +194,15 @@
], ],
"map":{ "map":{
"interface":[ "interface":[
{"key":"dk","replace":{"id":"4cd290346f79a501","name":"serialPort","type":"string"}}, {"key":"dk","replace":{"id":"2cd79a42dc42add9","name":"tcpPort","type":"string"}},
{"key":"bt","replace":{"id":"4cd290346f79a501","name":"serialBaudrate","type":"string"}}, {"key":"fw","replace":{"id":"2cd79a42dc42add9","name":"tcpHost","type":"string"}}
{"key":"sj","replace":{"id":"4cd290346f79a501","name":"serialDatabits","type":"string"}},
{"key":"tz","replace":{"id":"4cd290346f79a501","name":"serialStopbits","type":"string"}},
{"key":"jy","replace":{"id":"4cd290346f79a501","name":"serialParity","type":"string"}}
], ],
"protocol":[ "protocol":[
{"key":"unitid","replace":{"id":"7d08042446ad6297","name":"unitid","type":"string"}}, {"key":"unitid","replace":{"id":"7d08042446ad6297","name":"unitid","type":"string"}},
{"key":"dataType","replace":{"id":"7d08042446ad6297","name":"dataType","type":"string"}}, {"key":"dataType","replace":{"id":"7d08042446ad6297","name":"dataType","type":"string"}},
{"key":"adr","replace":{"id":"7d08042446ad6297","name":"adr","type":"string"}}, {"key":"adr","replace":{"id":"7d08042446ad6297","name":"adr","type":"string"}},
{"key":"quantity","replace":{"id":"7d08042446ad6297","name":"adr","type":"string"}}, {"key":"quantity","replace":{"id":"7d08042446ad6297","name":"quantity","type":"string"}},
{"key":"factor","replace":{"id":"4f986ed7787cc630","name":"func","type":"value"}} {"key":"factor","replace":{"id":"4f986ed7787cc630","name":"{{factor}}","type":"content"}}
] ]
} }
} }
\ No newline at end of file
{
"name": "MQTT",
"config": [
{
"name": "客户端ID",
"key": "clientid",
"type": "string",
"value": null,
"rules": [
{ "required": true, "message": "客户端ID不能为空", "trigger": "blur" }
],
"maxlength": 65535,
"width": "500px",
"hint": "MQTT客户端唯一标识(建议包含设备特征)"
},
{
"name": "用户名",
"key": "user",
"type": "string",
"value": null,
"rules": [
{ "max": 255, "message": "用户名最长255字符" }
],
"maxlength": 255,
"width": "500px",
"hint": "MQTT服务端认证用户名(可选)"
},
{
"name": "密码",
"key": "password",
"type": "string",
"value": null,
"rules": [
{ "max": 255, "message": "密码最长255字符" }
],
"maxlength": 255,
"width": "500px",
"hint": "MQTT服务端认证密码(可选)"
},
{
"name": "订阅主题",
"key": "topic",
"type": "string",
"value": null,
"rules": [
{ "required": true, "message": "订阅/发布主题不能为空", "trigger": "blur" }
],
"width": "500px",
"hint": "MQTT主题(示例:device/status)"
},
{
"name": "QoS",
"key": "qos",
"type": "select",
"value": "0",
"option": [
{ "label": "QoS 0", "value": "0" },
{ "label": "QoS 1", "value": "1" },
{ "label": "QoS 2", "value": "2" }
],
"rules": [{ "required": true, "message": "必须选择服务质量等级", "trigger": "change" }],
"hint": "消息传输质量等级"
},
{
"name": "读对象",
"key": "read_obj",
"type": "string",
"value": null,
"rules": [
{ "required": true, "message": "读对象不能为空", "trigger": "blur" }
],
"width": "500px",
"hint": "读取接收的消息中的指定对象的数据,如读{obj:100}中obj的值,填:obj;如读取{list:[1,2,3,4]}中的第1个元素,填:list[0"
}
],
"nodes": [
{
"id": "da7a0f42ae981076",
"type": "subflow",
"name": "被测设备",
"info": "",
"category": "",
"in": [
{
"x": 60,
"y": 140,
"wires": []
}
],
"out": [
{
"x": 580,
"y": 140,
"wires": [
{
"id": "d80b7fa87a21f707",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "43a232752953e9f6",
"type": "mqtt in",
"z": "da7a0f42ae981076",
"name": "",
"topic": "testtopic/wubi",
"qos": "2",
"datatype": "auto-detect",
"broker": "39a254acb98cd7d6",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 210,
"y": 140,
"wires": [
[
"d80b7fa87a21f707"
]
]
},
{
"id": "d80b7fa87a21f707",
"type": "function",
"z": "da7a0f42ae981076",
"name": "读对象",
"func": "function findJsonValue(jsonObj, path) {\n node.error(jsonObj);\n // 辅助函数:通过完整路径遍历获取值\n const traverse = (current, parts) => {\n for (let i = 0; i < parts.length; i++) {\n if (typeof current !== 'object' || current === null) {\n return undefined;\n }\n const part = parts[i];\n const isArrayIndex = /^\\d+$/.test(part); // 检查是否为纯数字(数组索引)\n\n if (isArrayIndex && Array.isArray(current)) {\n const index = parseInt(part, 10);\n if (index < current.length) {\n current = current[index];\n } else {\n return undefined; // 索引越界\n }\n } else if (typeof current === 'object' && current !== null && Object.prototype.hasOwnProperty.call(current, part)) {\n current = current[part];\n } else {\n return undefined; // 路径部分不存在\n }\n\n // 如果当前值是字符串,并且不是路径的最后一部分,尝试解析它看是否为JSON字符串\n if (typeof current === 'string' && i < parts.length - 1) {\n try {\n const parsedJson = JSON.parse(current);\n if (typeof parsedJson === 'object' && parsedJson !== null) {\n current = parsedJson; // 如果是合法的JSON对象/数组,则用解析后的结果继续遍历\n }\n } catch (e) {\n // 不是合法的JSON字符串,或者解析失败,则保持 current 不变,下一轮循环可能会因此返回 undefined\n }\n }\n }\n return current;\n };\n\n // 辅助函数:深度优先搜索对象中的键\n // 返回找到的第一个匹配键的值\n const deepSearch = (obj, keyToFind) => {\n if (typeof obj !== 'object' || obj === null) {\n return undefined;\n }\n\n // 直接在当前对象层级查找\n if (Object.prototype.hasOwnProperty.call(obj, keyToFind)) {\n return obj[keyToFind];\n }\n\n // 遍历对象的每个属性/元素\n for (const k in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, k)) {\n const item = obj[k];\n let foundValue;\n\n // 如果属性值是对象或数组,递归搜索\n if (typeof item === 'object' && item !== null) {\n foundValue = deepSearch(item, keyToFind);\n }\n // 如果属性值是字符串,尝试解析为JSON并搜索\n else if (typeof item === 'string') {\n try {\n const parsedJson = JSON.parse(item);\n if (typeof parsedJson === 'object' && parsedJson !== null) {\n // 先检查解析后的JSON顶层是否有该键,然后才考虑深度搜索解析后的内容\n if (Object.prototype.hasOwnProperty.call(parsedJson, keyToFind)) {\n foundValue = parsedJson[keyToFind];\n } else {\n foundValue = deepSearch(parsedJson, keyToFind);\n }\n }\n } catch (e) {\n // 不是可解析的JSON字符串\n }\n }\n\n if (foundValue !== undefined) {\n return foundValue; // 一旦找到,立即返回\n }\n }\n }\n return undefined; // 在当前对象及其子结构中未找到\n };\n\n // 主函数逻辑开始\n if (typeof jsonObj !== 'object' || jsonObj === null || typeof path !== 'string') {\n return undefined;\n }\n\n \n\n // 判断路径是简单键名还是复杂路径\n if (path.includes('.') || path.includes('[')) {\n // 复杂路径:使用路径遍历逻辑\n const parts = path.split(/[.\\[\\]]+/).filter(Boolean); // 分割路径并移除空字符串\n return traverse(jsonObj, parts);\n } else {\n // 简单键名:\n // 1. 首先尝试直接从顶层获取 (更符合直接输入键名的直觉)\n if (Object.prototype.hasOwnProperty.call(jsonObj, path)) {\n return jsonObj[path];\n }\n // 2. 如果顶层没有,则进行深度搜索\n return deepSearch(jsonObj, path);\n }\n}\n\nvar read_input_obj = \"{{read_input}}\"\n//read_input_obj = \"RS_SD\";\nconst val2 = findJsonValue(msg.payload, read_input_obj);\nmsg.payload = val2;\nif (read_input_obj == \"{{read_input}}\"){\n node.error(\"读对象未设置!\");\n}\nnode.warn(msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 390,
"y": 140,
"wires": [
[]
]
},
{
"id": "39a254acb98cd7d6",
"type": "mqtt-broker",
"name": "",
"broker": "broker.emqx.io",
"port": "1883",
"clientid": "mqttx_9d4db9ea22",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"autoUnsubscribe": true,
"birthTopic": "",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closeRetain": "false",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willRetain": "false",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": "",
"credentials": {
"user": "{{user}}",
"password": "{{password}}"
}
}
],
"map": {
"interface": [
{"key": "fw", "replace": {"id": "39a254acb98cd7d6", "name": "broker", "type": "string"}},
{"key": "dk", "replace": {"id": "39a254acb98cd7d6", "name": "port", "type": "string"}}
],
"protocol": [
{"key": "clientid", "replace": {"id": "39a254acb98cd7d6", "name": "clientid", "type": "string"}},
{"key": "user", "replace": {"id": "39a254acb98cd7d6", "name": "{{user}}", "type": "content"}},
{"key": "password", "replace": {"id": "39a254acb98cd7d6", "name": "{{password}}", "type": "content"}},
{"key": "topic", "replace": {"id": "43a232752953e9f6", "name": "topic", "type": "string"}},
{"key": "qos", "replace": {"id": "43a232752953e9f6", "name": "qos", "type": "string"}},
{"key": "read_obj", "replace": {"id": "d80b7fa87a21f707", "name": "{{read_input}}", "type": "content"}}
]
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
"type": "function", "type": "function",
"z": "c6f6c91c824708d6", "z": "c6f6c91c824708d6",
"name": "指标参数判断", "name": "指标参数判断",
"func": "\nvar t = msg.payload;\nif (t < 50 && t > -20) {\n msg.payload = 1;\n} else {\n msg.payload = 0;\n}\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n", "func": "\nvar t = msg.payload;\nvar type_input = \"{{type_input}}\"//由服务端处理\nvar type = \"number\"\nif (type_input == \"string\"){\n type = type_input;\n}\nif(type == \"number\"){\n var min_input = \"{{min_input}}\"//由服务端处理\n var max_input = \"{{max_input}}\"//由服务端处理\n var min = -20;\n var max = 100;\n\n if (!Number.isNaN(Number(min_input))){\n min = Number(min_input)\n }\n\n if (!Number.isNaN(Number(max_input))) {\n max = Number(max_input)\n }\n\n if (t <= max && t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n}else if(type == \"string\"){\n var value_input = \"{{value_input}}\"////由服务端处理\n if(t == value_input){\n msg.payload = 1;\n }else{\n msg.payload = 0;\n }\n}else{\n msg.payload = 0;\n}\n\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
...@@ -180,7 +180,7 @@ ...@@ -180,7 +180,7 @@
"type": "function", "type": "function",
"z": "0b96e65cf9d2c6a0", "z": "0b96e65cf9d2c6a0",
"name": "测试策略", "name": "测试策略",
"func": "if(msg.payload.is_init){\n var loop_size = 10;//10次 测试次数\n var loop_time = 60*1000;//60秒 测试持续时间\n var time = loop_time +new Date().getTime();\n var loop_mode = \"time\"; // size 测试次数 time 持续时间\n global.set(\"loop_size\", loop_size);\n global.set(\"loop_time\",time);\n global.set(\"loop_mode\",loop_mode);\n global.set(\"loop_end\",false);\n global.set(\"result\",[]);//初始化结果\n global.set(\"has_result\",1);\n global.set(\"complete\",false);\n if(loop_mode == \"size\"){\n msg.loop_info = loop_size;\n }else if(loop_mode == \"time\"){\n msg.loop_info = loop_time;\n }\n msg.payload = {\"msg\":\"流程初始化成功\",\"code\":0};\n return msg;\n}\n", "func": "if(msg.payload.is_init){\n var loop_mode_input = \"{{loop_mode}}\"//由服务端处理\n var loop_size_input = \"{{loop_size}}\"//由服务端处理\n var loop_time_input = \"{{loop_time}}\"//由服务端处理\n\n var loop_size = 10;//10次 测试次数\n var loop_time = 60*1000;//60秒 测试持续时间\n\n if (!Number.isNaN(Number(loop_size_input))){\n loop_size = Number(loop_size_input)\n }\n\n if (!Number.isNaN(Number(loop_time_input))) {\n loop_time = Number(loop_time_input)*1000\n }\n\n var time = loop_time +new Date().getTime();\n var loop_mode = \"time\"; // size 测试次数 time 持续时间\n if (loop_mode_input == \"time\" || loop_mode_input == \"size\"){\n loop_mode = loop_mode_input\n }\n global.set(\"loop_size\", loop_size);\n global.set(\"loop_time\",time);\n global.set(\"loop_mode\",loop_mode);\n global.set(\"loop_end\",false);\n global.set(\"result\",[]);//初始化结果\n global.set(\"has_result\",1);\n global.set(\"complete\",false);\n if(loop_mode == \"size\"){\n msg.loop_info = loop_size;\n }else if(loop_mode == \"time\"){\n msg.loop_info = loop_time;\n }\n msg.payload = {\"msg\":\"流程初始化成功\",\"code\":0};\n return msg;\n}\n",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
...@@ -688,16 +688,6 @@ ...@@ -688,16 +688,6 @@
"y": 240, "y": 240,
"wires": [] "wires": []
}, },
{
"id": "e3388481541cf887",
"type": "comment",
"z": "b676dbe90b296890",
"name": "TODO",
"info": "1.持续时间策略实现。 完成\n2.测试日志上报实现,使用wbsocket。完成\n3.针对主动上报传感器进行流程配置。\n4.日志保存接口",
"x": 870,
"y": 140,
"wires": []
},
{ {
"id": "be9582addda9e660", "id": "be9582addda9e660",
"type": "function", "type": "function",
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
"type": "function", "type": "function",
"z": "c6f6c91c824708d6", "z": "c6f6c91c824708d6",
"name": "指标参数判断", "name": "指标参数判断",
"func": "\nvar t = msg.payload;\nif (t < 50 && t > -20) {\n msg.payload = 1;\n} else {\n msg.payload = 0;\n}\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n", "func": "\nvar t = msg.payload;\nvar type_input = \"{{type_input}}\"//由服务端处理\nvar type = \"number\"\nif (type_input == \"string\"){\n type = type_input;\n}\nif(type == \"number\"){\n var min_input = \"{{min_input}}\"//由服务端处理\n var max_input = \"{{max_input}}\"//由服务端处理\n var min = -20;\n var max = 100;\n\n if (!Number.isNaN(Number(min_input))){\n min = Number(min_input)\n }\n\n if (!Number.isNaN(Number(max_input))) {\n max = Number(max_input)\n }\n\n if (t <= max && t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n}else if(type == \"string\"){\n var value_input = \"{{value_input}}\"////由服务端处理\n if(t == value_input){\n msg.payload = 1;\n }else{\n msg.payload = 0;\n }\n}else{\n msg.payload = 0;\n}\n\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
...@@ -180,7 +180,7 @@ ...@@ -180,7 +180,7 @@
"type": "function", "type": "function",
"z": "0b96e65cf9d2c6a0", "z": "0b96e65cf9d2c6a0",
"name": "测试策略", "name": "测试策略",
"func": "if(msg.payload.is_init){\n var loop_size = 10;//10次 测试次数\n var loop_time = 60*1000;//60秒 测试持续时间\n var time = loop_time +new Date().getTime();\n var loop_mode = \"time\"; // size 测试次数 time 持续时间\n global.set(\"loop_size\", loop_size);\n global.set(\"loop_time\",time);\n global.set(\"loop_mode\",loop_mode);\n global.set(\"loop_end\",false);\n global.set(\"result\",[]);//初始化结果\n global.set(\"has_result\",1);\n global.set(\"complete\",false);\n if(loop_mode == \"size\"){\n msg.loop_info = loop_size;\n }else if(loop_mode == \"time\"){\n msg.loop_info = loop_time;\n }\n msg.payload = {\"msg\":\"流程初始化成功\",\"code\":0};\n return msg;\n}\n", "func": "if(msg.payload.is_init){\n var loop_mode_input = \"{{loop_mode}}\"//由服务端处理\n var loop_size_input = \"{{loop_size}}\"//由服务端处理\n var loop_time_input = \"{{loop_time}}\"//由服务端处理\n\n var loop_size = 10;//10次 测试次数\n var loop_time = 60*1000;//60秒 测试持续时间\n\n if (!Number.isNaN(Number(loop_size_input))){\n loop_size = Number(loop_size_input)\n }\n\n if (!Number.isNaN(Number(loop_time_input))) {\n loop_time = Number(loop_time_input)*1000\n }\n\n var time = loop_time +new Date().getTime();\n var loop_mode = \"time\"; // size 测试次数 time 持续时间\n if (loop_mode_input == \"time\" || loop_mode_input == \"size\"){\n loop_mode = loop_mode_input\n }\n global.set(\"loop_size\", loop_size);\n global.set(\"loop_time\",time);\n global.set(\"loop_mode\",loop_mode);\n global.set(\"loop_end\",false);\n global.set(\"result\",[]);//初始化结果\n global.set(\"has_result\",1);\n global.set(\"complete\",false);\n if(loop_mode == \"size\"){\n msg.loop_info = loop_size;\n }else if(loop_mode == \"time\"){\n msg.loop_info = loop_time;\n }\n msg.payload = {\"msg\":\"流程初始化成功\",\"code\":0};\n return msg;\n}\n",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
...@@ -511,7 +511,7 @@ ...@@ -511,7 +511,7 @@
"out": [ "out": [
{ {
"x": 740, "x": 740,
"y": 400, "y": 440,
"wires": [ "wires": [
{ {
"id": "8c69042a7c33e65a", "id": "8c69042a7c33e65a",
...@@ -521,7 +521,7 @@ ...@@ -521,7 +521,7 @@
}, },
{ {
"x": 900, "x": 900,
"y": 180, "y": 220,
"wires": [ "wires": [
{ {
"id": "be9582addda9e660", "id": "be9582addda9e660",
...@@ -548,14 +548,15 @@ ...@@ -548,14 +548,15 @@
"upload": false, "upload": false,
"swaggerDoc": "", "swaggerDoc": "",
"x": 80, "x": 80,
"y": 260, "y": 300,
"wires": [ "wires": [
[ [
"b392bde36a456c1b", "b392bde36a456c1b",
"8c69042a7c33e65a", "8c69042a7c33e65a",
"b721ed0459e1f45e", "b721ed0459e1f45e",
"042194dedfa417f2", "042194dedfa417f2",
"09e9ca0caf4be738" "09e9ca0caf4be738",
"f14cd04ff0981269"
] ]
] ]
}, },
...@@ -573,7 +574,7 @@ ...@@ -573,7 +574,7 @@
"statusVal": "payload", "statusVal": "payload",
"statusType": "auto", "statusType": "auto",
"x": 440, "x": 440,
"y": 80, "y": 120,
"wires": [] "wires": []
}, },
{ {
...@@ -586,7 +587,7 @@ ...@@ -586,7 +587,7 @@
"content-type": "application/json" "content-type": "application/json"
}, },
"x": 730, "x": 730,
"y": 300, "y": 340,
"wires": [] "wires": []
}, },
{ {
...@@ -602,7 +603,7 @@ ...@@ -602,7 +603,7 @@
"finalize": "", "finalize": "",
"libs": [], "libs": [],
"x": 440, "x": 440,
"y": 320, "y": 360,
"wires": [ "wires": [
[ [
"39280fec7a243b6d", "39280fec7a243b6d",
...@@ -624,7 +625,7 @@ ...@@ -624,7 +625,7 @@
"finalize": "", "finalize": "",
"libs": [], "libs": [],
"x": 440, "x": 440,
"y": 260, "y": 300,
"wires": [ "wires": [
[ [
"39280fec7a243b6d", "39280fec7a243b6d",
...@@ -646,7 +647,7 @@ ...@@ -646,7 +647,7 @@
"finalize": "", "finalize": "",
"libs": [], "libs": [],
"x": 440, "x": 440,
"y": 200, "y": 240,
"wires": [ "wires": [
[ [
"39280fec7a243b6d", "39280fec7a243b6d",
...@@ -668,7 +669,7 @@ ...@@ -668,7 +669,7 @@
"finalize": "", "finalize": "",
"libs": [], "libs": [],
"x": 440, "x": 440,
"y": 140, "y": 180,
"wires": [ "wires": [
[ [
"39280fec7a243b6d", "39280fec7a243b6d",
...@@ -684,17 +685,7 @@ ...@@ -684,17 +685,7 @@
"name": "1.管理接口", "name": "1.管理接口",
"info": "", "info": "",
"x": 80, "x": 80,
"y": 200, "y": 240,
"wires": []
},
{
"id": "e3388481541cf887",
"type": "comment",
"z": "b676dbe90b296890",
"name": "TODO",
"info": "1.持续时间策略实现。 完成\n2.测试日志上报实现,使用wbsocket。完成\n3.针对主动上报传感器进行流程配置。\n4.日志保存接口",
"x": 870,
"y": 100,
"wires": [] "wires": []
}, },
{ {
...@@ -710,7 +701,7 @@ ...@@ -710,7 +701,7 @@
"finalize": "", "finalize": "",
"libs": [], "libs": [],
"x": 740, "x": 740,
"y": 180, "y": 220,
"wires": [ "wires": [
[] []
] ]
...@@ -725,7 +716,7 @@ ...@@ -725,7 +716,7 @@
"upload": false, "upload": false,
"swaggerDoc": "", "swaggerDoc": "",
"x": 70, "x": 70,
"y": 320, "y": 360,
"wires": [ "wires": [
[ [
"f32963fe4ffa3ed1" "f32963fe4ffa3ed1"
...@@ -744,11 +735,12 @@ ...@@ -744,11 +735,12 @@
"initialize": "", "initialize": "",
"finalize": "", "finalize": "",
"libs": [], "libs": [],
"x": 450, "x": 310,
"y": 400, "y": 480,
"wires": [ "wires": [
[ [
"39280fec7a243b6d" "39280fec7a243b6d",
"97b8ee4efd068ae6"
] ]
] ]
}, },
...@@ -769,7 +761,7 @@ ...@@ -769,7 +761,7 @@
"senderr": false, "senderr": false,
"headers": [], "headers": [],
"x": 920, "x": 920,
"y": 500, "y": 540,
"wires": [ "wires": [
[ [
"0355fe86416440f5" "0355fe86416440f5"
...@@ -789,7 +781,7 @@ ...@@ -789,7 +781,7 @@
"finalize": "", "finalize": "",
"libs": [], "libs": [],
"x": 740, "x": 740,
"y": 500, "y": 540,
"wires": [ "wires": [
[ [
"adc5c720c9afd2c8", "adc5c720c9afd2c8",
...@@ -811,7 +803,7 @@ ...@@ -811,7 +803,7 @@
"statusVal": "", "statusVal": "",
"statusType": "auto", "statusType": "auto",
"x": 980, "x": 980,
"y": 580, "y": 620,
"wires": [] "wires": []
}, },
{ {
...@@ -828,9 +820,64 @@ ...@@ -828,9 +820,64 @@
"statusVal": "", "statusVal": "",
"statusType": "auto", "statusType": "auto",
"x": 1120, "x": 1120,
"y": 500, "y": 540,
"wires": [] "wires": []
}, },
{
"id": "97b8ee4efd068ae6",
"type": "file",
"z": "b676dbe90b296890",
"name": "写token",
"filename": "token.json",
"filenameType": "str",
"appendNewline": true,
"createDir": false,
"overwriteFile": "true",
"encoding": "none",
"x": 500,
"y": 480,
"wires": [
[]
]
},
{
"id": "f14cd04ff0981269",
"type": "file in",
"z": "b676dbe90b296890",
"name": "读token",
"filename": "token.json",
"filenameType": "str",
"format": "utf8",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": false,
"x": 300,
"y": 60,
"wires": [
[
"704f7527daf47e31"
]
]
},
{
"id": "704f7527daf47e31",
"type": "function",
"z": "b676dbe90b296890",
"name": "保存TOKEN",
"func": "node.warn(msg.payload);\nglobal.set(\"token\",msg.payload.token);\nglobal.set(\"host\",msg.payload.host);\nif(msg.payload.testTaskId){\n global.set(\"testTaskId\",msg.payload.testTaskId);\n}\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 470,
"y": 60,
"wires": [
[]
]
},
{ {
"id": "da7a0f42ae981076", "id": "da7a0f42ae981076",
"type": "subflow", "type": "subflow",
......
This diff is collapsed.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
"type": "function", "type": "function",
"z": "c6f6c91c824708d6", "z": "c6f6c91c824708d6",
"name": "指标参数判断", "name": "指标参数判断",
"func": "\nvar t = msg.payload; //采集到的数据\nvar type_input = \"{{type_input}}\"//由服务端处理\nvar type = \"number\"//number string send_speed collect_speed list raw location\nif (type_input == \"string\"){\n type = type_input;\n}\nif(type == \"number\" || type == \"collect_speed\"){\n var min_input = \"{{min_input}}\"//由服务端处理\n var max_input = \"{{max_input}}\"//由服务端处理\n var min = -20;\n var max = 100;\n\n if (!Number.isNaN(Number(min_input))){\n min = Number(min_input)\n }\n\n if (!Number.isNaN(Number(max_input))) {\n max = Number(max_input)\n }\n\n if (t <= max && t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n if(type == \"collect_speed\" && msg.payload == 1 && global.get(\"timing\")!=0){//达到目标值,计算时间\n var current_time = new Date().getTime();\n var collect_speed = 1000/(current_time - global.get(\"timing\"))\n collect_speed = parseFloat((collect_speed).toFixed(2))//单位Hz\n msg.payload = collect_speed\n global.set(\"timing\",0)\n }\n}else if(type == \"string\"){\n var value_input = \"{{value_input}}\"////由服务端处理\n if(t == value_input){\n msg.payload = 1;\n }else{\n msg.payload = 0;\n }\n}else if(type == \"send_speed\"){\n msg.payload = msg.speed\n}else if(type == \"list\"){//列表值对比\n var list = JSON.parse(\"{{list}}\")//服务器替换list如[\"123\",\"456\"]\n var glist = global.get(\"list\",null)\n if(glist == null){\n global.set(\"list\",list)\n }\n msg.payload=0\n if(list.length >0){\n for (let i = 0; i < list.length; i++) {\n if(list[i] == t){\n msg.payload = t\n break;\n }\n }\n }\n}\n\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n", "func": "\nvar t = msg.payload; //采集到的数据\nvar type_input = \"{{type_input}}\"//由服务端处理\nvar type = \"number\"//number string send_speed collect_speed list raw location\nif (type_input == \"string\"){\n type = type_input;\n}\nif(type == \"number\" || type == \"collect_speed\"){\n var min_input = \"{{min_input}}\"//由服务端处理\n var max_input = \"{{max_input}}\"//由服务端处理\n var min = -20;\n var max = 100;\n\n if (!Number.isNaN(Number(min_input))){\n min = Number(min_input)\n }\n\n if (!Number.isNaN(Number(max_input))) {\n max = Number(max_input)\n }\n\n if (t <= max && t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n \n}else if(type == \"string\"){\n var value_input = \"{{value_input}}\"////由服务端处理\n if(t == value_input){\n msg.payload = 1;\n }else{\n msg.payload = 0;\n }\n}else if(type == \"send_speed\"){\n var min_input = \"{{min_input}}\"//由服务端处理\n var min = 1;\n\n if (!Number.isNaN(Number(min_input))) {\n min = Number(min_input)\n }\n\n if (t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n \n msg.payload = msg.speed\n}else if(type == \"collect_speed\"){\n var min_input = \"{{min_input}}\"//由服务端处理\n var min = 1;\n\n if (!Number.isNaN(Number(min_input))) {\n min = Number(min_input)\n }\n\n if (t >= min) {\n msg.payload = 1;\n } else {\n msg.payload = 0;\n }\n\n if(type == \"collect_speed\" && msg.payload == 1 && global.get(\"timing\")!=0){//达到目标值,计算时间\n var current_time = new Date().getTime();\n var collect_speed = 1000/(current_time - global.get(\"timing\"))\n collect_speed = parseFloat((collect_speed).toFixed(2))//单位Hz\n msg.payload = collect_speed\n global.set(\"timing\",0)\n }\n}else if(type == \"list\"){//列表值对比\n var list = JSON.parse(\"{{list}}\")//服务器替换list如[\"123\",\"456\"]\n var glist = global.get(\"list\",null)\n if(glist == null){\n global.set(\"list\",list)\n }\n msg.payload=0\n if(list.length >0){\n for (let i = 0; i < list.length; i++) {\n if(list[i] == t){\n msg.payload = t\n break;\n }\n }\n }\n}\n\nvar list = global.get(\"result\") || [];\nlist.push(msg.payload);\nglobal.set(\"result\", list);\nglobal.set(\"has_result\", 1);\nmsg.payload = { \"msg\": `采集数据:${t},指标检测:${msg.payload}`, \"code\": 0 };\nreturn msg;\n\n",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
...@@ -75,6 +75,17 @@ ...@@ -75,6 +75,17 @@
"meta": {}, "meta": {},
"color": "#DDAA99" "color": "#DDAA99"
}, },
{
"id": "1adcccd216682ef9",
"type": "http response",
"z": "410a1eb0ca263f28",
"name": "",
"statusCode": "",
"headers": {},
"x": 630,
"y": 80,
"wires": []
},
{ {
"id": "15e9c48ab6cc5d0c", "id": "15e9c48ab6cc5d0c",
"type": "http request", "type": "http request",
...@@ -95,7 +106,7 @@ ...@@ -95,7 +106,7 @@
"y": 80, "y": 80,
"wires": [ "wires": [
[ [
"df26f8041ec2388b" "1adcccd216682ef9"
] ]
] ]
}, },
...@@ -104,7 +115,7 @@ ...@@ -104,7 +115,7 @@
"type": "function", "type": "function",
"z": "410a1eb0ca263f28", "z": "410a1eb0ca263f28",
"name": "function 3", "name": "function 3",
"func": "///admin/wlp/taskLog/add\nmsg.url = `${global.get(\"host\")}/admin/wlp/taskLog/add`\nmsg.headers = {\n \"Authorization\":global.get(\"token\"),\n \"Content-Type\": \"application/json\"\n}\nvar status = global.get(\"flow_status\");\nmsg.payload = {\n data:{\n \"testTaskId\": global.get(\"testTaskId\"),\n \"msg\": msg.payload\n}}\nreturn msg;", "func": "\nreturn msg;",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
...@@ -136,23 +147,6 @@ ...@@ -136,23 +147,6 @@
"y": 140, "y": 140,
"wires": [] "wires": []
}, },
{
"id": "df26f8041ec2388b",
"type": "debug",
"z": "410a1eb0ca263f28",
"name": "debug 1",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 640,
"y": 80,
"wires": []
},
{ {
"id": "b676dbe90b296890", "id": "b676dbe90b296890",
"type": "subflow", "type": "subflow",
...@@ -969,11 +963,6 @@ ...@@ -969,11 +963,6 @@
"x": 960, "x": 960,
"y": 160, "y": 160,
"wires": [] "wires": []
},
{
"x": 960,
"y": 300,
"wires": []
} }
], ],
"env": [], "env": [],
...@@ -1005,9 +994,6 @@ ...@@ -1005,9 +994,6 @@
"wires": [ "wires": [
[ [
"93ec4400cac2352e" "93ec4400cac2352e"
],
[
"5c7dd7a96bc8af3a"
] ]
] ]
}, },
...@@ -1073,14 +1059,5 @@ ...@@ -1073,14 +1059,5 @@
"ebf4104ff1d325fd" "ebf4104ff1d325fd"
] ]
] ]
},
{
"id": "5c7dd7a96bc8af3a",
"type": "subflow:410a1eb0ca263f28",
"z": "f2b3c541197aea23",
"name": "被测设备日志上报",
"x": 770,
"y": 300,
"wires": []
} }
] ]
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
[
{
"id": "7162f0ea94f3d943",
"type": "modbus-getter",
"z": "da7a0f42ae981076",
"name": "",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"logIOActivities": false,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "1",
"quantity": "1",
"server": "63b0e1b641ec09c1",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 220,
"y": 140,
"wires": [
[
"381beaa06c9ca34d"
],
[]
]
},
{
"id": "381beaa06c9ca34d",
"type": "function",
"z": "da7a0f42ae981076",
"name": "数据转换",
"func": "msg.payload = (msg.payload[0]-2000)/100;\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 420,
"y": 140,
"wires": [
[]
]
},
{
"id": "63b0e1b641ec09c1",
"type": "modbus-client",
"name": "",
"clienttype": "simpleser",
"bufferCommands": true,
"stateLogEnabled": false,
"queueLogEnabled": false,
"failureLogEnabled": true,
"tcpHost": "127.0.0.1",
"tcpPort": "502",
"tcpType": "DEFAULT",
"serialPort": "/dev/ttyUSB0",
"serialType": "RTU-BUFFERD",
"serialBaudrate": "9600",
"serialDatabits": "8",
"serialStopbits": "1",
"serialParity": "none",
"serialConnectionDelay": "100",
"serialAsciiResponseStartDelimiter": "0x3A",
"unit_id": "1",
"commandDelay": "1",
"clientTimeout": "1000",
"reconnectOnTimeout": true,
"reconnectTimeout": "2000",
"parallelUnitIdsAllowed": true,
"showErrors": false,
"showWarnings": true,
"showLogs": true
}
]
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment