MqttMonitor/MqttMonitorWidget.py

branch
eric7
changeset 132
b4fde9ee3d83
parent 131
899c7cb866a2
child 138
871d54655ef1
equal deleted inserted replaced
131:899c7cb866a2 132:b4fde9ee3d83
10 import collections 10 import collections
11 import contextlib 11 import contextlib
12 import copy 12 import copy
13 import os 13 import os
14 14
15 from PyQt6.QtCore import QFileInfo, QPoint, Qt, QTimer, pyqtSlot 15 from PyQt6.QtCore import QFileInfo, QLocale, QPoint, Qt, QTimer, pyqtSlot
16 from PyQt6.QtGui import QBrush, QColor, QFont, QTextCursor 16 from PyQt6.QtGui import QBrush, QColor, QFont, QTextCursor
17 from PyQt6.QtWidgets import QDialog, QMenu, QWidget 17 from PyQt6.QtWidgets import QDialog, QMenu, QWidget
18 18
19 from eric7 import Utilities 19 from eric7 import Utilities
20 20
243 prefix + "load/publish/received": self.loadPublishReceivedLabel, 243 prefix + "load/publish/received": self.loadPublishReceivedLabel,
244 prefix + "load/publish/dropped": self.loadPublishDroppedLabel, 244 prefix + "load/publish/dropped": self.loadPublishDroppedLabel,
245 prefix + "load/connections": self.loadConnectionsLabel, 245 prefix + "load/connections": self.loadConnectionsLabel,
246 prefix + "load/sockets": self.loadSocketsLabel, 246 prefix + "load/sockets": self.loadSocketsLabel,
247 } 247 }
248 self.__statusFormatMapping = {
249 # broker
250 prefix + "version": None,
251 prefix + "timestamp": None,
252 prefix + "uptime": self.__formatUptime,
253 prefix + "subscriptions/count": self.__formatInt,
254 # clients
255 prefix + "clients/connected": self.__formatInt,
256 prefix + "clients/disconnected": self.__formatInt,
257 prefix + "clients/expired": self.__formatInt,
258 prefix + "clients/maximum": self.__formatInt,
259 prefix + "clients/total": self.__formatInt,
260 # messages
261 prefix + "messages/sent": self.__formatInt,
262 prefix + "messages/received": self.__formatInt,
263 prefix + "messages/stored": self.__formatInt,
264 prefix + "store/messages/count": self.__formatInt,
265 prefix + "messages/inflight": self.__formatInt,
266 prefix + "retained messages/count": self.__formatInt,
267 # publish messages
268 prefix + "publish/messages/sent": self.__formatInt,
269 prefix + "publish/messages/received": self.__formatInt,
270 prefix + "publish/messages/dropped": self.__formatInt,
271 # traffic
272 prefix + "bytes/sent": self.__formatData,
273 prefix + "bytes/received": self.__formatData,
274 # load
275 prefix + "load/bytes/sent": self.__formatFloat,
276 prefix + "load/bytes/received": self.__formatFloat,
277 prefix + "load/messages/sent": self.__formatFloat,
278 prefix + "load/messages/received": self.__formatFloat,
279 prefix + "load/publish/sent": self.__formatFloat,
280 prefix + "load/publish/received": self.__formatFloat,
281 prefix + "load/publish/dropped": self.__formatFloat,
282 prefix + "load/connections": self.__formatFloat,
283 prefix + "load/sockets": self.__formatFloat,
284 }
248 285
249 self.__statusLoadValues = collections.defaultdict(self.__loadDefaultDictFactory) 286 self.__statusLoadValues = collections.defaultdict(self.__loadDefaultDictFactory)
287 self.__statusLocale = QLocale()
250 288
251 def __createClient(self, clientId="", cleanSession=None, protocol=None): 289 def __createClient(self, clientId="", cleanSession=None, protocol=None):
252 """ 290 """
253 Private method to instantiate a MQTT client for a given protocol. 291 Private method to instantiate a MQTT client for a given protocol.
254 292
644 def on_brokerConnectionOptionsButton_clicked(self): 682 def on_brokerConnectionOptionsButton_clicked(self):
645 """ 683 """
646 Private slot to show a dialog to modify connection options or a 684 Private slot to show a dialog to modify connection options or a
647 dialog to edit connection profiles. 685 dialog to edit connection profiles.
648 """ 686 """
687 from .MqttConnectionProfilesDialog import MqttConnectionProfilesDialog
688 from .MqttConnectionOptionsDialog import MqttConnectionOptionsDialog
689
649 if self.__connectionModeProfile: 690 if self.__connectionModeProfile:
650 from .MqttConnectionProfilesDialog import MqttConnectionProfilesDialog
651
652 profileName = self.profileComboBox.currentText() 691 profileName = self.profileComboBox.currentText()
653 dlg = MqttConnectionProfilesDialog( 692 dlg = MqttConnectionProfilesDialog(
654 self.__plugin.getPreferences("BrokerProfiles"), 693 self.__plugin.getPreferences("BrokerProfiles"),
655 currentProfile=profileName, 694 currentProfile=profileName,
656 parent=self, 695 parent=self,
658 if dlg.exec() == QDialog.DialogCode.Accepted: 697 if dlg.exec() == QDialog.DialogCode.Accepted:
659 profilesDict = dlg.getProfiles() 698 profilesDict = dlg.getProfiles()
660 self.__plugin.setPreferences("BrokerProfiles", profilesDict) 699 self.__plugin.setPreferences("BrokerProfiles", profilesDict)
661 self.__populateProfileComboBox() 700 self.__populateProfileComboBox()
662 else: 701 else:
663 from .MqttConnectionOptionsDialog import MqttConnectionOptionsDialog
664
665 dlg = MqttConnectionOptionsDialog(self.__connectionOptions, parent=self) 702 dlg = MqttConnectionOptionsDialog(self.__connectionOptions, parent=self)
666 if dlg.exec() == QDialog.DialogCode.Accepted: 703 if dlg.exec() == QDialog.DialogCode.Accepted:
667 self.__connectionOptions = dlg.getConnectionOptions() 704 self.__connectionOptions = dlg.getConnectionOptions()
668 if self.__connectionOptions["TlsEnable"]: 705 if self.__connectionOptions["TlsEnable"]:
669 port = self.brokerPortComboBox.currentText().strip() 706 port = self.brokerPortComboBox.currentText().strip()
1274 if topic.startswith(MqttMonitorWidget.BrokerStatusTopicLoadPrefix): 1311 if topic.startswith(MqttMonitorWidget.BrokerStatusTopicLoadPrefix):
1275 self.__handleBrokerLoadStatusMessage(topic, payloadStr) 1312 self.__handleBrokerLoadStatusMessage(topic, payloadStr)
1276 else: 1313 else:
1277 with contextlib.suppress(KeyError): 1314 with contextlib.suppress(KeyError):
1278 label = self.__statusLabelMapping[topic] 1315 label = self.__statusLabelMapping[topic]
1279 label.setText(payloadStr) 1316 label.setText(self.__formatBrokerStatusValue(topic, payloadStr))
1280 1317
1281 def __handleBrokerLoadStatusMessage(self, topic, payloadStr): 1318 def __handleBrokerLoadStatusMessage(self, topic, payloadStr):
1282 """ 1319 """
1283 Private method to append a received message to the output. 1320 Private method to append a received message to the output.
1284 1321
1293 1330
1294 with contextlib.suppress(KeyError): 1331 with contextlib.suppress(KeyError):
1295 label = self.__statusLabelMapping[subtopic] 1332 label = self.__statusLabelMapping[subtopic]
1296 label.setText( 1333 label.setText(
1297 "{0} / {1} / {2}".format( 1334 "{0} / {1} / {2}".format(
1298 self.__statusLoadValues[subtopic]["1min"], 1335 self.__formatBrokerStatusValue(
1299 self.__statusLoadValues[subtopic]["5min"], 1336 subtopic, self.__statusLoadValues[subtopic]["1min"]
1300 self.__statusLoadValues[subtopic]["15min"], 1337 ),
1301 ) 1338 self.__formatBrokerStatusValue(
1302 ) 1339 subtopic, self.__statusLoadValues[subtopic]["5min"]
1340 ),
1341 self.__formatBrokerStatusValue(
1342 subtopic, self.__statusLoadValues[subtopic]["15min"]
1343 ),
1344 )
1345 )
1346
1347 def __formatBrokerStatusValue(self, topic, value):
1348 """
1349 Private method to format the value reported for a topic.
1350
1351 @param topic topic name
1352 @type str
1353 @param value value of the topic
1354 @type str
1355 @return reformatted value string
1356 @rtype str
1357 """
1358 try:
1359 formatFunc = self.__statusFormatMapping[topic]
1360 if formatFunc is None:
1361 return value
1362 else:
1363 return formatFunc(value)
1364 except KeyError:
1365 return value
1303 1366
1304 def __clearBrokerStatusLabels(self): 1367 def __clearBrokerStatusLabels(self):
1305 """ 1368 """
1306 Private method to clear the broker status labels. 1369 Private method to clear the broker status labels.
1307 """ 1370 """
1506 properties = self.__plugin.getPreferences(preferencesKey) 1569 properties = self.__plugin.getPreferences(preferencesKey)
1507 dlg = MqttUserPropertiesEditorDialog(header, properties.get(key, []), self) 1570 dlg = MqttUserPropertiesEditorDialog(header, properties.get(key, []), self)
1508 if dlg.exec() == QDialog.DialogCode.Accepted: 1571 if dlg.exec() == QDialog.DialogCode.Accepted:
1509 properties[key] = dlg.getProperties() 1572 properties[key] = dlg.getProperties()
1510 self.__plugin.setPreferences(preferencesKey, properties) 1573 self.__plugin.setPreferences(preferencesKey, properties)
1574
1575 #######################################################################
1576 ## some helper methods below
1577 #######################################################################
1578
1579 def __formatInt(self, valStr):
1580 """
1581 Private method to format the uptime string.
1582
1583 @param valStr string to be formatted
1584 @type str
1585 @return formatted string
1586 @rtype str
1587 """
1588 try:
1589 val = int(valStr)
1590 return self.__statusLocale.toString(val)
1591 except ValueError:
1592 return valStr
1593
1594 def __formatFloat(self, valStr):
1595 """
1596 Private method to format the uptime string.
1597
1598 @param valStr string to be formatted
1599 @type str
1600 @return formatted string
1601 @rtype str
1602 """
1603 try:
1604 val = float(valStr)
1605 return self.__statusLocale.toString(val)
1606 except ValueError:
1607 return valStr
1608
1609 def __formatUptime(self, valStr):
1610 """
1611 Private method to format the uptime string.
1612
1613 @param valStr string to be formatted
1614 @type str
1615 @return formatted string
1616 @rtype str
1617 """
1618 val, *suffix = valStr.split()
1619 try:
1620 val = int(val)
1621 vloc = self.__statusLocale.toString(val)
1622 if suffix:
1623 return f"{vloc} {' '.join(suffix)}"
1624 else:
1625 return vloc
1626 except ValueError:
1627 return valStr
1628
1629 def __formatData(self, valStr):
1630 """
1631 Private method to format the uptime string.
1632
1633 @param valStr string to be formatted
1634 @type str
1635 @return formatted string
1636 @rtype str
1637 """
1638 try:
1639 size = int(valStr)
1640 if size < 1024:
1641 return self.tr("{0} Bytes").format(
1642 self.__statusLocale.toString(size, "f", 2)
1643 )
1644 elif size < 1024 * 1024:
1645 size /= 1024
1646 return self.tr("{0} KiB").format(
1647 self.__statusLocale.toString(size, "f", 2)
1648 )
1649 elif size < 1024 * 1024 * 1024:
1650 size /= 1024 * 1024
1651 return self.tr("{0} MiB").format(
1652 self.__statusLocale.toString(size, "f", 2)
1653 )
1654 elif size < 1024 * 1024 * 1024 * 1024:
1655 size /= 1024 * 1024 * 1024
1656 return self.tr("{0} GiB").format(
1657 self.__statusLocale.toString(size, "f", 2)
1658 )
1659 else:
1660 size /= 1024 * 1024 * 1024 * 1024
1661 return self.tr("{0} TiB").format(
1662 self.__statusLocale.toString(size, "f", 2)
1663 )
1664 except ValueError:
1665 return valStr

eric ide

mercurial