Before applying such patch, it would make sense to think why the existing implementation doesn't include it, while was signed off as working. The obvious explanation is that "there's no memory" device can't keep a list of subscriptions (there's no memory), while "give me few more gigs" server can, should, and was tested to have do that (with suitable config).
@dpgeorge , please find the original ticket which lists required test setup for Mosquitto. If the explicit requirements for MQTT server aren't listed in umqtt documentation, that's a different matter, though it's implied that "there should be compliant MQTT server". If users use MQTT servers without full implementation of MQTT, that's again a different matter, outside the scope of umqtt.robust, whose purpose if to provide small, efficient MQTT client, utilizing the MQTT functionality offered by the standard.
That's the only working solution and the best one. I'm doing so as well with another mqtt client.
The only other solution would be to connect without a clean connect but that can result in getting all missed messages between connection loss and reconnection and is therefore not advised to do as it would likely crash your small microcontroller.
How to you re-subscribe to all topics on connection lost??
You have all your subscriptions stored and on reconnect you just subscribe all of them.
But I mean. If on my main while loop I only have client.wait_msg(). Where exactly do I execute the re-subscribe? Is there an onconnect / onreconnect function or something like this? (thanks for the quick response btw!)
Hmm you are right, the umqtt.robust doesn't really offer a convenient way of recognizing a reconnect.. I haven't used this code in years. I use an async mqtt client https://github.com/peterhinch/micropython-mqtt
It looks like you need to create a subclass so you can change the way the reconnect works so you can subscribe after a reconnect.
But maybe someone else who actually uses this code has a better solution.
I have maintained list of subscribed topic in my code itself, Whenever It gots to know about disconnection and gets reconnected I will again subscribing them, for prompt of disconnect I am running the publish event (just for checking) in the try block and checking problems in catch if any comes
UUuuuh, nice. Hadn´t thought about publishing just to check if it is subscribed to a topic, nice approach! Mainly cause I have only used umqtt to receive messages.
Now I fully understand your note
Thanks!
Hey guys, I am back and not with good news hehe.. I was wondering, @JDchauhan could you provide code to your publish-subscribe? I haven't spent too much time on this, but I must admit I haven't managed to make it work. I have tried to try-catch publish and then check_msg but it gives me
mqtt: OSError(-1,)Hoping to find a robust way to make it work
IMPORTANT EDIT: forgot to mention. If I only publish every 5 ~ 10 seconds its fine. It does publish. Gives me error when I
check_msg()after publishingI have to add I am using Adafruit IO to publish-subscribe... could that be issue? What service are you using? Perhaps I should run my own mosquitto on a pi? I rather use Adafruit for IFTTT...
Seeing the exact same issue, with Adafruit IO too.
Hi @turutupa & @alessionossa
I was using my own MQTT broker at that time.
Below is the part of the code I used back then that worked for me. I don't remember exactly but from the code, it seems like I am expecting the error to be thrown by
check_msg()instead ofpublish()and then subscribing again (if it helps)Same on my side. I'm using micropython on ESP32 C3. Next the workaround that works for me.
Main loop blocking:
In the main() loop, I've replaced the mqtt.robust check_msg() and wait_msg() by my own, because if there is no mqtt server, check_msg() is waiting forever. That happens because when it calls to wait_msg(), it waits forever instead of generate an exception that try to reconnect and then continue the main() loop
The problem arise because check_msg() set self.mqtt_client.sock.setblocking(False), and then calls to wait_msg()
On their side wait_msg() change self.mqtt_client.sock.setblocking(True) at its beginning, and then allowing to wait for a mqtt server connection.
My workaround is using my_check_msg(), that is an exact copy of the check_msg() except it calls my_wait_msg().
my_wait_msg() is an exact copy of wait_msg() except that the initial #self.mqtt_client.sock.setblocking(True) is commented.
I've tried this with class inheritance and monkey patching without success. May be side effects
Regenerate subscription mqtt:
All my appliances (sensor, switch, light,...) connected to mqtt have a _register_mqtt(self) procedure.
In the initial setup of every appliance, I add each appliance to a device_appliances{} dictionary (key=appl_id, value=appliance) and also call _register_mqtt(self)
To reconnect after a mqtt server (or Wifi) fault, the procedure reinitialize the mqtt_client and then calls the _register_mqtt() for each appliance in the device_appliances{} dictionary.
Finally also republish the availability_topic.
Subclass is the current recommended solution here, however it won't really work until this is merged. Take a look for more information & example about re-subscription
https://github.com/micropython/micropython-lib/pull/669