Skip to content

Commit 2197ad7

Browse files
author
Ed Hagerty
committed
refactor will_set function to match the publish function to allow the msg/payload to be encoded bytes
1 parent 5f222c2 commit 2197ad7

File tree

1 file changed

+49
-13
lines changed

1 file changed

+49
-13
lines changed

adafruit_minimqtt/adafruit_minimqtt.py

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -269,38 +269,74 @@ def mqtt_msg(self, msg_size: int) -> None:
269269

270270
def will_set(
271271
self,
272-
topic: Optional[str] = None,
273-
payload: Optional[Union[int, float, str]] = None,
274-
qos: int = 0,
272+
topic: str,
273+
msg: Union[str, int, float, bytes],
275274
retain: bool = False,
275+
qos: int = 0,
276276
) -> None:
277277
"""Sets the last will and testament properties. MUST be called before `connect()`.
278278
279279
: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.
280+
:param str|int|float|bytes msg: Last will disconnection msg.
281+
msgs of type int & float are converted to a string.
282+
msgs of type byetes are left unchanged, as it is in the publish function.
282283
:param int qos: Quality of Service level, defaults to
283284
zero. Conventional options are ``0`` (send at most once), ``1``
284285
(send at least once), or ``2`` (send exactly once).
285-
286286
.. 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
287+
:param bool retain: Specifies if the msg is to be retained when
288288
it is published.
289289
"""
290290
self.logger.debug("Setting last will properties")
291-
self._valid_qos(qos)
292291
if self._is_connected:
293292
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()
293+
294+
# check topic/msg/qos kwargs
295+
self._valid_topic(topic)
296+
if "+" in topic or "#" in topic:
297+
raise MMQTTException("Publish topic can not contain wildcards.")
298+
299+
if msg is None:
300+
raise MMQTTException("Message can not be None.")
301+
if isinstance(msg, (int, float)):
302+
msg = str(msg).encode("ascii")
303+
elif isinstance(msg, str):
304+
msg = str(msg).encode("utf-8")
305+
elif isinstance(msg, bytes):
306+
pass
298307
else:
299308
raise MMQTTException("Invalid message data type.")
309+
if len(msg) > MQTT_MSG_MAX_SZ:
310+
raise MMQTTException(f"Message size larger than {MQTT_MSG_MAX_SZ} bytes.")
311+
312+
self._valid_qos(qos)
313+
assert (
314+
0 <= qos <= 1
315+
), "Quality of Service Level 2 is unsupported by this library."
316+
317+
# fixed header. [3.3.1.2], [3.3.1.3]
318+
pub_hdr_fixed = bytearray([MQTT_PUBLISH | retain | qos << 1])
319+
320+
# variable header = 2-byte Topic length (big endian)
321+
pub_hdr_var = bytearray(struct.pack(">H", len(topic.encode("utf-8"))))
322+
pub_hdr_var.extend(topic.encode("utf-8")) # Topic name
323+
324+
remaining_length = 2 + len(msg) + len(topic.encode("utf-8"))
325+
if qos > 0:
326+
# packet identifier where QoS level is 1 or 2. [3.3.2.2]
327+
remaining_length += 2
328+
self._pid = self._pid + 1 if self._pid < 0xFFFF else 1
329+
pub_hdr_var.append(self._pid >> 8)
330+
pub_hdr_var.append(self._pid & 0xFF)
331+
332+
self._encode_remaining_length(pub_hdr_fixed, remaining_length)
333+
300334
self._lw_qos = qos
301335
self._lw_topic = topic
302-
self._lw_msg = payload
336+
self._lw_msg = msg
303337
self._lw_retain = retain
338+
self.logger.debug("Last will properties successfully set")
339+
304340

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

0 commit comments

Comments
 (0)