17 import os |
17 import os |
18 import collections |
18 import collections |
19 import copy |
19 import copy |
20 |
20 |
21 from PyQt5.QtCore import pyqtSlot, QTimer |
21 from PyQt5.QtCore import pyqtSlot, QTimer |
22 from PyQt5.QtGui import QTextCursor |
22 from PyQt5.QtGui import QFont |
23 from PyQt5.QtWidgets import QWidget, QDialog |
23 from PyQt5.QtWidgets import QWidget, QDialog |
24 |
24 |
25 from E5Gui import E5MessageBox |
25 from E5Gui import E5MessageBox |
26 from E5Gui.E5PathPicker import E5PathPickerModes |
26 from E5Gui.E5PathPicker import E5PathPickerModes |
27 |
27 |
31 mqttLogLevelString |
31 mqttLogLevelString |
32 |
32 |
33 import UI.PixmapCache |
33 import UI.PixmapCache |
34 import Utilities |
34 import Utilities |
35 |
35 |
36 |
|
37 # TODO: change messages display to use a tree widget |
|
38 # first row topic |
|
39 # second row qos and message |
|
40 # |
|
41 # include capability to filter on topic |
|
42 |
|
43 # TODO: change log display to a tree widget |
|
44 # two columns with log level and message |
|
45 # colorize entries depending on log level |
|
46 |
36 |
47 class MqttMonitorWidget(QWidget, Ui_MqttMonitorWidget): |
37 class MqttMonitorWidget(QWidget, Ui_MqttMonitorWidget): |
48 """ |
38 """ |
49 Class implementing the MQTT Monitor widget. |
39 Class implementing the MQTT Monitor widget. |
50 """ |
40 """ |
72 self.pixmapLabel.setPixmap(UI.PixmapCache.getPixmap( |
62 self.pixmapLabel.setPixmap(UI.PixmapCache.getPixmap( |
73 os.path.join("MqttMonitor", "icons", "mqtt48.png"))) |
63 os.path.join("MqttMonitor", "icons", "mqtt48.png"))) |
74 |
64 |
75 self.publishPayloadFilePicker.setMode(E5PathPickerModes.OpenFileMode) |
65 self.publishPayloadFilePicker.setMode(E5PathPickerModes.OpenFileMode) |
76 self.publishPayloadFilePicker.setFilters(self.tr("All Files (*)")) |
66 self.publishPayloadFilePicker.setFilters(self.tr("All Files (*)")) |
|
67 |
|
68 self.__messagesFormat = self.messagesEdit.currentCharFormat() |
|
69 self.__messagesTopicFormat = self.messagesEdit.currentCharFormat() |
|
70 self.__messagesTopicFormat.setFontWeight(QFont.Bold) |
|
71 self.__messagesQosFormat = self.messagesEdit.currentCharFormat() |
|
72 self.__messagesQosFormat.setFontItalic(True) |
77 |
73 |
78 for logLevel in (MqttClient.LogDisabled, |
74 for logLevel in (MqttClient.LogDisabled, |
79 MqttClient.LogDebug, |
75 MqttClient.LogDebug, |
80 MqttClient.LogInfo, |
76 MqttClient.LogInfo, |
81 MqttClient.LogNotice, |
77 MqttClient.LogNotice, |
271 except KeyError: |
267 except KeyError: |
272 # always show unknown log levels |
268 # always show unknown log levels |
273 pass |
269 pass |
274 |
270 |
275 txt = self.tr("{0}: {1}").format(mqttLogLevelString(level), message) |
271 txt = self.tr("{0}: {1}").format(mqttLogLevelString(level), message) |
276 if not txt.endswith(("\r\n", "\r", "\n")): |
272 |
277 txt += "\n" |
273 self.logEdit.appendPlainText(Utilities.filterAnsiSequences(txt)) |
278 |
|
279 tc = self.logEdit.textCursor() |
|
280 tc.movePosition(QTextCursor.End) |
|
281 self.logEdit.setTextCursor(tc) |
|
282 self.logEdit.insertPlainText(Utilities.filterAnsiSequences(txt)) |
|
283 self.logEdit.ensureCursorVisible() |
274 self.logEdit.ensureCursorVisible() |
284 |
275 |
285 @pyqtSlot(str, bytes, int, bool) |
276 @pyqtSlot(str, bytes, int, bool) |
286 def __messageReceived(self, topic, payload, qos, retain): |
277 def __messageReceived(self, topic, payload, qos, retain): |
287 """ |
278 """ |
298 """ |
289 """ |
299 if topic.startswith(MqttMonitorWidget.BrokerStatusTopicPrefix): |
290 if topic.startswith(MqttMonitorWidget.BrokerStatusTopicPrefix): |
300 # handle broker status messages |
291 # handle broker status messages |
301 self.__handleBrokerStatusMessage(topic, payload) |
292 self.__handleBrokerStatusMessage(topic, payload) |
302 else: |
293 else: |
303 self.__appendMessage(topic, payload) |
294 self.__appendMessage(topic, payload, qos) |
304 |
295 |
305 @pyqtSlot(int) |
296 @pyqtSlot(int) |
306 def __messagePublished(self, mid): |
297 def __messagePublished(self, mid): |
307 """ |
298 """ |
308 Private slot to handle a message being published. |
299 Private slot to handle a message being published. |
584 MqttMonitorWidget.BrokerStatusTopic) |
575 MqttMonitorWidget.BrokerStatusTopic) |
585 if rc == 0: |
576 if rc == 0: |
586 # successfully sent |
577 # successfully sent |
587 self.__setBrokerStatusSubscribed(True) |
578 self.__setBrokerStatusSubscribed(True) |
588 |
579 |
|
580 ####################################################################### |
|
581 ## Utility methods |
|
582 ####################################################################### |
|
583 |
589 def __setBrokerStatusSubscribed(self, subscribed): |
584 def __setBrokerStatusSubscribed(self, subscribed): |
590 """ |
585 """ |
591 Private method to set the subscription status for the broker status |
586 Private method to set the subscription status for the broker status |
592 topics. |
587 topics. |
593 |
588 |
601 self.tr("Press to deactivate the status display")) |
596 self.tr("Press to deactivate the status display")) |
602 else: |
597 else: |
603 self.brokerStatusButton.setText(self.tr("Subscribe")) |
598 self.brokerStatusButton.setText(self.tr("Subscribe")) |
604 self.brokerStatusButton.setToolTip( |
599 self.brokerStatusButton.setToolTip( |
605 self.tr("Press to activate the status display")) |
600 self.tr("Press to activate the status display")) |
606 |
|
607 ####################################################################### |
|
608 ## Utility methods |
|
609 ####################################################################### |
|
610 |
601 |
611 def __addBrokerToRecent(self, host, port): |
602 def __addBrokerToRecent(self, host, port): |
612 """ |
603 """ |
613 Private method to add a host name to the list of recently connected |
604 Private method to add a host name to the list of recently connected |
614 brokers. |
605 brokers. |
704 self.publishTopicComboBox.clearEditText() |
695 self.publishTopicComboBox.clearEditText() |
705 else: |
696 else: |
706 topicIndex = self.publishTopicComboBox.findText(currentTopic) |
697 topicIndex = self.publishTopicComboBox.findText(currentTopic) |
707 self.publishTopicComboBox.setCurrentIndex(topicIndex) |
698 self.publishTopicComboBox.setCurrentIndex(topicIndex) |
708 |
699 |
709 def __appendMessage(self, topic, payload): |
700 def __appendMessage(self, topic, payload, qos): |
710 """ |
701 """ |
711 Private method to append a received message to the output. |
702 Private method to append a received message to the output. |
712 |
703 |
713 @param topic topic of the received message |
704 @param topic topic of the received message |
714 @type str |
705 @type str |
715 @param payload payload of the received message |
706 @param payload payload of the received message |
716 @type bytes |
707 @type bytes |
|
708 @param qos quality of service indicator (0, 1, 2) |
|
709 @type int |
717 """ |
710 """ |
718 payloadStr = str(payload, encoding="utf-8", errors="replace") |
711 payloadStr = str(payload, encoding="utf-8", errors="replace") |
719 txt = self.tr("{0} -> {1}").format(topic, payloadStr) |
712 |
720 if not txt.endswith(("\r\n", "\r", "\n")): |
713 self.messagesEdit.setCurrentCharFormat(self.__messagesTopicFormat) |
721 txt += "\n" |
714 self.messagesEdit.appendPlainText(topic) |
722 |
715 self.messagesEdit.setCurrentCharFormat(self.__messagesQFormat) |
723 tc = self.messagesEdit.textCursor() |
716 self.messagesEdit.appendPlainText(self.tr("QoS: {0}").format(qos)) |
724 tc.movePosition(QTextCursor.End) |
717 self.messagesEdit.setCurrentCharFormat(self.__messagesFormat) |
725 self.messagesEdit.setTextCursor(tc) |
718 self.messagesEdit.appendPlainText( |
726 self.messagesEdit.insertPlainText(Utilities.filterAnsiSequences(txt)) |
719 Utilities.filterAnsiSequences(payloadStr)) |
|
720 self.messagesEdit.appendPlainText(60 * "#") |
727 self.messagesEdit.ensureCursorVisible() |
721 self.messagesEdit.ensureCursorVisible() |
728 |
722 |
729 def __handleBrokerStatusMessage(self, topic, payload): |
723 def __handleBrokerStatusMessage(self, topic, payload): |
730 """ |
724 """ |
731 Private method to append a received message to the output. |
725 Private method to append a received message to the output. |