Added support for 'Last Will' user properties and a button to clear the last will. eric7

Fri, 23 Jul 2021 17:48:22 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Fri, 23 Jul 2021 17:48:22 +0200
branch
eric7
changeset 104
9a4c9b7f078c
parent 103
5fe4f179975f
child 105
36ec7431ad04

Added support for 'Last Will' user properties and a button to clear the last will.

MqttMonitor/MqttClient.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttConnectionOptionsDialog.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttConnectionOptionsDialog.ui file | annotate | diff | comparison | revisions
MqttMonitor/MqttConnectionProfilesDialog.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttConnectionProfilesDialog.ui file | annotate | diff | comparison | revisions
MqttMonitor/MqttMonitorWidget.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttMonitorWidget.ui file | annotate | diff | comparison | revisions
--- a/MqttMonitor/MqttClient.py	Thu Jul 22 19:02:32 2021 +0200
+++ b/MqttMonitor/MqttClient.py	Fri Jul 23 17:48:22 2021 +0200
@@ -279,8 +279,8 @@
         """
         self.__mqttClient.user_data_set(userdata)
     
-    # TODO: MQTTv5: add support for WILL properties
-    def setLastWill(self, topic, payload=None, qos=0, retain=False):
+    def setLastWill(self, topic, payload=None, qos=0, retain=False,
+                    properties=None):
         """
         Public method to set the last will of the client.
         
@@ -293,9 +293,12 @@
         @param retain flag indicating to set as the "last known good"/retained
             message for the will topic
         @type bool
+        @param properties list of user properties to be sent with the
+            last will message
+        @type list of tuple of (str, str)
         """
         self.__mqttClient.will_set(topic, payload=payload, qos=qos,
-                                   retain=retain)
+                                   retain=retain, properties=properties)
     
     def clearLastWill(self):
         """
@@ -351,7 +354,7 @@
         self.__loopStarted = False
     
     def connectToServer(self, host, port=1883, keepalive=60, bindAddress="",
-                        properties=None):
+                        properties=None, clearWill=False):
         """
         Public method to connect to a remote MQTT broker.
         
@@ -369,7 +372,12 @@
         @param properties list of user properties to be sent with the
             subscription
         @type list of tuple of (str, str)
+        @param clearWill flag indicating to clear the last will previously set
+        @type bool
         """
+        if clearWill:
+            self.clearLastWill()
+        
         props = (
             self.__createPropertiesObject(PacketTypes.CONNECT, properties)
             if properties else
@@ -385,7 +393,7 @@
             self.startLoop()
     
     def connectToServerWithOptions(self, host, port=1883, bindAddress="",
-                                   options=None):
+                                   options=None, clearWill=False):
         """
         Public method to connect to a remote MQTT broker.
         
@@ -400,9 +408,12 @@
         @param options dictionary containing the connection options. This
             dictionary should contain the keys "ClientId", "ConnectionTimeout",
             "Keepalive", "CleanSession", "Username", "Password", "WillTopic",
-            "WillMessage", "WillQos", "WillRetain", "TlsEnable", "TlsCaCert",
-            "TlsClientCert", "TlsClientKey", "UserProperties".
+            "WillMessage", "WillQos", "WillRetain", "WillProperties",
+            "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey",
+            "UserProperties".
         @type dict
+        @param clearWill flag indicating to clear the last will previously set
+        @type bool
         """
         if options:
             parametersDict = self.defaultConnectionOptions()
@@ -420,16 +431,25 @@
                     self.setUserCredentials(parametersDict["Username"])
             
             # step 2: set last will data
-            if parametersDict["WillTopic"]:
+            if not clearWill and parametersDict["WillTopic"]:
                 if parametersDict["WillMessage"]:
                     willMessage = parametersDict["WillMessage"]
                 else:
                     # empty message to clear the will
                     willMessage = None
+                props = (
+                    self.__createPropertiesObject(
+                        PacketTypes.WILLMESSAGE,
+                        parametersDict["WillProperties"])
+                    if (parametersDict["WillProperties"] and
+                        self.__protocol == MqttProtocols.MQTTv5) else
+                    None
+                )
                 self.setLastWill(parametersDict["WillTopic"],
-                                 willMessage,
-                                 parametersDict["WillQos"],
-                                 parametersDict["WillRetain"])
+                                 payload=willMessage,
+                                 qos=parametersDict["WillQos"],
+                                 retain=parametersDict["WillRetain"],
+                                 properties=props)
             
             # step 3: set TLS parameters
             if parametersDict["TlsEnable"]:
@@ -466,11 +486,13 @@
             self.__cleanSession = parametersDict["CleanSession"]
             self.connectToServer(host, port=port,
                                  keepalive=parametersDict["Keepalive"],
-                                 properties=properties)
+                                 properties=properties,
+                                 clearWill=clearWill)
         else:
             keepalive = self.defaultConnectionOptions["Keepalive"]
             self.connectToServer(host, port=port, keepalive=keepalive,
-                                 bindAddress=bindAddress)
+                                 bindAddress=bindAddress,
+                                 clearWill=clearWill)
     
     @classmethod
     def defaultConnectionOptions(cls):
@@ -481,8 +503,8 @@
         @return dictionary containing the default connection options. It has
             the keys "ClientId", "Protocol", "ConnectionTimeout", "Keepalive",
             "CleanSession", "Username", "Password", "WillTopic", "WillMessage",
-            "WillQos", "WillRetain", "TlsEnable", "TlsCaCert", "TlsClientCert",
-            "TlsClientKey", "UserProperties".
+            "WillQos", "WillRetain", "WillProperties", "TlsEnable",
+            "TlsCaCert", "TlsClientCert", "TlsClientKey", "UserProperties".
         @rtype dict
         """
         return {
@@ -497,6 +519,7 @@
             "WillMessage": "",
             "WillQos": 0,
             "WillRetain": False,
+            "WillProperties": [],
             "TlsEnable": False,
             "TlsCaCert": "",
             "TlsClientCert": "",
--- a/MqttMonitor/MqttConnectionOptionsDialog.py	Thu Jul 22 19:02:32 2021 +0200
+++ b/MqttMonitor/MqttConnectionOptionsDialog.py	Fri Jul 23 17:48:22 2021 +0200
@@ -20,13 +20,13 @@
 from .MqttClient import MqttClient, MqttProtocols
 
 from Utilities.crypto import pwConvert
+import UI.PixmapCache
 
 
 class MqttConnectionOptionsDialog(QDialog, Ui_MqttConnectionOptionsDialog):
     """
     Class implementing a dialog to enter MQTT connection options.
     """
-    # TODO: add WILL user properties
     def __init__(self, options=None, parent=None):
         """
         Constructor
@@ -35,7 +35,8 @@
             populate the dialog with. It must have the keys "ClientId",
             "Protocol", "ConnectionTimeout", "Keepalive", "CleanSession",
             "Username", "Password", "WillTopic", "WillMessage", "WillQos",
-            "WillRetain", "TlsEnable", "TlsCaCert", "UserProperties".
+            "WillRetain", "WillProperties", "TlsEnable", "TlsCaCert",
+            "UserProperties".
         @type dict
         @param parent reference to the parent widget
         @type QWidget
@@ -47,6 +48,11 @@
         self.tlsCertsFilePicker.setFilters(
             self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
         
+        self.willPropertiesButton.setIcon(
+            UI.PixmapCache.getIcon("listSelection"))
+        
+        self.optionsWidget.setCurrentIndex(0)
+        
         # initialize MQTTv5 related stuff
         self.on_mqttv5Button_toggled(False)
         
@@ -119,7 +125,8 @@
             self.optionsWidget.indexOf(self.propertiesTab),
             checked
         )
-        # TODO: add code to enable the WILL properties button
+        self.willPropertiesButton.setEnabled(checked)
+        self.willPropertiesButton.setVisible(checked)
     
     @pyqtSlot(QAbstractButton)
     def on_buttonBox_clicked(self, button):
@@ -168,6 +175,18 @@
                 self.propertiesWidget.setProperties(
                     self.__userProperties["disconnect"])
     
+    @pyqtSlot()
+    def on_willPropertiesButton_clicked(self):
+        """
+        Private slot to edit the last will user properties.
+        """
+        from .MqttUserPropertiesEditor import MqttUserPropertiesEditorDialog
+        
+        dlg = MqttUserPropertiesEditorDialog(
+            self.tr("Last Will User Properties"), self.__willProperties, self)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            self.__willProperties = dlg.getProperties()
+    
     def __populateDefaults(self, options=None):
         """
         Private method to populate the dialog.
@@ -179,7 +198,7 @@
             the dialog with. It must have the keys "ClientId", "Protocol",
             "ConnectionTimeout", "Keepalive", "CleanSession", "Username",
             "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain",
-            "TlsEnable", "TlsCaCert", "UserProperties".
+            "WillProperties", "TlsEnable", "TlsCaCert", "UserProperties".
         @type dict
         """
         if options is None:
@@ -206,6 +225,8 @@
         self.willRetainCheckBox.setChecked(options["WillRetain"])
         self.willTopicEdit.setText(options["WillTopic"])
         self.willMessageEdit.setPlainText(options["WillMessage"])
+        self.__willProperties = copy.deepcopy(
+            options.get("WillProperties", []))
         
         # TLS parameters
         self.tlsEnableCheckBox.setChecked(options["TlsEnable"])
@@ -239,8 +260,8 @@
         @return dictionary containing the connection options. It has the keys
             "ClientId", "Protocol", "ConnectionTimeout", "Keepalive",
             "CleanSession", "Username", "Password", "WillTopic", "WillMessage",
-            "WillQos", "WillRetain", "TlsEnable", "TlsCaCert",
-            "UserProperties".
+            "WillQos", "WillRetain", "WillProperties", "TlsEnable",
+            "TlsCaCert", "UserProperties".
         @rtype dict
         """
         if self.mqttv31Button.isChecked():
@@ -263,6 +284,7 @@
                 self.samePropertiesCheckBox.isChecked())
         else:
             self.__userProperties = {}
+            self.__willProperties = []
         
         return {
             "ClientId": self.clientIdEdit.text(),
@@ -276,6 +298,7 @@
             "WillMessage": self.willMessageEdit.toPlainText(),
             "WillQos": self.willQosSpinBox.value(),
             "WillRetain": self.willRetainCheckBox.isChecked(),
+            "WillProperties": copy.deepcopy(self.__willProperties),
             "TlsEnable": self.tlsEnableCheckBox.isChecked(),
             "TlsCaCert": self.tlsCertsFilePicker.text(),
             "UserProperties": copy.deepcopy(self.__userProperties),
--- a/MqttMonitor/MqttConnectionOptionsDialog.ui	Thu Jul 22 19:02:32 2021 +0200
+++ b/MqttMonitor/MqttConnectionOptionsDialog.ui	Fri Jul 23 17:48:22 2021 +0200
@@ -275,6 +275,16 @@
        <string>Last Will</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_2">
+       <item row="0" column="0">
+        <widget class="QLineEdit" name="willTopicEdit">
+         <property name="toolTip">
+          <string>Enter the topic of the last will</string>
+         </property>
+         <property name="clearButtonEnabled">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
        <item row="0" column="1">
         <widget class="QLabel" name="label_5">
          <property name="text">
@@ -282,19 +292,6 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="0" colspan="4">
-        <widget class="QPlainTextEdit" name="willMessageEdit">
-         <property name="maximumSize">
-          <size>
-           <width>16777215</width>
-           <height>300</height>
-          </size>
-         </property>
-         <property name="toolTip">
-          <string>Enter the last will message to be sent</string>
-         </property>
-        </widget>
-       </item>
        <item row="0" column="2">
         <widget class="QSpinBox" name="willQosSpinBox">
          <property name="toolTip">
@@ -318,13 +315,26 @@
          </property>
         </widget>
        </item>
-       <item row="0" column="0">
-        <widget class="QLineEdit" name="willTopicEdit">
+       <item row="0" column="4">
+        <widget class="QToolButton" name="willPropertiesButton">
          <property name="toolTip">
-          <string>Enter the topic of the last will</string>
+          <string>Press to edit the user properties</string>
+         </property>
+         <property name="text">
+          <string/>
          </property>
-         <property name="clearButtonEnabled">
-          <bool>true</bool>
+        </widget>
+       </item>
+       <item row="1" column="0" colspan="5">
+        <widget class="QPlainTextEdit" name="willMessageEdit">
+         <property name="maximumSize">
+          <size>
+           <width>16777215</width>
+           <height>300</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Enter the last will message to be sent</string>
          </property>
         </widget>
        </item>
@@ -487,6 +497,7 @@
   <tabstop>willMessageEdit</tabstop>
   <tabstop>willQosSpinBox</tabstop>
   <tabstop>willRetainCheckBox</tabstop>
+  <tabstop>willPropertiesButton</tabstop>
   <tabstop>tlsEnableCheckBox</tabstop>
   <tabstop>tlsCertsFilePicker</tabstop>
   <tabstop>connectPropertiesButton</tabstop>
--- a/MqttMonitor/MqttConnectionProfilesDialog.py	Thu Jul 22 19:02:32 2021 +0200
+++ b/MqttMonitor/MqttConnectionProfilesDialog.py	Fri Jul 23 17:48:22 2021 +0200
@@ -31,7 +31,7 @@
     """
     Class implementing a dialog to edit the MQTT connection profiles.
     """
-    def __init__(self, profiles, parent=None):
+    def __init__(self, profiles, currentProfile="", parent=None):
         """
         Constructor
         
@@ -40,9 +40,11 @@
             "BrokerAddress", "BrokerPort", "ClientId", "Protocol",
             "ConnectionTimeout", "Keepalive", "CleanSession", "Username",
             "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain",
-            "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey",
-            "UserProperties".
+            "WillProperties", "TlsEnable", "TlsCaCert", "TlsClientCert",
+            "TlsClientKey", "UserProperties".
         @type dict
+        @param currentProfile name of the currently selected profile
+        @type str
         @param parent reference to the parent widget
         @type QWidget
         """
@@ -50,13 +52,15 @@
         self.setupUi(self)
         
         self.__profiles = collections.defaultdict(self.__defaultProfile)
-        self.__profiles.update(profiles)
+        self.__profiles.update(copy.deepcopy(profiles))
         self.__profilesChanged = False
         
         self.plusButton.setIcon(UI.PixmapCache.getIcon("plus"))
         self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy"))
         self.minusButton.setIcon(UI.PixmapCache.getIcon("minus"))
         self.showPasswordButton.setIcon(UI.PixmapCache.getIcon("showPassword"))
+        self.willPropertiesButton.setIcon(
+            UI.PixmapCache.getIcon("listSelection"))
         
         self.tlsCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.tlsCertsFilePicker.setFilters(
@@ -89,7 +93,7 @@
         self.__populatingProfile = False
         self.__deletingProfile = False
         
-        self.__populateProfilesList()
+        self.__populateProfilesList(currentProfile=currentProfile)
     
     @pyqtSlot(str)
     def on_profileEdit_textChanged(self, name):
@@ -113,7 +117,7 @@
             QDialogButtonBox.StandardButton.Apply
         ):
             currentProfile = self.__applyProfile()
-            self.__populateProfilesList(currentProfile)
+            self.__populateProfilesList(currentProfile=currentProfile)
         
         elif button == self.profileButtonBox.button(
             QDialogButtonBox.StandardButton.Reset
@@ -206,9 +210,11 @@
                                 """ already. Aborting...</p>""").format(
                             newProfileName))
                 else:
-                    profile = self.__defaultProfile()
-                    profile.update(self.__profiles[profileName])
-                    self.__profiles[newProfileName] = profile
+                    connectionProfile = self.__defaultProfile()
+                    connectionProfile.update(
+                        copy.deepcopy(self.__profiles[profileName]))
+                    self.__profiles[newProfileName] = connectionProfile
+                    self.__profilesChanged = True
                     
                     itm = QListWidgetItem(newProfileName, self.profilesList)
                     self.profilesList.setCurrentItem(itm)
@@ -246,12 +252,13 @@
             connection profiles. Each entry has the keys "BrokerAddress",
             "BrokerPort", "ClientId", "Protocol", "ConnectionTimeout",
             "Keepalive", "CleanSession", "Username", "Password", "WillTopic",
-            "WillMessage", "WillQos", "WillRetain", "TlsEnable", "TlsCaCert",
-            "TlsClientCert", "TlsClientKey", "UserProperties".
+            "WillMessage", "WillQos", "WillRetain", "WillProperties",
+            "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey",
+            "UserProperties".
         @rtype dict
         """
         profilesDict = {}
-        profilesDict.update(self.__profiles)
+        profilesDict.update(copy.deepcopy(dict(self.__profiles)))
         return profilesDict
     
     def __applyProfile(self):
@@ -281,6 +288,7 @@
                 self.samePropertiesCheckBox.isChecked())
         else:
             self.__userProperties = {}
+            self.__willProperties = []
         
         profileName = self.profileEdit.text()
         connectionProfile = {
@@ -297,6 +305,7 @@
             "WillMessage": self.willMessageEdit.toPlainText(),
             "WillQos": self.willQosSpinBox.value(),
             "WillRetain": self.willRetainCheckBox.isChecked(),
+            "WillProperties": copy.deepcopy(self.__willProperties),
             "TlsEnable": self.tlsGroupBox.isChecked(),
             "TlsCaCert": "",
             "TlsClientCert": "",
@@ -400,6 +409,8 @@
         self.willMessageEdit.setPlainText(connectionProfile["WillMessage"])
         self.willQosSpinBox.setValue(connectionProfile["WillQos"])
         self.willRetainCheckBox.setChecked(connectionProfile["WillRetain"])
+        self.__willProperties = copy.deepcopy(
+            connectionProfile.get("WillProperties", []))
         
         # SSL/TLS tab
         self.tlsGroupBox.setChecked(connectionProfile["TlsEnable"])
@@ -467,6 +478,7 @@
         self.willMessageEdit.setPlainText("")
         self.willQosSpinBox.setValue(0)
         self.willRetainCheckBox.setChecked(False)
+        self.__willProperties = []
         self.tlsGroupBox.setChecked(False)
         self.tlsDefaultCertsButton.setChecked(True)
         self.tlsCertsFileButton.setChecked(True)
@@ -556,6 +568,12 @@
                 connectionProfile["WillRetain"] or
                 self.tlsGroupBox.isChecked() != connectionProfile["TlsEnable"]
             )
+            # check will properties only, ig not yet changed
+            if not changed and protocol == MqttProtocols.MQTTv5:
+                changed |= (
+                    sorted(self.__willProperties) !=
+                    sorted(connectionProfile["WillProperties"])
+                )
             # check TLS stuff only, if not yet changed
             if not changed:
                 if self.tlsCertsFileButton.isChecked():
@@ -683,7 +701,8 @@
             self.profileTabWidget.indexOf(self.propertiesTab),
             checked
         )
-        # TODO: add code to enable the WILL properties button
+        self.willPropertiesButton.setEnabled(checked)
+        self.willPropertiesButton.setVisible(checked)
     
     @pyqtSlot(bool)
     def on_showPasswordButton_toggled(self, checked):
@@ -699,6 +718,18 @@
             self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password)
         )
     
+    @pyqtSlot()
+    def on_willPropertiesButton_clicked(self):
+        """
+        Private slot to edit the last will user properties.
+        """
+        from .MqttUserPropertiesEditor import MqttUserPropertiesEditorDialog
+        
+        dlg = MqttUserPropertiesEditorDialog(
+            self.tr("Last Will User Properties"), self.__willProperties, self)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            self.__willProperties = dlg.getProperties()
+    
     @pyqtSlot(str)
     def on_tlsCertsFilePicker_textChanged(self, path):
         """
--- a/MqttMonitor/MqttConnectionProfilesDialog.ui	Thu Jul 22 19:02:32 2021 +0200
+++ b/MqttMonitor/MqttConnectionProfilesDialog.ui	Fri Jul 23 17:48:22 2021 +0200
@@ -466,6 +466,13 @@
             </widget>
            </item>
            <item row="0" column="1">
+            <widget class="QLabel" name="label_13">
+             <property name="text">
+              <string>QoS:</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="2">
             <widget class="QSpinBox" name="willQosSpinBox">
              <property name="toolTip">
               <string>Enter the desired QoS value</string>
@@ -478,7 +485,7 @@
              </property>
             </widget>
            </item>
-           <item row="0" column="2">
+           <item row="0" column="3">
             <widget class="QCheckBox" name="willRetainCheckBox">
              <property name="toolTip">
               <string>Select to retain the last will message</string>
@@ -488,7 +495,17 @@
              </property>
             </widget>
            </item>
-           <item row="1" column="0" colspan="3">
+           <item row="0" column="4">
+            <widget class="QToolButton" name="willPropertiesButton">
+             <property name="toolTip">
+              <string>Press to edit the user properties</string>
+             </property>
+             <property name="text">
+              <string/>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="0" colspan="5">
             <widget class="QPlainTextEdit" name="willMessageEdit">
              <property name="maximumSize">
               <size>
@@ -860,6 +877,7 @@
   <tabstop>willMessageEdit</tabstop>
   <tabstop>willQosSpinBox</tabstop>
   <tabstop>willRetainCheckBox</tabstop>
+  <tabstop>willPropertiesButton</tabstop>
   <tabstop>tlsGroupBox</tabstop>
   <tabstop>tlsDefaultCertsButton</tabstop>
   <tabstop>tlsCertsFileButton</tabstop>
--- a/MqttMonitor/MqttMonitorWidget.py	Thu Jul 22 19:02:32 2021 +0200
+++ b/MqttMonitor/MqttMonitorWidget.py	Fri Jul 23 17:48:22 2021 +0200
@@ -137,6 +137,8 @@
         ))
         self.__populateBrokerComboBoxes()
         self.brokerStatusLabel.hide()
+        self.clearWillButton.setIcon(
+            UI.PixmapCache.getIcon("certificateDelete"))
         
         self.subscribeButton.setIcon(UI.PixmapCache.getIcon("plus"))
         self.subscribeButton.setEnabled(False)
@@ -294,16 +296,22 @@
         """
         self.brokerStatusLabel.hide()
         
-        # TODO: add support for flags[‘session present’]
         if rc == 0:
             self.__connectedToBroker = True
             self.__connectionOptions = None
         
+        try:
+            sessionPresent = flags["session present"] == 1
+        except KeyError:
+            sessionPresent = False
+        
         msg = (
             mqttReasonCode(rc, packetType)
             if packetType is not None else
             mqttConnackMessage(rc)
         )
+        if sessionPresent:
+            msg = self.tr("{0} - Session still present").format(msg)
         self.__flashBrokerStatusLabel(msg)
         
         if properties:
@@ -600,8 +608,10 @@
             from .MqttConnectionProfilesDialog import (
                 MqttConnectionProfilesDialog
             )
+            profileName = self.profileComboBox.currentText()
             dlg = MqttConnectionProfilesDialog(
-                self.__plugin.getPreferences("BrokerProfiles"), parent=self)
+                self.__plugin.getPreferences("BrokerProfiles"),
+                currentProfile=profileName, parent=self)
             if dlg.exec() == QDialog.DialogCode.Accepted:
                 profilesDict = dlg.getProfiles()
                 self.__plugin.setPreferences("BrokerProfiles", profilesDict)
@@ -1296,9 +1306,17 @@
             
             self.__addBrokerToRecent(host, port)
             self.connectButton.setEnabled(False)
+            
+            if self.clearWillButton.isChecked():
+                clearWill = True
+                self.clearWillButton.setChecked(False)
+            else:
+                clearWill = False
+            
             if self.__connectionOptions is None:
                 self.__client = self.__createClient()
-                self.__client.connectToServer(host, port=port)
+                self.__client.connectToServer(
+                    host, port=port, clearWill=clearWill)
             else:
                 self.__client = self.__createClient(
                     clientId=self.__connectionOptions["ClientId"],
@@ -1306,7 +1324,8 @@
                     protocol=self.__connectionOptions["Protocol"]
                 )
                 self.__client.connectToServerWithOptions(
-                    host, port=port, options=self.__connectionOptions)
+                    host, port=port, options=self.__connectionOptions,
+                    clearWill=clearWill)
     
     def __profileConnectToBroker(self):
         """
@@ -1332,13 +1351,20 @@
             
             self.connectButton.setEnabled(False)
             
+            if self.clearWillButton.isChecked():
+                clearWill = True
+                self.clearWillButton.setChecked(False)
+            else:
+                clearWill = False
+            
             self.__client = self.__createClient(
                 clientId=connectionProfile["ClientId"],
                 cleanSession=connectionProfile["CleanSession"],
                 protocol=protocol
             )
             self.__client.connectToServerWithOptions(
-                host, port=port, options=connectionProfile)
+                host, port=port, options=connectionProfile,
+                clearWill=clearWill)
     
     def __showProperties(self, typeStr, properties):
         """
--- a/MqttMonitor/MqttMonitorWidget.ui	Thu Jul 22 19:02:32 2021 +0200
+++ b/MqttMonitor/MqttMonitorWidget.ui	Fri Jul 23 17:48:22 2021 +0200
@@ -136,6 +136,19 @@
           </property>
          </widget>
         </item>
+        <item>
+         <widget class="QToolButton" name="clearWillButton">
+          <property name="toolTip">
+           <string>Select to clear a previously set last will message</string>
+          </property>
+          <property name="text">
+           <string/>
+          </property>
+          <property name="checkable">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
        </layout>
       </item>
       <item row="1" column="0" colspan="3">
@@ -1477,6 +1490,7 @@
   <tabstop>brokerPortComboBox</tabstop>
   <tabstop>brokerConnectionOptionsButton</tabstop>
   <tabstop>connectButton</tabstop>
+  <tabstop>clearWillButton</tabstop>
   <tabstop>brokerWidget</tabstop>
   <tabstop>subscribeTopicEdit</tabstop>
   <tabstop>subscribeQosSpinBox</tabstop>

eric ide

mercurial