Projekt Hladinomer (Watmonitor) tvorí webaplikácia, ktorá umožňuje vizualizáciu a zber dát zo senzorového uzla poskytujúceho údaj o rozdielovej výške hladiny vody v studni, nádrži, žumpe (je možná aj reálna výška hladina vody reportovaná zo senzora priamo, ktorý ju vypočíta, ak je splnená podmienka nastavenej hĺbky studne 0 vo webovom rozhraní). Samotná webaplikácia mala integráciu Google Charts pre grafy a využívali sa tu grafy typu Gauge pre vizualizovanie maxím a miním, ktoré nastali za posledných 24 hodín, 7 dní a 30 dní. Používali sa aj čiarové Area grafy pre vizualizáciu výšky hladiny vody v studni / nádrži za 2 hodiny, 24 hodín, 7 dní, 30 dní, 365 dní. Grafy boli už vizuálne zastaralé, viditeľne s inými grafickými knižnicami pre grafy zaostávali. Patrilo sa už modernizovať, nakoľko sa na túto časť projektu nešahlo niekoľko rokov.
Grafy typu Gauge (budíky, analógové ukazovatele), ktoré boli implementované v projekte skrz Google Charts obsahovali konfiguračné parametre. Medzi nimi jednotku (label), ktorú popisujú a taktiež aj staticky nastavený rozsah minima a maxima, vrátane farebných ukazovateľov, ktoré boli konfigurovateľné v rozsahu od-do staticky. Preto som hĺadal niečo podobné s rovnakými možnosťami.
Dlho nenechádzal vhodnú alternatívu tak, aby vyzerala moderne pre vizualizáciu výšky hladiny vody a zároveň bola aj dostatočne konfigurovateľné. Nakoniec som sa ale rozhodol pre JustGage, nakoľko jeho grafy typu Gauge majú polkruhový tvar, bez analógovej ručičky, ktorá v Google Charts prechádzala rovno cez meranú jednotku a občas bolo ťažké určiť, čo sa pod ňou skrýva. Autor JustGage túto knižnicu nenazýva knižnicou, ale pluginom, pričom uvádza, že vychádza, alebo je postavený na knižnici Raphaël pre vektorovú kresbu. Webaplikácia používa súbor pluginu JustGage a knižnice Raphaël , ťahá ich z CDN servera, ale je možné ich stiahnuť aj lokálne a tak ich aj nalinkovať do projektu.
Samotný gauge má niekoľko konfigurovateľných parametrov, ale je to veľmi prehľadné. Používateľ definuje id, ktoré bude obsahovať div, ktorý graf vykreslí. Následne samozrejme aj konkrétnu hodnotu, jednotku - label a iné. Zaujímavým riešením, ktoré JustGage ponúka je použiť vlastnú farebnú paletu v poli. Farby RGB modelu sú definované v poli a dynamicky použité v grafe na základe aktuálnej hodnoty.
Fragment JS kódu s parametrami pre Gauge graf:
V mojom prípade som zvolil celkovo 3 farby a to červenú - indikátor nízkej hladiny vody v studni, žltú - stredná hodnota rozsahu, zelenú - plná studňa. Dynamicky sa však farba mení a medzi červenou a žltou je možné dynamicky pozornovať prechod oranžovej farby medzi nimi v závislosti na aktuálnej hodnote. Rovnako tak aj prechod od žltej k zelenej.
Využil som aj parameter maxima, ktorý je u všetkých grafov Gauges rovnaký a to celková hĺbka studne, čo je parameter, ktorý sa vo webaplikácii používa aj na dynamický prepočet výšky hladiny vody na litre. Teda ak používateľ vo webaplikácii zmení maximálnu hĺbku studne, prejaví sa to aj na stupnici Gauge grafu, pričom RGB paleta sa dynamicky posunie na tento rozsah, teda pri násobnom navýšení hĺbky studne bude potrebné násobne-väčšia zmena pre hlbšiu zmenu farby, aby sa to v danom rozsahu prejavilo.
Výsledok zmeny posúďte sami. Grafy sa pekne vizualizujú aj na smartfóne na jeho obrazovku.
Pred:
Po:
Tieto Gauge grafy majú aj animáciu a pri spustení / reloade stránky sa dynamicky vykreslia od hodnoty 0 po nastavenú hodnotu. V prípade tejto webaplikácie tento typ grafov ukazuje najvyššiu a najnižšiu nameranú hodnotu za konkrétne časové obdobie. Taktiež je tam ešte extra gauge graf, ktorý ukazuje posledné meranie a taktiež som k nemu doplnil aj sekundárny gauge na vizualizáciu percenta aktuálneho objemu studne 67% tj. cca 269 z 400 cm.
V druhej fáze som riešil modernizáciu pôvodných Area grafov, ktoré vizualizovali výšku hladiny vody v časovej postupnosti v závislosti od grafu za posledné 2-hodinové okno až 1 rok spätne. Taktiež som istý čas strávil hľadaním vhodného riešenia. Pôvodné grafy boli tiež z knižnice Google Charts. Area graf je v podstate Line (čiarový) graf, ktorý má ale výplň od spodnej hranice po úroveň, ktorú definuje bod v čase. Vizualizuje tak hladinu vody, prípadne som tieto grafy používal aj pre vizualizáciu aktívneho obdobia, napríklad v projekte vykurovania, kde bolo vidieť časové obdobie, kedy šiel kotol, toho času veľmi primitívnou metódou binárneho zápisu 1 - plynový kotol beží, 0 - plynový koto vypnutý.
Rozhodol som sa pre ApexCharts.js. Je to open-source knižnica, ktorá je veľmi dobre dokumentovaná a ukazuje mnoho príkladov, ktoré sa dajú rovno použiť. ApexCharts som pôvodne zamýšľal aj pre Gauge grafy, ale žiaľ žiadny neponúka. Area Chart z tejto knižnice ponúka aj ďalšie zaujímavé featury. Má veľmi veľa konfigurovateľných parametrov a je to naozaj silný nástroj na peknú vizualizáciu. V mojom prípade som použil napríklad parameter stroke, ktorý umožňuje nastaviť prechod medzi bodmi záznamu. Hladinomer štandardne ukladá dáta raz za 5 minút. Teda táto 5 minútová prestávka bude vo vizualizácii znamenať medzeru.
Fragment JS kódu Area grafu:
V závislosti od šírky časového okna bude táto medzera dynamicky reagovať veľkosťou. Tento stav môže spôsobiť, že susedné namerané hodnoty môžu "zubovo" skákať. To vie práve stroke vyriešiť, ak je nastavený parametrom curve na smooth. Táto funkcionalita vyhladí priebeh spojitej funkcie meraní v čase a urobiť priebeh plynulejší. Ide ale len o prechod medzi hodnotami, samotné hodnoty v konkrétnom čase tým nie sú ovplyvnené.
Pri ApexCharts je nutné preštudovať si časový formát, ktorý používa. Viete si tak prispôsobiť podľa potreby čas na 12, alebo 24 hodinový formát. Taktiež pri dátumoch je možné používať pre čísla menej ako 10 hodnotu 0, teda napr. 01 02 03 a pod., rovnako tak mesiace je možné vypísať v rôznom formáte, či už formou čísel, alebo rôznych textových formátov s celým názovom mesiaca, alebo jeho skratkou.
Rovnako tak podporuje formatter, prostredníctvom ktorého je možné nastaviť špecifický formát tooltipu, ktorý vyskočí, ak kurzorom myši prejdete nad konkrétny bod. V mojom prípade sa k hodnote dopísala aj jednotka a rovnako tak aj názov veličiny, resp. merania (Hladina (cm)). Tento text bol vnorený do JS kódu, nakoľko je obsahom jazykového slovníka, ktorý je dosiahnuteľný z PHP. Tým sa tak v jednom kroku zrealizovalo to, že text sa dynamicky zmení podľa nastaveného jazyka vo webaplikácii. V súčasnosti je vo webaplikácii integrovaný slovenský, anglický, nemecký, ruský, francúzsky a španielský jazyk.
Detail tooltipu v slovenskej jazykovej sade:
Detail tooltipu v ruskej jazykovej sade:
Poďme sa teda pozrieť na rozdiely grafov pred a po zmene.
Pred:
Po (žiaľ, nemal som momentálne viac dát v systéme na ukážku):
Na obrázku Area grafu z knižnice ApexCharts je vidieť v jeho pravej hornej časti ikony. Sú to nástroje daného grafu, ktoré sú implementované priamo v knižnici a používateľ nemusí nič nastavovať. Tieto nástroje slúžia na priblíženie grafu, oddialenie grafu, alebo priblíženie konkrétnej sekcie, ktorú používateľ ťahom myši vyberie. Taktiež je tam ikona ruky, ktorá ak sa nemýlim, tak funguje na zastavenie animácie. V mojom prípade nevyužívam animáciu, ani dynamickú vizualizáciu dát (ak počas otvoreného grafu príde nový zápis), tak tento nástroj pri mojom použití nemá funkciu.
Ďalej je tam home button, ktorým sa graf nastaví na pôvodný rozsah, ako pri pôvodnom vykreslení, napr. ak používateľ doanalyzoval časť vybratého grafu a chce sa vrátiť späť a vidieť celý priebeh grafu. Aj tieto grafy sú plne responzívne a prispôsobia sa aj obrazovke telefónu. Práca s ikonami z telefónu je o niečo zložitejšia. Poslednou ikonou je možnosť stiahnuť si aktuálne zobrazený graf (áno, funguje to aj na priblížený výrez), ktorý si používateľ vie stiahnuť v rôznych formátoch - pixelový .PNG, vektorový .SVG, alebo exportný formát s dátami - .CSV.
V prípade .csv je exportovaná kompletná sada dát, teda používateľ dostane záznam s hodnotou hladiny vody a aj času, ku ktorému prislúcha. Čas je závislý na použitom formáte, napríklad graf s 2-hodinovým oknom používa len vizualizáciu hodín a minút, ale všetky ostatné Area grafy vizualizujú čas vo formáte s dňom, mesiacom a časom. Používateľ si tak pohodlne môže zo systému vyexportovať akékoľvek dáta, ktoré chce ďalej spracovať cez iné nástroje, napríklad MATLAB a podobne. Rovnako tak si môže grafy vyzualizovať inou metódou, napríklad v Exceli, Calcu, či Google Sheets. Exportovaný súbor dostane vždy random meno.
Z pohľadu implementácie týchto grafov miesto Google Charts to bolo trochu náročnejšie. Pôvodné PHP scripty, ktoré ťahali dáta z MySQL databázy potrebovali prerobiť v časti enkapsulácie dát do JSON poľa. Následne už ale použitie bolo ľahké vďaka prehľadnému Javascript kódu. Veľmi pomohla dokumentácia ApexCharts k implementácii v krátkom čase.
Viac o projekte hladinomer nájdete na jeho webe, kde môžete hladinomer vyskúšať kedykoľvek s vašim hardvérom: https://martinius96.github.io/hladinomer-studna-scripty/
Môžete si urobiť vlastnú programovú implementáciu pre váš hardvér, alebo využiť dostupné ukážkové zdrojové kódy pre open-source hardvér Arduino (ATmega), ESP8266, ESP32 (Arduino Core) a využiť dostupné komunikačné metódy cez Ethernet, PHY Ethernet, WiFi a iné.. Tieto programové implementácie sú urobené pre ultrazvukové senzory vzdialenosti, teda napr. HC-SR04, JSN-SR04T, URM09 DFROBOT a podobne.
Pre ESP32 sú dostupné aj programové implementácie vo frameworku ESP-IDF Espressif IoT Development Framework s podporou FreeRTOS, ktorý boli minulý týždeň aktualizované pre ESP-IDF v5.2, k dispozícii HTTP, i HTTPS variant pripojenia na web Hladinomera.
V poslednej časti som sa venoval ešte úprave updatovaných zdrojových kódov pre mikrokontroléry, ktoré boli dostupné aj na webe hladinomera priamo, ktoré stačilo prekopírovať a skompilovať, nakoľko dynamicky obsahovali umiestnenie podľa servera na ktorom boli uložené, aby sedela cesta k cieľovému PHP súboru pre zapis dát.
Využil som knižnicu highlight.js s niekoľkými rozšíreniami a ponechal som zdrojové kódy iba pre ESP32. Myslím, že v súčasnosti už veľa ľudí Arduino s Ethernetom do podobného projektu prať nebude, už je to prežitok ako ENC28J60, či Wiznety W5100, W5500, keď sú tu ďaleko lacnejšie a výkonnejšie alternatívy v podobe ESP32. Rovnako tak už aj ESP8266 je na ústupe a aj jeho Arduino Core nemalo update už viac ako rok.
ESP32 je tak oficiálnou vlajkovou loďou projektu, ktorá zvláda pripojenie po WiFi 4, resp. WiFi 6 podľa modulu a má podporu aj pre PHY Ethernet moduly, ktoré je možné pripojiť k ESP32 skrz rozhranie RMII, najčastejšie LAN8720.
Ponechal som tak jeden zdrojový kód pre WiFi, druhý pre PHY Ethernet pre každú z metód pripojenia - HTTP alebo HTTPS vo webaplikácii. Viac programových implementácii bude stále na Githube a môže ich použiť každý, kto chce, vrátane starších aj pre Arduino, či ESP8266 a budú tam aj ESP-IDF implementácie, skrátka program sa bez podporných súborov projektu neskompiluje tak ľahko ako v prípade Arduino IDE sketchu s jedným súborom.
Knižnicou highlight.js som dosiahol, že zdrojové kódy na webe projektu majú syntax zvýraznenú a vyzerajú tak ako zdroják v prostredí Arduino IDE. Je to síce len grafické zvýraznenie, ale verím, že si to komunita obľúbi a zvýši to aj mieru skúšania webového prostredia, ktoré je dostupné 24/7. Okrem knižníc bolo nutné pridať len code párový HTML element a vnoriť ho do medzi pre tagy, o všetko ostatné sa postarala už knižnica a nevyžadovala žiadny zásah do HTML dokumentu.
Trochu som sa pohral aj s hostorickými výpismi, ktoré sú vypísané do HTML tabuľky. Tabuľka mala aj funkciu zmazania záznamu, ak napríklad senzor kvôli poruche zaznamenal inú hodnotu, či bol senzor odstránený a posielal nesprávne dáta počas údržby studne a podobne. Používateľ na tejto stránke sa musel po kliknutí prihlásiť cez HTTP Auth, aby mohol request autorizovať a konkrétny záznam prislúchajúci konkrétnemu dátumu odstrániť z SQL databázy. Následne sa záznam hladinomera odstránil, ale aktualizovala sa aj celý HTML stránka.
Z toho dôvodu musel používateľ znova scrollovať a v prípade tisícov záznamov to bolo otravné. Využil som preto AJAX na asynchrónne volanie súboru, ktorý záznam odstráni s tým, že pôvodná HTML stránka ostáva v nezmenenej podobe a upraví sa aj HTML element dynamicky, ktorý riadok databázy z výpisu odstráni s efektom fade. Ak sa používateľ neprihlási, alebo zadá zlé meno a heslo, taktiež ho o neúspechu informuje aj systém priamo alertom. V predchádzajúcej verzii to bol len priamo výpis s HTTP hlavičkou 401 o Unauthorized stave.
Rovnako tak pre lepšiu orientáciu som do tabuľky pridal aj ID záznamu a ďalšie veci priamo z Bootstrap knižnice. Medzi to patrilo zvýraznenie hlavičky tabuľky s označením jednotlivých stĺpcov, došlo k miernemu resizingu ikón. Bola pridaná aj trieda tabuľky hover, ktorá pri prechádzaní s kurzorom zvýrazní aktuálny riadok, čo uľahčuje navedenie na tlačidlo. Do budúcna možno bude aj auto-paging systém.
Fragment AJAX scriptu pre fade HTML elementu riadku tabuľky, ktorý zanikne v dĺžke efektu 500 ms. Daný tr element zmizne aj z HTML tabuľky priamo, teda v tabuľke je efekt, teda vo výpise neostane diera po zmazaní riadku.
Vyskúšajte Watmonitor online s vašim hardvérom: https://hladinomer.eu/, prípadne si vytvorte vlastný senzorový uzol.