M2M: UDP protocol

Tato stránka popisuje funkci zařízení SDS první produktové řady - protože SDS druhé produktové řady používají jiný protokol.

rychlá komunikace

Pomocí speciálního protokolu, kdy se data přenášejí prostřednictvím UDP, je možné získávat informace z výrobků řady SDS/OnlineTechnology.

PORT 280

Komunikace probíhá formou DOTAZ - ODPOVĚĎ. To znamená, že ten, kdo má o informace zájem (vzdálený uživatel) pošle dotaz (korektně vyplněný UDP paket, viz dále) a obratem obdrží od zařízení odpověď, UDP paket s informacemi.

Přenos dat využívá údajů ve formátu DWORD: signed (int32_t) nebo unsigned long (uint32_t), tj. 4 bajtové slova. MSB je "vlevo" (zapsáno jako první).


firmware

Pouze firmware od 26.9.2010 má k dispozici následující funkce. Starší verze firmware sice podporují UDP protokol také, avšak obsah se liší od popisu na této stránce.

Pozor, firmware od 17.10.2010 má doplněný obsah UDP paketu (změna oproti původní verzi). Došlo k doplnění ROMCODE pro teplotní čidla.

Firmware od 29.7.2011 má k původní funkci UDP paketu (query) přidánu funkci zápisu do sys[] proměnných (write).

Firmware od 2.10.2011 má navíc přidány funkce: čtení vybraných sys[] a čtení a zápis vybraných položek v ram[].


vyhledání SDS přes jiný UDP paket

Tato funkcionalita - nalezení SDS modulu na síti - je popsána jinde: M2M: UDP search.

Tato stránka se týká přímé komunikace s SDS přes UDP protokol.


formát UDP paketu (paket poslán DO zařízení - tzv. dotaz/příkaz)

OFFSET DATA
+0 0x00
+1 'A'
+2 'N'
+3 '-'
+4 'D'
+5 '.'
+6 'c'
+7 'z'
+8 '/'
+9 'S'
+10 'D'
+11 'S'
+12 0x02
+13 0x06
+14 0x00

Ihned následuje typ příkazu - query nebo write nebo rdsys nebo rdram nebo wrram nebo wrsys, zakončený znakem 0x00 :

+15 'q'
+16 'u'
+17 'e'
+18 'r'
+19 'y'
+20 0x00

respektive

+15 'w'
+16 'r'
+17 'i'
+18 't'
+19 'e'
+20 0x00

respektive

+15 'r'
+16 'd'
+17 's'
+18 'y'
+19 's'
+20 0x00

respektive

+15 'r'
+16 'd'
+17 'r'
+18 'a'
+19 'm'
+20 0x00

respektive

+15 'w'
+16 'r'
+17 'r'
+18 'a'
+19 'm'
+20 0x00

respektive

+15 'w'
+16 'r'
+17 's'
+18 'y'
+19 's'
+20 0x00

Základní data (pro query) mají tedy celkem 21 Bajtů. Jsou vloženy ihned na začátek datové části UDP paketu. Tabulka: vše co je zapsáno stylem 'A' znamená jeden ASCII znak, hodnota typu 0x00 atd. je přímo hex kódem znaku.

Těchto 21 Bajtů (nebo více, dle typu příkazu) pošlete na port 280 zařízení a obratem bude odeslána odpověď.

Hlavička obsahuje 'AN-D.cz/SDS' a číslo verze: novější verze se dají odlišit, protože číslo verze protokolu je zapsáno právě v kombinaci 0x02,0x06. Tolik hlavička, a aktuální požadavek je pak 'query' nebo 'write'. Pokud je přijatý UDP paket s jiným než s tímto uvedeným obsahem, je ignorován a není odpovězeno.


query

Pokud zařízení obdrží správně zadaný paket s tímto příkazem, okamžitě odpoví dle popisu který je uveden dále na této stránce.


write, rdsys, rdram, wrsys, wrram

Pokud zařízení obdrží správně zadaný paket s jedním z těchto příkazů, převezme všechny zaslané údaje a zpracuje je, podle typu příkazu.

Všechny tyto příkazy mají stejný základní formát dat který musíte poslat:

OFFSET DATA
+21 0x00 (jeden Byte) - pro dorovnání na zarovnání
+22 0x00 (jeden Byte) - pro dorovnání na zarovnání
+23 0x00 (jeden Byte) - pro dorovnání na zarovnání
+24 [DWORD] váš

identifikátor (číslo zde zapsané je předáno i v odpovědi, umožňuje to rozlišit odpovědi od sebe, jak typově tak časově)

+28 [DWORD] délka hesla zapsaného v tomto paketu
+32 pole znaků (přesně 32 bajtů), obsahující zabezpečené heslo - nepoužité znaky zapište jako 0x00
+64 [DWORD] počet následujících uložených párů
+68 začátek párů

Aby byl příkaz proveden, musíte poslat heslo. Jako heslo je myšleno heslo do webového rozhraní konkrétního zařízení.

Heslo je jednoduše zabezpečeno jednoduchou metodou, a to celobitovým XOR každého znaku hesla.

Příklad: na vstupu máte heslo v plaintextu (tj. čisté, lidsky čitelné textové heslo). Nad každým znakem provedete operaci XOR (v jazyce C je to ^, v Pascalu je to xor, atd.) vůči konstantě hex A5.

Teprve takto upravný text zapíšete do paketu.

 zapsany_znak_hesla[i] = cisty_text_hesla[i] ^ 0xA5;

Proč je tato metoda použita - aby případný náhodný odposlech paketů přímo na první pohled neposkytnul čisté heslo. V plánu je bezpečnější metoda, toto je pouze rychlé řešení pro uvedení nové funkce. Do budoucna plánujeme dynamický salting, zatím tedy ale máme tohle.

Jakmile zapíšete heslo (vždy se musí zapsat všech 32 bajtů, takže jestli máte kratší heslo, doplňte to až při zápisu bajty 0x00), zapíšete unsigned long číslo s počtem následně zapsaných párů.


páry

Páry - zde se jedná o seznam, obsahující vždy dvojici čísel (2x 4 bytes). První číslo je index, druhé je hodnota. Každý pár tedy zapíšete jako osm bajtů. Párů může být více za sebou, zapisují se hned za sebe.

+0 [1x DWORD] index
+4 [1x signed DWORD] hodnota

Hodnota: -2 na 312 na 31 (signed long).

Index: vždy od nuly až po N (kde N je závislé na konkrétním příkazu, např. 1023 pro write nebo wrsys).


detail: write

Toto je specifický příkaz, který nastaví nové hodnoty do vybraných indexů v poli sys[] a následně vrátí specifický formát odpovědi odesílateli příkazového UDP paketu, ve stejném formátu jako je odpověď pro query paket (jen tímto se liší od příkazu wrsys).

Posláním platného write UDP paketu můžete najednou postupně zapsat libovolné hodnoty až do 128 sys[] systémových proměnných najednou. Např. hromadně ovládat relé na dálku, předat hodnoty do svého SDS-C programu a tak dále.

Samozřejmě pro možnosti zápisu do sys[] (co a kam) platí stejná omezení, jako by jste zapisovali přímo v SDS-C programu. Seznam systémových proměnných je zde.

Příklad omezení je např. zápis do sys[], které ovládají relé. Tento zápis (i přes UDP protokol) se převede do hardware pouze v případě, že ovládání relé je nastaveno tak, že konkrétní relé je ovládáno z SDS-C (nikoliv manuálně nebo z IP Watchdogu). A tak dále, vše viz popis v seznamu systémových proměnných.

Program při příjmu UDP write paketu nejprve ověří heslo, a potom čte postupně jednotlivé páry a každý pár co přečte ihned předá do SDS-C tak, že dojde k následujícímu zápisu:

 /*write*/ sys[Index] = Hodnota;

Index:

write: 11023 (unsigned long) - omezení dáno velikostí pole sys[]

Pozn. příkaz write ignoruje položku "váš identifikátor", vzhledem k formátu odpovědi jakou poskytuje.

detail: wrsys a wrram

Příkaz wrsys prakticky kopíruje funkčnost příkazu write, ovšem má jiný formát odpovědi (viz dále).

Příkazy wrsys a wrram umožnují zápis nových hodnot do polí sys[] respektive ram[].


detail: rdsys a rdram

Tyto dva příkazy umožňují čtení z polí sys[] respektive ram[], a to z konkrétních poptávaných indexů. Při zaslání příkazu vyplňte páry, v nich zapište ty indexy které vás zajímají, a zařízení vám odpoví doplněním hodnot do těchto párů.


formát UDP odpovědi pro query a write

Zde popsaná odpověď je poslána jak pro query, tak pro write požadavek.

Odpověd se skládá z hlavičky a datového obsahu. Hlavička má 15 Bajtů a je stejná jako původní hlavička (tj. 0x00 AN-D.cz/SDS 0x02 0x06 0x00).

Následují data, každá položka, bez ohledu na typ přenášené informace, má vždy 4 Bajty (dword). Některé položky jsou však brány jako text, a pak mají velikost vždy v násobku 4 Bajtů (každý znak je však uložen po jednom Bajtu, bez mezer, za sebou).

OFFSET DATA
+15 typ firmware (SDS MICRO LM: 0xD0000001 atd. dle zařízení)
+19 uptime (číslo: násobky 10 msec)
+23 NTP time (přímo celý UNIX time)
+27 8x dword reserved (obsahuje 0x00)
+59 text 16 Bajtů (4x DWORD) - sysLocation
+75 vždy pevná hodnota 0x00000000
+79 stav IP watchdog (aktivní nebo vypnutý)
+83 stav výstupu IP watchdog (ovládání relé)
+87 hodnota RTT pro IP watchdog (pro poslední test)
+91 (4x DWORD) reserved
+107 stav relé č. 1 až 32
+235 stav pinu D0
+239 raw hodnoty A/D vstupů 1 až 4 (každý 1x dword)
+255 přepočtené hodnoty A/D vstupů 1 až 4 (každý 1x dword)
+271 stav optického vstupu č. 1 až 32 (pozn. hodnota 0 = LED v optočlenu svítí)
+399 počet detekovaných zařízení na 1-Wire®
+403 32x BLOK po 4x DWORD : PRO KAŽDÉ TEPLOTNÍ ČIDLO - viz další tabulka
+915 (8x DWORD) reserved
+947 stav tarifního vstupu S0 (aktuální tarif)
+951 hodnoty S0 vstupů - tři bloky za sebou - každý blok má 7x dword

Jednotlivé položky obsahují stejné hodnoty, jaké naleznete při čtení ze systémových proměnných (sys[]). Podívejte se proto na seznam systémových proměnných pro bližší vysvětlení obsahu.

Hodnoty pro teplotní čidla 1-Wire® jsou zapsány vždy po 4 DWORD slovech postupně za sebou. Čidel je (dle výrobku) až 32. Nepoužité položky (čidla) jsou prázdné.

Obsah každého bloku pro teplotní čidla:

OFFSET DATA
+0 8 bajtů s ROMCODE (tj. 2x DWORD)
+8 (1x signed DWORD) teplota - pozor, údaj ve stupních Celsia násoben 100 (tj. 12.53°C bude uloženo jako číslo 1253)
+12 (1x DWORD) stav konkrétního čidla

POZOR údaj o teplotě má dvě vlastnosti, se kterými musíte počítat:

1) Uložený údaj je násoben číslem 100 - toto je zde z důvodu potřeby jednoduché metody přenosu desetinných hodnot. Ve vašem programu si přečtený údaj vydělíte 100 a dostanete skutečnou hodnotu.

2) Hodnota je uložena jako signed long (32 bitové číslo se znaménkem). Například decimální hodnota "-2000" je hexadecimálně zapsána jako 0xFFFFF830, nebo např. hodnota ta samá hodnota ale kladná ("+2000") je zapsaná jako 0x000007D0.


Stavy teplotních čidel (v okamžik odpovědi na UDP dotaz):

  • 0 Čidlo není instalováno, nebo neznámá chyba či stav
  • 2 Vše v pořádku, právě byl získán údaj o teplotě z čidla
  • 4 Čidlo ohlásilo svou přítomnost
  • 8 Právě byl spuštěn další (nový) převod teploty
  • 16 Nepovedlo se začít převod (chyba)
  • 32 Bylo přijato neplatné CRC - buď chyba čidla (málo pravděpodobné), nebo chyba spojovacího vedení (nebo rušení)



Hodnoty pro S0 vstupy jsou zapsány jako bloky 7x dword (tj. 28 Bajtů), přičemž máme tolik bloků uložených hned za sebou, kolik má zařízení S0 vstupů (např. SDS MICRO LM má tři S0 vstupy).

Obsah bloku S0 (pro jeden vstup, ostatní jsou sestaveny shodně):

OFFSET DATA
+0 informace o volbě tohoto konkrétního vstupu jako S0 vstup
+4 informace o použití tarifního rozlišení pro tento vstup
+8 počítadlo impulsů pro tento vstup, pro tarif T0
+12 počítadlo impulsů pro tento vstup, pro tarif T1
+16 uživatelem nastavený offset počítadla T0+T1 (průběžné nulování pro výpočet ceny)
+20 konstanta počet impulsů na jednotku (pro přepočet)
+24 poslední změřené doba mezi posledními přijatými impulsy, v msec

Pozn. na konec paketu je pak vložen jeden DWORD s nulovou hodnotou.

Pozn. hodnota na pozici [+16] je dána součtem offsetu pro hodnotu při tarifu T0 a offsetu pro hodnotu při tarifu T1. A to bez ohledu na to, zda-li je nebo není tarifní rozdělení pro daný S0 vstup použito.


formát UDP odpovědi pro rdsys, rdram, wrsys, wrram

Odeslány jsou páry pro jednotlivé položky sys[] respektive ram[]. Hodnoty jsou doplněny do jednotlivých míst v párech, pro každý index je doplněna aktuální hodnota.

solid; border-color: #000"
OFFSET DATA
+15 pět znaků určující typ příkazu (viz seznam nahoře), sem je opsán text příkazu
+20 reserved (1x DWORD) - vždy 0x00000000
+24 (1x DWORD) váš identifikátor (zde je vloženo stejné číslo, jaké jste zapsali v paketu s příkazem)
+28 typ firmware (SDS MICRO LM: 0xD0000001 atd. dle zařízení)
+32 uptime (číslo: násobky 10 msec)
+36 NTP time (přímo celý UNIX time)
+40 (1x DWORD) reserved (obsahuje 0x00000000)
+44 text 16 Bajtů (4x DWORD) - sysLocation
+60 vždy pevná hodnota (1x DWORD) 0x00000000
+64 (1x DWORD) počet párů
+68 odpovědi zapsané do párů (původní přijaté páry jsou doplněny o aktuální hodnoty pro každý index)

Pozn. všimněte si že odpověď má položku sysLocation na pozici +48 (oproti odpovědi pro query a write). Celé uspořádání odpovědi je dáno pevnou pozicí +68 pro páry (stejná pozice jako v dotazu).

Jednotlivé hodnoty, které byly poptávány (tj. hodnoty z sys[] respektive z ram[]) jsou zapsány na příslušné hodnoty do párů. To znamená, že tak jak jste v příkazu předvyplnili indexy pro jednotlivé páry, tak jsou tyto indexy doplněny o příslušné hodnoty, což si právě v odpovědi následně přečtete.

Pozn. pro příkazy rdram, rdsys: při vyplňování párů v příkazu jsou důležité jen indexy, hodnoty jsou ignorovány. Pozn. pro příkazy wrram, write: při vyplňování párů v příkazu jsou důležité indexy i hodnoty.

Využijte obsahu od +15 do +19 včetně, pro určení obsahu odpovědi - toto přijde jako zvláště vhodé, pokud posíláte více různých dotazů na různé položky (sys/ram), a pak vám přijde hromadně více UDP odpovědí. Bez tohoto rozlišení pak nepoznáte, zda-li data patří do pole sys[] nebo do pole ram[]. Současně můžete použít i odlišení pomocí čísla "váš identifikátor", kde si můžete zapsat libovolné číslo při posílání příkazu, a pak podle tohoto čísla rozpoznat konkrétní odpověď.