Skip to content

Commit 1d1f6ac

Browse files
puuuian-llewellyn
authored andcommitted
umqtt.robust: let reconnect() call the connect() method of the top class
This allows overriding of the connect() method by a subclass as per the included examples: `example_lwt_robust.py` and `example_resubscribe_robust.py`. Co-authored by: Ian Cotter-Llewellyn <ian_llewellyn@hotmail.com> Date: Thu May 25 11:42:20 2023 +0100
1 parent 7128d42 commit 1d1f6ac

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import umqtt.robust
2+
import time
3+
4+
# Last will and testament (LWT) is commonly used to signal a device as being
5+
# online or offline. This example builds on umqtt.robust to provide a more
6+
# reliable connection with the MQTT broker and signal its status as being
7+
# either Online or Offline. This feature adds to code size and isn't required
8+
# in all circumstances, so hasn't been included by default.
9+
10+
11+
class MyMQTTClient(umqtt.robust.MQTTClient):
12+
def connect(self, clean_session=True):
13+
self.set_last_will(b"tele/test/LWT", b"Offline", retain=True)
14+
try:
15+
return super().connect(clean_session)
16+
finally:
17+
self.publish(b"tele/test/LWT", b"Online", retain=True)
18+
19+
20+
# Change the server to test on your MQTT broker
21+
c = MyMQTTClient("test_client", "localhost", keepalive=5)
22+
c.DEBUG = True
23+
24+
c.connect()
25+
26+
# wait_msg() only returns when a message is received, so this example
27+
# highlights the LWT feature. In practical applications, the broker keeps
28+
# the connection alive only if there is traffic from the client (ping(), etc.)
29+
c.wait_msg()
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import umqtt.robust
2+
import time
3+
4+
# A common expectation of the robust client is that it should re-subscribe to
5+
# topics after a reconnect(). This feature adds to code size and isn't required
6+
# in all circumstances, so hasn't been included by default.
7+
8+
# You can easily inherit from umqtt.robust.MQTTClient to add this feature...
9+
10+
11+
class MyMQTTClient(umqtt.robust.MQTTClient):
12+
def __init__(self, *args, **kwargs):
13+
super().__init__(*args, **kwargs)
14+
self.topics = []
15+
16+
def connect(self, clean_session=True):
17+
if not super().connect(clean_session):
18+
# Session was not restored - need to resubscribe
19+
for topic in self.topics:
20+
self.subscribe(topic)
21+
22+
return False # Session was not restored
23+
24+
return True # Session was restored
25+
26+
def subscribe(self, topic):
27+
print("Subscribing to", topic)
28+
super().subscribe(topic)
29+
if topic not in self.topics:
30+
self.topics.append(topic)
31+
32+
33+
# Change the server to test on your MQTT broker
34+
c = MyMQTTClient("test_client", "localhost", keepalive=5)
35+
c.DEBUG = True
36+
37+
c.set_callback(print)
38+
39+
c.connect()
40+
c.subscribe(b"test/topic/a")
41+
42+
c.publish(b"test/topic/a", b"message 1")
43+
c.wait_msg()
44+
45+
# Connection breaks once keepalive expires
46+
time.sleep(8)
47+
48+
c.publish(b"test/topic/a", b"message 2") # publish() doesn't detect OSError, message 2 is lost
49+
c.check_msg() # check_msg() detects OSError and will reconnect()
50+
51+
c.publish(b"test/topic/a", b"message 3")
52+
c.wait_msg()

micropython/umqtt.robust/manifest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
metadata(
2-
description='Lightweight MQTT client for MicroPython ("robust" version).', version="1.0.2"
2+
description='Lightweight MQTT client for MicroPython ("robust" version).', version="1.0.3"
33
)
44

55
# Originally written by Paul Sokolovsky.

micropython/umqtt.robust/umqtt/robust.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ def reconnect(self):
2020
i = 0
2121
while 1:
2222
try:
23-
return super().connect(False)
23+
# self.connect will call a subclass definition (if any)
24+
# else fall back to parent class definition
25+
return self.connect(False)
2426
except OSError as e:
2527
self.log(True, e)
2628
i += 1

0 commit comments

Comments
 (0)