验证环境:http://192.168.1.173:1880/
1 多对多设备联动
1.1 只有最新值场景
[
{
"id": "7a95d3d95324b85f",
"type": "tab",
"label": "流程 1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "905db84ed6a353bd",
"type": "mqtt in",
"z": "7a95d3d95324b85f",
"name": "输入1",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/B4E3F9FFFE2A84B2:1",
"qos": "0",
"datatype": "json",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 310,
"y": 300,
"wires": [
[
"86435d330e4e9307"
]
]
},
{
"id": "210e979eb5d36d43",
"type": "mqtt in",
"z": "7a95d3d95324b85f",
"name": "输入2",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/70B3D50580014EE5:1",
"qos": "2",
"datatype": "auto-detect",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 310,
"y": 520,
"wires": [
[
"86435d330e4e9307"
]
]
},
{
"id": "f8b3df832c57c108",
"type": "function",
"z": "7a95d3d95324b85f",
"name": "转换",
"func": "node.log(msg)\n\nvar products = flow.get(\"products\");\n\nvar devType = msg.payload.devType;\nvar content = msg.payload.content;\nvar type = msg.payload.type;\nvar eventTime = msg.payload.eventTime;\n\nif (type === \"event\") {\n for (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (devType == products[i].devType) {\n if (content[property]) {\n context.set(property, content[property]);\n }\n }\n }\n}\n\nvar payload = { \"time\": msg.payload.eventTime };\nfor (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (context.get(property) != undefined) {\n payload[property] = context.get(property);\n }\n}\n\n\n\nreturn { \"payload\": payload };",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"products\", [\n {\"devType\": \"ZR-HC-TC\",\"property\": \"turnOnState\"},\n {\"devType\": \"ZR-HC-TH-Z\",\"property\": \"temperature\"},\n])",
"finalize": "",
"libs": [],
"x": 730,
"y": 420,
"wires": [
[
"0b6330f39d54510e"
]
]
},
{
"id": "0b6330f39d54510e",
"type": "switch",
"z": "7a95d3d95324b85f",
"name": "判断",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "jsonata_exp",
"v": "$.payload.turnOnState = \"OFF\" and $.payload.temperature > 26",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 910,
"y": 420,
"wires": [
[
"6caec92ff6d52762"
]
]
},
{
"id": "6caec92ff6d52762",
"type": "change",
"z": "7a95d3d95324b85f",
"name": "指令",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1090,
"y": 420,
"wires": [
[
"16c72d51259cb967"
]
]
},
{
"id": "16c72d51259cb967",
"type": "http request",
"z": "7a95d3d95324b85f",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1290,
"y": 420,
"wires": [
[]
]
},
{
"id": "86435d330e4e9307",
"type": "function",
"z": "7a95d3d95324b85f",
"name": "时间判断",
"func": "// 将日期转换成当天的毫秒值\nfunction convertDateToDayOfSeconds(date) {\n let hour = date.getHours();\n let minutes = date.getMinutes();\n let seconds = date.getSeconds();\n return hour * 3600 + minutes * 60 + seconds;\n}\n\n// 将时间转换成当天的毫秒值\nfunction convertTimeToDayOfSeconds(time) {\n var parts = time.split(\":\");\n return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60;\n}\n\nconst date = new Date(msg.payload.eventTime);\nconst weekday = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\nlet currentSeconds = convertDateToDayOfSeconds(date);\nlet startSeconds = convertTimeToDayOfSeconds(flow.get(\"startTime\"));\nlet endSeconds = convertTimeToDayOfSeconds(flow.get(\"endTime\"));\nlet minSeconds = 0;\nlet maxSeconds = 86400;\nlet dayOfWeek = weekday[date.getDay()];\n\nif (flow.get(\"dayOfWeeks\").indexOf(dayOfWeek) == -1) {\n // 星期不匹配\n return;\n}\n\nif (endSeconds >= startSeconds) {\n // 当日\n if (startSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n} else {\n // 跨天\n if (startSeconds <= currentSeconds && currentSeconds <= maxSeconds) {\n return msg;\n }\n if (minSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n}\n\nreturn null;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"startTime\", \"08:30\");\nflow.set(\"endTime\", \"18:30\");\nflow.set(\"dayOfWeeks\", [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]);",
"finalize": "",
"libs": [],
"x": 540,
"y": 420,
"wires": [
[
"f8b3df832c57c108"
]
]
},
{
"id": "2a79133abdde8c0d",
"type": "mqtt-broker",
"name": "开发环境MQTT",
"broker": "192.168.1.173",
"port": "1883",
"clientid": "",
"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": ""
}
]
1、function 节点实现时间有效期的判断
变量定义
1)开始时间(格式:HH:mm
)
2)结束时间(格式:HH:mm
)
3)星期数组,格式如下:
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
完整格式如下:
flow.set("startTime", "08:30");
flow.set("endTime", "18:30");
flow.set("dayOfWeeks", ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]);
2、function 节点实现属性抽取合并
变量定义
1)定义设备类型以及对应的属性值,抽取后属性Key不变
完整格式如下:
flow.set("products", [
{"devType": "ZR-HC-TC","property": "turnOnState"},
{"devType": "ZR-HC-TH-Z","property": "temperature"},
]);
3、switch 节点 基于JSONata语法实现条件判断
$.payload.turnOnState = "OFF" and $.payload.temperature > 26
1.2 最新值&值变化场景
[
{
"id": "0bf2b97a10229979",
"type": "tab",
"label": "流程 3",
"disabled": false,
"info": "",
"env": []
},
{
"id": "ffaa61c4335f724e",
"type": "mqtt in",
"z": "0bf2b97a10229979",
"name": "输入1",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/B4E3F9FFFE2A84B2:1",
"qos": "0",
"datatype": "json",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 110,
"y": 240,
"wires": [
[
"c9fb54874f8f7054"
]
]
},
{
"id": "986a1ba7e0368d38",
"type": "mqtt in",
"z": "0bf2b97a10229979",
"name": "输入2",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/70B3D50580014EE5:1",
"qos": "2",
"datatype": "auto-detect",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 110,
"y": 440,
"wires": [
[
"9caf2cfb623a060d"
]
]
},
{
"id": "7397ec9a20beb03a",
"type": "function",
"z": "0bf2b97a10229979",
"name": "转换",
"func": "node.log(msg)\n\nvar products = flow.get(\"products\");\n\nvar devType = msg.payload.devType;\nvar content = msg.payload.content;\nvar type = msg.payload.type;\nvar eventTime = msg.payload.eventTime;\n\nif (type === \"event\") {\n for (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (devType == products[i].devType) {\n if (content[property]) {\n context.set(property, content[property]);\n }\n }\n }\n}\n\nvar payload = { \"time\": msg.payload.eventTime };\nlet finished = true;\nfor (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (context.get(property) != undefined) {\n payload[property] = context.get(property);\n } else {\n finished = false;\n }\n}\nif (finished) {\n return { \"payload\": payload }\n}\nreturn;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"products\", [\n { \"devType\": \"ZR-HC-TC\",\"property\": \"turnOnState\"},\n { \"devType\": \"ZR-HC-TH-Z\", \"property\": \"_temperatureChange\" },\n { \"devType\": \"ZR-HC-TH-Z\",\"property\": \"temperature\"},\n])",
"finalize": "",
"libs": [],
"x": 770,
"y": 320,
"wires": [
[
"a45d11929011912e"
]
]
},
{
"id": "a45d11929011912e",
"type": "switch",
"z": "0bf2b97a10229979",
"name": "判断",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "jsonata_exp",
"v": "$.payload.turnOnState = \"OFF\" and $.payload.temperature > 26 and $.paload._temperatureChange",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 950,
"y": 320,
"wires": [
[
"2a01d87901e108a1"
]
]
},
{
"id": "2a01d87901e108a1",
"type": "change",
"z": "0bf2b97a10229979",
"name": "指令",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1130,
"y": 320,
"wires": [
[
"18e2ffd174800c31"
]
]
},
{
"id": "18e2ffd174800c31",
"type": "http request",
"z": "0bf2b97a10229979",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1310,
"y": 320,
"wires": [
[]
]
},
{
"id": "c9fb54874f8f7054",
"type": "function",
"z": "0bf2b97a10229979",
"name": "时间判断",
"func": "// 将日期转换成当天的毫秒值\nfunction convertDateToDayOfSeconds(date) {\n let hour = date.getHours();\n let minutes = date.getMinutes();\n let seconds = date.getSeconds();\n return hour * 3600 + minutes * 60 + seconds;\n}\n\n// 将时间转换成当天的毫秒值\nfunction convertTimeToDayOfSeconds(time) {\n var parts = time.split(\":\");\n return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60;\n}\n\nconst date = new Date(msg.payload.eventTime);\nconst weekday = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\nlet currentSeconds = convertDateToDayOfSeconds(date);\nlet startSeconds = convertTimeToDayOfSeconds(flow.get(\"startTime\"));\nlet endSeconds = convertTimeToDayOfSeconds(flow.get(\"endTime\"));\nlet minSeconds = 0;\nlet maxSeconds = 86400;\nlet dayOfWeek = weekday[date.getDay()];\n\nif (flow.get(\"dayOfWeeks\").indexOf(dayOfWeek) == -1) {\n // 星期不匹配\n return;\n}\n\nif (endSeconds >= startSeconds) {\n // 当日\n if (startSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n} else {\n // 跨天\n if (startSeconds <= currentSeconds && currentSeconds <= maxSeconds) {\n return msg;\n }\n if (minSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n}\n\nreturn null;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"startTime\", \"08:30\");\nflow.set(\"endTime\", \"18:30\");\nflow.set(\"dayOfWeeks\", [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]);",
"finalize": "",
"libs": [],
"x": 300,
"y": 240,
"wires": [
[
"3c0f8804dcb0a618"
]
]
},
{
"id": "3c0f8804dcb0a618",
"type": "rbe",
"z": "0bf2b97a10229979",
"name": "值变化",
"func": "rbei",
"gap": "",
"start": "",
"inout": "out",
"septopics": true,
"property": "payload.content.temperature",
"topi": "topic",
"x": 490,
"y": 240,
"wires": [
[
"62a662d6bc2df772"
]
]
},
{
"id": "9caf2cfb623a060d",
"type": "function",
"z": "0bf2b97a10229979",
"name": "时间判断",
"func": "// 将日期转换成当天的毫秒值\nfunction convertDateToDayOfSeconds(date) {\n let hour = date.getHours();\n let minutes = date.getMinutes();\n let seconds = date.getSeconds();\n return hour * 3600 + minutes * 60 + seconds;\n}\n\n// 将时间转换成当天的毫秒值\nfunction convertTimeToDayOfSeconds(time) {\n var parts = time.split(\":\");\n return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60;\n}\n\nconst date = new Date(msg.payload.eventTime);\nconst weekday = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\nlet currentSeconds = convertDateToDayOfSeconds(date);\nlet startSeconds = convertTimeToDayOfSeconds(flow.get(\"startTime\"));\nlet endSeconds = convertTimeToDayOfSeconds(flow.get(\"endTime\"));\nlet minSeconds = 0;\nlet maxSeconds = 86400;\nlet dayOfWeek = weekday[date.getDay()];\n\nif (flow.get(\"dayOfWeeks\").indexOf(dayOfWeek) == -1) {\n // 星期不匹配\n return;\n}\n\nif (endSeconds >= startSeconds) {\n // 当日\n if (startSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n} else {\n // 跨天\n if (startSeconds <= currentSeconds && currentSeconds <= maxSeconds) {\n return msg;\n }\n if (minSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n}\n\nreturn null;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"startTime\", \"08:30\");\nflow.set(\"endTime\", \"18:30\");\nflow.set(\"dayOfWeeks\", [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]);",
"finalize": "",
"libs": [],
"x": 300,
"y": 440,
"wires": [
[
"7397ec9a20beb03a"
]
]
},
{
"id": "62a662d6bc2df772",
"type": "change",
"z": "0bf2b97a10229979",
"name": "设定值",
"rules": [
{
"t": "set",
"p": "payload.content._temperatureChange",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 630,
"y": 280,
"wires": [
[
"7397ec9a20beb03a"
]
]
},
{
"id": "2a79133abdde8c0d",
"type": "mqtt-broker",
"name": "开发环境MQTT",
"broker": "192.168.1.173",
"port": "1883",
"clientid": "",
"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": ""
}
]
在1.1 的基础上增加以下内容
1、filter 节点实现阻塞直至值发生变化
2、change 节点设置字段变化标识 ,下划线+属性+Change后缀,例如,温度(temperature
)发生变化,则变化标识为_temperatureChange
。
1.3 无值场景
[
{
"id": "e80a89cff5ac2b8b",
"type": "tab",
"label": "流程 4",
"disabled": false,
"info": "",
"env": []
},
{
"id": "6cee7166c49c0c37",
"type": "mqtt in",
"z": "e80a89cff5ac2b8b",
"name": "输入1",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/B4E3F9FFFE2A84B2:1",
"qos": "0",
"datatype": "json",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 290,
"y": 300,
"wires": [
[
"c90ee361a3a738c5"
]
]
},
{
"id": "c90ee361a3a738c5",
"type": "trigger",
"z": "e80a89cff5ac2b8b",
"name": "看门狗",
"op1": "",
"op2": "{\"devId\":0,\"devCode\":\"B4E3F9FFFE2A84B2:1\",\"devType\":\"ZR-HC-TH-Z\",\"type\":\"event\",\"title\":\"property\",\"content\":{\"timeout\":true}}",
"op1type": "nul",
"op2type": "json",
"duration": "5",
"extend": true,
"overrideDelay": false,
"units": "s",
"reset": "",
"bytopic": "all",
"topic": "topic",
"outputs": 1,
"x": 610,
"y": 340,
"wires": [
[
"a83a9fbb696497de"
]
]
},
{
"id": "fbe268cdb0815607",
"type": "inject",
"z": "e80a89cff5ac2b8b",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "0.1",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 300,
"y": 380,
"wires": [
[
"c90ee361a3a738c5"
]
]
},
{
"id": "a83a9fbb696497de",
"type": "debug",
"z": "e80a89cff5ac2b8b",
"name": "debug 14",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 820,
"y": 340,
"wires": []
},
{
"id": "2a79133abdde8c0d",
"type": "mqtt-broker",
"name": "开发环境MQTT",
"broker": "192.168.1.173",
"port": "1883",
"clientid": "",
"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": ""
}
]
1、Trigger 节点实现超过多长时间后,没有收到值,触发timeout消息。
2、Inject 节点负责初始化Trigger 节点
1.4 提取变量
- 设备Topic:设备管理获取
- 设备类型:物模型定义
- 设备属性:物模型属性定义
- 有效时间:星期数、开始时间、结束时间
- 属性判断条件(AND / OR):物模型属性&事件定义的判断条件
- 指令:物模型中行为定义生成的指令
- 被控设备ID:设备管理获取
- MQTT地址:MQTT broker
2 定时开机
[
{
"id": "37db6140f11b9ed3",
"type": "tab",
"label": "流程 2",
"disabled": false,
"info": "",
"env": []
},
{
"id": "08fa4d0914e8854b",
"type": "inject",
"z": "37db6140f11b9ed3",
"name": "定时",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "00 08 * * 1,2,3,4,5",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"payloadType": "json",
"x": 250,
"y": 400,
"wires": [
[
"44e5f67b322531bf"
]
]
},
{
"id": "44e5f67b322531bf",
"type": "http request",
"z": "37db6140f11b9ed3",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 510,
"y": 400,
"wires": [
[]
]
}
]
提取变量
- 指令:物模型中行为定义生成的指令
- 重复周期:执行频率
- 立即执行
- 立即执行延时:单位秒
- 被控设备ID:设备管理获取
3 Web API
POST http://192.168.1.173:1880/flows
{
"flows": [
{
"id": "7a95d3d95324b85f",
"type": "tab",
"label": "流程 1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "37db6140f11b9ed3",
"type": "tab",
"label": "流程 2",
"disabled": false,
"info": "",
"env": []
},
{
"id": "0bf2b97a10229979",
"type": "tab",
"label": "流程 3",
"disabled": false,
"info": "",
"env": []
},
{
"id": "e80a89cff5ac2b8b",
"type": "tab",
"label": "流程 4",
"disabled": false,
"info": "",
"env": []
},
{
"id": "8c7b2b68557c1c81",
"type": "tab",
"label": "Sheet 1"
},
{
"id": "2a79133abdde8c0d",
"type": "mqtt-broker",
"name": "开发环境",
"broker": "192.168.1.173",
"port": "1883",
"clientid": "",
"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": ""
},
{
"id": "2a79133abdde8c0b",
"type": "mqtt-broker",
"z": "8c7b2b68557c1c81",
"name": "开发环境MQTT1",
"broker": "192.168.1.173",
"port": "1883",
"clientid": "node-red",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": false,
"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": ""
},
{
"id": "13419d82be3ea3ad",
"type": "mqtt-broker",
"name": "测试环境1",
"broker": "192.168.1.203",
"port": "1883",
"clientid": "",
"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": ""
},
{
"id": "905db84ed6a353bd",
"type": "mqtt in",
"z": "7a95d3d95324b85f",
"name": "输入1",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/B4E3F9FFFE2A84B2:1",
"qos": "0",
"datatype": "json",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 310,
"y": 300,
"wires": [
[
"86435d330e4e9307"
]
]
},
{
"id": "210e979eb5d36d43",
"type": "mqtt in",
"z": "7a95d3d95324b85f",
"name": "输入2",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/70B3D50580014EE5:1",
"qos": "2",
"datatype": "auto-detect",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 310,
"y": 520,
"wires": [
[
"86435d330e4e9307"
]
]
},
{
"id": "f8b3df832c57c108",
"type": "function",
"z": "7a95d3d95324b85f",
"name": "转换",
"func": "node.log(msg)\n\nvar products = flow.get(\"products\");\n\nvar devType = msg.payload.devType;\nvar content = msg.payload.content;\nvar type = msg.payload.type;\nvar eventTime = msg.payload.eventTime;\n\nif (type === \"event\") {\n for (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (devType == products[i].devType) {\n if (content[property]) {\n context.set(property, content[property]);\n }\n }\n }\n}\n\nvar payload = { \"time\": msg.payload.eventTime };\nfor (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (context.get(property) != undefined) {\n payload[property] = context.get(property);\n }\n}\n\n\n\nreturn { \"payload\": payload };",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"products\", [\n {\"devType\": \"ZR-HC-TC\",\"property\": \"turnOnState\"},\n {\"devType\": \"ZR-HC-TH-Z\",\"property\": \"temperature\"},\n])",
"finalize": "",
"libs": [],
"x": 730,
"y": 420,
"wires": [
[
"0b6330f39d54510e"
]
]
},
{
"id": "0b6330f39d54510e",
"type": "switch",
"z": "7a95d3d95324b85f",
"name": "判断",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "jsonata_exp",
"v": "$.payload.turnOnState = \"OFF\" and $.payload.temperature > 26",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 910,
"y": 420,
"wires": [
[
"6caec92ff6d52762"
]
]
},
{
"id": "6caec92ff6d52762",
"type": "change",
"z": "7a95d3d95324b85f",
"name": "指令",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1090,
"y": 420,
"wires": [
[
"16c72d51259cb967"
]
]
},
{
"id": "16c72d51259cb967",
"type": "http request",
"z": "7a95d3d95324b85f",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1290,
"y": 420,
"wires": [
[]
]
},
{
"id": "86435d330e4e9307",
"type": "function",
"z": "7a95d3d95324b85f",
"name": "时间判断",
"func": "// 将日期转换成当天的毫秒值\nfunction convertDateToDayOfSeconds(date) {\n let hour = date.getHours();\n let minutes = date.getMinutes();\n let seconds = date.getSeconds();\n return hour * 3600 + minutes * 60 + seconds;\n}\n\n// 将时间转换成当天的毫秒值\nfunction convertTimeToDayOfSeconds(time) {\n var parts = time.split(\":\");\n return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60;\n}\n\nconst date = new Date(msg.payload.eventTime);\nconst weekday = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\nlet currentSeconds = convertDateToDayOfSeconds(date);\nlet startSeconds = convertTimeToDayOfSeconds(flow.get(\"startTime\"));\nlet endSeconds = convertTimeToDayOfSeconds(flow.get(\"endTime\"));\nlet minSeconds = 0;\nlet maxSeconds = 86400;\nlet dayOfWeek = weekday[date.getDay()];\n\nif (flow.get(\"dayOfWeeks\").indexOf(dayOfWeek) == -1) {\n // 星期不匹配\n return;\n}\n\nif (endSeconds >= startSeconds) {\n // 当日\n if (startSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n} else {\n // 跨天\n if (startSeconds <= currentSeconds && currentSeconds <= maxSeconds) {\n return msg;\n }\n if (minSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n}\n\nreturn null;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"startTime\", \"08:30\");\nflow.set(\"endTime\", \"18:30\");\nflow.set(\"dayOfWeeks\", [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]);",
"finalize": "",
"libs": [],
"x": 540,
"y": 420,
"wires": [
[
"f8b3df832c57c108"
]
]
},
{
"id": "08fa4d0914e8854b",
"type": "inject",
"z": "37db6140f11b9ed3",
"name": "定时",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "00 08 * * 1,2,3,4,5",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"payloadType": "json",
"x": 250,
"y": 400,
"wires": [
[
"44e5f67b322531bf"
]
]
},
{
"id": "44e5f67b322531bf",
"type": "http request",
"z": "37db6140f11b9ed3",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 510,
"y": 400,
"wires": [
[
"254abbf2c595fffb"
]
]
},
{
"id": "f684199b114fb4b8",
"type": "inject",
"z": "37db6140f11b9ed3",
"name": "定时",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "30 18 * * 1,2,3,4,5",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"turnOff\":{}}",
"payloadType": "json",
"x": 250,
"y": 580,
"wires": [
[
"2b67ad52b4f4a704"
]
]
},
{
"id": "2b67ad52b4f4a704",
"type": "http request",
"z": "37db6140f11b9ed3",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 510,
"y": 580,
"wires": [
[
"f22399cd22748ba7"
]
]
},
{
"id": "f22399cd22748ba7",
"type": "debug",
"z": "37db6140f11b9ed3",
"name": "debug 12",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 760,
"y": 580,
"wires": []
},
{
"id": "254abbf2c595fffb",
"type": "debug",
"z": "37db6140f11b9ed3",
"name": "debug 13",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 740,
"y": 400,
"wires": []
},
{
"id": "ffaa61c4335f724e",
"type": "mqtt in",
"z": "0bf2b97a10229979",
"name": "输入1",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/B4E3F9FFFE2A84B2:1",
"qos": "0",
"datatype": "json",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 110,
"y": 240,
"wires": [
[
"c9fb54874f8f7054"
]
]
},
{
"id": "986a1ba7e0368d38",
"type": "mqtt in",
"z": "0bf2b97a10229979",
"name": "输入2",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/70B3D50580014EE5:1",
"qos": "2",
"datatype": "auto-detect",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 110,
"y": 440,
"wires": [
[
"9caf2cfb623a060d"
]
]
},
{
"id": "7397ec9a20beb03a",
"type": "function",
"z": "0bf2b97a10229979",
"name": "转换",
"func": "node.log(msg)\n\nvar products = flow.get(\"products\");\n\nvar devType = msg.payload.devType;\nvar content = msg.payload.content;\nvar type = msg.payload.type;\nvar eventTime = msg.payload.eventTime;\n\nif (type === \"event\") {\n for (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (devType == products[i].devType) {\n if (content[property]) {\n context.set(property, content[property]);\n }\n }\n }\n}\n\nvar payload = { \"time\": msg.payload.eventTime };\nlet finished = true;\nfor (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (context.get(property) != undefined) {\n payload[property] = context.get(property);\n } else {\n finished = false;\n }\n}\nif (finished) {\n return { \"payload\": payload }\n}\nreturn;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"products\", [\n { \"devType\": \"ZR-HC-TC\",\"property\": \"turnOnState\"},\n { \"devType\": \"ZR-HC-TH-Z\", \"property\": \"_temperatureChange\" },\n { \"devType\": \"ZR-HC-TH-Z\",\"property\": \"temperature\"},\n])",
"finalize": "",
"libs": [],
"x": 770,
"y": 320,
"wires": [
[
"a45d11929011912e"
]
]
},
{
"id": "a45d11929011912e",
"type": "switch",
"z": "0bf2b97a10229979",
"name": "判断",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "jsonata_exp",
"v": "$.payload.turnOnState = \"OFF\" and $.payload.temperature > 26 and $.paload._temperatureChange",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 950,
"y": 320,
"wires": [
[
"2a01d87901e108a1"
]
]
},
{
"id": "2a01d87901e108a1",
"type": "change",
"z": "0bf2b97a10229979",
"name": "指令",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1130,
"y": 320,
"wires": [
[
"18e2ffd174800c31"
]
]
},
{
"id": "18e2ffd174800c31",
"type": "http request",
"z": "0bf2b97a10229979",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1310,
"y": 320,
"wires": [
[]
]
},
{
"id": "c9fb54874f8f7054",
"type": "function",
"z": "0bf2b97a10229979",
"name": "时间判断",
"func": "// 将日期转换成当天的毫秒值\nfunction convertDateToDayOfSeconds(date) {\n let hour = date.getHours();\n let minutes = date.getMinutes();\n let seconds = date.getSeconds();\n return hour * 3600 + minutes * 60 + seconds;\n}\n\n// 将时间转换成当天的毫秒值\nfunction convertTimeToDayOfSeconds(time) {\n var parts = time.split(\":\");\n return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60;\n}\n\nconst date = new Date(msg.payload.eventTime);\nconst weekday = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\nlet currentSeconds = convertDateToDayOfSeconds(date);\nlet startSeconds = convertTimeToDayOfSeconds(flow.get(\"startTime\"));\nlet endSeconds = convertTimeToDayOfSeconds(flow.get(\"endTime\"));\nlet minSeconds = 0;\nlet maxSeconds = 86400;\nlet dayOfWeek = weekday[date.getDay()];\n\nif (flow.get(\"dayOfWeeks\").indexOf(dayOfWeek) == -1) {\n // 星期不匹配\n return;\n}\n\nif (endSeconds >= startSeconds) {\n // 当日\n if (startSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n} else {\n // 跨天\n if (startSeconds <= currentSeconds && currentSeconds <= maxSeconds) {\n return msg;\n }\n if (minSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n}\n\nreturn null;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"startTime\", \"08:30\");\nflow.set(\"endTime\", \"18:30\");\nflow.set(\"dayOfWeeks\", [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]);",
"finalize": "",
"libs": [],
"x": 300,
"y": 240,
"wires": [
[
"3c0f8804dcb0a618"
]
]
},
{
"id": "3c0f8804dcb0a618",
"type": "rbe",
"z": "0bf2b97a10229979",
"name": "值变化",
"func": "rbei",
"gap": "",
"start": "",
"inout": "out",
"septopics": true,
"property": "payload.content.temperature",
"topi": "topic",
"x": 490,
"y": 240,
"wires": [
[
"62a662d6bc2df772"
]
]
},
{
"id": "9caf2cfb623a060d",
"type": "function",
"z": "0bf2b97a10229979",
"name": "时间判断",
"func": "// 将日期转换成当天的毫秒值\nfunction convertDateToDayOfSeconds(date) {\n let hour = date.getHours();\n let minutes = date.getMinutes();\n let seconds = date.getSeconds();\n return hour * 3600 + minutes * 60 + seconds;\n}\n\n// 将时间转换成当天的毫秒值\nfunction convertTimeToDayOfSeconds(time) {\n var parts = time.split(\":\");\n return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60;\n}\n\nconst date = new Date(msg.payload.eventTime);\nconst weekday = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\nlet currentSeconds = convertDateToDayOfSeconds(date);\nlet startSeconds = convertTimeToDayOfSeconds(flow.get(\"startTime\"));\nlet endSeconds = convertTimeToDayOfSeconds(flow.get(\"endTime\"));\nlet minSeconds = 0;\nlet maxSeconds = 86400;\nlet dayOfWeek = weekday[date.getDay()];\n\nif (flow.get(\"dayOfWeeks\").indexOf(dayOfWeek) == -1) {\n // 星期不匹配\n return;\n}\n\nif (endSeconds >= startSeconds) {\n // 当日\n if (startSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n} else {\n // 跨天\n if (startSeconds <= currentSeconds && currentSeconds <= maxSeconds) {\n return msg;\n }\n if (minSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n}\n\nreturn null;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"startTime\", \"08:30\");\nflow.set(\"endTime\", \"18:30\");\nflow.set(\"dayOfWeeks\", [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]);",
"finalize": "",
"libs": [],
"x": 300,
"y": 440,
"wires": [
[
"7397ec9a20beb03a"
]
]
},
{
"id": "62a662d6bc2df772",
"type": "change",
"z": "0bf2b97a10229979",
"name": "设定值",
"rules": [
{
"t": "set",
"p": "payload.content._temperatureChange",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 630,
"y": 280,
"wires": [
[
"7397ec9a20beb03a"
]
]
},
{
"id": "6cee7166c49c0c37",
"type": "mqtt in",
"z": "e80a89cff5ac2b8b",
"name": "输入1",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/B4E3F9FFFE2A84B2:1",
"qos": "0",
"datatype": "json",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 290,
"y": 300,
"wires": [
[
"c90ee361a3a738c5",
"162b0c5454489e29"
]
]
},
{
"id": "c90ee361a3a738c5",
"type": "trigger",
"z": "e80a89cff5ac2b8b",
"name": "看门狗",
"op1": "",
"op2": "{\"devId\":0,\"devCode\":\"B4E3F9FFFE2A84B2:1\",\"devType\":\"ZR-HC-TH-Z\",\"type\":\"event\",\"title\":\"property\",\"content\":{\"timeout\":true}}",
"op1type": "nul",
"op2type": "json",
"duration": "5",
"extend": true,
"overrideDelay": false,
"units": "s",
"reset": "",
"bytopic": "all",
"topic": "topic",
"outputs": 1,
"x": 750,
"y": 300,
"wires": [
[
"a83a9fbb696497de"
]
]
},
{
"id": "a83a9fbb696497de",
"type": "debug",
"z": "e80a89cff5ac2b8b",
"name": "debug 14",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1020,
"y": 300,
"wires": []
},
{
"id": "fbe268cdb0815607",
"type": "inject",
"z": "e80a89cff5ac2b8b",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "0.1",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 300,
"y": 420,
"wires": [
[
"c90ee361a3a738c5",
"e348289785630df4"
]
]
},
{
"id": "162b0c5454489e29",
"type": "debug",
"z": "e80a89cff5ac2b8b",
"name": "debug 15",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 540,
"y": 180,
"wires": []
},
{
"id": "e348289785630df4",
"type": "debug",
"z": "e80a89cff5ac2b8b",
"name": "debug 16",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 540,
"y": 520,
"wires": []
},
{
"id": "f14d615ae9d215e8",
"type": "mqtt in",
"z": "8c7b2b68557c1c81",
"name": "",
"topic": "/iot/device/#",
"qos": "2",
"datatype": "auto-detect",
"broker": "13419d82be3ea3ad",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 350,
"y": 300,
"wires": [
[]
]
}
],
"rev": "bc113ed3b28649102e453800244a760b11611bfd4c649a7754656ede06af3a1b"
}
GET http://192.168.1.173:1880/flows
同上
3.1 Tab
流程标签
{
"id":"7a95d3d95324b85f",
"type":"tab",
"label":"流程 1",
"disabled":false,
"info":"",
"env":[
]
}
变量:
1、流程ID
2、流程名称
3.2 mqtt-broker
{
"id":"2a79133abdde8c0b",
"type":"mqtt-broker",
"name":"开发环境MQTT1",
"broker":"192.168.1.173",
"port":"1883",
"clientid":"node-red",
"autoConnect":true,
"usetls":false,
"protocolVersion":"4",
"keepalive":"60",
"cleansession":false,
"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":"admin",
"password":"admin"
}
}
变量:
1、配置ID
2、配置名称
3、mqtt地址
4、mqtt端口
默认值:1883
5、客户端ID
6、mqtt用户名
7、mqtt密码
3.3 mqtt in
{
"id": "210e979eb5d36d43",
"type": "mqtt in",
"z": "7a95d3d95324b85f",
"name": "输入2",
"topic": "/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/70B3D50580014EE5:1",
"qos": "2",
"datatype": "auto-detect",
"broker": "2a79133abdde8c0d",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 310,
"y": 520,
"wires": [
[
"86435d330e4e9307"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、broker
5、topic
3.4 function
- 有效期验证
{
"id": "86435d330e4e9307",
"type": "function",
"z": "7a95d3d95324b85f",
"name": "时间判断",
"func": "// 将日期转换成当天的毫秒值\nfunction convertDateToDayOfSeconds(date) {\n let hour = date.getHours();\n let minutes = date.getMinutes();\n let seconds = date.getSeconds();\n return hour * 3600 + minutes * 60 + seconds;\n}\n\n// 将时间转换成当天的毫秒值\nfunction convertTimeToDayOfSeconds(time) {\n var parts = time.split(\":\");\n return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60;\n}\n\nconst date = new Date(msg.payload.eventTime);\nconst weekday = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\nlet currentSeconds = convertDateToDayOfSeconds(date);\nlet startSeconds = convertTimeToDayOfSeconds(flow.get(\"startTime\"));\nlet endSeconds = convertTimeToDayOfSeconds(flow.get(\"endTime\"));\nlet minSeconds = 0;\nlet maxSeconds = 86400;\nlet dayOfWeek = weekday[date.getDay()];\n\nif (flow.get(\"dayOfWeeks\").indexOf(dayOfWeek) == -1) {\n // 星期不匹配\n return;\n}\n\nif (endSeconds >= startSeconds) {\n // 当日\n if (startSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n} else {\n // 跨天\n if (startSeconds <= currentSeconds && currentSeconds <= maxSeconds) {\n return msg;\n }\n if (minSeconds <= currentSeconds && currentSeconds <= endSeconds) {\n return msg;\n }\n}\n\nreturn null;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"startTime\", \"08:30\");\nflow.set(\"endTime\", \"18:30\");\nflow.set(\"dayOfWeeks\", [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]);",
"finalize": "",
"libs": [],
"x": 540,
"y": 420,
"wires": [
[
"f8b3df832c57c108"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、开始时间(startTime
)
默认值:00:00
5、结束时间(endTime
)
默认值:24:00
6、星期数(数组)
默认值:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
- 数据抽取
{
"id": "f8b3df832c57c108",
"type": "function",
"z": "7a95d3d95324b85f",
"name": "转换",
"func": "node.log(msg)\n\nvar products = flow.get(\"products\");\n\nvar devType = msg.payload.devType;\nvar content = msg.payload.content;\nvar type = msg.payload.type;\nvar eventTime = msg.payload.eventTime;\n\nif (type === \"event\") {\n for (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (devType == products[i].devType) {\n if (content[property]) {\n context.set(property, content[property]);\n }\n }\n }\n}\n\nvar payload = { \"time\": msg.payload.eventTime };\nfor (var i = 0; i < products.length; i++) {\n let property = products[i].property;\n if (context.get(property) != undefined) {\n payload[property] = context.get(property);\n }\n}\n\n\n\nreturn { \"payload\": payload };",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "flow.set(\"products\", [\n {\"devType\": \"ZR-HC-TC\",\"property\": \"turnOnState\"},\n {\"devType\": \"ZR-HC-TH-Z\",\"property\": \"temperature\"},\n])",
"finalize": "",
"libs": [],
"x": 730,
"y": 420,
"wires": [
[
"0b6330f39d54510e"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、设备属性定义(数组)
例如:[{"devType": "ZR-HC-TC","property": "turnOnState"}, {"devType": "ZR-HC-TH-Z","property": "temperature"}]
3.5 switch
{
"id": "0b6330f39d54510e",
"type": "switch",
"z": "7a95d3d95324b85f",
"name": "判断",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "jsonata_exp",
"v": "$.payload.turnOnState = \"OFF\" and $.payload.temperature > 26",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 910,
"y": 420,
"wires": [
[
"6caec92ff6d52762"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、条件判断
例如:$.payload.turnOnState = \"OFF\" and $.payload.temperature > 26
3.6 change
- 指令
{
"id": "6caec92ff6d52762",
"type": "change",
"z": "7a95d3d95324b85f",
"name": "指令",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1090,
"y": 420,
"wires": [
[
"16c72d51259cb967"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、指令集
例如:{ "turnOn": {} }
- 值变化设置标识
{
"id": "62a662d6bc2df772",
"type": "change",
"z": "0bf2b97a10229979",
"name": "设定值",
"rules": [
{
"t": "set",
"p": "payload.content._temperatureChange",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 630,
"y": 280,
"wires": [
[
"7397ec9a20beb03a"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、属性Key
例如:temperature
3.7 inject
- 初始化看门狗
{
"id": "fbe268cdb0815607",
"type": "inject",
"z": "e80a89cff5ac2b8b",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "0.1",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 300,
"y": 380,
"wires": [
[
"c90ee361a3a738c5"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
- 定时触发
{
"id": "08fa4d0914e8854b",
"type": "inject",
"z": "37db6140f11b9ed3",
"name": "定时",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "00 08 * * 1,2,3,4,5",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"turnOn\":{},\"setMode\":{\"mode\":\"COOL\"},\"setTargetTemperature\":{\"targetTemperature\":18},\"setFanSpeed\":{\"fanSpeed\":\"HIGH\"}}",
"payloadType": "json",
"x": 250,
"y": 400,
"wires": [
[
"44e5f67b322531bf"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、指令集
例如:{ "turnOn": {} }
5、cron表达式
6、是否立即执行
7、立即执行延迟
3.8 filter
{
"id": "3c0f8804dcb0a618",
"type": "rbe",
"z": "0bf2b97a10229979",
"name": "值变化",
"func": "rbei",
"gap": "",
"start": "",
"inout": "out",
"septopics": true,
"property": "payload.content.temperature",
"topi": "topic",
"x": 490,
"y": 240,
"wires": [
[
"62a662d6bc2df772"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、属性Key
例如:temperature
3.9 trigger
{
"id": "c90ee361a3a738c5",
"type": "trigger",
"z": "e80a89cff5ac2b8b",
"name": "看门狗",
"op1": "",
"op2": "{\"devId\":0,\"devCode\":\"B4E3F9FFFE2A84B2:1\",\"devType\":\"ZR-HC-TH-Z\",\"type\":\"event\",\"title\":\"property\",\"content\":{\"timeout\":true}}",
"op1type": "nul",
"op2type": "json",
"duration": "5",
"extend": true,
"overrideDelay": false,
"units": "s",
"reset": "",
"bytopic": "all",
"topic": "topic",
"outputs": 1,
"x": 610,
"y": 340,
"wires": [
[
"a83a9fbb696497de"
]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、设备编码
5、设备类型
6、延时时长
7、延时单位
3.10 http request
{
"id": "18e2ffd174800c31",
"type": "http request",
"z": "0bf2b97a10229979",
"name": "执行",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.1.173:8081/iot-service/v1/device/actions/524081739883085829",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1310,
"y": 320,
"wires": [
[]
]
}
变量:
1、节点ID
2、流程ID
3、下一节点ID
4、IP地址
5、端口号
5、设备ID
附录A 模拟MQTT消息
1 温湿度传感器
Topic:/iot/device/iot-gateway-zigbee-04CD15FFFEABB431/B4E3F9FFFE2A84B2:1
- 属性上报–温度数据
{
"devId":0,
"devCode":"B4E3F9FFFE2A84B2:1",
"devType":"ZR-HC-TH-Z",
"type":"event",
"title":"property",
"eventTime":1721299561512,
"content":{
"temperature":29.9
}
}
- 属性上报–湿度数据
2 空调温控器
Topic: /iot/device/iot-gateway-zigbee-04CD15FFFEABB431/70B3D50580014EE5:1
- 属性上报–空调开关状态
{
"devId":0,
"devCode":"70B3D50580014EE5:1",
"devType":"ZR-HC-TC",
"type":"event",
"title":"property",
"eventTime":1721298281997,
"content":{
"turnOnState":"ON"
}
}
附录B 参考资料
1 JSONata
document:https://docs.jsonata.org/overview.html