Skip to content

Commit 828b1a7

Browse files
Update simple.py
**Summary of Changes** 1. Explicit UTF-8 Encoding: - Both the topic and msg are now explicitly encoded using UTF-8 (topic.encode('utf-8') and msg.encode('utf-8')). - This ensures that multi-byte characters are correctly represented. 2. Accurate Size Calculation: - The size of the message (sz) is calculated based on the byte length of the encoded topic and message Signed-off-by: FallenPhoenix8 <[email protected]>
1 parent e4cf095 commit 828b1a7

File tree

1 file changed

+43
-33
lines changed

1 file changed

+43
-33
lines changed

micropython/umqtt.simple/umqtt/simple.py

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,39 +115,49 @@ def ping(self):
115115
self.sock.write(b"\xc0\0")
116116

117117
def publish(self, topic, msg, retain=False, qos=0):
118-
pkt = bytearray(b"\x30\0\0\0")
119-
pkt[0] |= qos << 1 | retain
120-
sz = 2 + len(topic) + len(msg)
121-
if qos > 0:
122-
sz += 2
123-
assert sz < 2097152
124-
i = 1
125-
while sz > 0x7F:
126-
pkt[i] = (sz & 0x7F) | 0x80
127-
sz >>= 7
128-
i += 1
129-
pkt[i] = sz
130-
# print(hex(len(pkt)), hexlify(pkt, ":"))
131-
self.sock.write(pkt, i + 1)
132-
self._send_str(topic)
133-
if qos > 0:
134-
self.pid += 1
135-
pid = self.pid
136-
struct.pack_into("!H", pkt, 0, pid)
137-
self.sock.write(pkt, 2)
138-
self.sock.write(msg)
139-
if qos == 1:
140-
while 1:
141-
op = self.wait_msg()
142-
if op == 0x40:
143-
sz = self.sock.read(1)
144-
assert sz == b"\x02"
145-
rcv_pid = self.sock.read(2)
146-
rcv_pid = rcv_pid[0] << 8 | rcv_pid[1]
147-
if pid == rcv_pid:
148-
return
149-
elif qos == 2:
150-
assert 0
118+
print(f"Preparing to publish: topic={topic}, msg={msg}, retain={retain}, qos={qos}")
119+
120+
# Encode the topic and message in UTF-8
121+
topic = topic.encode('utf-8')
122+
msg = msg.encode('utf-8')
123+
124+
# Calculate the size of the message
125+
sz = 2 + len(topic) + len(msg)
126+
if qos > 0:
127+
sz += 2
128+
129+
assert sz < 2097152 # MQTT supports a maximum of 2MB messages
130+
print(f"Calculated message size: {sz}")
131+
132+
# Create the packet header
133+
pkt = bytearray(5) # Header can be up to 5 bytes
134+
pkt[0] = 0x30 | (qos << 1) | retain # Message type (PUBLISH)
135+
i = 1
136+
while sz > 0x7F: # Multi-byte length encoding
137+
pkt[i] = (sz & 0x7F) | 0x80
138+
sz >>= 7
139+
i += 1
140+
pkt[i] = sz
141+
142+
# Send the header and data
143+
self.sock.write(pkt[:i + 1]) # Header
144+
self._send_str(topic) # Topic
145+
self.sock.write(msg) # Message
146+
print(f"Message sent: {msg.decode('utf-8')}")
147+
148+
# QoS handling
149+
if qos == 1:
150+
while True:
151+
op = self.wait_msg()
152+
if op == 0x40:
153+
sz = self.sock.read(1)
154+
assert sz == b'\x02'
155+
rcv_pid = self.sock.read(2)
156+
rcv_pid = rcv_pid[0] << 8 | rcv_pid[1]
157+
if self.pid == rcv_pid:
158+
return
159+
elif qos == 2:
160+
raise NotImplementedError("QoS level 2 not implemented")
151161

152162
def subscribe(self, topic, qos=0):
153163
assert self.cb is not None, "Subscribe callback is not set"

0 commit comments

Comments
 (0)