Wednesday, July 4, 2018

Support for MQTT has evolved in LabPlot

Hey guys. It's been a while since my last post, however we haven't lazed since then. We solved the problems presented in the previous post, and also implemented the "next steps". To get in the picture you may want to read the previous post.

So let's just go through the new things step by step. I'll try to explain the respective feature, and also give examples using videos or screenshots.

The biggest problem was that these topics are completely INDIVIDUAL, so they may send totally different amount of data (this amount of data may differ from message to message as well, given one topic) and this hasn't made possible putting the data of these messages in the same container (spreadsheet). The idea used for the solution came from my mentor Kristóf and his former mentor Alexander Semke. 3 new classes were implemented, in order to represent better the tree like structure of the topics: 
  • MQTTClient which contains the information about the QMqttClient which connects to the broker and manages it, manages the connection, contains the reading and update options, presented in the previous post, is responsible for subscribing and unsubscribing
  • MQTTSubscription which represents the subscriptions made by the client. This is the core of the tree like structure, because if the subscribed topic contains wildcards, then every topic from which a message was received by the subscription will be added as its child
  • MQTTTopic which is responsible for saving the data in columns according to the reading and update options of the MQTTClient. This is basically a spreadsheet containing at least 2 columns:
          • value: the data received from the message
          • timestamp: the time when the message was received in order to be able to plot the values of a single topic, without using any other topic's values
          • one optional index column
This not has only solved the problem of sets of messages with not equal amount of data, but also we no longer have to enforce synchrony for the topics, since they are handled individually.
The "tree" structure of the new classes in the project explorer

The next change was brought by the previous one. Since we represent the subscribed topic in a tree like structure in the project explorer, I couldn't stand the fact that in the ImportFileWidget we could only select the topics to be subscribed via a QComboBox. Therefore I improved the ui of ImportFileWidget. Now we use a QTreeWidget to list the available topics, in order to represent them in their natural tree structure. Searching for "roots" is also possible for better navigation, the QTreeWidget scrolls to the given root item. Another upgrade of the ui is that its content is now scrollable, this change was needed because the amount of ui items needed for the MQTT setup has become quite large.
 
Upgraded ImportFileWidget design and functionality


The next feature is setting the will message of the client. Each client can specify its last will message (a normal MQTT message with topic, retained flag, QoS and payload) when connecting to a broker. The broker will store the message until it detects that the client has disconnected ungracefully. If the client disconnect abruptly, the broker sends the message to all subscribed clients on the topic, which was specified in the last will message. The stored LWT message will be discarded if a client disconnects gracefully by sending a DISCONNECT message.
The user can choose the will topic from the topics of the MQTTSubscriptions. The user can set the QoS, retain flag and payload as well. For the payload we implemented 3 variants:
          1. Own message: the user can set any message using a QLineEdit
          2. Last message received (from the will topic)
          3. Statistics: several options which can be selected by list of checkboxes (for instance Minimum, Maximum, Median, Variance, etc.)
The user can also set when and how to set/update the will message. There are 2 options: by click and after a set time interval.
 
Setting Will Message

Another implemented feature is subscribing and unsubscribing to topics during runtime in LiveDataDock. If we subscribe to a topic that "contains" one that we are already subscribed to, this can only happen if the new contains # or + wildcard(s) and it includes the "old" topic. If this happens we don't throw away the data which was received until that moment by the to be deleted MQTTSubscription, but we "reparent" the MQTTTopics of the "old" MQTTSubscribtion to the new subscription.
 
Subscribe & Unsubscribe

The last big feature which was implemented is saving and loading the objects of the newly implemented classes. Saving and loading is a really important part of LabPlot so it was necessary to enable this for MQTT as well.
 
Save & Load

The preview of data in ImportFileWidget was also improved, now it works with messages containing different amount of data as well.
There was added another option, the user can choose from interpreting the retained messages or not.   

The next steps. There may be a lot. One short come still is that  LabPlot can't plot QDateTime for now, but as I've talked with Alexander, he said that this matter will be dealt with before the end of the project. One important thing that is still left is to modify PlotDataDialog, because now, at first, we can only plot from columns of a single MQTTTopic, then we can only later set other MQTTTopic's column as X or Y value. After this is dealt with, since, slowly, nearly every feature presented in the project proposal is implemented, we'll focus on improving, optimizing cleaning the code, making it easily readable, "comestible" for other developers. Writing documentation for the new classes and functions. Searching for bugs and correcting them, in order to LabPlot work smoothly. Writing tests for certain functions.

This is it for now guys. I will continue to work on the project with Kristóf and Alexander, who really help me a lot. I'm very thankful to them. When anything new will be finished and running I'll let you know. 

See you soon!
Bye!