@@ -267,40 +267,76 @@ def mqtt_msg(self, msg_size: int) -> None:
267
267
if msg_size < MQTT_MSG_MAX_SZ :
268
268
self ._msg_size_lim = msg_size
269
269
270
+ # pylint: disable=too-many-branches, too-many-statements
270
271
def will_set (
271
272
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 ],
275
275
retain : bool = False ,
276
+ qos : int = 0 ,
276
277
) -> None :
277
278
"""Sets the last will and testament properties. MUST be called before `connect()`.
278
279
279
280
: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.
282
284
:param int qos: Quality of Service level, defaults to
283
285
zero. Conventional options are ``0`` (send at most once), ``1``
284
286
(send at least once), or ``2`` (send exactly once).
285
-
286
287
.. 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
288
289
it is published.
289
290
"""
290
291
self .logger .debug ("Setting last will properties" )
291
- self ._valid_qos (qos )
292
292
if self ._is_connected :
293
293
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
298
308
else :
299
309
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
+
300
335
self ._lw_qos = qos
301
336
self ._lw_topic = topic
302
- self ._lw_msg = payload
337
+ self ._lw_msg = msg
303
338
self ._lw_retain = retain
339
+ self .logger .debug ("Last will properties successfully set" )
304
340
305
341
def add_topic_callback (self , mqtt_topic : str , callback_method ) -> None :
306
342
"""Registers a callback_method for a specific MQTT topic.
0 commit comments