MQTT - lekki protokół komunikacyjny
Dawid Pawlak , 21 czerwca 2024
![MQTT - lekki protokół komunikacyjny](https://impicode.pl/wp-content/uploads/2024/06/miniaturka-MQTT.jpg)
Podczas implementacji systemów IoT (Internetu Rzeczy) jednym z głównych wyzwań jest skuteczna komunikacja między urządzeniami. Dodatkowym utrudnieniem jest to, że wiele z tych urządzeń musi działać w trybie bardzo niskiego poboru energii (np. wodomierze na baterie) oraz bez gwarancji ciągłości połączenia. Aby sprostać tym wyzwaniom, stworzono lekki protokół komunikacji MQTT (z ang. Message Queuing Telemetry Transport) oparty na wzorcu Publish-Subscribe.
W celu wdrożenia internetu rzeczy (IoT) oraz przemysłowego internetu rzeczy (IIoT) stosuje się m.in.: protokół MQTT. Dopiero od kilku lat MQTT zyskuje na popularności w strefie przemysłowej. W dobie przemysłu 4.0 różnice między światami OT (technologii operacyjnych) a IT (technologii informatycznych) już nie stanowią przeszkody w celu podłączenia wszystkiego w jeden duży system.
Integracja systemów dzięki protokołowi MQTT
Integracja systemów sterowania i systemów informacyjnych umożliwia zaimplementowanie takich systemów jak MES, ERP oraz wykorzystanie Big Data i integracji sterowania ze sztuczną inteligencją. Można spotkać sterowniki PLC, które posiadają biblioteki umożliwiające komunikację przez MQTT. Również istnieją panele HMI, które posiadają zaimplementowaną obsługę tego protokołu.
Na rynku spotyka się również urządzenia zwane bramkami protokołów, które posiadają możliwość komunikacji z PLC wykorzystując obsługiwany przez niego protokół i przesyłają te dane do nadrzędnych systemów za pomocą np. MQTT. Dzięki czemu jest możliwość podłączenia do systemu informatycznych nawet starszych sterowników. Pozwalają one również na stworzenie tunelu VPN umożliwiającego zdalny dostęp do urządzeń podłączonych do sieci. Wykorzystanie tego typu urządzeń pozwala na silną integracją i wymianę danych między systemami i kolejnymi poziomami w piramidy automatyzacji.
![Piramida automatyzacji w fabryce](https://impicode.pl/wp-content/uploads/2024/06/piramida-automatyzacji-mqtt-1.png)
MQTT jest w stanie współpracować z protokołem OPC UA. Dzięki odpowiednim narzędziom można uzyskać wszystkie korzyści płynące z otwartej, rozproszonej architektury MQTT i łatwo zintegrować wszystkie dane wysyłane przez OPC UA z istniejącego sprzętu i oprogramowania. Jedną z podstaw przemysłu 4.0 jest zbieranie danych, powyższe protokoły mogą to zapewnić od najniższej warstwy typu czujniki do tych wyższych czyli systemy MES i ERP.
Protokół MQTT
MQTT jest bardzo lekkim protokołem komunikacyjnym opartym na wzorcu publisher/subscriber. Prace nad tym protokołem rozpoczęły się w IBM w 1999 roku. Dobrze sprawdza się w IoT, ponieważ nie wymaga dużej mocy obliczeniowej oraz zapewnia niezawodność.
MQTT jest również bardzo łatwy w diagnostyce, pomagają w tym takie programy jak MQTT Explorer. Pozwala on na śledzenie każdego powstałego tematu w sieci, podgląd wysłanych wiadomości wraz z czasem otrzymania oraz na publikację wiadomości w danym temacie. Dobrą praktyką jest stosowanie TLS z MQTT w celu zapewnienia zabezpieczonej transmisji danych w warstwie transportowej. Protokół ten bardzo upraszcza wymianę danych urządzenie-chmura i chmura-urządzenie.
Specyfikacja protokołu MQTT
MQTT to bardzo lekki protokół komunikacyjny oparty na wzorcu publisher/subscriber. Działa na warstwie TCP/IP, co zapewnia mu dużą przepustowość danych (np. 1 Gb/s).
W sieci MQTT istnieją dwa typy urządzeń:
- Broker MQTT – odpowiada za komunikację z klientami. W sieci może być wielu brokerów, które wzajemnie synchronizują dane między sobą, tworząc wrażenie, że cała sieć działa tak jak by był tylko jeden broker.
- Klient MQTT – łączy się z jednym brokerem i wymienia z nim wiadomości. Klientów może być nieograniczona liczba (np. milion). Klient w zalezności od wykonywanej akcji wysyłania/odbierania wiadomości pełni rolę publish/subscribe.
W tym protokole rolę serwera odgrywa tzw. broker MQTT, który informuje klientów subskrybujących dany temat o nowej wiadomości (zasada Topic Based). Dzięki takiemu rozwiązaniu nie ma cyklicznego odpytywania serwera przez klienta o nowe dane.
Wiadomości w MQTT są zorganizowane w hierarchii tematów, a nie według adresatów i nadawców. Oznacza to, że każda wiadomość nadawana przez klienta (publishera) musi mieć przypisany temat. Broker, otrzymując wiadomość, rozsyła ją do wszystkich klientów subskrybujących (subscribera) dany temat. Jeśli nie ma żadnego subskrybenta danego tematu, broker odrzuca wiadomość, chyba że nadawca oznaczył ją jako wiadomość do zachowania. W takim przypadku nowy subskrybent, zapisując się do danego tematu, otrzyma od razu ostatni zapisany komunikat w tym temacie.
![Przykładowe nazewnictwo tematów dla wykorzystania MQTT w smarthome](https://impicode.pl/wp-content/uploads/2024/06/MQTT_topics.jpg)
Pojedynczy komunikat może mieć rozmiar od 2 bajtów do 256 MB. Pierwotnie protokół nie był szyfrowany, co umożliwiało podglądanie danych, jednak obecnie można zastosować szyfrowanie TLS. Domyślnym portem TCP dla nieszyfrowanej komunikacji jest 1883, a dla szyfrowanej 8883.
W związku z tym, że MQTT działa na szczycie warstwy TCP/IP, wszystkie urządzenia wykorzystujące ten model mogą korzystać z biblioteki MQTT i posiadać możliwość komunikacji z określonymi brokerami. Najczęściej można spotkać, że wykorzystuje się wtedy komunikację asynchroniczną.
![Wykorzystanie MQTT](https://impicode.pl/wp-content/uploads/2023/12/MQTT_examples-1024x745.png)
Szybkość obróbki danych oraz maksymalna ilość obsługiwanych klientów może się różnić w zależności od wybranego serwera (brokera).
Jakość usług QoS - Quality of Service
Jako parametr tematu ustawia się jakość usług (QoS) co pozwala na skalowalność sieci w zależności od wybranego poziomu. W celu zapewnienia odpowiedniego poziomu publisher i subscriber muszą mieć takie same QoS dla danego tematu. Wraz ze wzrostem poziomu wzrasta niezawodność wymiany danych lecz spada jego wydajność:
- 0: at most once - Publisher wysyła wiadomość do brokera tylko raz i nie ma potwierdzenia zwrotnego otrzymania wiadomości, więc subscriber może otrzymać wiadomość lub nie.
- 1: at least once - Publisher wyśle do brokera co najmniej jedną wiadomość, jest ona ponawiana jeśli nie otrzyma potwierdzenia otrzymania od brokera, więc subscriber otrzyma wiadomość raz lub kilka razy
- 2: exactly once - Publisher wyśle wiadomość tylko raz do brokera, a subscriber otrzyma z pewnością tylko jedną wiadomość
Brokery MQTT
Jest wiele rodzajów brokerów, które można użyć jako obsługę sieci w protokole MQTT. Wybór występuje w zależności jakie wymagania i jaką rolę ma spełniać dany system. Większość z nich jest typu opensource jak i wspierają najpopularniejsze wersje MQTT czyli v3.1.1 oraz v5.0.
![Brokery MQTT](https://impicode.pl/wp-content/uploads/2024/06/brokerzy-mqtt.png)
- EMQX -najbardziej skalowalna platforma typu opensource, posiada obsługę bardzo wysokiej przepustowości co zapewnia opóźnienia na poziomie milisekund. Oferuje dużo funkcji dla przedsiębiorstw, integrację danych oraz usługę hostingu w chmurze.
- Mosquitto - lekki i bardzo popularny opensource broker, który ma możliwość zainstalowania na różnych systemach operacyjnych typu windows, linux, raspbian. Wspiera SSL/TLS oraz WebSocket jednak nie zapewnia wielowątkowości i klastrowania.
- VerneMQ - zaprojektowany do obsługi nawet milionów jednoczesnych połączeń zachowując wysyłanie wiadomości przy niskim opóźnieniu i dużej przepustowości. Wykorzystuje architekturę klastrową opartą na bibliotece Plumtree, która implementuje algorytm drzew rozgłoszeniowych.
- HiveMQ - szeroko stosowany w korporacjach jak i w fabrykach. Udostępnia klaster dostępności co umożliwia awaryjne przełączenie serwera w przypadku awarii. Oferuje funkcje bezpieczeństwa typu TLS, uwierzytelnienie i autoryzację, a nawet integrację z zewnętrznymi systemami bezpieczeństwa. Posiada również funkcje automatycznej skalowalności, powodujący dostosowanie się brokera do zmieniających się obciążeń przy braku interwencji człowieka.
- Kafka - zaprojektowana do przesyłania strumieni danych w czasie rzeczywistym z dużą przepustowością i niskimi opóźnieniami. Idealnie się sprawdza w systemach z dużymi zbiorami danych.
- RabbitMQ - popularny lekki opensource broker, którego można wdrożyć lokalnie jak i w chmurze. Można go dostosować w zależności od skali i dostępności. Obsługuje zaawansowane funkcje dostarczenia wiadomości i ich potwierdzenia.
- AWS IoT Core – zapewnia bezpieczną komunikację dzięki certyfikatom i szyfrowaniu TLS, oraz integrację z innymi usługami AWS dla zaawansowanego przetwarzania i analizy danych. Umożliwia zarządzanie milionami urządzeń oraz synchronizację ich stanów za pomocą "cieni" urządzeń, nawet gdy są offline. W małej formie odbiega od standardowej wersji 5.0 jednak wspiera wiele jego funkcjonalności.
- Azure Event Grid – umożliwia klientom MQTT komunikowanie się ze sobą i z usługami platformy Azure w celu obsługi rozwiązań Internetu rzeczy (IoT) . Wspiera protokół w wersji 3.1.1 i 5.0 Obsługuje uwierzytelnienia X.509 i szyfrowanie TLS, istnieje możliwość posiadania wielu sesji jednocześnie.
MQTT 5.0 - najnowsza wersja protokołu MQTT
Protokół MQTT w wersji 5.0 został zaprezentowany w 2019 roku i wprowadza kilka istotnych nowości i ulepszeń w porównaniu do poprzedniej wersji 3.1.1. Oto główne nowości w MQTT v5.0:
- Wsparcie dla właściwości wiadomości: MQTT v5.0 wprowadza pojęcie właściwości, które mogą być dodawane do wiadomości. Właściwości mogą zawierać dodatkowe metadane o wiadomości, takie jak identyfikator sesji, priorytet, TTL (czas życia), typ danych, i wiele innych.
- Rozszerzone powiadomienia o błędach: W MQTT v5.0 wprowadzono szczegółowe powiadomienia o błędach, które mogą zawierać dodatkowe informacje na temat przyczyny błędu oraz inne pomocne informacje diagnostyczne.
- Obsługa sesji klienta: Nowa wersja protokołu umożliwia bardziej zaawansowaną obsługę sesji klienta. Klient może przywrócić wcześniejszy stan sesji, co jest szczególnie przydatne w przypadku utraty połączenia.
- Obsługa składowania offline: MQTT v5.0 wprowadza możliwość przesyłania wiadomości, które będą przechowywane w serwerze, nawet jeśli klient jest offline. Klient może odebrać te wiadomości po ponownym połączeniu.
- Możliwość odrzucania wiadomości: Serwer może odrzucić wiadomość, jeśli nie spełnia ona określonych kryteriów, takich jak rozmiar, priorytet czy złożoność.
- Usprawnienia dotyczące zabezpieczeń: MQTT v5.0 wprowadza dodatkowe opcje zabezpieczeń, w tym lepsze mechanizmy autoryzacji i uwierzytelniania.
- Rozbudowana obsługa UTF-8: Nowa wersja protokołu rozszerza obsługę kodowania UTF-8, co pozwala na bardziej wszechstronne i bezpieczne przesyłanie znaków specjalnych i znaków niestandardowych.
- Połączenia MQTT poprzez protokół transportowy QUIC. MQTT przez QUIC zapewnia lepszą wydajność poprzez zmniejszenie liczby wymian podczas procesu łączenia, zmniejszenie ogólnych opóźnień i lepszą obsługę przeciążenia sieci.
Te nowości sprawiają, że MQTT v5.0 jest bardziej elastyczny, skalowalny i bardziej odpowiedni do zaawansowanych zastosowań IoT i komunikacji maszynowej.
MQTT-SN - MQTT dla sieci sensorów
MQTT-SN (MQTT for Sensor Networks) to zoptymalizowana wersja protokołu dla sieci bezprzewodowych o ograniczonych zasobach, takich jak sieci sensorów lub innych urządzeniach IoT działających na bateriach. Pierwszą stabilna wersja protokołu została zaprezentowana w 2007 roku.Podstawowym celem MQTT-SN jest umożliwienie efektywnej komunikacji w środowiskach o niskiej przepustowości i dużych opóźnieniach
Główne różnice obejmują zmniejszenie rozmiaru wiadomości i eliminacja konieczności stałego połączenia poprzez wykorzystanie UDP jako protokołu transportowego.
Główne cechy MQTT-SN:
- Krótsze nagłówki wiadomości i używanie ID tematu zamiast nazwy
- Wykorzystanie predefiniowanych tematów.
- Działanie w sieciach, gdzie połączenia mogą być przerywane i wznawiane ("śpiący" klienci).
- Współpraca z sieciami typu mesh.
- Wprowadza mechanizmy adresowania urządzeń za pomocą krótkich identyfikatorów.
- Wbudowane wykrywani urządzeń (discovery), co ułatwia dynamiczne dołączanie i konfigurację urządzeń w sieci.
- Obsługuje różne poziomy Quality of Service (QoS)
- Zoptymalizowany do pracy w dużych sieciach sensorów, gdzie liczy się minimalizacja zużycia energii i efektywne zarządzanie przepustowością
Architektura sieci w protokole MQTT-SN
W MQTT-SN istnieją trzy rodzaje urządzeń:
- MQTT-SN gateway - bramka działa jako pośrednik między klientami MQTT-SN, a brokerem MQTT. Dla mniejszych systemów istnieje możliwość integracji bramki z brokerem. Istnieją dwa typy bramek: transparentne gdzie każde połączenie MQTT-SN ma odpowiadające mu połączenie MQTT i agregujące gdzie wiele połączeń MQTT-SN współużytkuje jedno połączenie MQTT.
- MQTT-SN client - klientem jest każde urządzenie, które wysyła lub odbiera dane za pośrednictwem brokera/ bramki MQTT-SN.
- MQTT-SN forwarder - jeśli klienci nie posiadają bezpośredniego połączenia z bramką, mogą uzyskać do niej dostęp za pomocą forwardera, który enkapsuluje otrzymane ramki MQTT-SN przekazuje niezmienione do bramki. W przeciwnym kierunku otrzymane ramki danych z bramy są dekapsulowane i wysyłane do klientów bez zmian.
![architektura MQTT-SN](https://impicode.pl/wp-content/uploads/2024/06/Zrzut-ekranu-2024-06-18-110534.png)
Biblioteki do komunikacji poprzez protokół MQTT
W związku z tym, że MQTT posiada szerokie zastosowanie istnieją biblioteki opensource w różnych językach, które umożliwiają implementacje protokołu MQTT na własny użytek.
Język programowania | Nazwa biblioteki |
---|---|
Python | paho.mqtt.python |
C | wolfMQTT, paho.mqtt.c |
C++ | paho.mqtt.cpp |
C# | MQTTnet |
JavaScript | MQTT.js |
Java | paho.mqtt.java |
paho mqtt - biblioteka do komunikacji MQTT w języku python
Do zainstalowania biblioteki można wykorzystać pip:
pip install paho-mqtt
Po zaimportowaniu biblioteki istnieje możliwość połączenia się do brokera.
import paho.mqtt.client as mqtt
broker = "localhost" # MQTT broker address
port = 1883 # default port for MQTT
client = mqtt.Client() # creating MQTT client
client.connect(broker, port, 60) # connecting with broker
client.disconnect() # If you want it's easy to disconnect
Dla publikacji wiadomości kontynuacja kodu będzie następująca
topic = "test/topic1"
message = "Hello, MQTT!"
client.publish(topic, message) #publish message on topic
Natomiast dla subskrypcji tematu kod wygląda następująco
topic = "test/topic1"
client.subscribe(topic) # subscribe for topic
client.loop_forever() # Loop for subscribe topic
Podsumowanie
MQTT znajduje zastosowanie również w Przemyśle 4.0, gdzie różnice między technologiami operacyjnymi (OT) a technologiami informatycznymi (IT) przestają być przeszkodą w tworzeniu dużych jednolitych systemów. Klasyczne protokoły komunikacji przemysłowej, takie jak EtherNet/IP, ProfiNet/ProfiBus, Modbus i EtherCAT, są zaprojektowane do przesyłania konkretnych informacji między parami urządzeń, nie zaś do zbierania wszystkich informacji.
Sukces MQTT w zastosowaniach IoT oraz jego uniwersalność przyczyniły się do jego wykorzystania również w komunikacji między serwisami WWW, mikro serwisami oraz aplikacjami mobilnymi i serwerami, eliminując potrzebę tworzenia dedykowanych API. Warto jednak pamiętać, że wzorzec Publish-Subscribe nie zawsze jest odpowiedni dla każdej integracji, co oznacza, że nie zawsze warto stosować MQTT.