--- a/MqttMonitor/MqttMonitorWidget.py Wed Aug 29 19:59:02 2018 +0200 +++ b/MqttMonitor/MqttMonitorWidget.py Thu Aug 30 18:57:57 2018 +0200 @@ -15,6 +15,7 @@ pass import os +import collections from PyQt5.QtCore import pyqtSlot, QTimer from PyQt5.QtGui import QTextCursor @@ -36,6 +37,7 @@ """ BrokerStatusTopicPrefix = "$SYS/broker/" BrokerStatusTopic = "$SYS/broker/#" + BrokerStatusTopicLoadPrefix = "$SYS/broker/load/" def __init__(self, plugin, parent=None): """ @@ -72,55 +74,50 @@ self.__topicQueue = {} self.__updateUnsubscribeTopicComboBox() + prefix = MqttMonitorWidget.BrokerStatusTopicPrefix self.__statusLabelMapping = { - MqttMonitorWidget.BrokerStatusTopicPrefix + "version": - self.versionLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "timestamp": - self.timestampLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "uptime": - self.uptimeLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "subscriptions/count": - self.subscriptionsLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "clients/connected": - self.clientsConnectedLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "clients/disconnected": - self.clientsDisconnectedLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "clients/expired": - self.clientsExpiredLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "clients/maximum": - self.clientsMaximumLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "clients/total": - self.clientsTotalLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "messages/sent": - self.messagesSentLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "messages/received": - self.messagesReceivedLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "messages/stored": - self.messagesStoredLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "store/messages/count": - self.messagesStoredLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "messages/inflight": - self.messagesInflightLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + \ - "retained messages/count": - self.messagesRetainedLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + \ - "publish/messages/sent": - self.publishMessagesSentLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + \ - "publish/messages/received": + # broker + prefix + "version": self.versionLabel, + prefix + "timestamp": self.timestampLabel, + prefix + "uptime": self.uptimeLabel, + prefix + "subscriptions/count": self.subscriptionsLabel, + # clients + prefix + "clients/connected": self.clientsConnectedLabel, + prefix + "clients/disconnected": self.clientsDisconnectedLabel, + prefix + "clients/expired": self.clientsExpiredLabel, + prefix + "clients/maximum": self.clientsMaximumLabel, + prefix + "clients/total": self.clientsTotalLabel, + # messages + prefix + "messages/sent": self.messagesSentLabel, + prefix + "messages/received": self.messagesReceivedLabel, + prefix + "messages/stored": self.messagesStoredLabel, + prefix + "store/messages/count": self.messagesStoredLabel, + prefix + "messages/inflight": self.messagesInflightLabel, + prefix + "retained messages/count": self.messagesRetainedLabel, + # publish messages + prefix + "publish/messages/sent": self.publishMessagesSentLabel, + prefix + "publish/messages/received": self.publishMessagesReceivedLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + \ - "publish/messages/dropped": + prefix + "publish/messages/dropped": self.publishMessagesDroppedLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "bytes/sent": - self.bytesSentLabel, - MqttMonitorWidget.BrokerStatusTopicPrefix + "bytes/received": - self.bytesReceivedLabel, -## MqttMonitorWidget.BrokerStatusTopicPrefix + "": -## self.versionLabel, + # traffic + prefix + "bytes/sent": self.bytesSentLabel, + prefix + "bytes/received": self.bytesReceivedLabel, + # load + prefix + "load/bytes/sent": self.loadBytesSentLabel, + prefix + "load/bytes/received": self.loadBytesReceivedLabel, + prefix + "load/messages/sent": self.loadMessagesSentLabel, + prefix + "load/messages/received": self.loadMessagesReceivedLabel, + prefix + "load/publish/sent": self.loadPublishSentLabel, + prefix + "load/publish/received": self.loadPublishReceivedLabel, + prefix + "load/publish/dropped": self.loadPublishDroppedLabel, + prefix + "load/connections": self.loadConnectionsLabel, + prefix + "load/sockets": self.loadSocketsLabel, } + self.__statusLoadValues = collections.defaultdict( + self.__loadDefaultDictFactory) + self.__client = MqttClient() # connect the MQTT client signals @@ -156,6 +153,8 @@ self.subscribeGroup.setEnabled(True) self.unsubscribeGroup.setEnabled(True) self.brokerStatusButton.setEnabled(True) + + self.__statusLoadValues.clear() @pyqtSlot(int) def __brokerDisconnected(self, rc): @@ -185,6 +184,8 @@ self.subscribeGroup.setEnabled(False) self.unsubscribeGroup.setEnabled(False) self.brokerStatusButton.setEnabled(False) + + self.__statusLoadValues.clear() @pyqtSlot(str, bytes, int, bool) def __messageReceived(self, topic, payload, qos, retain): @@ -317,7 +318,7 @@ self, self.tr("Subscribe to Topic"), self.tr("Subscriptions to the Status topic '$SYS' shall" - " be done on the Status tab.")) + " be done on the 'Status' tab.")) else: self.__topicQueue[ self.__client.subscribe(topic, qos)[1]] = topic @@ -427,10 +428,51 @@ @type bytes """ payloadStr = str(payload, encoding="utf-8", errors="replace").strip() + topic = topic.strip() + + if topic.startswith(MqttMonitorWidget.BrokerStatusTopicLoadPrefix): + self.__handleBrokerLoadStatusMessage(topic, payloadStr) + else: + try: + label = self.__statusLabelMapping[topic] + label.setText(payloadStr) + except KeyError: + # ignore topics not shown in display + pass + + def __handleBrokerLoadStatusMessage(self, topic, payloadStr): + """ + Private method to append a received message to the output. + + @param topic topic of the received message + @type str + @param payloadStr string representation of the payload of the + received message + @type str + """ + subtopic, topicElement = topic.rsplit("/", 1) + self.__statusLoadValues[subtopic][topicElement] = payloadStr try: - label = self.__statusLabelMapping[topic.strip()] - label.setText(payloadStr) + label = self.__statusLabelMapping[subtopic] + label.setText("{0} / {1} / {2}".format( + self.__statusLoadValues[subtopic]["1min"], + self.__statusLoadValues[subtopic]["5min"], + self.__statusLoadValues[subtopic]["15min"], + )) except KeyError: # ignore topics not shown in display pass + + def __loadDefaultDictFactory(self): + """ + Private method to populate non-existing load items. + + @return default dictionary entry + @rtype dict + """ + return { + "1min": "-", + "5min": "-", + "15min": "-", + }