@@ -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