215 client.onConnectV3.connect(self.__brokerConnected) |
215 client.onConnectV3.connect(self.__brokerConnected) |
216 client.onConnectV5.connect(self.__brokerConnected) |
216 client.onConnectV5.connect(self.__brokerConnected) |
217 client.onDisconnectedV3.connect(self.__brokerDisconnected) |
217 client.onDisconnectedV3.connect(self.__brokerDisconnected) |
218 client.onDisconnectedV5.connect(self.__brokerDisconnected) |
218 client.onDisconnectedV5.connect(self.__brokerDisconnected) |
219 client.onLog.connect(self.__clientLog) |
219 client.onLog.connect(self.__clientLog) |
220 client.onMessage.connect(self.__messageReceived) |
220 client.onMessageV3.connect(self.__messageReceived) |
|
221 client.onMessageV5.connect(self.__messageReceived) |
221 client.onPublish.connect(self.__messagePublished) |
222 client.onPublish.connect(self.__messagePublished) |
222 client.onSubscribeV3.connect(self.__topicSubscribed) |
223 client.onSubscribeV3.connect(self.__topicSubscribed) |
223 client.onSubscribeV5.connect(self.__topicSubscribedV5) |
224 client.onSubscribeV5.connect(self.__topicSubscribedV5) |
224 client.onUnsubscribe.connect(self.__topicUnsubscribed) |
225 client.onUnsubscribeV3.connect(self.__topicUnsubscribed) |
|
226 client.onUnsubscribeV5.connect(self.__topicUnsubscribedV5) |
225 |
227 |
226 client.connectTimeout.connect(self.__connectTimeout) |
228 client.connectTimeout.connect(self.__connectTimeout) |
227 |
229 |
228 return client |
230 return client |
229 |
231 |
230 ####################################################################### |
232 ####################################################################### |
231 ## Slots handling MQTT related signals |
233 ## Slots handling MQTT related signals |
232 ####################################################################### |
234 ####################################################################### |
233 |
235 |
234 # TODO: change to accept ReasonCode for rc |
|
235 @pyqtSlot(dict, int) |
236 @pyqtSlot(dict, int) |
236 @pyqtSlot(dict, int, int) |
237 @pyqtSlot(dict, int, int) |
237 def __brokerConnected(self, flags, rc, packetType=None): |
238 def __brokerConnected(self, flags, rc, packetType=None): |
238 """ |
239 """ |
239 Private slot to handle being connected to a broker. |
240 Private slot to handle being connected to a broker. |
240 |
241 |
241 @param flags flags set for the connection |
242 @param flags flags set for the connection |
242 @type dict |
243 @type dict |
243 @param rc CONNACK result code or tuple containing the result code and |
244 @param rc CONNACK result code or MQTTv5 reason code |
244 the packet type of the MQTTv5 reason code |
245 @type int |
245 @type int or tuple of (int, int) |
246 @param packetType packet type as reported by the client |
|
247 @type int |
246 """ |
248 """ |
247 self.brokerStatusLabel.hide() |
249 self.brokerStatusLabel.hide() |
248 |
250 |
249 # TODO: add support for flags[‘session present’] |
251 # TODO: add support for flags[‘session present’] |
250 if rc == 0: |
252 if rc == 0: |
365 if self.followLogMessagesCheckBox.isChecked(): |
367 if self.followLogMessagesCheckBox.isChecked(): |
366 self.logEdit.ensureCursorVisible() |
368 self.logEdit.ensureCursorVisible() |
367 else: |
369 else: |
368 self.logEdit.verticalScrollBar().setValue(scrollbarValue) |
370 self.logEdit.verticalScrollBar().setValue(scrollbarValue) |
369 |
371 |
|
372 # TODO: add support for MQTT v5 properties |
370 @pyqtSlot(str, bytes, int, bool) |
373 @pyqtSlot(str, bytes, int, bool) |
371 def __messageReceived(self, topic, payload, qos, retain): |
374 def __messageReceived(self, topic, payload, qos, retain, properties=None): |
372 """ |
375 """ |
373 Private slot to handle the receipt of a message. |
376 Private slot to handle the receipt of a message. |
374 |
377 |
375 @param topic topic of the message |
378 @param topic topic of the message |
376 @type str |
379 @type str |
378 @type bytes |
381 @type bytes |
379 @param qos quality of service indicator |
382 @param qos quality of service indicator |
380 @type int |
383 @type int |
381 @param retain flag indicating a retained message |
384 @param retain flag indicating a retained message |
382 @type bool |
385 @type bool |
|
386 @param properties properties sent with the message (MQTT v5) |
|
387 @type Properties |
383 """ |
388 """ |
384 if topic.startswith(MqttMonitorWidget.BrokerStatusTopicPrefix): |
389 if topic.startswith(MqttMonitorWidget.BrokerStatusTopicPrefix): |
385 # handle broker status messages |
390 # handle broker status messages |
386 self.__handleBrokerStatusMessage(topic, payload) |
391 self.__handleBrokerStatusMessage(topic, payload) |
387 else: |
392 else: |
388 self.__appendMessage(topic, payload, qos) |
393 self.__appendMessage(topic, payload, qos, retain, |
|
394 properties=properties) |
389 |
395 |
390 @pyqtSlot(int) |
396 @pyqtSlot(int) |
391 def __messagePublished(self, mid): |
397 def __messagePublished(self, mid): |
392 """ |
398 """ |
393 Private slot to handle a message being published. |
399 Private slot to handle a message being published. |
422 """ |
428 """ |
423 Private slot to handle being subscribed to topics (MQTT v5). |
429 Private slot to handle being subscribed to topics (MQTT v5). |
424 |
430 |
425 @param mid ID of the subscribe request |
431 @param mid ID of the subscribe request |
426 @type int |
432 @type int |
427 @param grantedQos tuple of granted quality of service |
433 @param reasonCodes list of reason codes, one for each topic |
428 @type tuple of int |
434 @type list of ReasonCodes |
429 """ |
435 """ |
430 msg = mqttReasonCode(reasonCodes[0].value, reasonCodes[0].packetType) |
436 msg = mqttReasonCode(reasonCodes[0].value, reasonCodes[0].packetType) |
431 self.__flashBrokerStatusLabel(msg) |
437 self.__flashBrokerStatusLabel(msg) |
432 self.__topicSubscribed(mid) |
438 self.__topicSubscribed(mid) |
433 |
439 |
434 @pyqtSlot(int) |
440 @pyqtSlot(int) |
435 def __topicUnsubscribed(self, mid): |
441 def __topicUnsubscribed(self, mid): |
436 """ |
442 """ |
437 Private slot to handle being unsubcribed from a topic. |
443 Private slot to handle being unsubcribed from a topic (MQTT v3.1, |
|
444 MQTT v3.1.1). |
438 |
445 |
439 @param mid ID of the unsubscribe request |
446 @param mid ID of the unsubscribe request |
440 @type int |
447 @type int |
441 """ |
448 """ |
442 if mid in self.__topicQueue: |
449 if mid in self.__topicQueue: |
443 topic = self.__topicQueue.pop(mid) |
450 topic = self.__topicQueue.pop(mid) |
444 with contextlib.suppress(ValueError): |
451 with contextlib.suppress(ValueError): |
445 self.__subscribedTopics.remove(topic) |
452 self.__subscribedTopics.remove(topic) |
446 self.__updateUnsubscribeTopicComboBox() |
453 self.__updateUnsubscribeTopicComboBox() |
447 self.__updatePublishTopicComboBox() |
454 self.__updatePublishTopicComboBox() |
|
455 |
|
456 @pyqtSlot(int, int, int) |
|
457 def __topicUnsubscribedV5(self, mid, rc, packetType): |
|
458 """ |
|
459 Private slot to handle being unsubscribed to topics (MQTT v5). |
|
460 |
|
461 @param mid ID of the subscribe request |
|
462 @type int |
|
463 @param rc MQTTv5 reason code |
|
464 @type int |
|
465 @param packetType packet type as reported by the client |
|
466 @type int |
|
467 """ |
|
468 msg = mqttReasonCode(rc, packetType) |
|
469 self.__flashBrokerStatusLabel(msg) |
|
470 self.__topicUnsubscribed(mid) |
448 |
471 |
449 ####################################################################### |
472 ####################################################################### |
450 ## Slots handling UI interactions |
473 ## Slots handling UI interactions |
451 ####################################################################### |
474 ####################################################################### |
452 |
475 |
911 self.publishTopicComboBox.clearEditText() |
934 self.publishTopicComboBox.clearEditText() |
912 else: |
935 else: |
913 topicIndex = self.publishTopicComboBox.findText(currentTopic) |
936 topicIndex = self.publishTopicComboBox.findText(currentTopic) |
914 self.publishTopicComboBox.setCurrentIndex(topicIndex) |
937 self.publishTopicComboBox.setCurrentIndex(topicIndex) |
915 |
938 |
916 def __appendMessage(self, topic, payload, qos): |
939 def __appendMessage(self, topic, payload, qos, retain, properties=None): |
917 """ |
940 """ |
918 Private method to append a received message to the output. |
941 Private method to append a received message to the output. |
919 |
942 |
920 @param topic topic of the received message |
943 @param topic topic of the received message |
921 @type str |
944 @type str |
922 @param payload payload of the received message |
945 @param payload payload of the received message |
923 @type bytes |
946 @type bytes |
924 @param qos quality of service indicator (0, 1, 2) |
947 @param qos quality of service indicator (0, 1, 2) |
925 @type int |
948 @type int |
926 """ |
949 @param retain flag indicating a retained message |
|
950 @type bool |
|
951 @param properties properties sent with the message (MQTT v5) |
|
952 @type Properties |
|
953 """ |
|
954 # TODO: add Output for retain and properties |
927 scrollbarValue = self.messagesEdit.verticalScrollBar().value() |
955 scrollbarValue = self.messagesEdit.verticalScrollBar().value() |
928 |
956 |
929 textCursor = self.messagesEdit.textCursor() |
957 textCursor = self.messagesEdit.textCursor() |
930 if not self.messagesEdit.document().isEmpty(): |
958 if not self.messagesEdit.document().isEmpty(): |
931 textCursor.movePosition(QTextCursor.MoveOperation.End) |
959 textCursor.movePosition(QTextCursor.MoveOperation.End) |
946 self.messagesEdit.setCurrentCharFormat(self.__messagesTopicFormat) |
974 self.messagesEdit.setCurrentCharFormat(self.__messagesTopicFormat) |
947 self.messagesEdit.insertPlainText(topic + "\n") |
975 self.messagesEdit.insertPlainText(topic + "\n") |
948 |
976 |
949 self.messagesEdit.setCurrentCharFormat(self.__messagesQosFormat) |
977 self.messagesEdit.setCurrentCharFormat(self.__messagesQosFormat) |
950 self.messagesEdit.insertPlainText(self.tr("QoS: {0}\n").format(qos)) |
978 self.messagesEdit.insertPlainText(self.tr("QoS: {0}\n").format(qos)) |
|
979 |
|
980 if retain: |
|
981 self.messagesEdit.setCurrentCharFormat(self.__messagesQosFormat) |
|
982 self.messagesEdit.insertPlainText(self.tr("Retained Message\n")) |
951 |
983 |
952 payloadStr = str(payload, encoding="utf-8", errors="replace") |
984 payloadStr = str(payload, encoding="utf-8", errors="replace") |
953 self.messagesEdit.setCurrentCharFormat(self.__messagesFormat) |
985 self.messagesEdit.setCurrentCharFormat(self.__messagesFormat) |
954 self.messagesEdit.insertPlainText( |
986 self.messagesEdit.insertPlainText( |
955 Utilities.filterAnsiSequences(payloadStr)) |
987 Utilities.filterAnsiSequences(payloadStr)) |