How can I confirm that a device received and processed a command using MQTT?


#1

I have been building a small motor-driven fish feeder with Losant and my raspberry pi 3. I would like to build some safeguards into my workflow so that, if the workflow timer issues the spin command and the pi has somehow become disconnected from the Losant MQTT broker, an SMS will be sent to notify me that the command was not received. I already have a notification triggered by “On Disconnect”, but I would like to add another if I somehow miss the disconnect notification.

From what I understand about MQTT, it is largely “fire and forget” with QoS 0, so I am unsure how to go about this. I have attached my workflow, if that is any help, and I am grateful for your suggestions.

Thanks,

Andrew


#2

I can think of a couple of approaches.

Firstly you could keep a count of the spin commands and date-time of last received command on the pi.
The pi then periodically sends this information as part of a heartbeat.

Store this as a property of the pi on losant.

Your workflow can then check if it’s notion of count and time matches the pi. If it varies you can then issue a warning.
You probably need to keep a sliding window of time so you can deal with lags between time sent and time recieved.

You will also need to have some way of resetting the count’s in the workflow or pi to clear the discrepancy.

There will be a bunch of corner cases you will have to deal with, such as not clearing the mismatched state etc…
So you don’t repeatedly send out warnings. Using latches will probably help here. (ie only send out a single alert until you manually reset).

Another idea and probably better approach is to generate a token in losant, send that with the command. Store the token. A PI heartbeat sends the last token received. If they don’t match send the alert. Lattch the alert state in the workflow.

Then next command successfully received and replied with the correct token would reset the alarm state.
This is much simpler, and probably more reliable than the first suggestion.

Cheers

T


#3

Both are wonderful suggestions, and I’m going to give the second one a try. Thank you!


#4

My recommended approach is that a command should result in some form of device state change. For example if you send the “spin” command, the device could report back a “status” state of “spinning”, or possibly a “lastSpin” with the date/time of the last spin.

Then your workflow could verify the state changed appropriately in reaction to the command. You can do this with a delay node and a gauge query. The delay waits few seconds for the device to get the command and report state back. The gauge query lets you request the most recent state for a specific attribute. You can then verify the state changed as a result of the command. If it didn’t, send yourself an SMS.