@@ -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.
0 commit comments