Delay node queue

I need a little help because I'm not sure how to do that.

In my flow I try to do a test every hour and, if the test conditions are not met, I send a message to a delay node, which sends it 600 seconds later. Again it checks the conditions and chooses whether it can be done or not. Below the delay node I can see that it has a saved message and every 10 minutes it tries. All in order. My problem comes when an hour has passed and from the other branch of the flow it asks to run the test. As the conditions are still not met, the delay node accumulates already two messages. I would like that, if a correct test is executed, that queue of messages is deleted. ChatGPT has suggested resetQueue, clearDelayQueue... but none seem to work, is there any way to manage that queue?
This is the relevant part of the flow:

[
    {
        "id": "f999d97252cdff61",
        "type": "function",
        "z": "4bc9c196469b40da",
        "name": "function 16",
        "func": "var pruebaEnCurso = global.get(\"pruebaEnCurso\");\n\nif (pruebaEnCurso === 1) {\n    // No pasar el mensaje si la prueba está en curso\n    return null;\n} else {\n    return msg;\n}\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2750,
        "y": 3520,
        "wires": [
            [
                "a80b8efb8fd23641"
            ]
        ]
    },
    {
        "id": "2ac20b42f105efea",
        "type": "delay",
        "z": "4bc9c196469b40da",
        "name": "Retardo prueba",
        "pauseType": "delayv",
        "timeout": "600",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 2480,
        "y": 3520,
        "wires": [
            [
                "f999d97252cdff61"
            ]
        ]
    },
    {
        "id": "c60dab23eb6b8b79",
        "type": "function",
        "z": "4bc9c196469b40da",
        "name": "Borrar cola de retardo",
        "func": "if (msg.resetQueue) {\n    context.set('delayQueue', []);\n    node.status({ fill: 'yellow', shape: 'dot', text: 'Cola de mensajes borrada' });\n    return null;\n}\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2260,
        "y": 3520,
        "wires": [
            [
                "2ac20b42f105efea"
            ]
        ]
    },
    {
        "id": "cdaef70eb0cbcb74",
        "type": "function",
        "z": "4bc9c196469b40da",
        "name": "Establecer tiempo repeticiĂłn",
        "func": "var valorguardado = global.get(\"valorguardado\");\n\nif (valorguardado === 2) {\n    msg.delay = global.get('repeticionPrueba');\n    return msg;\n} else {\n    return null;\n}\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2000,
        "y": 3520,
        "wires": [
            [
                "c60dab23eb6b8b79"
            ]
        ]
    },
    {
        "id": "a80b8efb8fd23641",
        "type": "function",
        "z": "4bc9c196469b40da",
        "name": "interrumpeFlujo",
        "func": "var permitirFlujo = global.get(\"permitirFlujo\");\nvar AlarmasL1 = global.get(\"AlarmasL1\");\nvar AlarmasL2 = global.get(\"AlarmasL2\");\nvar AlarmasL3 = global.get(\"AlarmasL3\");\nvar Alarmas = AlarmasL1 + AlarmasL2 + AlarmasL3;\nvar Pminima = parseFloat(global.get(\"Pminima\"));\nvar pruebaEnCurso = global.get(\"pruebaEnCurso\");\nvar sumaPotencias = parseFloat(global.get(\"sumaPotencias\"));\n\nif (pruebaEnCurso === 0) {\nif (permitirFlujo === true && Alarmas === 0 && (sumaPotencias >= Pminima)) {\n    return [msg, null];\n} else {\n    return [null, msg];\n}\n} else {\n    return [null, null];\n}",
        "outputs": 2,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1540,
        "y": 3520,
        "wires": [
            [
                "db98972b6495dd4b"
            ],
            [
                "cdaef70eb0cbcb74"
            ]
        ]
    },
    {
        "id": "965e7851219bc56d",
        "type": "function",
        "z": "4bc9c196469b40da",
        "name": "Calculo porcentaje ahorro global",
        "func": "msg.payload = Number((((global.get(\"n4500sin\") - global.get(\"n4500\")) / global.get(\"n4500\")) * 100).toFixed(2));\nglobal.set(\"ahorroglobal\", msg.payload);\nglobal.set(\"pruebaEnCurso\", 0);\nreturn msg;\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1570,
        "y": 3420,
        "wires": [
            [
                "73282d0ba95dd0f8"
            ]
        ]
    },
    {
        "id": "73282d0ba95dd0f8",
        "type": "function",
        "z": "4bc9c196469b40da",
        "name": "0 < Ahorro < 20",
        "func": "if ((msg.payload > 0) && (msg.payload <= 20)) {\n    var msg1 = { ...msg }; // Copia del mensaje original para enviar por la salida 1\n    var msg2 = { resetQueue: true }; // Sólo contiene clearDelayQueue para enviar por la salida 2\n    return [msg1, msg2];\n} else {\n    return [null, msg]; // Enviar por la salida 2 si el ahorro está fuera del rango\n}",
        "outputs": 2,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1820,
        "y": 3420,
        "wires": [
            [
                "516ceafb171cf084"
            ],
            [
                "cdaef70eb0cbcb74"
            ]
        ]
    },
    {
        "id": "516ceafb171cf084",
        "type": "function",
        "z": "4bc9c196469b40da",
        "name": "Establecer ahorro global",
        "func": "if (msg.payload <= 0) {\n    msg.payload = 0;\n    global.set(\"ahorroglobal\", 0.0);\n} else if (msg.payload > 20) {\n    msg.payload = 20;\n    global.set(\"ahorroglobal\", 20.0);\n}\nreturn msg;\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 2150,
        "y": 3420,
        "wires": [
            [
                "c4bca1adc670cbd3",
                "0f71729b007040d6"
            ]
        ]
    }
]

You can use a trigger node to resend a message every 10 minutes


Note the option to reset the trigger if msg.payload = "reset".

This will keep sending the message for ever.
When your tests have passed you have to send msg.payload "reset" to the trigger node to prevent another iteration.

Here is an example flow, but the precise details will depend on how you do your tests. The key point is that the only payload you ever feed back into the system is "reset".

To cover the chance that the tests have not passed for an entire hour, the hourly inject to start the process first sends "reset" before starting a fresh cycle.

2 Likes

I'm not sure that's going to meet my needs. As you can see in my image above, there are two lines. The top line corresponds to a test performed. In the second line, the first function node is the one that decides if the conditions to perform the test are met (first output) and, if they are not met, by the second output it sends the message to the second function node (where the time to repeat it is processed; the user can configure it although by default it is 10 minutes). Function node 16 forwards the message to check again if the test can be performed.
The second node function "0 < Savings < 20" evaluates the test result. If it is correct it sends the message with the results by the first output. If not, it sends the message on the second output. I was looking for the option that, in case of being correct, it would also send a "reset" for the delay node through the second output.

Rather than chatgpt, how about the built in help in the right toolbar...
Screenshot 2024-07-03 at 19.26.44

3 Likes

You are totally right :facepalm: As I'm new with Javascript I'm not sure how to handle reset message property. My try dosen´t work:

if ((msg.payload > 0) && (msg.payload <= 20)) {
    var msg1 = { payload: msg.payload }; 
    var msg2 = { payload: { reset: true } }; 
    return [msg1, msg2];
} else {
    return [null, msg];
}

Msg.payload is not some magic description of a Node-red message.
It is just a message property alongside any other.

A message can have many properties which might include msg.payload or msg.topic and might sometimes include msg.reset.

Also note that a message property must have a key eg "reset" but it's value might be null.

1 Like

Thanks to all. Now it is working. My solution:

if (msg.payload > 0 && msg.payload <= 20) {
    var msg1 = { payload: msg.payload }; 
    var msg2 = { reset: true }; 
    return [msg1, msg2];
} else {
    var msg2 = { reset: false }; 
    return [null, msg2];
}

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.