diff -r 899c7cb866a2 -r b4fde9ee3d83 MqttMonitor/MqttMonitorWidget.py --- a/MqttMonitor/MqttMonitorWidget.py Sat Dec 31 16:27:45 2022 +0100 +++ b/MqttMonitor/MqttMonitorWidget.py Tue Jul 04 15:13:37 2023 +0200 @@ -12,7 +12,7 @@ import copy import os -from PyQt6.QtCore import QFileInfo, QPoint, Qt, QTimer, pyqtSlot +from PyQt6.QtCore import QFileInfo, QLocale, QPoint, Qt, QTimer, pyqtSlot from PyQt6.QtGui import QBrush, QColor, QFont, QTextCursor from PyQt6.QtWidgets import QDialog, QMenu, QWidget @@ -245,8 +245,46 @@ prefix + "load/connections": self.loadConnectionsLabel, prefix + "load/sockets": self.loadSocketsLabel, } + self.__statusFormatMapping = { + # broker + prefix + "version": None, + prefix + "timestamp": None, + prefix + "uptime": self.__formatUptime, + prefix + "subscriptions/count": self.__formatInt, + # clients + prefix + "clients/connected": self.__formatInt, + prefix + "clients/disconnected": self.__formatInt, + prefix + "clients/expired": self.__formatInt, + prefix + "clients/maximum": self.__formatInt, + prefix + "clients/total": self.__formatInt, + # messages + prefix + "messages/sent": self.__formatInt, + prefix + "messages/received": self.__formatInt, + prefix + "messages/stored": self.__formatInt, + prefix + "store/messages/count": self.__formatInt, + prefix + "messages/inflight": self.__formatInt, + prefix + "retained messages/count": self.__formatInt, + # publish messages + prefix + "publish/messages/sent": self.__formatInt, + prefix + "publish/messages/received": self.__formatInt, + prefix + "publish/messages/dropped": self.__formatInt, + # traffic + prefix + "bytes/sent": self.__formatData, + prefix + "bytes/received": self.__formatData, + # load + prefix + "load/bytes/sent": self.__formatFloat, + prefix + "load/bytes/received": self.__formatFloat, + prefix + "load/messages/sent": self.__formatFloat, + prefix + "load/messages/received": self.__formatFloat, + prefix + "load/publish/sent": self.__formatFloat, + prefix + "load/publish/received": self.__formatFloat, + prefix + "load/publish/dropped": self.__formatFloat, + prefix + "load/connections": self.__formatFloat, + prefix + "load/sockets": self.__formatFloat, + } self.__statusLoadValues = collections.defaultdict(self.__loadDefaultDictFactory) + self.__statusLocale = QLocale() def __createClient(self, clientId="", cleanSession=None, protocol=None): """ @@ -646,9 +684,10 @@ Private slot to show a dialog to modify connection options or a dialog to edit connection profiles. """ + from .MqttConnectionProfilesDialog import MqttConnectionProfilesDialog + from .MqttConnectionOptionsDialog import MqttConnectionOptionsDialog + if self.__connectionModeProfile: - from .MqttConnectionProfilesDialog import MqttConnectionProfilesDialog - profileName = self.profileComboBox.currentText() dlg = MqttConnectionProfilesDialog( self.__plugin.getPreferences("BrokerProfiles"), @@ -660,8 +699,6 @@ self.__plugin.setPreferences("BrokerProfiles", profilesDict) self.__populateProfileComboBox() else: - from .MqttConnectionOptionsDialog import MqttConnectionOptionsDialog - dlg = MqttConnectionOptionsDialog(self.__connectionOptions, parent=self) if dlg.exec() == QDialog.DialogCode.Accepted: self.__connectionOptions = dlg.getConnectionOptions() @@ -1276,7 +1313,7 @@ else: with contextlib.suppress(KeyError): label = self.__statusLabelMapping[topic] - label.setText(payloadStr) + label.setText(self.__formatBrokerStatusValue(topic, payloadStr)) def __handleBrokerLoadStatusMessage(self, topic, payloadStr): """ @@ -1295,12 +1332,38 @@ label = self.__statusLabelMapping[subtopic] label.setText( "{0} / {1} / {2}".format( - self.__statusLoadValues[subtopic]["1min"], - self.__statusLoadValues[subtopic]["5min"], - self.__statusLoadValues[subtopic]["15min"], + self.__formatBrokerStatusValue( + subtopic, self.__statusLoadValues[subtopic]["1min"] + ), + self.__formatBrokerStatusValue( + subtopic, self.__statusLoadValues[subtopic]["5min"] + ), + self.__formatBrokerStatusValue( + subtopic, self.__statusLoadValues[subtopic]["15min"] + ), ) ) + def __formatBrokerStatusValue(self, topic, value): + """ + Private method to format the value reported for a topic. + + @param topic topic name + @type str + @param value value of the topic + @type str + @return reformatted value string + @rtype str + """ + try: + formatFunc = self.__statusFormatMapping[topic] + if formatFunc is None: + return value + else: + return formatFunc(value) + except KeyError: + return value + def __clearBrokerStatusLabels(self): """ Private method to clear the broker status labels. @@ -1508,3 +1571,95 @@ if dlg.exec() == QDialog.DialogCode.Accepted: properties[key] = dlg.getProperties() self.__plugin.setPreferences(preferencesKey, properties) + + ####################################################################### + ## some helper methods below + ####################################################################### + + def __formatInt(self, valStr): + """ + Private method to format the uptime string. + + @param valStr string to be formatted + @type str + @return formatted string + @rtype str + """ + try: + val = int(valStr) + return self.__statusLocale.toString(val) + except ValueError: + return valStr + + def __formatFloat(self, valStr): + """ + Private method to format the uptime string. + + @param valStr string to be formatted + @type str + @return formatted string + @rtype str + """ + try: + val = float(valStr) + return self.__statusLocale.toString(val) + except ValueError: + return valStr + + def __formatUptime(self, valStr): + """ + Private method to format the uptime string. + + @param valStr string to be formatted + @type str + @return formatted string + @rtype str + """ + val, *suffix = valStr.split() + try: + val = int(val) + vloc = self.__statusLocale.toString(val) + if suffix: + return f"{vloc} {' '.join(suffix)}" + else: + return vloc + except ValueError: + return valStr + + def __formatData(self, valStr): + """ + Private method to format the uptime string. + + @param valStr string to be formatted + @type str + @return formatted string + @rtype str + """ + try: + size = int(valStr) + if size < 1024: + return self.tr("{0} Bytes").format( + self.__statusLocale.toString(size, "f", 2) + ) + elif size < 1024 * 1024: + size /= 1024 + return self.tr("{0} KiB").format( + self.__statusLocale.toString(size, "f", 2) + ) + elif size < 1024 * 1024 * 1024: + size /= 1024 * 1024 + return self.tr("{0} MiB").format( + self.__statusLocale.toString(size, "f", 2) + ) + elif size < 1024 * 1024 * 1024 * 1024: + size /= 1024 * 1024 * 1024 + return self.tr("{0} GiB").format( + self.__statusLocale.toString(size, "f", 2) + ) + else: + size /= 1024 * 1024 * 1024 * 1024 + return self.tr("{0} TiB").format( + self.__statusLocale.toString(size, "f", 2) + ) + except ValueError: + return valStr