Skip to content

Commit 617fff7

Browse files
authored
Merge pull request #221 from ehagerty/will_set_bytes
refactor will_set function to match the publish function and allow the msg/payload to be encoded bytes, not just str, int or float.
2 parents 5f222c2 + 9c0ecfc commit 617fff7

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

adafruit_minimqtt/adafruit_minimqtt.py

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -267,40 +267,76 @@ def mqtt_msg(self, msg_size: int) -> None:
267267
if msg_size < MQTT_MSG_MAX_SZ:
268268
self._msg_size_lim = msg_size
269269

270+
# pylint: disable=too-many-branches, too-many-statements
270271
def will_set(
271272
self,
272-
topic: Optional[str] = None,
273-
payload: Optional[Union[int, float, str]] = None,
274-
qos: int = 0,
273+
topic: str,
274+
msg: Union[str, int, float, bytes],
275275
retain: bool = False,
276+
qos: int = 0,
276277
) -> None:
277278
"""Sets the last will and testament properties. MUST be called before `connect()`.
278279
279280
:param str topic: MQTT Broker topic.
280-
:param int|float|str payload: Last will disconnection payload.
281-
payloads of type int & float are converted to a string.
281+
:param str|int|float|bytes msg: Last will disconnection msg.
282+
msgs of type int & float are converted to a string.
283+
msgs of type byetes are left unchanged, as it is in the publish function.
282284
:param int qos: Quality of Service level, defaults to
283285
zero. Conventional options are ``0`` (send at most once), ``1``
284286
(send at least once), or ``2`` (send exactly once).
285-
286287
.. note:: Only options ``1`` or ``0`` are QoS levels supported by this library.
287-
:param bool retain: Specifies if the payload is to be retained when
288+
:param bool retain: Specifies if the msg is to be retained when
288289
it is published.
289290
"""
290291
self.logger.debug("Setting last will properties")
291-
self._valid_qos(qos)
292292
if self._is_connected:
293293
raise MMQTTException("Last Will should only be called before connect().")
294-
if payload is None:
295-
payload = ""
296-
if isinstance(payload, (int, float, str)):
297-
payload = str(payload).encode()
294+
295+
# check topic/msg/qos kwargs
296+
self._valid_topic(topic)
297+
if "+" in topic or "#" in topic:
298+
raise MMQTTException("Publish topic can not contain wildcards.")
299+
300+
if msg is None:
301+
raise MMQTTException("Message can not be None.")
302+
if isinstance(msg, (int, float)):
303+
msg = str(msg).encode("ascii")
304+
elif isinstance(msg, str):
305+
msg = str(msg).encode("utf-8")
306+
elif isinstance(msg, bytes):
307+
pass
298308
else:
299309
raise MMQTTException("Invalid message data type.")
310+
if len(msg) > MQTT_MSG_MAX_SZ:
311+
raise MMQTTException(f"Message size larger than {MQTT_MSG_MAX_SZ} bytes.")
312+
313+
self._valid_qos(qos)
314+
assert (
315+
0 <= qos <= 1
316+
), "Quality of Service Level 2 is unsupported by this library."
317+
318+
# fixed header. [3.3.1.2], [3.3.1.3]
319+
pub_hdr_fixed = bytearray([MQTT_PUBLISH | retain | qos << 1])
320+
321+
# variable header = 2-byte Topic length (big endian)
322+
pub_hdr_var = bytearray(struct.pack(">H", len(topic.encode("utf-8"))))
323+
pub_hdr_var.extend(topic.encode("utf-8")) # Topic name
324+
325+
remaining_length = 2 + len(msg) + len(topic.encode("utf-8"))
326+
if qos > 0:
327+
# packet identifier where QoS level is 1 or 2. [3.3.2.2]
328+
remaining_length += 2
329+
self._pid = self._pid + 1 if self._pid < 0xFFFF else 1
330+
pub_hdr_var.append(self._pid >> 8)
331+
pub_hdr_var.append(self._pid & 0xFF)
332+
333+
self._encode_remaining_length(pub_hdr_fixed, remaining_length)
334+
300335
self._lw_qos = qos
301336
self._lw_topic = topic
302-
self._lw_msg = payload
337+
self._lw_msg = msg
303338
self._lw_retain = retain
339+
self.logger.debug("Last will properties successfully set")
304340

305341
def add_topic_callback(self, mqtt_topic: str, callback_method) -> None:
306342
"""Registers a callback_method for a specific MQTT topic.

adafruit_minimqtt/matcher.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,9 @@ def rec(node: MQTTMatcher.Node, i: int = 0):
8888
else:
8989
part = lst[i]
9090
if part in node.children:
91-
for content in rec(node.children[part], i + 1):
92-
yield content
91+
yield from rec(node.children[part], i + 1)
9392
if "+" in node.children and (normal or i > 0):
94-
for content in rec(node.children["+"], i + 1):
95-
yield content
93+
yield from rec(node.children["+"], i + 1)
9694
if "#" in node.children and (normal or i > 0):
9795
content = node.children["#"].content
9896
if content is not None:

0 commit comments

Comments
 (0)