05 - Protokół MQTT

Systemy Wbudowane i Przetwarzanie Brzegowe

Politechnika Poznańska, Instytut Robotyki i Inteligencji Maszynowej

Ćwiczenie laboratoryjne 5: Protokół MQTT

Powrót do spisu treści ćwiczeń laboratoryjnych

Protokół MQTT

MQTT (z ang. Message Queue Telemetry Transport) jest to lekki protokół komunikacyjny bazujący na wzorcu klient-serwer, gdzie serwerem jest broker MQTT, a klientami są urządzenia, które chcą wysyłać lub odbierać wiadomości. Protokół ten został zaprojektowany z myślą o urządzeniach IoT cechujących się ograniczonymi zasobami. Protokół MQTT jest oparty na protokole TCP/IP, a jego głównym celem jest przesyłanie wiadomości pomiędzy urządzeniami z wykorzystaniem niewielkiej ilości poleceń oraz przy minimalnym obciążeniu sieci. Wiadomości te są wysyłane w postaci pakietów, które zawierają informacje o temacie, na którym została opublikowana wiadomość, a także jej treść. Co więcej, Wiadomości mogą być wysyłane w dwóch trybach: bez gwarancji dostarczenia (QoS 0) oraz z gwarancją dostarczenia (QoS 1). W pierwszym przypadku wiadomość jest wysyłana raz, a w drugim wiadomość jest wysyłana do momentu otrzymania potwierdzenia przez odbiorcę. Za przechowywanie wiadomości, które nie zostały jeszcze dostarczone do odbiorców, a także za przekazywanie wiadomości do odbiorców odpowiedzialny jest broker MQTT. Może on być uruchomiony na dowolnym urządzeniu, które obsługuje protokół TCP/IP.

Jako główne zalety protkołu MQTT można wymienić:

  1. łatwość wykorzystania,
  2. niewielkie wymagania względem zasobów,
  3. niski pobór energii,
  4. minimalizacja obciążenia łącza sieci,
  5. wymiana wiadomości praktycznie w czasie rzeczywistym,
  6. skalowalność.

Mosquitto - broker MQTT

Eclipse Mosquitto jest pośrednikiem wiadomości protokołu MQTT o otwartym kodzie źródłowym. Został przygotowany do wykorzystania dla szerokiego zakresu urządzeń i systemów operacyjnych zaczynając od komputerów jednopłytkowych o ograniczonych zasobach, a kończąc na serwerach chmurowych. Broker Mosquitto może być używany w różnych scenariuszach, od domowych zastosowań, przez urządzenia IoT, aż po rozwiązania przemysłowe. Dodatkowo pakiet ten zapewnia bibliotekę w języku C, służącą do tworzenie klientów MQTT oraz komendy mosquitto_pub i mosquitto_sub umożliwiające publikację oraz subskrypcję tematów z poziomu wiersza poleceń.

Aby zainstalować pakiet Mosquitto w systemie Linux należy użyć polecenia:

sudo apt install mosquitto

Następnie zweryfikuj jego działanie poleceniem: systemctl status mosquitto.

Dodatkowo, aby móc korzystać z komend mosquitto_pub i mosquitto_sub należy zainstalować dodatkowy pakiet przy użyciu komendy:

sudo apt install mosquitto-clients

Zadanie 1.
Korzystając z komend mosquitto_pub i mosquitto_sub przetestuj działanie protokołu MQTT wysyłając wiadomość MQTT test na temat swpb-<NUMER ZESTAWU>/mqtt_test.

Biblioteka Paho - klient MQTT

Eclipse Paho jest biblioteką w języku Python do obsługi klienta MQTT, umożliwiającą publikowanie wiadomości oraz subskrypcję tematów. Aby zainstalować bibliotekę należy użyć polecenia:

pip3 install paho-mqtt

W celu przetestowania działania biblioteki można wykonać poniższy skrypt:

import time

import paho.mqtt.client as mqtt


def main():
    client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
    client.connect('localhost', 1883, 60)

    topic_name = 'swpb-<NUMER ZESTAWU>/topic'

    # send a message to the specified topic every 1 second, 5 times in a row
    for i in range(5):
        # the four parameters are: topic, sending content, 
        # QoS (the quality of service level to use) and whether retaining the message respectively
        client.publish(topic_name, payload=i, qos=0, retain=False)
        print(f'Send {i} to {topic_name}')
        time.sleep(1)

    client.disconnect()


if __name__ == '__main__':
    main()

Przedstawiony kod źródłowy pozwala na nawiązanie połączenia z brokerem Mosquitto wykorzystując hosta lokalnego, a następnie na publikację wiadomości na temat swpb-<NUMER ZESTAWU>/topic co 1 sekundę, 5 razy z rzędu. W celu przetestowania działania skryptu należy uruchomić go w dwóch terminalach. W pierwszym terminalu należy uruchomić broker Mosquitto i nasłuchiwać tematu przy wykorzystaniu polecenia: mosquitto_sub. Natomiast w drugim oknie terminala należy uruchomić powyższy skrypt.


Zadanie 2.
Zmodyfikuj powyższy skrypt tak, aby była możliwość przesyłania wiadomości pomiędzy hostem (komputerem wykorzystywanym podczas zajęć) oraz Raspberry Pi. W podanym przypadku broker MQTT powinien znajdować się komputerze PC, a klient na Raspberry Pi.

Uwaga W przypadku wystąpienia błędu Connection refused należy dodać następujące linie do pliku /etc/mosquitto/mosquitto.conf:

allow_anonymous true
port 1883

Powyższe linie umożliwiają łączenie z brokerem bez podawania loginu i hasła wykorzystując port 1883. Aby wprowadzone zmiany zostały uwzględnione należy ponownie uruchomić serwis Mosquitto przy pomocy polecenia: sudo systemctl restart mosquitto.

Wizualizacja tematów MQTT

MQTT Explorer jest prostym programem do przeglądania i wizualizowania tematów MQTT. Aby zainstalować program w systemie Ubuntu należy skorzystać z polecenia snap install mqtt-explorer.


Zadanie 3.
Korzystając z biblioteki paho-mqtt, biblioteki gpiozero, oraz kodu programu przygotowanego podczas zajęć 03 - Raspberry Pi napisz program, który po naciśnięciu przycisku na Raspberry Pi będzie publikował wiadomość na temat swpb-<NUMER ZESTAWU>/button. Dodaj wizualizację tematu swpb-<NUMER ZESTAWU>/button do panelu wizualizacyjnego w programie MQTT Explorer.


Zadanie 4.
Wykorzystaj kod źródłowy z zadania z żyroskopem, przygotowany podczas laboratorium 03 - Raspberry Pi do publikowania informacji o prędkości kątowej odczytanej z urządzenia na temat swpb-<NUMER ZESTAWU>/gyro_<OŚ>. Dodaj do panelu wizualizację tematu w czasie rzeczywistym.


Zadanie 5.
Korzystając z przygotowanego skryptu do detekcji twarzy (zadanie 2, laboratorium 04 - Przetwarzanie obrazów z wykorzystaniem Raspberry Pi) napisz program, który po wykryciu twarzy na obrazie z kamery Raspberry Pi będzie publikował wiadomość na temat swpb-<NUMER ZESTAWU>/face zawierającą fragment obrazu z wykrytą twarzą. Dla uproszczenia komunikacji zapewnij aby wysyłany fragment obrazu miał rozmiar 100x100 pikseli.

Uzupełnij i skorzystaj z poniższego skryptu do subskrypcji tematu swpb-<NUMER ZESTAWU>/face i zapisu fragmentu obrazu do pliku. Skrypt powinien zostać wywołany po stronie hosta (komputera PC).

task5_subscriber.py
from datetime import datetime

import numpy as np
from PIL import Image
import paho.mqtt.client as mqtt


def on_connect(client, userdata, flags, rc):
    # This will be called once the client connects
    print(f"Connected with result code {rc}")

    ##### Student code #####

    topic_name = None

    ########################

    # Subscribe here!
    client.subscribe(topic_name)


def on_message(client, userdata, msg):
    ##### Student code #####
    # odczytaj zawartość wiadomości (msg.payload) i zapisz ją do pliku

    filename = None

    ########################

    print(f"Message received [{msg.topic}]. Saved as {filename}.")


def main():
    client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)

    ##### Student code #####
    host_name = None
    ########################

    client.connect(host_name, 1883, 60)

    client.on_connect = on_connect
    client.on_message = on_message

    client.loop_forever()


if __name__ == '__main__':
    main()