MQTT callback to set variable, (what if there's no retained message)?

Hi all,

When my ESP8266 boots, I know how to use callback to obtain a retained message and save it to a variable. I have been initially setting the retained message via node red, and all is good.

My question is, what if there is no retained message already on the broker?
How can I check this in code, and if there's no message, then publish a default message to that topic?

Seems like a catch 22.

I hope this is clear, please ask for any clarification. Code not included as it seems a generic issue.

When you subscribe to the topic, note the time using millis. If after some time, you haven't got any message, publish to the topic specifying retain.

I am unclear as to your use of ESP8266. Is it a client your are making or a broker? If it is a broker, who are the clients? If it is a client, what is the broker?

wildbill:
When you subscribe to the topic, note the time using millis. If after some time, you haven't got any message, publish to the topic specifying retain.

(Apologies for the delay, I had to pop out).

That is exactly what I want to do, but am unclear on how to implement.

My understanding is:

Subscribe in MQTT connect:

MQTTclient.subscribe((base_mqtt_topic + "/active").c_str());         //Retained - (alarm enabled or disabled)

The MQTT broker will return a retained message, or not.

If a message arrives, it is filtered in the callback function.

If a message does not arrive, nothing is called.

So you are saying I could:
Subscribe to the topic, and record millis as subscribedMillis

If the message arrives via callback, do nothing. But how do I stop the millis function?

If the message does not arrive after say (currentMillis - subscribedMillis > 5000), publish the retained value manually. This checking would have to be done in the main loop, correct?

Perehama:
I am unclear as to your use of ESP8266. Is it a client your are making or a broker? If it is a broker, who are the clients? If it is a client, what is the broker?

Hi Perehama,

It's a client, the broker is a Raspberry Pi.

When you get a message, grab millis and set a flag to indicate that you did. Use a boolean.

In loop, if time's up and the flag is still false, publish.

If the retained message of the published topic is set to false, then upon the first instance of the keep alive loop of the subscriber, which is what causes the message to be retrieved from the broker and triggers the callback, a NULL value is received for the subscribed topic, as explained in the MQTT PubSubClient API. Have your subscription parsing code detect and handle a message with a NULL value. Me, I cause the the Python script running on the RPi, to initially publish a default package with a non-null and I set the retained flag for each message, published by RPi, to true.

@wilbill thanks, I think I could manage that. My only concern is the wasted processing time in checking each time through the loop, just for initial setting of a variable.

quote author=Idahowalker link=msg=4679198 date=1595073977]
If the retained message of the published topic is set to false, then upon the first instance of the keep alive loop of the subscriber, which is what causes the message to be retrieved from the broker and triggers the callback, a NULL value is received for the subscribed topic, as explained in the MQTT PubSubClient API. Have your subscription parsing code detect and handle a message with a NULL value. Me, I cause the the Python script running on the RPi, to initially publish a default package with a non-null and I set the retained flag for each message, published by RPi, to true.
[/quote]

Thank you, this seems more like what I wanted, as it only runs once on connection and then if a new message is received.

You are saying that if the message is non-retained, it returns NULL. So I can handle this in the callback function.

What if there is no message at all, i.e. the topic does not exist?

I agree this is unlikely, but could occur in case of the broker being reset/data deleted. Seems like a weak link.

877:
Thank you, this seems more like what I wanted, as it only runs once on connection and then if a new message is received.

You are saying that if the message is non-retained, it returns NULL. So I can handle this in the callback function.

What if there is no message at all, i.e. the topic does not exist?

I agree this is unlikely, but could occur in case of the broker being reset/data deleted. Seems like a weak link.

Here take a look for yourself to see what PubSubClient is doing pubsubclient/PubSubClient.cpp at master · knolleary/pubsubclient · GitHub

When I reboot the machine the MQTT broker is on, the clients detect a MQTT disconnect based on my use of the mqttClient.loop() and how pingTheMQTTBroker thingy works. Upon the clients detecting a disconnect from the MQTT Broker, the clients, using code I wrote, will re-connect with the Broker. Part of the re-connect routine is to resubscribe to topics and generate base data for retention.

See pubsubclient/PubSubClient.cpp at master · knolleary/pubsubclient · GitHub, https://github.com/knolleary/pubsubclient/blob/master/src/PubSubClient.h,https://pubsubclient.knolleary.net/, and Arduino Client for MQTT
for more info.