====== IOT4: Connecting to the MQTT and subscribing to the messages ====== In the following scenario, you will learn how to connect to the MQTT broker and subscribe to the message. ===== Prerequisites ===== To implement this scenario, it is necessary to get familiar with at least one of the following scenarios first: * [[en:iot-open:practical:hardware:sut:esp32:emb5_1|]], * [[en:iot-open:practical:hardware:sut:esp32:emb6_1|]], * [[en:iot-open:practical:hardware:sut:esp32:emb7_1|]], and obligatory: * [[[en:iot-open:practical:hardware:sut:esp32:iot_2|]]. There are many implementations of the MQTT protocol, but we will use the following library: lib_deps = knolleary/PubSubClient@^2.8 ===== Suggested Readings and Knowledge Resources ===== * [[en:iot-open:introductiontoembeddedprogramming2:cppfundamentals]], * [[en:iot-open:hardware2:esp32|]], * [[en:iot-open:practical:hardware:sut:esp32|]], * [[en:iot-open:iotprogramming2:espressif_networking|]]. ===== Hands-on Lab Scenario ===== Note—this scenario can be used in tandem with [[[en:iot-open:practical:hardware:sut:esp32:iot_3|]] to build a publish-subscribe solution using two devices (two laboratory nodes: publisher and subscriber). You need to book two devices then and develop them in parallel. Watch the result validation section for more options. ==== Task to be implemented ==== Connect to the "internal IoT" WiFI access point as presented in the scenario [[[en:iot-open:practical:hardware:sut:esp32:iot_2|]]—present connection status on display. Once connected to the networking layer (WiFi), connect the MQTT client to the MQTT broker and present the connection status on the display, then subscribe to the MQTT message of your choice, identified by the topic (may include wildcards). Present the message payload on the display. MQTT clients are identified by their name, so use a unique one, e.g., the end of the IP address assigned, your unique name, etc. It is essential because if you accidentally use someone else's name, then you will mess with messages, and your MQTT client will be instantly disconnected when another one with the same name connects! ==== Start ==== Check if you can clearly see a full display (of your choice) in your video stream. Book a device and create a dummy Arduino file with ''void setup()...'' and ''void loop()...''. \\ Implement a connection to the "internal IoT" network as a client. Refer to the supervisor or the technical documentation on credentials (SSID, passphrase). We do not provide the exact code on how to connect to the WiFi as it is a part of [[[en:iot-open:practical:hardware:sut:esp32:iot_2|]] scenario. \\ ==== Steps ==== === Step 1 === Once the device is booked, check if your display of choice is visible in the camera's FOV.\\ Refer to the hardware documentation and ensure an understanding of the network infrastructure you're interfacing with.\\ Implement the code to display on the selected device.\\ Connect to the WiFi in the STA mode (as a client) and ensure the connection is OK and you got an IP from the DHCP server.\\ Note - as you're consuming messages here, you either need to have implemented and running publisher as a separate device (as described in the scenario [[[en:iot-open:practical:hardware:sut:esp32:iot_3|]]) or to connect to the MQTT broker using some software, as described in the results validation section below. === Step 2 === Include the MQTT implementation library header in your code: #include === Step 3 === Declare necessary addresses, constants, etc.: IPAddress mqttServer(127,0,0,1); //change it to the MQTT broker IP #define mqtt_user "mqtt user" #define mqtt_password "mqtt password" #define mqtt_client_id "some_unique_client_id" #define mqtt_topic "/sample/topic/comes/here/change/it/please" Refer to the technical documentation (nodes) or the supervisor's guidance if working in the interactive mode to obtain the ''mqttServer'' IP address, the ''mqtt_user'' and ''mqtt_password''.\\ **Remember to choose some unique client ID and topic corresponding to the one that is being published to the MQTT broker!** You can use wildcards when subscribing to the broker. Still, please note that using a single star to subscribe to ALL MQTT messages is not a good option as there are many technical topics published by the broker internally, so the number of messages incoming every second to your solution can quickly overwhelm your device's resources. === Step 4 === Declare WiFi communication client and MQTT communication client: WiFiClient espClient; PubSubClient client(espClient); Note that your clients are not yet online! === Step 5 === Declare an asynchronous handler function that will be called every time the client receives the MQTT message: void callback(char* topic, byte* payload, unsigned int length) { //prepare a code to display the message (payload) to the display } Note that the payload is a byte array, so you may need to copy it to process it outside the callback function (e.g. using ''memcpy'').\\ Also, note that you may distinguish which message you're handling if you subscribe using wildcards: the ''topic'' parameter provided the exact topic as it was published to the MQTT broker by the publisher. === Step 6 === Set MQTT client's configuration (proposed in the ''void setup()'' function: ... client.setServer(mqttServer,1883); //default port is 1883, change if needed client.setCallback(callback); //a callback function to handle incoming messages //as declared in Step 5 ... === Step 7 === Finally, connect the MQTT client to the MQTT broker and publish a message (sample code, adjust to your case): while (!client.connected()) { if (client.connect(mqtt_client_id,mqtt_user,mqtt_password)) { // Drop some info on the display that the MQTT broker is connected client.subscribe(mqtt_topic); } else { int status = client.state(); //read error code //present it on the display to trace/troubleshoot } } In the case, the client does not connect to the MQTT broker, the ''client.state();'' returns an int that can be interpreted as below: // Possible values for client.state() #define MQTT_CONNECTION_TIMEOUT -4 #define MQTT_CONNECTION_LOST -3 #define MQTT_CONNECT_FAILED -2 #define MQTT_DISCONNECTED -1 #define MQTT_CONNECTED 0 #define MQTT_CONNECT_BAD_PROTOCOL 1 #define MQTT_CONNECT_BAD_CLIENT_ID 2 #define MQTT_CONNECT_UNAVAILABLE 3 #define MQTT_CONNECT_BAD_CREDENTIALS 4 #define MQTT_CONNECT_UNAUTHORIZED 5 === Step 8 === Run client handling routine in the loop to receive messages: void loop() { if (!client.connected()) { //reconnect the client (and eventually the WiFi if gone) } client.loop(); //process incoming MQTT messages } ==== Result validation ==== You should be able to connect to the WiFi and MQTT broker (verified by the status present on the selected display) and then subscribe to the message (identified by topic). Depending on whether you're fully remote or able to access our networks with an additional device, you need to implement a publisher on another laboratory node (as present in the scenario [[[en:iot-open:practical:hardware:sut:esp32:iot_3|]]) or use MQTT Explorer (or any other application capable of connecting to our MQTT Broker) to send messages that you subscribe to. ===== FAQ ===== **My MQTT client disconnects randomly**: The most common reason is you're using a non-unique MQTT client name. Please change it to some other (even random generated) and give it another try.\\ **How do I send messages to which I am subscribed?**: Use a software client, such as [[http://mqtt-explorer.com/| MQTT Explorer]], if you're able to access the "internal IoT" network (you're in the range of the network). If you're remote, the only way is to book another device and implement a client publishing a message with the appropriate topic, as presented in the scenario [[[en:iot-open:practical:hardware:sut:esp32:iot_3|]]. Our MQTT broker is also visible in the campus network on the wired interfaces so that you can access it, e.g. via EduVPN or from the laboratory computers. Refer to the supervisor for IP and credentials.\\ **Do I need to authorise to publish and subscribe?**: Yes, you do. The supervisor provides the user and password on demand, also presented in the Node's technical documentation. ===== Project information ===== {{:en:iot-open:logo_iot_200_px.png?200|}}\\ This Intellectual Output was implemented under the Erasmus+ KA2.\\ Project IOT-OPEN.EU Reloaded – Education-based strengthening of the European universities, companies and labour force in the global IoT market.\\ Project number: 2022-1-PL01-KA220-HED-000085090. **__Erasmus+ Disclaimer__**\\ This project has been funded with support from the European Commission. \\ This publication reflects the views of only the author, and the Commission cannot be held responsible for any use that may be made of the information contained therein. **__Copyright Notice__**\\ This content was created by the IOT-OPEN.EU Reloaded consortium, 2022,2024.\\ The content is Copyrighted and distributed under CC BY-NC [[https://en.wikipedia.org/wiki/Creative_Commons_license|Creative Commons Licence]], free for Non-Commercial use.
{{:en:iot-open:ccbync.png?100|}}