Interní meteostanice v učebnách

🖋 upravit

Stavy prostředí učeben lze monitorovat na adrese meteo.microlab.space.


Meteostanice jsou IoT zařízení postavené na hardwaru HARDWARIO Tower (dříve BigClown). Ten je vyráběný stejnojmennou českou firmou HARDWARIO, která se zabývá vývojem vlastní IoT elektroniky. Rozhodli jsme se použít tuto elektroniku nejen proto, že se sama nabízí právě na naše použití, ale i proto, že naše katedra od firmy HARDWARIO získala darem spoustu jejich zařízení.

Měřící jednotky

Měčící stanice jsou v podstatě postaveny jako oficiální CO2 Monitor Kit. Core modul tedy obsahuje oficiální firmware pro CO2 Monitor Kit a je i stejně zapojen, tj. Battery Module, CO2 module, Tagy pro měření teploty, vlhkosti a tlaku, Core Module a vpředu Cover Module. Vše je uzavřeno ve vytištěné krabičce.

Stanice odesílají data o stavu pomocí rádia.

Server

Server je zařízení, které přijíma data o stavech měřících stanic a zároveň data zpracovává. Běží na něm MQTT broker a Node-RED, na kterém je postavené i UI.

Instalace

Instalace proběhla podle dokumentace.

Firewall

apt install ufw
ufw default deny incoming
ufw allow in from <nginx-reverse-proxy-ip>
ufw enable

Program a UI

Node-RED flow:

[{"id":"7e6bdded.671214","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"6c54c074.21406","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013H/hygrometer/0:4/relative-humidity","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":270,"y":120,"wires":[["550301cc.92926"]]},{"id":"550301cc.92926","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"14251a25.aba736","order":5,"width":0,"height":0,"gtype":"gage","title":"Vlhkost","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#b5b5b5","#b1cde6","#4289ca"],"seg1":"","seg2":"","x":620,"y":120,"wires":[]},{"id":"26b00bd4.85bc04","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"14251a25.aba736","order":4,"width":0,"height":0,"gtype":"gage","title":"Teplota","label":"°C","format":"{{value}}","min":"0","max":"50","colors":["#5789b5","#8fe658","#ca4244"],"seg1":"","seg2":"","x":620,"y":280,"wires":[]},{"id":"3f60372b.a3d628","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013H/co2-meter/-/concentration","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":290,"y":200,"wires":[["9f76dbb.d4a9328","d6f199.84257e68"]]},{"id":"9f76dbb.d4a9328","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"14251a25.aba736","order":2,"width":0,"height":0,"gtype":"gage","title":"Koncentrace CO2","label":"ppm","format":"{{value}}","min":"300","max":"2000","colors":["#8fe658","#e6d260","#ca4244"],"seg1":"1000","seg2":"1500","x":650,"y":180,"wires":[]},{"id":"b76af9f2.d19eb8","type":"comment","z":"7e6bdded.671214","name":"R013H","info":"","x":390,"y":60,"wires":[]},{"id":"da1c8890.8a1bd8","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013H/thermometer/0:0/temperature","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":280,"y":280,"wires":[["26b00bd4.85bc04"]]},{"id":"e9a764d2.7bb0c8","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013J/hygrometer/0:4/relative-humidity","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":270,"y":460,"wires":[["270bc9ca.373656"]]},{"id":"270bc9ca.373656","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"76bb0228.e9031c","order":4,"width":0,"height":0,"gtype":"gage","title":"Vlhkost","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#b5b5b5","#b1cde6","#4289ca"],"seg1":"","seg2":"","x":620,"y":460,"wires":[]},{"id":"a920e2c8.636f3","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"76bb0228.e9031c","order":3,"width":0,"height":0,"gtype":"gage","title":"Teplota","label":"°C","format":"{{value}}","min":"0","max":"50","colors":["#5789b5","#8fe658","#ca4244"],"seg1":"","seg2":"","x":620,"y":620,"wires":[]},{"id":"c11268ab.ed1be8","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013J/co2-meter/-/concentration","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":290,"y":540,"wires":[["774fc04c.d3757","fb1d2008.2ea4a"]]},{"id":"774fc04c.d3757","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"76bb0228.e9031c","order":1,"width":0,"height":0,"gtype":"gage","title":"Koncentrace CO2","label":"ppm","format":"{{value}}","min":"300","max":"2000","colors":["#8fe658","#e6d260","#ca4244"],"seg1":"1000","seg2":"1500","x":650,"y":520,"wires":[]},{"id":"ddfd0912.11c438","type":"comment","z":"7e6bdded.671214","name":"R013J","info":"","x":390,"y":400,"wires":[]},{"id":"c3574ac4.8ca128","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013J/thermometer/0:0/temperature","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":280,"y":620,"wires":[["a920e2c8.636f3"]]},{"id":"24e7a4be.f1d84c","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013B/hygrometer/0:4/relative-humidity","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":270,"y":800,"wires":[["65407316.59ff0c"]]},{"id":"65407316.59ff0c","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"50804a81.7f1004","order":5,"width":0,"height":0,"gtype":"gage","title":"Vlhkost","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#b5b5b5","#b1cde6","#4289ca"],"seg1":"","seg2":"","x":620,"y":800,"wires":[]},{"id":"ff44697d.4846c8","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"50804a81.7f1004","order":4,"width":0,"height":0,"gtype":"gage","title":"Teplota","label":"°C","format":"{{value}}","min":"0","max":"50","colors":["#5789b5","#8fe658","#ca4244"],"seg1":"","seg2":"","x":620,"y":960,"wires":[]},{"id":"2d0ddbe0.d02844","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013B/co2-meter/-/concentration","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":290,"y":880,"wires":[["52967c8e.8c8924","f2b3ec96.197c3"]]},{"id":"52967c8e.8c8924","type":"ui_gauge","z":"7e6bdded.671214","name":"","group":"50804a81.7f1004","order":2,"width":0,"height":0,"gtype":"gage","title":"Koncentrace CO2","label":"ppm","format":"{{value}}","min":"300","max":"2000","colors":["#8fe658","#e6d260","#ca4244"],"seg1":"1000","seg2":"1500","x":650,"y":860,"wires":[]},{"id":"4a087e89.6c8f1","type":"comment","z":"7e6bdded.671214","name":"R013B","info":"","x":390,"y":740,"wires":[]},{"id":"8c67b534.520768","type":"mqtt in","z":"7e6bdded.671214","name":"","topic":"node/R013B/thermometer/0:0/temperature","qos":"2","datatype":"auto","broker":"6f3564ce.64310c","x":280,"y":960,"wires":[["ff44697d.4846c8"]]},{"id":"e1b256de.26d8c8","type":"ui_text","z":"7e6bdded.671214","group":"14251a25.aba736","order":3,"width":0,"height":0,"name":"","label":"Stav:","format":"{{msg.payload}}","layout":"row-center","x":770,"y":220,"wires":[]},{"id":"d6f199.84257e68","type":"function","z":"7e6bdded.671214","name":"set text","func":"if(msg.payload < 1000){\n    msg.payload = \"Optimální\";\n}\nelse if(msg.payload < 1500){\n    msg.payload = \"Vysoká koncentrace\";\n}\nelse {\n    msg.payload = \"Kritická koncentrace!\"\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":620,"y":220,"wires":[["e1b256de.26d8c8"]]},{"id":"62d4223c.c471bc","type":"ui_text","z":"7e6bdded.671214","group":"50804a81.7f1004","order":3,"width":0,"height":0,"name":"","label":"Stav:","format":"{{msg.payload}}","layout":"row-center","x":770,"y":900,"wires":[]},{"id":"f2b3ec96.197c3","type":"function","z":"7e6bdded.671214","name":"set text","func":"if(msg.payload < 1000){\n    msg.payload = \"Optimální\";\n}\nelse if(msg.payload < 1500){\n    msg.payload = \"Vysoká koncentrace\";\n}\nelse {\n    msg.payload = \"Kritická koncentrace!\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":900,"wires":[["62d4223c.c471bc"]]},{"id":"99a974f0.24fb68","type":"ui_text","z":"7e6bdded.671214","group":"76bb0228.e9031c","order":2,"width":0,"height":0,"name":"","label":"Stav:","format":"{{msg.payload}}","layout":"row-center","x":770,"y":560,"wires":[]},{"id":"fb1d2008.2ea4a","type":"function","z":"7e6bdded.671214","name":"set text","func":"if(msg.payload < 1000){\n    msg.payload = \"Optimální\";\n}\nelse if(msg.payload < 1500){\n    msg.payload = \"Vysoká koncentrace\";\n}\nelse {\n    msg.payload = \"Kritická koncentrace!\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":560,"wires":[["99a974f0.24fb68"]]},{"id":"6f3564ce.64310c","type":"mqtt-broker","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"14251a25.aba736","type":"ui_group","name":"R013H - Hnědá","tab":"6390d0b3.d0714","order":2,"disp":true,"width":"6","collapse":false},{"id":"76bb0228.e9031c","type":"ui_group","name":"R013J - Modrá","tab":"6390d0b3.d0714","order":3,"disp":true,"width":"6","collapse":false},{"id":"50804a81.7f1004","type":"ui_group","name":"R013B - Zelená","tab":"6390d0b3.d0714","order":4,"disp":true,"width":"6","collapse":false},{"id":"6390d0b3.d0714","type":"ui_tab","name":"Statistiky prostředí v učebnách","icon":"wb_cloudy","disabled":false,"hidden":false}]

Reverzní proxy z Internetu

Na UI, které je v podstatě jen webová aplikace, směřuje z našeho web serveru reverzní http proxy, která aplikaci přesměruje ke klientovi.

location / {
	proxy_pass http://<address>:<port>/ui/;
}

Zobrazovač

Konstrukce

Tělo prototypu je vygravírováno z překližky za použití laseru. LCD je z přední části chráněno polyakrilátem také vyřezaného laserem. V původní konstrukci se LCD lepilo na plexisklo, proto byli vytištěny rohové plastové separátory, které odsazují LCD od čelní desky. Všechny výkresy a modely jsou ke stažení na našem gitu.

Počítač

Jádrem je počítač Raspberry Pi Zero W. To jsme vybrali z důvodu malých rozměrů a integrovaného IEEE 802.11. Díky tomu nemusíme ke každému displeji tahat zvláštní síťové kabely.

Operační systém

Na Raspberry PI jsme zvolili systém Alpine Linux, nikoliv běžný Raspbian. Důvodem zvolení Alpine je fakt, že Debian, ze kterého vznikl Raspbian, je podle nás špatně navržený a zbytečně obrovský. Obsahuje i software, který nemáme rádi, tj. systemd a podobné věci.

Raspberry PI má otevřený přístup pouze na SSH a ostatní příchozí komunikace jsou blokovány. SSH je autentizováno pomocí asymetrických klíčů.

Kiosk mód

xinit /usr/bin/midori -e Fullscreen -a https://meteo.microlab.space

Automatické vypínání displeje

Není třeba, aby displej svítil i během doby, kdy je budova uzavřena. Ovládat power management displeje lze pomocí utility xset. Do systému je třeba doinstalovat balíček x11-xserver-utils.

Záznam v crontabu poté vypadá následovně.

0 8 * * 1-5 /usr/bin/env DISPLAY=:0 /usr/bin/xset dpms force on
0 16 * * 1-5 /usr/bin/env DISPLAY=:0 /usr/bin/xset dpms force off