Node-Red探索之旅-导入领导整合资料

验证环境: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值