当前位置: 首页 > 软件库 > 其他开源 > 物联网 >

node-red-contrib-join-wait

授权协议 MIT License
开发语言 JavaScript
所属分类 其他开源、 物联网
软件类型 开源软件
地区 不详
投 递 者 裴彦
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Node RED join-wait

This Node-RED module waits for incoming messages from different input paths to arrive within a fixed time window.

Node-RED is a tool for wiring together hardware devices, APIs and online services in new and interesting ways.

Description

This node waits for messages from all items in the Paths (Wait) array, which must be received inside of a designated time window.

If all of the messages are received in that interval, a merged output is sent to the success output. Otherwise, any expired messages are sent to the timeout output. Either output can be optionally connected for further processing.

In the event of multiple messages, the time window is adjusted as needed to continue evaluation on subsequent messages. This node has several potential applications, including home automation. For instance, to handle a case where the light turning on/off is also triggering a motion sensor: IF a) light turned OFF, b) motion sensor activated, c) light turned ON all occur within 10 seconds, then turn light OFF.

Memory is managed to delete objects after they reach the Timeout.

Configuration

  • Each item in the Paths (Wait) array corresponds with an input path to wait for. E.g., ["path_1", "path_2", "other_path"]. Each path item must have a unique name.

This can also be configured at runtime by passing an array using msg.pathsToWait.

  • Each item in the Paths (Expire) array corresponds with an input path that will immediately expire all messages in the queue without further processing. This acts as a reset. Each path item must have a unique name.

This can also be configured at runtime by passing an array using msg.pathsToExpire.

  • If the Use regex option is enabled, each item in the Paths array will be treated as a regular expression.

This can also be configured at runtime by passing msg.useRegex as a boolean.

  • Paths topic must be set to a msg property, which is used to check each flow to see if all of the elements in Paths (Wait) are matched. This can be msg.topic, msg.paths, etc. If this is not specified, msg.paths is the default.

Note that Paths topic can be set in one of two ways:

  1. As a string, set to the path to check, e.g., msg.paths = "path_1";
  2. As an object, set to any value (e.g., msg.paths["path_1"] = {"example": "data"}; or msg.paths["path_1"] = 42;).

If the object format is used, multiple paths can be specified. For example, msg.paths = {"path_1": true, "path_2": true}; This can be useful if one flow needs to trigger multiple paths.

  • Correlation topic can be set, if desired, to ensure that only related messages are grouped. E.g., msg._msgid can be used to ensure that only messages from a single split flow are grouped together.

If left blank, all messages will be assumed to be related.

  • Timeout is required to designate the time window to receive all of the messages from Paths (Wait).

  • Sequence order defines the criteria to evaluate the received messages. An exact match can be specified, otherwise, it will match them in any order.

To determine the order, the timestamp on the latest valid Paths (Wait) is used, even if multiple messages arrived earlier. In this case of waiting for ["path_1", "path_2", "path_3"], the * indicates which messages are used: ["path_1", "path_2", "path_1"*, "path_2"*, "path_3"*].

  • Base message defines which message object should be returned as the base message. Either the first message in a sequence or the last.

  • Merged data defines how the data from msg.paths (or, another designed Paths topic) will be returned. Either, it can be merged in its original form, or, it can be overwritten with each respective msg.payload. This merged data is then appended to the Base message.

In the event that multiple messages arrive in this time interval with the same Paths (Wait), only the data from the latest item is returned. For instance, if Paths (Wait) = ["path_1", "path_2", "path_3"], the * indicates which messages are used in this sequence: ["path_1", "path_2", "path_1", "path_2", "path_1"*, "path_2"*, "path_3"*]. These additional messages (not starred) will be expired.

Notes and Caveats

  • There is support for repeated paths. For example, ["path_1", "path_2", "path_1", "path_2"].
  • If any order is used, Paths (Wait) is evaluated to determine the count for repeated paths. If regex is used, paths will be counted in a greedy fashion from left to right. For example, ["path_[12]", "path_2"] would never complete because all instances of "path_1" and "path_2" would be counted for the first path.
  • If exact order is used, note that unexpected paths would still be tolerated.
  • In the case of duplicate paths, only the data from the latest path(s) will be used.
  • If the regex option is enabled, each path will be treated as a regular expression. So, ["^path\d+$"] would match any path1, path2, path3, etc. Note that ^$ are not required, and if omitted, would just perform a partial match. For example ["path\d+"] would match "my_path1_test". This property can also be set at runtime by passing msg.useRegex.

  • If the msg.complete property is set, the message queue will be evaluated for completion, and then any remaining items in the queue will be immediately expired. This feature can be disabled in the settings, if desired.

  • All values within Paths topic must be contained by either Paths (Wait) or Paths (Expire), or an error will be thrown. The Unmatched paths error notification can be disabled within the settings.

  • If msg.pathsToWait is used instead of setting Paths (Wait), note that each successive msg.pathsToWait will overwrite the previously stored global value. Due to the nature of the timeout, Paths (Wait) needs to be evaluated even after a message has arrived. Changing the value of msg.pathsToWait between messages may cause unexpected behavior.

  • Timeout should be padded with a small amount of overhead (i.e., ~5-10 ms or so) for the time it takes to evaluate all of the messages and conditions. This may become critical under very short timeouts.

Example 1: Wait 5 seconds for input from 2 flows (in any order)

Flow
[
    {
        "id": "7382168d.c47858",
        "type": "inject",
        "z": "fb783323.7e308",
        "name": "",
        "topic": "topic1",
        "payload": "{\"brightness\":\"20\"}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "x": 950,
        "y": 1460,
        "wires": [["93c1545b.dca6f8"]]
    },
    {
        "id": "3b8f6807.956d78",
        "type": "debug",
        "z": "fb783323.7e308",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "complete": "true",
        "x": 1610,
        "y": 1320,
        "wires": []
    },
    {
        "id": "5866d421.7eb66c",
        "type": "inject",
        "z": "fb783323.7e308",
        "name": "",
        "topic": "topic1",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "x": 960,
        "y": 1380,
        "wires": [["8d0b69cc.b2b228"]]
    },
    {
        "id": "337256a2.04446a",
        "type": "debug",
        "z": "fb783323.7e308",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 1610,
        "y": 1480,
        "wires": []
    },
    {
        "id": "8d0b69cc.b2b228",
        "type": "change",
        "z": "fb783323.7e308",
        "name": "Set path_1",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_1", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1210,
        "y": 1380,
        "wires": [["959a4717.0b5138"]]
    },
    {
        "id": "93c1545b.dca6f8",
        "type": "change",
        "z": "fb783323.7e308",
        "name": "Set path_2",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_2", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1210,
        "y": 1460,
        "wires": [["959a4717.0b5138"]]
    },
    {
        "id": "959a4717.0b5138",
        "type": "join-wait",
        "z": "fb783323.7e308",
        "name": "",
        "paths": "[\"path_1\", \"path_2\"]",
        "pathsToExpire": "",
        "ignoreUnmatched": false,
        "pathTopic": "paths",
        "pathTopicType": "msg",
        "correlationTopic": "",
        "correlationTopicType": "msg",
        "timeout": "5",
        "timeoutUnits": "1000",
        "exactOrder": "false",
        "firstMsg": "true",
        "mapPayload": "true",
        "disableComplete": false,
        "x": 1420,
        "y": 1400,
        "wires": [["3b8f6807.956d78"], ["337256a2.04446a"]]
    },
    {
        "id": "6ae4802.e40238",
        "type": "comment",
        "z": "fb783323.7e308",
        "name": "(optional) expired messages",
        "info": "",
        "x": 1660,
        "y": 1520,
        "wires": []
    }
]

Example 2: Wait 5 seconds for input from a split flow (in any order); one message does not arrive in time

  • _msgid is used as the Correlation topic, so that flows from split queues can be tracked.

Flow
[
    {
        "id": "c5aae6a2.78f4d8",
        "type": "debug",
        "z": "fb783323.7e308",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "complete": "true",
        "x": 1590,
        "y": 1440,
        "wires": []
    },
    {
        "id": "4644d839.170ac8",
        "type": "inject",
        "z": "fb783323.7e308",
        "name": "",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "x": 800,
        "y": 1500,
        "wires": [["f785671e.2f1ac8", "2869e698.5a1daa", "373d1571.a4d5fa"]]
    },
    {
        "id": "3ed2d37b.3a852c",
        "type": "debug",
        "z": "fb783323.7e308",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 1590,
        "y": 1600,
        "wires": []
    },
    {
        "id": "f785671e.2f1ac8",
        "type": "change",
        "z": "fb783323.7e308",
        "name": "Set path_1",
        "rules": [
            { "t": "set", "p": "paths", "pt": "msg", "to": "path_1", "tot": "str" },
            { "t": "set", "p": "payload", "pt": "msg", "to": "true", "tot": "bool" }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1190,
        "y": 1500,
        "wires": [["c492296e.f80428"]]
    },
    {
        "id": "84493c9a.b98f9",
        "type": "change",
        "z": "fb783323.7e308",
        "name": "Set path_2",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_2", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1190,
        "y": 1580,
        "wires": [["c492296e.f80428"]]
    },
    {
        "id": "c492296e.f80428",
        "type": "join-wait",
        "z": "fb783323.7e308",
        "name": "",
        "paths": "[\"path_1\", \"path_2\"]",
        "pathsToExpire": "",
        "pathTopic": "paths",
        "pathTopicType": "msg",
        "correlationTopic": "_msgid",
        "correlationTopicType": "msg",
        "timeout": "5",
        "timeoutUnits": "1000",
        "exactOrder": "false",
        "firstMsg": "true",
        "mapPayload": "true",
        "x": 1400,
        "y": 1520,
        "wires": [["c5aae6a2.78f4d8"], ["3ed2d37b.3a852c"]]
    },
    {
        "id": "a73abdd0.1bd6",
        "type": "comment",
        "z": "fb783323.7e308",
        "name": "(optional) expired messages",
        "info": "",
        "x": 1640,
        "y": 1640,
        "wires": []
    },
    {
        "id": "2869e698.5a1daa",
        "type": "delay",
        "z": "fb783323.7e308",
        "name": "",
        "pauseType": "delay",
        "timeout": "4",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 1000,
        "y": 1580,
        "wires": [["84493c9a.b98f9"]]
    },
    {
        "id": "373d1571.a4d5fa",
        "type": "delay",
        "z": "fb783323.7e308",
        "name": "",
        "pauseType": "delay",
        "timeout": "7",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 1000,
        "y": 1640,
        "wires": [["84493c9a.b98f9"]]
    }
]

Example 3: Wait 5 seconds for input from Events 1A and 1B; Wait 5 seconds for input from Events 2A and 2B; Wait 1 minute for both event groups to complete.

  • Shows an example of how multiple join-wait nodes can be chained
  • If Event 3A is received, reset queue

Flow
[
    {
        "id": "ecf4478b.5bcf28",
        "type": "change",
        "z": "ee7b2f38.64383",
        "name": "Set event_1B",
        "rules": [{ "t": "set", "p": "name", "pt": "msg", "to": "event_1B", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 760,
        "y": 740,
        "wires": [["fb17fdab.13bc6"]]
    },
    {
        "id": "fb17fdab.13bc6",
        "type": "join-wait",
        "z": "ee7b2f38.64383",
        "name": "",
        "paths": "[\"event_1A\", \"event_1B\"]",
        "pathsToExpire": "",
        "ignoreUnmatched": false,
        "pathTopic": "name",
        "pathTopicType": "msg",
        "correlationTopic": "",
        "correlationTopicType": "msg",
        "timeout": "5",
        "timeoutUnits": "1000",
        "exactOrder": "false",
        "firstMsg": "true",
        "mapPayload": "true",
        "disableComplete": false,
        "x": 960,
        "y": 680,
        "wires": [["8d4ce0e0.362b7"], []]
    },
    {
        "id": "c264c765.36e3c8",
        "type": "change",
        "z": "ee7b2f38.64383",
        "name": "Set event_1A",
        "rules": [{ "t": "set", "p": "name", "pt": "msg", "to": "event_1A", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 750,
        "y": 660,
        "wires": [["fb17fdab.13bc6"]]
    },
    {
        "id": "6a032c55.883394",
        "type": "delay",
        "z": "ee7b2f38.64383",
        "name": "",
        "pauseType": "delay",
        "timeout": "2",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 560,
        "y": 740,
        "wires": [["ecf4478b.5bcf28"]]
    },
    {
        "id": "8d4ce0e0.362b7",
        "type": "join-wait",
        "z": "ee7b2f38.64383",
        "name": "",
        "paths": "[\"event_1A\", \"event_1B\", \"event_2A\", \"event_2B\"]",
        "pathsToExpire": "[\"event_3A\"]",
        "ignoreUnmatched": false,
        "pathTopic": "name",
        "pathTopicType": "msg",
        "correlationTopic": "",
        "correlationTopicType": "msg",
        "timeout": "1",
        "timeoutUnits": "60000",
        "exactOrder": "false",
        "firstMsg": "true",
        "mapPayload": "false",
        "disableComplete": false,
        "x": 1200,
        "y": 800,
        "wires": [["f4c5e7c1.831528"], ["830ebf9c.f1588"]]
    },
    {
        "id": "2830e00c.06bde",
        "type": "inject",
        "z": "ee7b2f38.64383",
        "name": "",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "x": 300,
        "y": 780,
        "wires": [["4213bd84.2c68b4", "6a032c55.883394", "c47ba83d.c17548", "d2839a03.b24e98"]]
    },
    {
        "id": "7e51b1f.75d755",
        "type": "change",
        "z": "ee7b2f38.64383",
        "name": "Set event_2B",
        "rules": [{ "t": "set", "p": "name", "pt": "msg", "to": "event_2B", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 760,
        "y": 900,
        "wires": [["4d466044.9e7ba"]]
    },
    {
        "id": "4213bd84.2c68b4",
        "type": "change",
        "z": "ee7b2f38.64383",
        "name": "Set event_2A",
        "rules": [{ "t": "set", "p": "name", "pt": "msg", "to": "event_2A", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 750,
        "y": 840,
        "wires": [["4d466044.9e7ba"]]
    },
    {
        "id": "c47ba83d.c17548",
        "type": "delay",
        "z": "ee7b2f38.64383",
        "name": "",
        "pauseType": "delay",
        "timeout": "4",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 560,
        "y": 900,
        "wires": [["7e51b1f.75d755"]]
    },
    {
        "id": "4d466044.9e7ba",
        "type": "join-wait",
        "z": "ee7b2f38.64383",
        "name": "",
        "paths": "[\"event_2A\", \"event_2B\"]",
        "pathsToExpire": "",
        "ignoreUnmatched": false,
        "pathTopic": "name",
        "pathTopicType": "msg",
        "correlationTopic": "",
        "correlationTopicType": "msg",
        "timeout": "5",
        "timeoutUnits": "1000",
        "exactOrder": "false",
        "firstMsg": "true",
        "mapPayload": "true",
        "disableComplete": false,
        "x": 940,
        "y": 860,
        "wires": [["89331b9.e9fbce8"], []]
    },
    {
        "id": "a335f9be.14d698",
        "type": "change",
        "z": "ee7b2f38.64383",
        "name": "Set event_3A",
        "rules": [{ "t": "set", "p": "name", "pt": "msg", "to": "event_3A", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 950,
        "y": 1040,
        "wires": [["8d4ce0e0.362b7"]]
    },
    {
        "id": "b3d43a9c.4f0558",
        "type": "inject",
        "z": "ee7b2f38.64383",
        "name": "",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "x": 780,
        "y": 1040,
        "wires": [["a335f9be.14d698"]]
    },
    {
        "id": "830ebf9c.f1588",
        "type": "debug",
        "z": "ee7b2f38.64383",
        "name": "Expired",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "x": 1360,
        "y": 840,
        "wires": []
    },
    {
        "id": "f4c5e7c1.831528",
        "type": "debug",
        "z": "ee7b2f38.64383",
        "name": "Success",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 1360,
        "y": 760,
        "wires": []
    },
    {
        "id": "89331b9.e9fbce8",
        "type": "delay",
        "z": "ee7b2f38.64383",
        "name": "",
        "pauseType": "delay",
        "timeout": "10",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 1000,
        "y": 800,
        "wires": [["8d4ce0e0.362b7"]]
    },
    {
        "id": "d2839a03.b24e98",
        "type": "delay",
        "z": "ee7b2f38.64383",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 560,
        "y": 660,
        "wires": [["c264c765.36e3c8"]]
    },
    {
        "id": "69bf4156.8d7b8",
        "type": "comment",
        "z": "ee7b2f38.64383",
        "name": "Expire all messages with event_3A",
        "info": "",
        "x": 860,
        "y": 1000,
        "wires": []
    }
]

Example 4: Wait 10 seconds for Event 1 to fire 3 times, followed by Event 3. Must be in this exact order.

  • Shows an example of repeated path names
  • Shows an example of setting multiple paths by a single event

Flow
[
    {
        "id": "cc9d6391.878ea",
        "type": "debug",
        "z": "d21c3caf.1c4a6",
        "name": "success",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 800,
        "y": 120,
        "wires": []
    },
    {
        "id": "98108d1f.bc6aa",
        "type": "join-wait",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "paths": "[\"path_1\",\"path_1\",\"path_1\",\"path_3\"]",
        "pathsToExpire": "",
        "useRegex": false,
        "warnUnmatched": false,
        "pathTopic": "paths",
        "pathTopicType": "msg",
        "correlationTopic": "",
        "correlationTopicType": "undefined",
        "timeout": "10",
        "timeoutUnits": "1000",
        "exactOrder": "true",
        "firstMsg": "true",
        "mapPayload": "true",
        "disableComplete": false,
        "x": 600,
        "y": 180,
        "wires": [["cc9d6391.878ea"], ["38e19f0c.ff2a9"]]
    },
    {
        "id": "38e19f0c.ff2a9",
        "type": "debug",
        "z": "d21c3caf.1c4a6",
        "name": "expired",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 800,
        "y": 260,
        "wires": []
    },
    {
        "id": "9d4f0eed.15eb3",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_1 and path_3",
        "rules": [
            { "t": "set", "p": "paths", "pt": "msg", "to": "{\"path_1\": true, \"path_3\":true}", "tot": "json" }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 360,
        "y": 260,
        "wires": [["98108d1f.bc6aa"]]
    },
    {
        "id": "c1809b24.8990f8",
        "type": "delay",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 160,
        "y": 260,
        "wires": [["9d4f0eed.15eb3"]]
    },
    {
        "id": "b69f3131.98969",
        "type": "inject",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 140,
        "y": 120,
        "wires": [["bb0b9bc5.c65ee8", "c1809b24.8990f8", "8969e7ba.e36038"]]
    },
    {
        "id": "bb0b9bc5.c65ee8",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_1",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_1", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 330,
        "y": 120,
        "wires": [["98108d1f.bc6aa"]]
    },
    {
        "id": "8969e7ba.e36038",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_1",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_1", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 330,
        "y": 180,
        "wires": [["98108d1f.bc6aa"]]
    }
]

Example 5: Wait 10 seconds for the exact event order "path_1", "path_2", "path_1", "path_2".

  • Shows an example of repeated path names
  • Shows an example of an unexpected path name being observed. This can be caught by another node, if desired.

Flow
[
    {
        "id": "cc9d6391.878ea",
        "type": "debug",
        "z": "d21c3caf.1c4a6",
        "name": "success",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 800,
        "y": 120,
        "wires": []
    },
    {
        "id": "98108d1f.bc6aa",
        "type": "join-wait",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "paths": "[\"path_1\",\"path_2\",\"path_1\",\"path_2\"]",
        "pathsToExpire": "",
        "useRegex": false,
        "warnUnmatched": true,
        "pathTopic": "paths",
        "pathTopicType": "msg",
        "correlationTopic": "",
        "correlationTopicType": "undefined",
        "timeout": "10",
        "timeoutUnits": "1000",
        "exactOrder": "true",
        "firstMsg": "true",
        "mapPayload": "true",
        "disableComplete": false,
        "x": 640,
        "y": 160,
        "wires": [["cc9d6391.878ea"], ["38e19f0c.ff2a9"]]
    },
    {
        "id": "38e19f0c.ff2a9",
        "type": "debug",
        "z": "d21c3caf.1c4a6",
        "name": "expired",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 800,
        "y": 240,
        "wires": []
    },
    {
        "id": "c1809b24.8990f8",
        "type": "delay",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 160,
        "y": 200,
        "wires": [["bb0b9bc5.c65ee8", "2f5d90da.fabdf", "77c09e21.8cb11"]]
    },
    {
        "id": "b69f3131.98969",
        "type": "inject",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 140,
        "y": 120,
        "wires": [["bb0b9bc5.c65ee8", "2f5d90da.fabdf", "c1809b24.8990f8"]]
    },
    {
        "id": "bb0b9bc5.c65ee8",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_1",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_1", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 430,
        "y": 100,
        "wires": [["98108d1f.bc6aa"]]
    },
    {
        "id": "8969e7ba.e36038",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_2",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_2", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 470,
        "y": 220,
        "wires": [["98108d1f.bc6aa"]]
    },
    {
        "id": "2f5d90da.fabdf",
        "type": "delay",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "pauseType": "delay",
        "timeout": "100",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 430,
        "y": 160,
        "wires": [["8969e7ba.e36038"]]
    },
    {
        "id": "77c09e21.8cb11",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_3",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_3", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 470,
        "y": 260,
        "wires": [["98108d1f.bc6aa"]]
    }
]

Example 6: Wait 10 seconds for two "path_1" events and one "path_2" event in any order.

Flow
[
    {
        "id": "cc9d6391.878ea",
        "type": "debug",
        "z": "d21c3caf.1c4a6",
        "name": "success",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 800,
        "y": 120,
        "wires": []
    },
    {
        "id": "98108d1f.bc6aa",
        "type": "join-wait",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "paths": "[\"path_1\",\"path_2\",\"path_1\"]",
        "pathsToExpire": "",
        "useRegex": false,
        "warnUnmatched": true,
        "pathTopic": "paths",
        "pathTopicType": "msg",
        "correlationTopic": "",
        "correlationTopicType": "undefined",
        "timeout": "10",
        "timeoutUnits": "1000",
        "exactOrder": "false",
        "firstMsg": "true",
        "mapPayload": "true",
        "disableComplete": false,
        "x": 640,
        "y": 160,
        "wires": [["cc9d6391.878ea"], ["38e19f0c.ff2a9"]]
    },
    {
        "id": "38e19f0c.ff2a9",
        "type": "debug",
        "z": "d21c3caf.1c4a6",
        "name": "expired",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 800,
        "y": 240,
        "wires": []
    },
    {
        "id": "b69f3131.98969",
        "type": "inject",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 140,
        "y": 180,
        "wires": [["1546292e.21d097", "25f3441b.c9fd9c", "3c1f3edc.6a53c2"]]
    },
    {
        "id": "bb0b9bc5.c65ee8",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_1",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_1", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 140,
        "wires": [["98108d1f.bc6aa"]]
    },
    {
        "id": "8969e7ba.e36038",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_1",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_1", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 180,
        "wires": [["98108d1f.bc6aa"]]
    },
    {
        "id": "77c09e21.8cb11",
        "type": "change",
        "z": "d21c3caf.1c4a6",
        "name": "Set path_2",
        "rules": [{ "t": "set", "p": "paths", "pt": "msg", "to": "path_2", "tot": "str" }],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 220,
        "wires": [["98108d1f.bc6aa"]]
    },
    {
        "id": "25f3441b.c9fd9c",
        "type": "delay",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "pauseType": "random",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "25",
        "randomUnits": "milliseconds",
        "drop": false,
        "x": 300,
        "y": 140,
        "wires": [["bb0b9bc5.c65ee8"]]
    },
    {
        "id": "1546292e.21d097",
        "type": "delay",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "pauseType": "random",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "25",
        "randomUnits": "milliseconds",
        "drop": false,
        "x": 300,
        "y": 180,
        "wires": [["8969e7ba.e36038"]]
    },
    {
        "id": "3c1f3edc.6a53c2",
        "type": "delay",
        "z": "d21c3caf.1c4a6",
        "name": "",
        "pauseType": "random",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "25",
        "randomUnits": "milliseconds",
        "drop": false,
        "x": 300,
        "y": 220,
        "wires": [["77c09e21.8cb11"]]
    }
]

Get Help

For bug reports and feature requests, open issues. ��

Installation

First of all, install Node-RED

# Then open the user data directory `~/.node-red` and install the package
$ cd ~/.node-red
$ npm install node-red-contrib-join-wait

Or search for join-wait in the manage palette menu

How to contribute

Have an idea? Found a bug? Contributions and pull requests are welcome.

Support my projects

I try to reply to everyone needing help using these projects. Obviously, this takes time. However, if you get some profit from this or just want to encourage me to continue creating stuff, there are few ways you can do it:

  • Starring and sharing the projects you like ��
  • PayPal— You can make one-time donations via PayPal.
  • Venmo— You can make one-time donations via Venmo.
  • Bitcoin— You can send me Bitcoin at this address: 33sT6xw3tZWAdP2oL4ygbH5TVpVMfk9VW7

Credits

MIT License

 相关资料
  • Homebridge Automation powered by Node-RED The above Node-RED Flow, turns on my 'Outside Office' light when the powder room is turned on, and turns them both off after 10 seconds. Not practical but a g

  • Node-RED 是一种编程事件驱动应用程序的低代码方法。基于流的编程创建网络,使其能够可视化表示,从而使其成为一种更容易访问的编程方式。JavaScript 函数可以使用富文本编辑器构建,内置库允许访问有用的函数、模板或流以供重用。

  • 您好,需要帮助吗?我尝试在node red上安装node-red-contrib-db2-for-i包(我在ibm cloud上使用了node red作为服务),但失败了。我有一个错误:安装失败:node-red-contrib-db2-for-i。

  • Node-RED是一个轻量级的开源集成技术,用JavaScript编写。它使用图形流程来集成不同的节点,节点可以接收数据、转换数据和输出数据。 Node-RED通常用于快速建立物联网样式应用的原型,或将现有的互联网服务连接在一起。 您可以使用Hyperledger Composer Node-RED来: 提交交易 读取和更新资产和参与者 订阅时间 删除资产和参与者 Hyperledger Comp

  • 新的节点红色,只是第一次尝试这个节点。 我希望将时间戳用作文件名,但似乎无法弄清楚如何使AWS节点将属性用作文件名。 根据文件“Amazon S3 out节点。将内容上载到Amazon S3 bucket。bucket名称可以在node bucket属性或msg.bucket属性中指定。Amazon S3上的文件名取自node filename属性或msg.filename属性。内容取自node属

  • 本文向大家介绍node-red File读取好保存实例讲解,包括了node-red File读取好保存实例讲解的使用技巧和注意事项,需要的朋友参考一下 File节点是操作文件的节点 file文件的保存 拖拽 注入节点inject  file节点(writes msg.payload to a file)和 debug节点到工作区,并连线 设置file节点的文件路径 windows如果不设置路径,会