What is MQTT (Message Queues)? Well I could write up and down about just that subject, but other people have done that before and are properly better at explaining it than me. Google it (Heck use Bing if you are feeling lucky today).
Lazy? Okay then. It is a small footprint protocol on top of the TCP/IP protocol and is for sending information. Mostly used on embedded devices (IoT) where CPU power is limited. You can not have an Intel octa-core powerhouse, when it has to run for a year on a coincell battery.
REST is not an option, it is way to resource heavy for simple sensor data.
One of the things you need to decide when using MQTT is what QoS you want to use.
What is QoS (Quality of Service)?
The QoS level is an agreement between sender and receiver of a message regarding the guarantees of delivering a message. There are 3 QoS levels in MQTT:
- At most once (0)
- At least once (1)
- Exactly once (2)
Why is this important for us? Well it depends on what you use MQTT for. If you just want to record temperatures from 4 different sensors in the office like me, then it does not matter if one measurement does not get though, there will be another one in 30 secs anyway. So I use level 0. But I can easily see cases in NAV where you would use level 2.
What else am I using MQTT (Message Queuing Telemetry Transport) for?
Temperature sensors and a doorbell of course.
Hold on! A doorbell?! Yep. I have modified an off-the-shelf wireless doorbell to send a MQTT message when someone pushes the button outside.
Beside a lot of other things happening when the button is pressed (Smartwatch notifications and other stuff) an entry is added to my MQTT Log table in my local NAV sandbox.
Why? Stop asking that. Because I can!
This blog is not about showing what you can use it for, but rather that you can. Let me handle the “how”, if you are here you properly have the “why”.
“Less mumbling, example please”.
First a pre-requirement, a MQTT library. I just searched for “MQTT .Net” on Google and one of the hits were this m2mqtt.
But how do you get what you need? Check the page for a Nuget package link (check under Download). You can use VS or .Net SDK for installation, but the easiest way to do it is to press the “Manual download” link to the right on nuget.org.
Then you will get a “.nupkg” file – this is actually just a 7z file. Unpack it to a folder of your choice.
Copy “lib\net45\M2Mqtt.Net.dll” to the Service Addins folder.
Hint: You can find a lot of inspiration on Nuget this way.
Now it is time for C/AL (Finally, some would say).
I created a new Codeunit and made it a singleinstance CU.
Now add a few variables to the CU:
Remember to set the WithEvents property on the MQTT variable to True.
First I setup the MQTT broker/server I want to connect to – in this example it is an Mosquitto server running on an Asus Tinker Board.
I choose NAVClient as ID, but you can use anything. Messages sent from here will be stamped with this ID.
Then I add what Topics to subscribe to.
To do this you need two Arrays: a string and a byte array. This is because the subscription is based on pairs of a Text and a Byte; the Text indicates the topic and the byte the QoS Level.
I assign the array types by passing either an empty Text or Byte var. The “4” indicates the array size. Then just fill the array – remember to start from Index 0.
I am using a Page to show the output in this demo. So I call f_Connect() on the OnInit() of the page and just run the page.
But hold on, you also need to handle when messages arrive. First we create a couple of functions to handle each type of message.
Then we call them based on the Topics the messages arrived from.
I just insert the string directly – in a real-world scenario you would properly handle the message instead of just storing it raw.
I presume in my example that the payload is a simple string. You can actually have way more in it. The Topic maximum size is 65536 bytes, and the Payload/Message limit is 268,435,456 bytes. More than enough room for most XML or JSON payloads.
Best practice is plain-text payloads, so if you need to transfer binary data, just convert it to a BASE64 String and embed it in the JSON.
On a later blog post, there will be an example on how to use an XMLport to exchange shipping notices between two NAV setups, though MQTT.
But for now you can check the attached source code for an example on hold to pass an xmlport directly into a message.