Browsed by
Tag: vstupy

Propojení dat z MQTT do Loxone pomocí HTTP vstupů

Propojení dat z MQTT do Loxone pomocí HTTP vstupů

Jak jsem psal v minulém článku, kde jsem bojoval s BigClownem, poslední fáze propojení (a vlastně i ta nejdůležitejší), je dostat data ze senzorů, která je posílají přes MQTT protokol do Loxone.

Není to nic složitého, ale napoprvé může člověk v několika místech narazit. V rámci článku budu předpokládat, že už máte nainstalovaný a rozchozený nějaký MQTT server (například Mosquitto) a že už Vám běhá NodeRED (třeba v NASu, RaspPI,…). Pokud ještě nemáte, mrkněte na moje články o NodeRED a Mosquitto, kde je instalace a použití popsáno.

Jako zdroj dat budu používat data z BigClown senzorů. Stejně tak jdou ale data simulovat napřímo pomocí příkazové řádku a příkazu mosquitto_pub. 

mosquitto_pub.exe -h dockerserver.dum -t node/kit-co2-monitor:0/co2-meter/1:0/concentration -m 10000

Takže například tímto příkazem simulujeme čidlo CO2 monitoru na zařízení s IDčkem 0 a posíláme data “concentration” s hodnotou 10000ppm (takže vlastně smrtící dávka :)) ).

A teď už k samotnému NodeRED. Abychom mohli data z MQTT přijmout a zpracovat, vložíme prvek Input – mqtt.

 

Po rozkliknutí prvku mqtt můžeme zadat několik vlastností. Name slouží jen k pojmenování v rámci diagramu, QoS je priorita služeb, která nás nezajímá. A pak Topic. Jako topic zadáme buď absolutní název topicu, nebo nějakou jeho masku. Maska funguje tak, že namísto jedné úrovně zadáme znak +, nebo místo více úrovní znak #. Takže pokud chceme chytat všechny zprávy, týkající se senzoru nula, může maska vypadat takto:

Pokud máme dvě zařízení, můžeme buď masku ještě více zobecnit, nebo přidat dva MQTT inputy a každému přiřadit jinou masku topicu. Já šel druhou cestou, jelikož se mi to více hodilo při ladění a testování.

Tím bychom měli data v NodeRED. Nyní musíme vyřešit, jak data předat do Loxonu. Jsou vlastně dvě cesty. Jedna je data do Loxonu nastavit, druhá pak nechat Loxone, aby si o data řekl. Dneska popíšu cesta, aby si o data Loxone řekl. Z tohoto důvodu si musíme data někam v NodeRED uložit a pak na základě Loxone dotazu mu hodnoty sdělit.

Přidáme další dva prvky do našeho projektu. Tím prvním je prvek Debug. Ten slouží k tomu, že cokoli se do něj pošle, to on ukáže v debug okně. Ideální na ladění a ověření, že data z MQTT přicházejí. Náš testovací příkaz z mosquitto_pub se v NodeRED debugu zobrazí takto:

 

Druhý prvek je Function. Díky ní můžeme v NodeRED psát vlastní JavaScriptové funkce a pracovat s datama. V mém případě jsem si ji pojmenoval DataBuffer a to proto, že ukládá do bufferu všechny hodnoty z MQTT pro pozdější využití.

var dataObjectName;
if ( msg.topic.indexOf("kit-co2-monitor:0") != -1)
dataObjectName = "BCG-data0";
else
dataObjectName = "BCG-data1";
var dataObject = flow.get(dataObjectName);
if ( typeof(dataObject) == "undefined" )  
dataObject = {};
var currentdate = new Date(); 
dataObject.lastModification = "" + currentdate.getFullYear() + (currentdate.getMonth() + 1) + currentdate.getDate() + currentdate.getHours() + currentdate.getMinutes();
if ( msg.topic.indexOf("humidity") != -1)
dataObject.humidity = msg.payload;
if ( msg.topic.indexOf("temperature") != -1)
dataObject.temperature = msg.payload;
if ( msg.topic.indexOf("pressure") != -1)
dataObject.pressure = msg.payload;
if ( msg.topic.indexOf("altitude") != -1)
dataObject.altitude = msg.payload;
if ( msg.topic.indexOf("concentration") != -1)
dataObject.concentration = msg.payload;
if ( msg.topic.indexOf("voltage") != -1)
dataObject.voltage = msg.payload;
flow.set(dataObjectName, dataObject);
msg = null;
return msg;

Program funguje tak, že nejprve zjistí, ze kterého čidla data přišla. To udělá tak, že v názvu Topicu vyhledá text “kit-co2-monitor:0”. Když tam text je, je to monitor0, když ne, je to monitor1. Název topicu je uložen v msg.topic.

Jako druhý krok pak vezme (a nebo vytvoří, pokud ještě neexistuje) objekt z flow contextu (jedná se o objekt sdílený v rámci jednoho projektu/záložky, nikoli celého NodeRED), do kterého hodnoty uložíme. Tím, že se jedná o flow objekt, budou data dostupná i v jiném prvku “Function”. Rozdíl mezi contextem, flow contextem a global contextem vysvětlen zde.

Následně pak už jen zjistíme, jaký typ hodnoty nám vlastně přišel a uložíme si ji do odpovídající proměnné v našem datovém objektu. K tomu si ještě uložíme informaci o tom, kdy jsme obdrželi poslední změnu hodnot z daného čidla. A to proto, abychom mohli monitorovat, kdy naposledy čidlo komunikovalo.

A tady je drobná obtíž s Loxonem. Bohužel, HTTP Inputs v Loxonu neumí textové hodnoty (debilní co), takže je potřeba to poslat jako číslo. Proto si poskládám číslo ala 201718121822, což znamena 2017-18-12 18:22.

Takže hodnoty máme uložené a nyní musíme naučit NodeRED, aby byl schopný hodnoty servírovat dál. Na to má naprosto super prvek Input – http. Pomocí něj si nadefinujete, na jakých URL adresách má nodeRED poslouchat a jaká data vracet. Takže například chceme, aby na adrese http://nodered.dum/bigclown/kit0 se vracely hodnoty z prvního čidla, na adrese http://nodered.dum/bigclown/kit1 pak z druhého čidla.

Jednoduché, že? Tímto jsme ho právě naučili poslouchat na zvolené adrese. Teď mu ještě nějak musíme předat data. Proto přidáme opět prvek Function a spojíme ho s obouma vstupama a zároveň výstup funkce spojíme s prvkem Output – http response. Ten je k tomu, aby se pro daný http požadavek vrátila nějaká data.

Jednoduché, elegantní :). Zbývá už jen napsat funkci DataGetter, která vezme uložená data z flow contextu a vrátí je na výstup:

var dataName;
if ( msg.req.originalUrl == "/bigclown/kit0" )
dataName = "BCG-data0";
else
dataName = "BCG-data1";
var dataObject = flow.get(dataName);
msg.payload = 
"lastUpdate=" + dataObject.lastModification  +
" humidity=" + dataObject.humidity +
" temperature=" + dataObject.temperature +
" pressure=" + dataObject.pressure +
" altitude=" + dataObject.altitude +
" concentration=" + dataObject.concentration +
" voltage=" + dataObject.voltage;
return msg;

Ta funguje tak, že z originalUrl zjistíme, jaká data máme vrátit (jeslti čidlo 0 nebo 1). Data pak získáme pomoci flow.get() a sestavíme z nich textový řetězec v podobě name=value name1=value1….., který pak následně vrátíme jako msg.payload. V objekt msg pak data jdou do http-response, a zobrazí se jako http odpověď. Takže když pak zavoláme adresu http://nodered.dum/bigclown/kit0, jako odpověď získáme toto:

A tím jsme s NodeRED skončili. Data máme z MQTT načtena a umíme je vystavit dál. Zbývá už jen naučit Loxone si o data říct. Do projektu v Loxone Configu přidáme dva HTTP Virtuální vstupy,

které si pojmenujeme třeba BigClown kit 0 a BigClown kit 1.

A každému příkazu zadáme dotazovací url. V mém případě již zmiňovaný http://nodered.dum/bigclown/kit0 http://nodered.dum/bigclown/kit1

Do těchto virtuálních vstupů pak přidáme jednotlivé HTTP příkazy. Pro každou načítanou hodnotu jeden příkaz:

A každému příkazu řekneme, jak má hodnotu z textového řetězce vyparsovat, jak se má hodnota vypisovat, na kolik má být desetinných míst, jednotku, …

Takto například vypadá CO2 čidlo. Má rovnou zapnutou i statistiku, která se zaznamenává jednou za 10minut jakožto průměr hodnot. Parsování se provádí pomocí příkazu “concentration=\v”, je na jedno desetinné místo s jednotkou ppm (pomocí <v.1> ppm).

A to je vše. Tím máme hodnoty v Loxone :). Pro zajímavost, hodnoty Tepota/vlhkost jsou hodnoty z čidel od Sedtronicu, zatímco hodnoty z BigClowna jsou ty s označením “kit0”. Teplota i vlhkost se trošku liší, jelikož čidla Sedtronic jsou pod vypínačem ve zdi, zatímco čidlo BigClownu je vedle postele na stolku. Jde na tom občas hezky vidět, jak se rychleji zahřeje vzduch, než cihla :).

A to je pro teď vše. Příště zkusím dát dohromady ještě návod za pomoci virtuální vstupů. To zatím ještě nemám, protože mne to napadlo až teď při psaní článku :). Myslím, že by to také mělo také jít. Jen je otázka, jeslti nad tím půjdou i statistiky a další věci.

Aktualizace můstku Quido-Loxone

Aktualizace můstku Quido-Loxone

Nějak jsem úplně zapoměl veřejně oznámit novou aktualizaci na můj program pro propojení Quida (Papoucha) a Loxone. Díky tomu ale můžu po několika týdnech testování s klidným svědomím říct, že opravdu funguje vše jak má a nemusíte se případně bát aktualizovat :-).

Ovládání relátek na Quidovi

Nová verze obsahuje několik novinek. Tou první, hlavní, je možnost ovládat relátka na Quidovi. Relátka lze ovládat na všech modulech Quida, které relátka mají. Tzn jak na modulu 100/3, tak až po modul 2/32. Vše v ethernet verzi.

Drobná komplikace během vývoje nastala v omezení Loxonu zpracovávat operace asynchroně. Jelikož toto Loxone (PicoC) neumí, nelze zároveň poslouchat sockety a zároveň je odesílat. Z toho vyplívá, že v okamžiku spínání relé nemusí dorazit info o uvolnění tlačítka, což mělo za důsledek dost náhodné chování žaluzií 😉

Z tohoto důvodu je potřeba použít zvlášť komponentu “Loxone program” pro vstupy a zvlášť pro výstupy.  PicoC jako takový je stejný, jen se v hlavičce programu nastaví, zda obsluhuje vstupy nebo výstupy. Pokud vstupy nebo výstupy nepotřebujete, stačí použít jen jeden program takový, který potřebujete.

Relátka se ovládají přes připravené Loxone bloky. Na každý vzorec lze připojit až 4 vstupy pro relé a ty jsou pak napojeny na jeden společný Loxone program, který z nastavených hodnot relé sepne nebo rozepne.

Automaticky generované pakety

Druhá novinka je kompletní předělání vnitřností programu tak, abych už nemusel generovat ručně pakety, ale aby si program vše dělal sám. Na jednu stranu to ulehčí konfiguraci, na druhou stranu to dost zkomplikovalo SW. Bohužel, jelikož se každé relé spíná vždy jiným příkazem, nebylo zbytí. Jinak bych musel generovat až 40 paketů pro každého uživatele zvlášť, a to by mi mrdlo.

Díky tomu se ale i hodně zjednodušilo nastavení celého programu. Stačí zadat jen IP a port pro Loxone a pro Quida, nastavit režim programu (0/1 vstupy/výstupy) a hotovo.

Paměťová i procesorová optimalizace programu

Třetí novinka je, že je celý Loxone program zkomprimovaný. Jelikož už byl díky všem rozšířením a komentářům opravdu dlouhý, napsal jsem si komprimátor tak, aby z kódu zmizely všechny zbytečné komentáře a dlouhé názvy a program tak v Loxonu nezabíral zbytečně pamět (a i parser PicoC má tím pádem méně práce), takže program celkově méně zatěžuje Loxone.

Vypnutí zbytečných výstupů do logu

Poslední novinkou je pak odstranění některých výpisů do logu Loxone configu. Ty jsem tam měl z doby ladění a zůstaly i u některých z Vás. Bohužel, když se tam nechaly nějakou dobu, dokázaly pár MB dat v logu udělat. Pokud by se to týkalo i Vás, můžete logy promazat přes FTP přímo v Loxonu.

A to je vše

Tím končí soupis změn z aktuální verze. Pro ty z Vás, kteří si už program koupili, tak je aktualizace dostupná ve sdílené Dropbox složce tak jako dřív. Je aktualizovaný jak program, tak Loxone projekt, kde ve dvou záložkách najdete schéma pro vstupy a výstupy.

Pokud ještě program nemáte, ale čekali jste třeba právě na výstupy, neváhejte se mi ozvat na email [email protected]. Cena zůstává stále stejná, ačkoli je program opět o několik řádů vylepšený 😉

PS: Zároveň jsem aktualizoval i návod na původní stránce o Papouchovi – https://www.vodnici.net/2016/10/loxone-propojeni-s-modulem-quido-od-papoucha/

 

 

Quido na steroidech

Quido na steroidech

Tak tu máme první velkou aktualizaci SW pro Papouchova Quida. Jak jsem v předchozích článcích, původně bylo implementováno vše jen pro vstupy, ale výstupy jsem neřešil. A protože už je zájem i o výstupy, nedalo se nic dělat a hurá k parodii na C jazyk nazývanou PicoC :).

Bohužel z mého odhadu, že to bude fik fik za hoďku hotové nakonec dost sešlo. První problém byl, že ovládat jednotlivé relé znamená mít spoustu dalších různých řídících paketů, což by obnášelo spoustu manuálního generování. Takže nezbylo než se zanořit ještě hloubš do dokumentace a napsat si vlastní generátor a podepisovač paketů.

Výhoda je, že už nemusím připravovat pro nové uživatele pakety ručně, nevýhoda byla, že to vzalo hromadu času. Krom samotné implementace to hlavně chtělo zavést už i nějaké testování, protože lazení v Loxone program editoru je naprosté peklo (jako třeba proč nefunguje ani blbá klávesa PageUp-PageDown je mi záhadou).

Takže jsem si rozběhal projekt ve Visual Studiu, namockoval Loxone metody tak, aby nic nedělali, ale program šel zkompilovat a pustil se do rozšiřování. Kromě samotného podepisování, které je plné bitových operací, to chtělo ještě nějaké parsery na vyčtení dat z IP adresy, výpočty bitů pro stavy relé a hromadu dalších věcí, které už nabouchat jen od boku není úplně bezpečné.

Takže krom toho, že to jde kompilovat ve VS, čímž eliminuju zdlouhavý proces přes Loxone, tak jsem tam udělal ještě sadu spousty testů, které všechny tyhle metody před nasazením do Loxonu otestují.

Co se začíná ukazovat jako dost komplikace je fakt, že celý progam musí být jen v jednom souboru. Žádné pěkné oddělení, žádné objekty, žádná struktura. Pěkně všechno pod sebou, navíc ideálně v globálních proměných osekaných na dřeň, aby to žralo co nejméně paměti.

Takže je to ošklivý špagety kód. Navíc ručně optimalizovaný tak, aby se nikde nealokovala žádná pamět, ale používal se sdílený buffer, aby to žralo co nejméně procesoru a hlavně to nepadalo a prošlo to i tím příšerným PicoC interpretem.

Když bylo vše naprogramováno, přišlo na řadu první testování v reálném prostředí. Bohužel to hned odhalilo druhý velký problém. Ukázalo se, že moje myšlenka se sdíleným kódem pro vstupy i výstupy je mimo a že to takto nepůjde.

Problém totiž je, že PicoC neumí asynchroní čtení ze streamu. Takže stream buď čte, ale pak je program blokován čekáním a čtením, nebo nečte, a pak se pakety zkrátka nezpracují.

Původně jsem to měl tak, že se vždy jen zjistilo, jestli jsou nová data, když ne, zjistilo se, jestli je na vstupech nějaká změna. A když ne, znova se zjistili data, …..

Jenže, v okamžiku, kdy se zjišťovali vstupy, tak se třeba nenačetlo, že člověk pustil tlačítko žaluzie, a tak žaluzie sjížděla vesele dál. Nebo nezaregistroval stistknutí, nebo otevření okna,… Protože když nečetl, paket zůstal nevyslyšen.

A bohužel, toto nijak vyřešit nejde. Pročetl jsem dokumentaci, pročetl diskuze, a je to prostě tak. Takže jediné řešení jsou dvě smyčky. Jedna co načítá data z Papoucha, druhý co načítá vstupy z Loxonu.

A když dvě smyčky, tak dva Loxone programy. Takže pokud někdo budete chtít využít obě funkce, je nutné použít dva samostatné bloky. Když jen jednu z nich, druhý se použít nemusí.

A aby se program dobře nastavoval i distribuoval, je to udělané tak, že je program jeden a ten stejný a jen pomocí přepínače se nastavuje, jestli se má chovat jako Relé můstek nebo můstek pro Vstupy.

Celé nastavení programu tak nyní vypadá takto

char * c_remote_listen_address = "/dev/udp/192.168.1.254/10001";
char * c_remote_write_address = "/dev/udp/192.168.1.254/10002";
//pocet rele
unsigned int c_relays_count = 3;
//automaticky refreshnout stav vstupu pro pripad, ze se ztratil UDP paket s notifikaci (treba otevrene okno)
unsigned int c_auto_refresh_every_sec = 60;
//jak casto se detekuji vstupy kvuli rele. Cim mene, tim vice se bude zatezovat miniserver
unsigned int c_relay_check_period_msec = 100;
//rezim 0-INPUTS [digitalni vstupy], 1-OUTPUTS [rele]
unsigned int quido_bridge_mode = 1;

Jak je vidět, zmizelo nastavení paketů, to se dělá dynamicky. Jediné co je potřeba, je správně zadat IP adresu a počet relé, které Quido má (při větším čísle než kolik jich je k dispozici pak nefunguje žádné!). Jako poslední nastavení Nově pak jsou nastavení rezimu INPUTS a OUTPUTS a konstanta, která určuje, jak často se mají vstupy kontrolovat.

To je totiž další vykutálenost Loxonu. Namísto, aby se dalo říct “čekej, než se vstup změní”, tak se musí dělat “už se změnilo?”,”už?”,”už?”,… A čim častěji se ptá, tím víc to žere prostředky. A když se taková smyčka pustí bez uspání, žere 100% procesoru.

Takže jsem jako výchozí nastavil 100ms. Pokud by to bylo někomu málo, může si to vytunit, ale s rizikem, že to bude žrát více prostředků Loxonu. Imho si myslím, že 100ms je dostatečný fofr.

Co se týká blokového zapojení v Loxone configu, tak k tomu můžu říct jen jediné. Loxone programátoři by se nad sebou měli zamyslet a dodělat logické chybějící bloky. Nehápu, proč když Loxone nabízí Binární dekodér, nemá i logický protikus binární kodér. Nechápu, proč když se zeptám na podpoře, tak jim přijde logická odpověd “použijte vzorec”. A nechápu, proč když už doprd… mám použít vzorec, tak proč vzorec nemá aspoň osm vstupů, ale jen čtyři, takže to práci pekelně komplikuje.

Ale ok. Jedno přísloví říká, že na všechno je potřeba se koukat ne jako na problém, ale jako na příležitost, a tak jsem se té příležitosti chopil a poskládal to ze vzorců.

Samotné využití a napojení na reálný dům je pak už hodně jednoduché. Na vstupy vzorce se přivede 0 nebo 1 a vzorce spolu s programem dle toho zapnout dané relé. Pokud na vstup přivedete cokoli víc než 1, výsledek je random a nejspíš se nestane vůbec nic. Je to proto, že ve vzorci převádím binární 0 a 1 na číslo a třeba taková 2 v tom udělá dost brajgl :).

Níže je video ukázka jak to funguje, především pak rychlost. Podle mě je suprová ;-). Nedokážu si předtavit, že byste dokázali klikat rychleji, než kolik můstek zvládá Quida (Papoucha) ovládat.

Momentálně probíhá testování v mém domě, kdy se jednak testuje původní část na vstupy pomocí žaluzií a stavů oken. Výstupy pak testuju jen napojenou diodou v rozvaděči, protože jsem takto narychlo neměl žádný siloproud, co bych tam zapojil a přepojovat rozvaděč se mi nechtělo.

Pokud půjde všechno jak má, tak novou verzi pustím do světa do konce týdne. Odvážným majitelům předchozí verze klidně poskytnu dříve, ale jen na vlastní riziko :).