If second message is not received then resend message

I have a node it send me messages periodically or if there is a change.

Now I need to send it a message and I need acknowledgement that it received it, if not after the 2nd message received I need to resend the message.

Sequence of messages

I send a message to a node - it only receives it after it has sent a message. (listens only after transmitting).

If the node receives a message it send me a acknowledgement in the second message after I sent it to it (this I got the logic done). If I don't get the acknowledgment, I need to resend the message

Cant get my head around some logic today -- I need help :grinning:

You may need to explain it a bit better, sorry.

Ok, so we will call it the input.

Too many pronouns there sorry.

Now I need to send it a message.....
it?
What is it?

So to reword that:
An input message is received.

But I am not sure.

I'll try to make something that does what I think you mean.
But also.... who is sending the message?
Is it inside Node-Red or an external device?

This is what I make of what you want:

[{"id":"551987b32f6c9f7c","type":"inject","z":"437e4108076e5928","name":"Event happens","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"event","payloadType":"str","x":120,"y":580,"wires":[["5e9111fb135beb8f"]]},{"id":"5e9111fb135beb8f","type":"trigger","z":"437e4108076e5928","name":"Delay / check message is sent","op1":"","op2":"","op1type":"pay","op2type":"pay","duration":"3","extend":false,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":360,"y":580,"wires":[["ab5b38cbb53dd04a"]]},{"id":"7b71d07e62d565f3","type":"change","z":"437e4108076e5928","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":140,"y":630,"wires":[["5e9111fb135beb8f"]]},{"id":"63ec6a72c012ec86","type":"function","z":"437e4108076e5928","name":"Receiver","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":580,"wires":[["7b71d07e62d565f3","a809de586ccd66fb"]]},{"id":"ad3ed249aba3686b","type":"comment","z":"437e4108076e5928","name":"Ack message received","info":"","x":920,"y":620,"wires":[]},{"id":"a809de586ccd66fb","type":"debug","z":"437e4108076e5928","name":"The rest of the flow.","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1080,"y":580,"wires":[]},{"id":"6733d3d2f99af943","type":"comment","z":"437e4108076e5928","name":"Adjust the node below as needed","info":"","x":360,"y":540,"wires":[]},{"id":"ab5b38cbb53dd04a","type":"delay","z":"437e4108076e5928","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":640,"y":580,"wires":[["63ec6a72c012ec86"]]},{"id":"325dd8ceb86f897e","type":"comment","z":"437e4108076e5928","name":"Inherrent delays","info":"","x":660,"y":540,"wires":[]}]

I have a node (devise) it send me messages periodically or if there is a change. This is via MQTT

Now I need to send the node (devise) a message from node-red (I push the button on a inject node and it sends a MQTT) and I need acknowledgement back that the node (devise) received my message, if not after the 2nd message received a acknowledgment I need to resend the message.

Sequence of messages

I send a message to a node (devise) (this is from node-red to the node (devise)) - it only receives it after it has sent me a message. (listens only after transmitting).

If the node (devise) receives the message it send me a acknowledgement in the second message after I sent it to it (this I got the logic done). If I don't get the acknowledgment, I need to resend the message

[
    {
        "id": "79902647c6ad0e8a",
        "type": "inject",
        "z": "066b6e4829326d09",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "dev",
                "v": "eui-ababcbcbdcdccdcd",
                "vt": "str"
            },
            {
                "p": "app",
                "v": "sotracking@ttn",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "C0",
        "payloadType": "str",
        "x": 150,
        "y": 320,
        "wires": [
            [
                "8d081365deeb06fa"
            ]
        ]
    }
]

chrome_UxDeNaeJnf

External device

1: it would have been nice if you said you were using MQTT in the first post.
So QOS should cover your needs of the message getting through.

Again, you are not really explaining what is happening.
I push a button on it and it sends a message to it and if it gets the message it is ok, but if it doesn't it sends the message again.

Nah. Sorry. I can't handle that.

Understand?

You need to clarify what is what:

The sending device, the receiving device. (Ok, Node-red)
Where is the button.... "On it" doesn't mean anything at this point in time.

Example:

Remote device:
Something happens, and a MQTT message is sent to Node-Red.

Node-red receives the message.
(Confusion)
I press a button to acknowledge the message is received.
Node-red sends a message back to the device that the message has been received. (Via MQTT)

That message is received on the remote device.
If within a certain time then the message is not re-sent.
If it is not received (by the remote device) the message is sent again.

Note:
There is no way you can give a 100% guarantee that all messages get through.

If you aren't there and don't press the button and the message is sent again:
what happens if you again don't press the button?

Why can't you make the reply automatic as I showed you in my example?
I know it isn't done with node-red nodes, but that is the mechanics of what needs to be done.

There is no QOS in the MQTT, the service don't support it. The entire network is best effort.

I am lost for word a bit here.

If the node (devise) receives the message it send me a acknowledgement in the second message after I sent the message to it (node (devise) ) (this I got the logic done). If I don't get the acknowledgment, I need to resend the message to the node( Device)

A inject node in node-red

The node replies it received the msg (coded)

It is based on msg sent and received, not on time

The node (devise) sends the acknowledgment back here. I need to figure the logic in node-red flow

image

MQTT has a QOS option.

Sorry, here is the link:

Which message? The event message or the message you send back to the device upon receipt of the actual message?

I think I am not qualified to help you beyond this.

As this is a given - as no network can be 100% reliable.
QOS is what you need to use AFAIK.

It seems you are making it more complicated than it needs to be.
But I could (am usually) be wrong.

Good luck. I'm outa here.

Yes I know that MQTT supports 3 levels of QOS - the service I am using (not set up by me) does not support any QOS.

The message I sent it.

I want to ensure the message I sent were received by the node, if it (node (device)) does not receive it I need to resend the message to the (node (device) ).

Thank you for you effort.

The Trigger node will probably help you here.

Here's a recipe that shows how it can be used to trigger a message if one is received within a required interval: Trigger a flow if a message isn’t received after a defined time : Node-RED

Thanks, this is time base, I need it based on if I don't get a acknowledgment back from the device within in the last two messages, that the device received my message. ( The device side works and the device sends the acknowledgment when it received my message)

I am struggling to understand too, sorry. I suspect it's a language difficulty, especially you describing your external device as a node.

You don't like knolleary's suggestion of a trigger node because it is time based, but you say
"I have a node it send me messages periodically".
Can't you set the trigger node wait time to twice your regular message period?

Do you have access to the code on your external device?
It seems likely that your problem is caused by "I send a message to a node - it only receives it after it has sent a message. (listens only after transmitting)."
If you can change the device code so that transmitting does not block receiving - using a call-out maybe - it will perhaps help.

Can you use a different MQTT broker that does offer QOS?
(But I confess I don't understand how the 3 QOS settings "fire and forget", "at least once" and "once and once only" can guarantee delivery)

If there is a change greater than the limits the node (device) sends the sensors reading. The node (device) is a LoraWAN device.

It is a LoraWAN device so it is in sleep mode and it only wakes up on a periodical period or when a internal interrupt wakes it up. It sends data and then listens for an messages from the server, the server only sends the message once it receives a message from the device.

I do understand how it works, just I don't have control over the MQTT service and cant change the QOS.

OK hopefully I understand now.
Would this work?

When you send a message to the device, set a counter in flow context flow.set('waitcount', 1)

When a message arrives from the device and the counter > 0 {
If it's the acknowledgement, set the counter to 0
Otherwise increment the counter
}

Frequently check the counter. If it's > 2 {
Resend the message
Reset the counter to 1
}

Johan,

It seems that there is confusion because you are using the word 'node' for the LoraWAN device and it is not clear (to me at least) if Node-RED is waiting for the second message or the LoraWAN device is. Also I assume there is a second Lora device (L2) receiving the data sent by the first Lora device (L1)

Could you give a step by step description of what is happening and needs to happen. Like this:

  1. Lora device1 (L1) wakes up because of an interrupt.
  2. If L1 notes a limit change it sends a message to L2 (the Lora receiver)
  3. L1 stays awake until it gets a msg back from L2
  4. L2 sends a message to Node-RED via ????
  5. Node-red sends a reply back to L2 via ????
    and at this point I'm confused as to what is happening . If you could produce something like this, I think it would go a long way to getting your issue solved.
  1. From node-red via MQTT a message is sent to the join server/application server. (payload.downlinks[0].frm_payload : wA==)
  2. The join server/application server schedules the message to be sent to the LoRaWAN (Device / Sensor) (payload.downlinks[0].frm_payload : wA==)
  3. The LoRaWAN (Device / Sensor) wakes up and sends sensor data and watchdog bit “0” to the join server/application server
  4. Join server/application server sends the sensor data and watchdog bit “0” via MQTTT to my Node-Red application.
  5. The join server sends the message (5sec later) to the LoRaWAN (Device / Sensor) (payload.downlinks[0].frm_payload : wA==)
  6. LoRaWAN (Device / Sensor) receives the message (payload.downlinks[0].frm_payload : wA==) and set the watchdog bit to “1”.
  7. LoRaWAN (Device / Sensor) go to sleep until the internal interrupt wakes it up.
  8. LoRaWAN (Device / Sensor) sends sensor data and watchdog bit “1” to the join server/application server
  9. Join server/application server sends the sensor data and watchdog bit “1” via MQTTT to my Node-Red application.
  10. Now if I don’t receive the watchdog bit “1” I want the send the again the message (payload.downlinks[0].frm_payload : wA==)
  11. If the message were the watchdog bit “1” is received no now message is sent (payload.downlinks[0].frm_payload : wA==)

So in essence creating my own QOS

So to rephrase it,

  1. Node-RED sends a message [M1] (via MQTT) to the Join/Server
  2. Join/Server stores [M1] in a queue
    time passes
  3. LoRa wakes up and sends a message to Join/Server [M2 data, wb=0] (wb - watchdog bit)
  4. Join/Server sends [M2 data wb=0] (via MQTT) to NR
    ...delay 5 seconds
  5. Join/Server sends a message (is this [M1] the queued message or a new one?) to LoRa
  6. LoRa receives message [M?], sets wb=1
  7. LoRa goes to sleep for a period of time (how long?)
  8. LoRa wakes up and sends message [M3 data, wb=1] to Join/Server
  9. Join/Server sends message [M3 data, wb=1] (via MQTT) to Node-RED

Ok, I think I understand up thru step 9.
questions:

  • step 4: What does NR do with the message [M2] it receives?
  • step 9: What does NR do with the message [M3] it receives?
  • At step 10 who (NR, Join/Server) is waiting for a message with the watchdog bit=1 ?
  • when did the waiting start?
  • How long is the wait?
  • what message message is to be sent?