====== Node RED ====== Nodered jsem instaloval v dockeru pomoci [[it:server:docker|IOTstack]]. Instalace v dockeru má nějaká omezení - zejména co se týče nodu **exec**. Proto je velmi užitečné prostudovat [[https://sensorsiot.github.io/IOTstack/Containers/Node-RED/|dokumentaci k IOTstack k Node-RED]]. ===== problém se seriovým portem ===== Při rozběhnutí [[https://flows.nodered.org/node/node-red-node-serialport|sériového portu v Noderedu]] jsem měl několik problémů. Nejprve mi Nodered psal, že se nepodařilo k /dev/ttyUSB0 připojit. To jsem vyřešil editací docker-compose.yml: services: nodered: container_name: nodered build: context: ./services/nodered/. args: - DOCKERHUB_TAG=latest - EXTRA_PACKAGES= restart: unless-stopped user: "0" environment: - TZ=Etc/UTC ports: - "1880:1880" volumes: - ./volumes/nodered/data:/data - ./volumes/nodered/ssh:/root/.ssh - /var/run/docker.sock:/var/run/docker.sock - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket devices: - "/dev/ttyUSB0:/dev/ttyAMA0" - "/dev/vcio:/dev/vcio" - "/dev/gpiomem:/dev/gpiomem" Púvodně bylo v devices tohle: **/dev/ttyAMA0:/dev/ttyAMA0**. Do Noderedu jsem chtěl ale posílat ttyUSB0, tak jsem to změnil na **/dev/ttyUSB0:/dev/ttyAMA0** a v dockeru budu přistupovat k zařízení /dev/ttyAMA0. Další problém, který se objevil byl, že když jsem nastavil nodered, tak havaroval s hlášením **segmentatin fault** vždycky, když se měl připojit k **/dev/ttyAMA0**. Takže se docker neustále restartoval. [[https://discourse.nodered.org/t/serialport-use-leads-to-segmentation-fault-when-using-docker/69487|V této diskusi]] jsem našel pomoc. Nejprve jsem se připojil do dockeru s noderedem. docker exec -it nodered bash Dále jsem zkusil vytvořil soubor test.js s tímto obsahem: const { SerialPort } = require("serialport"); var port = new SerialPort({path: '/dev/ttyAMA0', baudRate: 115200}); A otestovat spuštění: bash-5.1# node test.js Problém se pořád projevoval. Když jsem podle doporučení provedl rebuild pluginů, testovací příkaz prošel a modul opravdu začal fungovat. bash-5.1# npm rebuild --build-from-source Najednou v logu noderedu vidím namísto segfault tohle: 3 Jan 16:50:22 - [info] [serialconfig:2268525fcaad5010] serial port /dev/ttyAMA0 opened at 115200 baud 8N1 K vyčítání dat z mého zařízení na sériovém portu z Noderedu mi posloužil [[https://www.brainboxes.com/faq/bb400-serial-port-nodered|tento návod]]. Takto vypadá jednoduché propojení v Noderedu: {{:it:iot:pasted:20230103-183211.png}} A takto jsem musel nakonfigurovat sériovou linku pro mé zařízení: {{:it:iot:pasted:20230103-183304.png}} Samotnou zprávu pak posílám v json formátu: {{:it:iot:pasted:20230103-183346.png}} ===== vytvoření Node RED Dashboard ===== [[https://randomnerdtutorials.com/getting-started-node-red-dashboard/|Tutoriál popisuje]] jak vytvořit grafickou nástěnku pro Node RED. ===== zabezpečení Node RED ===== Při zabezpečení jsem čerpal z manuálu [[http://stevesnoderedguide.com/securing-node-red-ssl|Securing Node-Red with SSL and Username Authentication]]. ==== Komunikace přes SSL ==== Nejprve je potřeba vytvořit certifikáty. Protože jsem nechtěl vytvářet další certifikační autoritu, využil jsem certifikáty, které mi připravil skript v dokumentu [[it:iot:mosquitto|]]. Skript mi vytvořil certifikát **server-key.pem** a **server-cert.pem**. Jen pro úplnost. Node RED i Mosquitto mi běží na jednom serveru. Proto si mohu dovolit použít stejné certifikáty. Pokud by každá služba běžela na jiném serveru, musel bych vygenerovat nové certifikáty pro konkrétní IP adresu. Poté jsem editoval konfigurační soubor **settings.js** pro Node RED ve kterém jsem zadal absolutní cesty k certifikátům a zapnul vyžadování HTTPS. Bez absolutních cest nemohl Node RED najít certifikáty: https: function() { // This function should return the options object, or a Promise // that resolves to the options object return { key: require("fs").readFileSync('/data/server-key.pem'), cert: require("fs").readFileSync('/data/server-cert.pem') } }, requireHttps: true, ==== Přihlašování admina do editoru ==== Nejprve jsem si vygeneroval nové zaheshované heslo: docker exec -it nodered bash bash-5.1# node-red-admin hash-pw Password: $2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN. Poté v souboru settings.js odkomentuju následující řádky a nahradím hash hesla: adminAuth: { type: "credentials", users: [{ username: "admin", password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.", permissions: "*" }] }, Restartuju kontejner a při startu se mi už ke konfiguraci načítá přihlašovací obrazovka. {{:it:iot:pasted:20230104-235615.png}} ===== spouštění příkazů mimo kontejner ===== Protože Node RED běží v kontejneru, tak se všechny příkazy spustí uvnitř. V [[https://sensorsiot.github.io/IOTstack/Containers/Node-RED/|manuálu]] je popsáno, že když chci spouštět příkazy mimo kontejner, tak je řešení skrze SSH. Abych nemusel pokaždé vyplňovat heslo, vygeneruji klíč, kterým se přes ssh automaticky autentizuji. Nejprve je potřeba na straně docker kontejneru spusti následující: docker exec -it nodered ssh-keygen -q -t ed25519 -C "Node-RED container key-pair" -N "" Poté přenést klíč na raspberry, na kterém budu chtít povolit, aby se Node RED automaticky připojil. docker exec -it nodered ssh-copy-id myrpiuser@192.168.1.20 A nyní mohu otestovat, zda to funguje. Spustím v kontejneru v Node RED příkaz, který vypíše obsah adresáře mého Raspberry. docker exec -it nodered ssh myrpiuser@192.168.1.20 ls -l Pokud nechci zadávat dlouhé názvy serveru, mohu si vytvořit v kontejneru konfigurační soubor pro ssh. Soubor vytvořím v kontejneru v **/root/.ssh** host iot-dev hostname 192.168.1.20 user myrpiuser IdentitiesOnly yes IdentityFile /root/.ssh/id_ed25519 Pro jistotu upravit práva: chmod 644 config sudo chown root:root config No a nyní mohu volat ssh příkazy jednodušeji. docker exec -it nodered ssh iot-dev ls -l A tady ukázka z Node RED: {{:it:iot:pasted:20230105-101637.png}} ===== node-red-node-mysql ===== Chtěl jsem využít node [[https://flows.nodered.org/node/node-red-node-mysql|node-red-node-mysql ]] pro ukládání dat do databáze na hostovaném počítači. Situace se má tak, že na počítači mi běží MySQL databáze, která není v Dockeru. Je to z historických důvodů - ještě jsem neznal Docker. V Dockeru mi ale běží Node RED a chci, aby přistupoval k localhostu hostnovaného počítače, na kterém naslouchá MySQL databáze. První překážka k tomu, aby se Node RED dokázal připojit k databázi je, že pokud zadám v Node RED localhost, tak se bude snažit připojit na port MySQL databáze v Node RED, kde žádná databáze neběží. O mém problému popisuje tato [[https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach| diskuse]]. Zkoušel jsem nejdříve, aby MySQL naslouchala na IP adrese síťového bridge Node RED, ale pak bych musel vyřadit naslouchání MySQL na localhostu. A to jsme nechtěl. Proto jsem zvolil variantu, kdy kontejner v Node RED dostane k dispozici localhost hostitelského počítače. Není to úplně doporučované řešení, nicméně aktuálně mi to problém řeší a tím, že Node RED také může běžet pouze na localhostu, tak mi to až tak nevadí. Konfigurace Node RED pro docker-composer tedy vypadá takto (přidán parametr **network_mode: host**): version: '3.6' services: nodered: container_name: nodered ports: - '127.0.0.1:1880:1880' environment: - LANG=cs_CZ.UTF-8 - TZ=Europe/Prague volumes: - './volumes/nodered/data:/data' image: nodered/node-red network_mode: host To mi pomohlo, aby byla databáze dostupná. Pak jsem ale narazil na to, že uživatel neměl do databáze přístup. Setkal jsem se s hlášením: //Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'root'@'localhost' (using password: YES)// Z hostitelského počítače jsem problém s připojením neměl, takže to byl problém z kontejneru s Node RED. Někdo přede mnou měl také podobný problém: [[https://stackoverflow.com/questions/53283060/node-js-and-mysql-not-connecting-client-does-not-support-authentication-protoco|Node JS and mysql not connecting (client does not support authentication protocol requested by server consider upgrading mysql client)]] a vytvořil skript v kontejneru, který posloužil i mě na odhalení problému: const mysql = require('mysql2'); var connection = mysql.createConnection({ host : 'localhost', user : 'root', port : '3306', password : 'test12310', database : 'fys' }); connection.connect((err) => { if(!err) console.log('Database is geconnect!'); else console.log('Database connectie niet gelukt! : '+ JSON.stringify(err, undefined,2)); }); Skript jsem pak spustil v kontejneru: node jmenoskriptu.js Nakonec jsem přišel na to, že problém byl v MySQL databázi u uživatele. Vytvořil jsem uživatele s omezeným oprávněním přístupu do databáze. Namísto uživatele **mujzivatel@localhost** jsem měl vytvořil uživatele **mujuzivatel@%**. Tady se promítá to, že nepřistupuji jako uživatel z localhostu, ale kontejneru. V mém případě jsem u modulu zjistil ještě jednu zradu. Pro každý příkaz, který jde na nod MySQL, se vytvoří zvlášť připojení do MySQL databáze. Protože mám počet připojení do databáze limitovaný, tak při velkém počtu připojení mi databáze spadla. Dalším průzkumem jsem zjistil, že v pluginu je max connection nastaven na 50. Například [[https://discourse.nodered.org/t/mysql-too-many-connections/68943/4| tady]] je o tom diskuse. Pro vypsání všech uživatelů a procesů v databázi slouží dotaz: show processlist; V kódu pluginu jsem vyčetl tento řádek: connectionLimit: RED.settings.mysqlConnectionLimit || 50, Řádek říká, že pokud je nastavená proměnná **RED.settings.mysqlConnectionLimit** v Node RED, tak vezme číslo z ní a pokud nastavená není, tak defaultní connectionLimit je 50. Řešením pro mě bylo nastavit proměnnou v Node RED v souboru **settings.js**: module.exports = { // tady přidávám proměnnou pro limit spojení s databází // přidání musí být za definicí module.exports = { mysqlConnectionLimit: 5, } ===== Animace v Node RED ===== Toto video popisuje práci s pluginem [[https://flows.nodered.org/node/node-red-contrib-ui-svg|node-red-contrib-ui-svg]], který vypadá poměrně zajímavě právě na tvorbu animací v NodeRED. {{youtube>sQx7dC1xtsk?}} Nabízí se připravit si v Inkscape SVG grafiku a pak jí v NodeRED dodělat "animace". {{youtube>8d3fbDEnuFo?}} ===== tutoriály na Node RED ===== * [[https://www.youtube.com/watch?v=L4RTrXKXd7M| How to create a data table in Node RED Dashboard]] * [[https://www.youtube.com/playlist?list=PLyNBB9VCLmo1hyO-4fIZ08gqFcXBkHy-6|Official channerl Node-RED Essesntials]] * [[https://www.youtube.com/playlist?list=PL5OK9BbV3Q0MmbrS_sxhNxY3wZ0ZI8YmK|Node-RED UIBuilder]] {{youtube>wX1_6W2GmNI?}} {{youtube>lBTIo-z9fSI?}} ==== InfluxDB ==== {{youtube>yHTWzFpgCuk?}} ==== InfluxDB2 ==== Zdá se, že je pouze pro 64 bit verzi operačního systému. Takže minimálně RPi4 a 64 bit verzi. {{youtube>4_kCNBfv1t4?}} {{youtube>T6lf39TYjAY?}} {{youtube>0osGkVHMugI?}}