MQTT

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
MQTT klient je dostupný pro První i Druhou Produktovou Řadu zařízení SDS.


MQTT is a Client Server publish/subscribe messaging transport protocol.

MQTT je tedy jednou z možných variant jak přenášet údaje mezi SDS ("MQTT client") a centrálním serverem ("MQTT broker").

SDS podporují MQTT komunikaci za předpokladu, že máte nainstalován aktuální firmware.

MQTT komunikace se provádí pomocí příslušných SDS-C / FULL-C funkcí.


K čemu je MQTT dobré

Postupem času se MQTT ustálilo jako nejjednodušší řešení centrálního bodu pro sběr a distribuci jednoduchých dat a údajů.

Samozřejmě pro složitější aplikace už není vhodný, ale např. pro malou domácí automatizaci, v rámci domácí sítě, je to akorát.

Modelový příklad: máte doma řadu chytrých zařízení které chceta navzájem provázat a to ideálně bez přidaných nákladů. Pokud tato zařízení umí komunikovat pomocí MQTT přes TCP protokol, pak vám stačí spustit MQTT Broker (např. na rPI) a všechna zařízení v tu chvíli mohou spolu instantně komunikovat stylem postupného předávání hodnot.

MQTT pracuje na principu "položka - hodnota" (TOPIC - VALUE). Je to takový neomezený seznam o dvou sloupcích a mnoha řádcích (tolik řádků kolik různyćh položek). Do tohoto seznamu můžete odkudkoliv zapisovat a tím měnit jednotlivé hodnoty nebo přidávat nové položky. A také se můžete jako klient přihlásit k odběru změn (jiný klient zapíše novou hodnotu a připojení přihlášení klienti ji dostanou).

Každou položku je potřeba založit - to se stane automaticky při prvním zápisu (klient vždy zapisuje ten pár Topic-Value). Pokud už položka existuje, tak se při zápisu jen změní její hodnota.

Zpátky k příkladu.

Mějme spoustu modulů SDS které jsou všichni MQTT klienti, připojení ke společnému MQTT brokeru (server spuštěný např. na rPI). První SDS měří teplotu a pravidelně publikuje její hodnotu na MQTT broker, do položky "teplota1".

Deset dalších SDS je přihlášeno k odběru (subscribe) této položky "teplota1", a každé toto přihlášené SDS obdrží všechny nové zapsané hodnoty do této položky (které tam píše to první SDS) a na základě této hodnoty mohou provádět nějakou regulační činnost.

Tím se elegantně vyřešení komunikace z prvního SDS do dalších deseti, aniž by se muselo řešit jak to složitě bez MQTT provádět.

Samozřejmě toto je jen jednoduchý příklad, protože typicky MQTT systém bývá mnohem složitější - ale stále stejně snadno realizovatelný (univerzální princip Publish/Subscribe).

Vždy je potřeba, aby v SDS byl nahrán aktuální FW, který MQTT podporuje - pro SDS-C to lze ověřit přes sys[2199].


Příklad: SDS a Node-RED

Node-RED je jedním z velice oblíbených nástrojů pro beznákladovou realizaci složitější automatizace.

Ze systému [Node-RED] lze SDS plně ovládat - a to formou obousměrné komunikace přes MQTT.


Příklad: SDS a SolPIPlog

SolPIPlog je program pro monitorování FVE měničů (MPP Solar). SDS umí s tímto programem komunikovat přes MQTT. Příkladem je např. přepínání režimu (SOL/BAT) podle stavu HDO (který SDS zjistí přes svůj optovstup, kam se připojí kontajt relé od HDO).

Samozřejmě MQTT má neomezené možnosti a dva zmíněné příklady jsou opravdu jen nástřelem toho, co se dá realizovat.


Specifikace

SDS podporuje základní MQTT 3.1.1 protokol (Level4), nad TCP; toto je současný průmyslový standard. Implementace odpovídá http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html .

Klíčové funkcionality protokolu, které lze vyvolat z SDS programu:

  • CONNECT
  • DISCONNECT
  • PUBLISH
  • SUBSCRIBE (+ ACK)
  • UNSUBSCRIBE (+ ACK)
  • PINGREQ (+ PINGRESP)

Interně SDS automaticky provándí MQTT PING směrem do Broker.

Všechny texty jsou přenášeny ve formátu UTF-8.

V tuto chvíli není implementováno WILL MESSAGE.

QoS je v režimu 0x00.

Keep-Alive je ve výchozím nastavení 120 sekund a odesílání PINGREQ tedy co 96 sekund. Toto nastavení lze změnit při připojení.


Použití

Použití MQTT máte v rámci SDS plně pod svou kontrolou, tím, že si vše ovládnete ve svém programu. MQTT tedy v rámci SDS není uzavřeno do webového rozhraní apod., právě naopak, je plně k dispozici.

Standardní postup je následující:

  • 1. otevřete spojení z SDS (klient) na MQTT server (broker)
  • 2. - podle potřeby odešlete data z SDS na server (funkce PUBLISH)
  • 3. - podle potřeby se přihlásíte k odběru dat ze serveru (funkce SUBSCRIBE)
  • 4. až nebude spojení na server potřeba, odpojíte se

Všechny čtyři body se ovládají voláním patřičných funkcí v programu, s vhodnými parametry, a se správným zpracováním výsledných hodnot.

Dokud není zavolaná funkce hotová (to si musí program hlídat čtením patřičného sys[]), nesmí být zavolána další !

Pozor: při každém novém startu SDS-C programu je MQTT Broker odpojen. Váš SDS-C program se tedy musí vždy nejprve připojit, aby mohl využívat další funkce pro komunikaci s brokerem.


Jak vyvíjet a testovat

Vývoj a testování vždy předchází plnému nasazení - je dobré si svůj program nejprve odladit.


Simulátor SDSC.exe

V okně "NETWORK" otevřete kartu "MQTT".

Zde lze simulovat chyby (neprovedené připojení, odmítnutí hesla) a tak odzkoušet robustnost svého SDS-C programu.

Dále je zde seznam položek (Topics) které jednak SDS-C program publikoval, a také ke kterým je SDS-C program přihlášen (subscribe).

Přihlášené položky jsou označeny číslem indexu do tabulky (#1 .. #31 - pozor, počet je různý pro různé SDS moduly).

Změna hodnoty (value) pro každou položku je možná (buď poklepáním na řádek v seznamu, nebo tlačítkem "broker publish"). Ve všech těchto případech, po provedení změny, dojde k odeslání nové hodnoty do SDS-C programu (ale to samozřejmě jen za předpokladu že program je na daný topic přihlášen).


Skutečné SDS

Fyzický modul SDS lze samozřejmě připojit k reálnému MQTT brokeru.

Při vývoji se může hodit pomocná stránka: 192.168.1.250/cgi_mqtt .


MQTT Broker snadno a rychle

Nainstalujte si Mosquitto MQTT broker na svůj počítač (Windows / Linux). Ověřeno to máme na Win7, Win10, a také na rPI a odroid.

https://mosquitto.org/download/

Pro Windows, pak stačí spustit "C:\Program Files\mosquitto\mosquitto.exe", který (při spuštění bez parametrů = výchozí stav) otevře prázdné konzolové okno a zůstane aktivní. V tuto chvíli máte na svém Win PC aktivní MQTT broker, a to na "localhost:1883" (dejte si pozor na firewall).

Samozřejmě pro Linux, rPI atd. platí jiný vhodný postup, ale výsledek je stejný.

SDS pak lze na tento broker (server) připojit a provádět Publish a Subscribe.

Pro kontrolu toho, jak se server chová a co vše v něm je (co tam SDS nebo jiní klienti poslali), tak je k dispozici vynikající nástroj MQTT Explorer.

http://mqtt-explorer.com/

Je opět zdarma a důrazně doporučuji se s ním seznámit a používat to.

Umožňuje jednak plnou kontrolu položek (Topics) a jejich hodnot, ale také umí tyto položky ručně vytvořit nebo do nich zapsat (což se pak přenese do klientů kteří mají Subscribe na danou položku). Zkrátka ideální pro vývoj a testování.


MQTT broker v Internetu

Pro bezpečnost je ideální mít svůj vlastní MQTT broker ve své síti. Stačí koupit malý Linuxový počítač (např. rPI) a tam MQTT broker nainstalovat a je to.

Pokud si provedete vhodné nastavení své sítě a firewallu, lze k tomuto brokeru přistupovat i z Internetu.

Toto je často žádoucí, např. máte-li svou domácí automatizaci která běží na MQTT a chcete ji dálkově ovládat a kontrolovat, např. z mobilní aplikace.

Druhá možnost je využít nějaký veřejný MQTT broker, je jich plný Internet - ale toto přináší řadu bezpečnostních rizik a nedoporučujeme to. Když už mít broker na Internetu, tak na svém vlastním serveru.

Důležité je, že SDS (MQTT klient) používá připojení k MQTT brokeru jako plain TCP, tedy nepoužívá v této verzi SSL/TLS (to až v budoucnu SDS třetí produktové řady).

Proto je důležité umístit MQTT broker do vnitřní sítě (stejná síť na které jsou SDS), která je oddělena od sítě Internet bezpečným a spravně nastaveným firewallem.

Takový MQTT broker pak může snadno obsluhovat všechny SDS a další klienty přes plain TCP spoje, a do Internetu může mít dodatečně zabezpečený TLS MQTT spoj. Takhle to nastavit jde.


Implementace v SDS-C a FULL-C

Názvy funkcí a postupy jsou pro oba programovací jazyky shodné.

Rozdíl je v indexech:

  • SDS-C má informace a údaje v sys[2199] až sys[2321]
  • FULL-C má informace a údaje dostupné přes get funkci od indexu 12199 až 12321.

Všimněte si, že význam indexů pro SDS-C (2199 až 2321) je 1:1 namapován na FULL-C indexy (12199 až 12321 - tedy FULL-C má pouze aplikováno pevné posunutí o 10000).

Detaily pro implementaci ve FULL-C (a příklady) naleznete zde.


Vzorový program SDS-C - připojení a Publish

Následující program je pro SDS První Produktové Řady, které se programují jazykem SDS-C.

MQTT Broker je spuštěn (např. na rPI) na adrese 192.168.4.249 (a TCP portu 1883). Náš klient (SDS) se přihlásí jako uživatel "sds1234" s heslem "password", a následně provede 2x PUBLISH a nakonec se odpojí.

// network communication shall be started only after the SDS is connected to network (ethernet is up)
 echo('waiting for network availability');
 
waiting_ethernet:
 if (sys[24] == 0) goto waiting_ethernet; // 0 = no ethernet
 if (sys[27] == 0) goto waiting_ethernet; // 0 = no IP address
 
 // OK, now we have an ethernet connection up and running

 ...

 // EXAMPLE START:


 // connect on start
 echo('connecting to MQTT Broker...');

 //           ip   ip   ip ip   port  client-id          username   password    keepalive(sec)
 mqtt_connect(192, 168, 4, 249, 1883, 'sds-client-1234', 'sds1234', 'password', 120);

 // wait for a complete connection
 label waiting_for_mqqt_conn:
  
 // error - failed ?
 if (sys[2200] <= 0) goto mqtt_conn_fail; // error ? (any negative number is error code)

 // done - connected ?
 if (sys[2200] != 4) goto waiting_for_mqqt_conn; // success ? (yes only if == 4)

 // test the CONNACK result - see "3.2.2.3 Connect Return code" - we expect "0" as OK

 if (sys[2201] != 0) goto mqtt_conn_fail; // is broker's result code OK ? (OK only if == 0)

 // connected (CONNACK result is 0x00)

 echo('connected to broker: OK');

 //

 
 // example: let us publish three various topics

 mqtt_publish('sds/teploty/cidlo1', sys[310]); 
 w1: 
 if (sys[2200] < 0) goto mqtt_conn_fail;    // disconnected ?
 if (sys[2202] == 1) goto w1;               // still working ?
 if (sys[2202] != 2)                        // success ?
  { echo('publish error = ', sys[2202]); };

 mqtt_publish('sds/teploty/cidlo2', sys[311]);
 w2: 
 if (sys[2200] < 0) goto mqtt_conn_fail;    // disconnected ?
 if (sys[2202] == 1) goto w2;               // still working ?
 if (sys[2202] != 2)                        // success ?
  { echo('publish error = ', sys[2202]); };
 
 mqtt_publish('sds/teploty/text_xyz', 'hello:', 1234, 'there');  // <- you can pass more than one parameter (all params will get joined together)
 w3: 
 if (sys[2200] < 0) goto mqtt_conn_fail;    // disconnected ?
 if (sys[2202] == 1) goto w3;               // still working ?
 if (sys[2202] != 2)                        // success ?
  { echo('publish error = ', sys[2202]); };

 // ...

 // and let us subscribe to a topic
 
 mqtt_subscribe(1, 'ha/output/q1/state');
 w4:
 if (sys[2200] < 0) goto mqtt_conn_fail;   // disconnected ?
 if (sys[2202] == 4) goto w4;              // still working ? 
 if (sys[2202] != 8)                       // success ?
  { echo('sub error = ', sys[2202]); };

 //...


 // finally, once done - close the connection 

 // go
 mqtt_disconnect();

 // we shall wait until the connection is properly closed
wait_for_disconnect:
 if (sys[2200] <= 0) goto error;                // error ?
 if (sys[2200] == 8) goto wait_for_disconnect;  // success, or still working ?

 // done !
 echo('DISCONNECTED from broker');

 wait(250);

 // EXIT the example - we are DONE
 return;


 // error handling
 label mqtt_conn_fail:
 echo('unable to connect... error=', sys[2200],' connack=', sys[2201]);

 // error handling
 label error:
 echo('error');


Pozn. mqtt_connect() - parametry:

  • keepalive - hodnota 0 použije výchozí nastavení (120 sec), další platné hodnoty jsou 15 až 600 (sekund).
  • client-id - vždy by to měla být unikátní identifikace vašeho SDS, typicky přidělena správcem MQTT Broker


Vzorový program FULL-C - připojení a Publish

Příklady pro FULL-C jsou na samostatné stránce: FULL-C: MQTT_functions.

Princip použití MQTT klient ve FULL-C je identický jako pro SDS-C, jen pozor na pevně posunuté indexy.


Odesílání hodnot do Brokeru

Je-li SDS úspěšně připojeno, pak lze odeslat libovolnou hodnotu libovolné položky (Topic) z SDS do Brokeru, který si ji uschová a který ji také předá všem dalším připojeným zařízením, které jsou k dané položce (Topic) přihlášeny (subscribed).

Názvy položek musí být centrálně koordinované, aby celá akce dávala smysl. To už je na vás.

Omezení je na současnou velikost (společnou délku) názvu položky (Topic Name) a její hodnoty (Value), což se spolu musí vlézt do nejvíce cca 1465 znaků.


POZOR - před, a po zavolání funkce mqtt_publish() je žádoucí testovat stav sys[2202] ( respektive pro FULL-C: get(12202) ), a dokud tam nebude očekávaný výsledek nebo chybový kód, tak nevolat další mqtt_xxx funkce !

Vždy musíte ve svém programu správně reagovat na všechny chybové stavy ve sys[2202] (respektive get 12202), je to váš úkol, SDS to za vás řešit nebude (a tím vám svazovat ruce).

Funkce mqtt_publish() umožňuje skládání parametrů - první parametr je vždy název položky (topic name), a všechny zbylé jsou převedeny na společnou hodnotu (value).

// you can use multiple parameters for the VALUE
   // only the very first parameter represents a TOPIC NAME

   mqtt_publish('topicname', '1234', 'abcd', 'efgh', 'xyz');

   // result: 'topicname' gets a new VALUE of '1234abcdefghxyz'


Příjem hodnot z Brokeru

SDS se umí přihlásit na odběr hodnot pro různé položky. Pokud je SDS takto přihlášeno, tak jakákoliv změna hodnoty na straně Brokera (např. způsobena zápisem jiného zařízení, aplikace, atd.), se prakticky ihned přenese do SDS, kde si aktualizovanou hodnotu může váš program zpracovat dle potřeby.

Přihlášení se provádí pomocí funkce mqtt_subscribe(). Aby se to povedlo, musíte být úspěšně připojeni k Brokeru.

Přihlásit se lze k libovolné položce (Topicu), jejíž celý textový název musíte samozřejmě znát.

Pozor - všechny názvy položek jsou citlivé na malé a velké písmena (nejsou záměnné).

Pozor - platné indexy jsou 1 až N (protože index 0 je vyhrazený pro aktuálně interně zpracovávanou položku, nelze jej využít pro program).

PŘÍKLAD V SDS-C:

// SDS-C

 // expectation: broker has to be already connected (see the previous example)

 // let us:
 //  subscribe to a topic named: "control/rele1", and let us assigned it a local index of 1

 mqtt_subscribe(1, 'control/rele1');

 // wait for the successful subscribe 
 wS: 
 if (sys[2200] < 0) goto mqtt_conn_fail; // disconnected (if any negative number)
 if (sys[2202] == 4) goto wS;            // still working... (done when != 4)
 if (sys[2202] != 8)                     // success ? (only if == 8, otherwise error or failure)
 { 
   // FAILED -> not subscribed !
   echo('sub error = ', sys[2202]); 
   return;
 };

 // now, as we are subscribed, we will watch for any incoming update (value change), as in the following example:

 var last1;
 last1 = 0;

loop:

 // any change ? (any new message?)
 if (last1 != sys[2291])  // sys[2291] is a timestamp for index #1
  {
    // store so we can compare it later, again
    last1 = sys[2291];

    // use the new value!
    echo('TOPIC #1: "',sys[2211],'" update to: "',sys[2251],'" ');
  };

 if (sys[2200] < 0) goto error; // disconnected

 // continue loop
 goto loop;

 
 // ...


 // once we are not interesed in the topic any more, we can unsubscribe
 mqtt_unsubscribe_index(1);

 // handle the job
 if (sys[2200] < 0) goto error; // disconnected
 wU: 
 if (sys[2202] < 0) goto error; // error (if any negative number)
 if (sys[2202] == 16) goto wU;  // waiting until done (done when result == 32)

 echo('unsubscribed');

Příklad přehledně ukazuje, jak systém funguje. Pro jednoduchost je zde hrubá nekonečná smyčka (loop) ale každý jistě vidí i své, jiné řešení vhodnější pro svůj vlastní program.

Základní princip je v používání SDS indexů #1 až #31, kterým přiřazujeme jednotlivé přihlášené položky (subscribed topics).

Je na tvůrci programu, jak indexy využije a kterému indexu přiřadí jaký název položky (topic name). A konkrétní názvy položek vždy záleží na celém systémovém návrhu, kde SDS je zcela transparentní.

Z principu MQTT protokolu, jsou hodnoty vždy uvedeny jako textový řetězec. Např. pomocí SDS-C funkce atoi to ale snadno převedete na číslo, se kterým lze dále pracovat, je-li to potřeba.

Funkce umožňuje skládání parametrů - první parametr je vždy index, a všechny zbylé jsou převedeny na název položky (topic name).


POZOR - před, a po zavolání funkce mqtt_subscribe() je žádoucí testovat stav sys[2202] (respektive get 12202), a dokud tam nebude očekávaný výsledek nebo chybový kód, tak nevolat další mqtt_xxx funkce !

Vždy musíte ve svém SDS-C programu správně reagovat na všechny chybové stavy ve sys[2202] (respektive get 12202), je to váš úkol, SDS to za vás řešit nebude (a tím vám svazovat ruce).


Maximální velikosti (položky subscribe tabulky)

Stav 06/2020

Maximální délka názvu položky (Topic Name) pro přihlášené položky je 128 znaků.

Maximální délka obsahu hodnoty (Value) pro přihlášené položky je 384 znaků.

Informace:

Chystáme úpravu aby byl aplikován jen celkový limit (512 znaků) a ne tyto dva samostatné limity. V současném FW ale zatím stále platí.

Toto omezení se vztahuje jen na Subscribe Tabulku a neplatí pro PUBLISH (tam jsou omezení jiná viz text výše).


Volba indexů

Je čistě na vás zvolit si každý použitý index do tabulky (tzn. první parametr do funkce mqtt_subscribe).

Pokud provedete přihlášení s jedním stejným indexem na více různých položek (topics), tak SDS daný požadavek do Brokeru odešle (pro každou žádost). Nicméně SDS si uschová ve své paměti jen tu nejposlednější pro každý index.

Takže si dejte pozor, aby jste si pro každý index provedli přihlášení (subscribe) jen a právě jednou.

Tabulka je vždy vyčištena při odpojení od Brokeru.

Nechcete-li využívat této pomocné tabulky, nemusíte; ale ztrácíte výhodu uchování poslední zaslané hodnoty pro každou položku v této tabulce uschovanou.

SDS samozřejmě dává programu k dispozici všechny příchozí zprávy z Brokeru, nicméně pokud jich přijde více za sebou v rychlém sledu, nemusíte je zdaleka stačit programem zpracovat. A právě proto je zde na pomoc tento systém s tabulkou, kam SDS zaručeně zařadí poslední přijaté hodnoty pro každou položku (Topic), která vás zajímá.


Pozor

Každé SDS má k dispozici jinak velkou tabulku pro Subscribe - tedy jsou SDS, které mají k dispozici méně indexů než plných 32. S tím musíte počítat, a můžete využívat jen tolik indexů (řádků v tabulce), kolik jich cílové SDS poskytuje.

Přesnou hodnotu si může SDS-C program zjistit čtením sys[2209] (respektive get 12209).

Pokud se stane, že by vám počet dostupných indexů nestačil, lze si snadno pomoct - lepším návrhem využití jednotlivých Topic. Můžete např. neplýtvat a použít jeden Topic na řízení více věcí (příklad: ovládání jednotlivých relé přes jednotlivé bity ve společném čísle, přenášeném v rámci jediného Topicu).

Při každém PŘIPOJENÍ k MQTT Brokeru dojde ke smazání celé tabulky (celého obsahu). Tzn. pokaždé když zavoláte mqtt_connect() tak dojde k vyčistění obsahu tabulky - a také ke zrušení všech přihlášení.

Při každém připojení tedy musíte vždy poslat všechny požadavky na přihlášení, které vás aktuálně zajímají, bez ohledu na to, k čemu jste byli přihlášeni v případném předchozím připojení.


Velikosti

Co můžete v rámci svého programu využít:

SDS MQTT klient FW verze max délka
ClientID
max délka
username
max délka
password
max délka
Topic Name
max délka
Value
počet položek ve
Subscribe tabulce

SDS: První Produktová Řada

SDS MICRO LM (LIGHT, E) není - 0 0 0 0 0 0
SDS IO6 LM ano (SDS-C) 26.6.2020
a novější
64 64 64 96 192 2
SDS MACRO LM není - 0 0 0 0 0 0
SDS UPS ONEDPS LM ano (SDS-C) 26.6.2020
jen EN verze
a novější
64 64 64 128 384 3

SDS: První Produktová Řada - verze ST

SDS MICRO ST ano (SDS-C) 26.6.2020
a novější
64 64 64 128 384 7
SDS MACRO ST ano (SDS-C) 19.10.2020
a novější
64 64 64 96 256 3
SDS IO6 ST ano (SDS-C) 26.6.2020
a novější
64 64 64 128 384 7
SDS TTCPRO ST ano (SDS-C) 26.6.2020
a novější
64 64 64 128 384 7
SDS MINI ST ano (SDS-C) 26.6.2020
a novější
64 64 64 128 384 7

SDS: Druhá Produktová Řada

SDS BIG 64/128 ano (FULL-C) 9.8.2020
a novější
64 64 64 128 384 7
SDS SMALL 64/128 ano (FULL-C) 9.8.2020
a novější
64 64 64 128 384 7
SDS STSW (OEM) ano (FULL-C) 9.8.2020
a novější
64 64 64 128 384 7