Differenze tra le versioni di "Centralina livello 1"
(70 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
<div style="float:right;border:1px solid black;padding:10px;margin:10px background:#F5F6CE; border:1px solid #a7d7f9; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;" "> | <div style="float:right;border:1px solid black;padding:10px;margin:10px background:#F5F6CE; border:1px solid #a7d7f9; vertical-align:top; color:#000; padding: 5px 10px 10px 8px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius:10px;" "> | ||
− | {| | + | {| style="text-align:center" |
− | ! | + | ![[File:Livello1-Debug.png|300px]] |
|- | |- | ||
| <hr> | | <hr> | ||
Riga 9: | Riga 9: | ||
|Centralina generale (?) gestione segnali | |Centralina generale (?) gestione segnali | ||
|- | |- | ||
− | |Repository: | + | |Repository: https://github.com/raspibo/Livello1 |
|} | |} | ||
</div> | </div> | ||
Riga 16: | Riga 16: | ||
= Centralina livello 1 = | = Centralina livello 1 = | ||
+ | |||
+ | ;ATTENZIONE | ||
+ | :Tutte le immagini sono puramente indicative, il progetto e` in pieno sviluppo, tutto e` passibile di modifiche, anche sostanziali. | ||
+ | :L'immagine di presentazione si riferisce alla sezione "debug", realizzata con Dokuwiki e (ad oggi) non fa parte del progetto (o si ?) | ||
+ | |||
== Prima e sommaria descrizione == | == Prima e sommaria descrizione == | ||
Riga 21: | Riga 26: | ||
Centralina di controllo segnali. | Centralina di controllo segnali. | ||
− | + | :(Ad oggi) | |
+ | :Acquisisce segnali, li suddivide in gruppi mono o multi utenza, dei quali: realizza grafici temporali, crea e gestisce allarmi. | ||
+ | |||
+ | |||
+ | Dal campo arrivano i valori della 'sensoristica' sottoforma di "Identificatore Valore", da queste informazioni sono aggiunti i sensori che eventualmente non sono presenti e le relative 'liste' dei valori (sono generate due chiavi, una dell'utenza e l'altra dei valori), altrimenti viene solo accodato il valore nella rispettiva lista (aggiungendo data-ora-minuti-secondi). | ||
+ | |||
+ | Acquisiti i sensori, e` possibile il loro raggruppamento (anche una sola utenza) ed il campionamento dei valori a tempi prestabiliti (generazione grafici tempo/valore). | ||
+ | |||
+ | Sempre previo raggruppamento (sempre "anche di un solo sensore"), e` possibile attivare/disattivare i relativi allarmi, il classico ON/OFF, ma anche un'automatico (che per esempio attivi i sensori del solaio/cantine dalle 20 alle 8, quando e` certo che nessuno si rechi in quegli spazi). | ||
+ | |||
+ | E poi il resto .. che sarebbe di arrivare non solo a leggere/interpretare segnali, ma anche a pilotare utenze (luci, serrande, elettrodomestici, ...) | ||
− | + | L'idea e` che tutto questo sia gestibile da: | |
+ | # interfaccia web | ||
+ | #* browser | ||
+ | #* cellulare | ||
+ | # linea di comando | ||
+ | # terminali operatore (display+tastiere) | ||
+ | # pulsanti, lampade, selettori, .. | ||
+ | # ... | ||
== Hardware e Software == | == Hardware e Software == | ||
;Hardware | ;Hardware | ||
− | :[[Raspberry Pi 3]], perche` completa di WiFi e Bluetooth | + | :Versione 1 - [[Raspberry Pi 3]], perche` completa di WiFi e Bluetooth |
+ | :Versione 2 (2018) - [[Raspberry Pi]] con chiavetta WiFi | ||
;Software | ;Software | ||
Riga 39: | Riga 62: | ||
: ... | : ... | ||
− | === Access Point | + | Sistema operativo: |
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | $ lsb_release -a | ||
+ | No LSB modules are available. | ||
+ | Distributor ID: Raspbian | ||
+ | Description: Raspbian GNU/Linux 11 (bullseye) | ||
+ | Release: 11 | ||
+ | Codename: bullseye | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | <!-- Embedded page --> | ||
+ | {{:Raspberry_Pi-Raspbian_default_post-install}} | ||
+ | |||
+ | == Access Point == | ||
Installato/configurato "[[Raspberry Pi Access Point WEP2]]", sfruttando il wifi integrato nel [[Raspberry Pi 3]]. | Installato/configurato "[[Raspberry Pi Access Point WEP2]]", sfruttando il wifi integrato nel [[Raspberry Pi 3]]. | ||
− | + | == Install == | |
+ | Installazione dei pacchetti utili, necessari (e qualcuno inutile): | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | apt install nginx fcgiwrap redis-server python3-redis mosquitto ssl-cert php8.0-fpm php8.0-xml python3-pip python3-paho-mqtt python3-pandas python3-cairosvg python3-tinycss python3-cssselect git mosquitto-clients redis-tools | ||
+ | pip3 install python-telegram-bot pygal | ||
+ | </pre> | ||
+ | |||
+ | Nelle precedenti versioni fu installato manualmente anche [http://www.dokuwiki.org dokuwiki], utilizzato per segnarsi appunti vari (e un po` di debug), e` facoltativo e non descritto le operazioni necessarie, ma i files di configurazione del web server si. | ||
+ | |||
+ | E` necessario scaricare il repository con i programmi (script python per lo piu`), si puo` fare da normale utente, per esempio: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | mkdir git | ||
+ | cd git | ||
+ | git clone https://github.com/raspibo/Livello1.git | ||
+ | cd Livello1 | ||
+ | </pre> | ||
+ | |||
+ | ==== Nginx ==== | ||
+ | |||
+ | Copiare i nuovi files di configurazione dal repository ed eliminare il web server configurato di default: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | cp etc/nginx/sites-available/level1 /etc/nginx/sites-available/ | ||
+ | ln -s /etc/nginx/sites-enabled/level1 /etc/nginx/sites-enabled/ | ||
+ | #cp etc/nginx/dokuwiki* etc/nginx/fcgiwrap.conf /etc/nginx/ # se installate dokuwiki | ||
+ | cp etc/nginx/fcgiwrap.conf /etc/nginx/ | ||
+ | rm /etc/nginx/sites-enabled/default | ||
+ | </pre> | ||
+ | |||
+ | Abbiamo effettuato tutte le operazioni come "root", ma assicuratevi che il proprietario sia corretto, se non lo e`: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | chown root:root -R /etc/nginx/ | ||
+ | </pre> | ||
+ | |||
+ | Potreste gia` riavviare il web server, ma non abbiamo ancora completato, riavvieremo il sistema alla fine di tutto, ma se volete: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo sytemctl restart nginx | ||
+ | </pre> | ||
+ | dovrebbe funzionare. | ||
+ | |||
+ | ==== Level1 (www) ==== | ||
+ | |||
+ | Ho messo tutti i files/script nella directory del web server. | ||
+ | |||
+ | Li copiamo dal repository e settiamo il giusto proprietario: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | cp -vapu var/www/ /var/ | ||
+ | chown www-data:www-data -R /var/www/ | ||
+ | </pre> | ||
+ | |||
+ | Serve anche la scrittura in "www": | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | chmod 775 /var/www | ||
+ | chown :www-data -R /var/www # oppure si poteva eliminare il "/" dal "chown" precedente | ||
+ | </pre> | ||
+ | |||
+ | ;Nota | ||
+ | :I permessi sono 755, quindi i files sono eseguibili da chiunque. | ||
+ | :Potrebbe essere necessario creare la directory "/var/www/archive" | ||
+ | |||
+ | ==== Mosquitto ==== | ||
+ | |||
+ | Copiare il file di configurazione dal repository ed assicurarsi i giusti permessi e proprietario: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | cp etc/mosquitto/conf.d/myadd.conf /etc/mosquitto/conf.d/ | ||
+ | chown root:root /etc/mosquitto/conf.d/myadd.conf | ||
+ | chmod 644 /etc/mosquitto/conf.d/myadd.conf | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | ==== Telegram Bot ==== | ||
+ | |||
+ | Scaricare il repository: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | cd ~/git | ||
+ | git clone hhttps://github.com/raspibo/bot4livello1.git | ||
+ | cd bot4livello1 | ||
+ | </pre> | ||
+ | |||
+ | Questo programma fu creato in origine nella directory "/home/pi/project/csv2image2telegram", quindi tutti i riferimenti sono a questa, copiate qua il programma oppure modificate la directory dove necessario ("/etc/rc.local"). | ||
+ | |||
+ | Il programma dev'essere esguito al boot di sistema e rimanere sempre in esecuzione. | ||
+ | |||
+ | ==== Avvio ==== | ||
+ | |||
+ | All'avvio del sistema, devono andare in esecuzione alcuni script (quasi "daemons") e rimanere attivi, per questo si deve modificare il file "/etc/rc.local" (lo trovate nel repository git): | ||
+ | |||
+ | ;/etc/rc.local | ||
+ | :Ho aggiunto le seguenti righe prima della "exit 0" | ||
+ | <pre style="color:green;overflow:auto"> | ||
+ | # Power On "Level 1" | ||
+ | DAEMON_NAME=mqtt2redis_d | ||
+ | PID=`ps -e -o pid,cmd | grep "$DAEMON_NAME[.]py" | awk '{ print $1 }'` | ||
+ | if [ $PID ] | ||
+ | then | ||
+ | echo "Non si e\` avviata correttamente Livello 1, oppure mqtt2redis_d e\` gia\` avviato:" | ||
+ | echo "Actual PID is: $PID" | ||
+ | else | ||
+ | echo "Avvio \"mqtt2redis_d\"" | ||
+ | #/var/www/cgi-bin/mqtt2redis_init.d.sh start # 20180115 | ||
+ | su -c "/var/www/cgi-bin/mqtt2redis_init.d.sh start" pi | ||
+ | # .. e un messaggio a centred quando si [ri]avvia | ||
+ | redis-cli -h centred hmset msg:alert:level1:$(date +\%Y\%m\%d\%H\%M\%S) type "alert" desc "Centralina level 1 [ri]avviata .." value "on" um "" date "$(date +\%Y/\%m/\%d\ \%H:\%M:\%S)" | ||
+ | fi | ||
+ | |||
+ | # Start Telegram Bot | ||
+ | DAEMON_NAME=bot4livello1 | ||
+ | PID=`ps -e -o pid,cmd | grep "$DAEMON_NAME[.]py" | awk '{ print $1 }'` | ||
+ | if [ $PID ] | ||
+ | then | ||
+ | echo "Non si e\` avviato il Telegram Bot, oppure era gia\` avviato:" | ||
+ | echo "Actual PID is: $PID" | ||
+ | else | ||
+ | echo "Avvio Telegram Bot" | ||
+ | cd /home/pi/project/csv2image2telegram | ||
+ | su pi -c "python3 bot4livello1.py &" | ||
+ | # .. e un messaggio a centred quando si [ri]avvia | ||
+ | redis-cli -h centred hmset msg:alert:level1:$(date +\%Y\%m\%d\%H\%M\%S) type "alert" desc "Avvio bot4livello1.py" value "on" um "" date "$(date +\%Y/\%m/\%d\ \%H:\%M:\%S)" | ||
+ | cd / | ||
+ | fi | ||
+ | </pre> | ||
+ | |||
+ | Inoltre, visto che puo` capitare s'interrompano, specialmente nelle prove di nuovi [[Centralina_livello_1#Devices|devices]], sono predisposti dei "check orari" che nel caso, li riavviano: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | cp -vapu etc/cron.hourly/mqtt2redis_check /etc/cron.hourly/ | ||
+ | cp -vapu etc/cron.hourly/bot4livello1_check /etc/cron.hourly/ # se installerete anche il bot telegram | ||
+ | </pre> | ||
+ | |||
+ | Ho anche previsto un messaggio settimanale di centralina in funzione tramite crontab dell'utente pi, copiate il file: | ||
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | cp -vapu var/spool/cron/crontabs/pi /var/spool/cron/crontabs/ | ||
+ | chown root:root /var/spool/cron/crontabs/pi | ||
+ | chmod 600 /var/spool/cron/crontabs/pi | ||
+ | </pre> | ||
+ | oppure aggiungete la linea (col comando "crontab -e"): | ||
<pre style="color:green;overflow:auto"> | <pre style="color:green;overflow:auto"> | ||
− | + | 0 7 * * 0 redis-cli -h centred hmset msg:redis:alive:$(date +\%Y\%m\%d\%H\%M\%S) type "alert" desc "Messaggio ciclico, centralina $(hostname) in funzione" value "on" um "" date "$(date +\%Y/\%m/\%d\ \%H:\%M:\%S)" > /dev/null | |
− | + | </pre> | |
− | |||
− | |||
− | + | ==== Backup ==== | |
− | |||
− | + | Oltre ad un "backup" che si occupa di salvare tutti i computer's della rete, ho aggiunto uno script per salvare giornalmente il database redis, come ulteriore sicurezza, i files sono salvati nella directory "/root": | |
+ | <pre style="background-color:black;color:white;overflow:auto"> | ||
+ | sudo su | ||
+ | cp -vapu etc/cron.daily/backupredis /etc/cron.daily/ | ||
</pre> | </pre> | ||
− | |||
== Rete == | == Rete == | ||
Riga 83: | Riga 261: | ||
::... | ::... | ||
− | == | + | === Configurazione e Funzionamento === |
+ | |||
+ | (Sommariamente) | ||
+ | |||
+ | Al primo avvio e` necesssario configurare prima il database Redis da utilizzare, poi quello della [[CentRed|centralina avvisi/allarmi]] (se avete intenzione di ricevere le comunicazioni relative agli allarmi e/o avvisi di malfunzionamenti). | ||
+ | |||
+ | Una volta "letti" i segnali, e` opera dell'utente aggiungere alcune caratteristiche [[#Segnali]], fatto questo si passa alla creazione dei [[#Gruppi]]. | ||
+ | |||
+ | Definiti i [[#Gruppi]], si passa ad avviare i servizi necessari [[#Daemons]], che si occupano di generare i grafici Tempo-Valore/i o gestione degli allarmi/anomalie. | ||
+ | |||
+ | == Arrivo dati e manipolazione == | ||
+ | |||
+ | I dati devono arrivare al broker MQTT nel formato: | ||
+ | |||
+ | '''{ "ID" : "Identificatore", "Valore" : "0" }''' | ||
+ | |||
+ | inviati nel topic: | ||
+ | |||
+ | '''TipoIO/PosizioneC/PosizioneP/PosizioneS/Tipo''' | ||
+ | |||
+ | |||
+ | Fate riferimento alla [[#Tabella dati e valori]] per comprendere meglio il significato. | ||
+ | |||
+ | Nell'immagine, una schermata dei test in corso, a sinistra gli errori di lettura, a destra un listato della "cgi-bin", sotto i falsi dati inviati (mi servono per i test che sto` facendo ;) ), e in fondo i dati ricevuti (veri e falsi). | ||
+ | |||
+ | [[File:Level1 201604170814.png|800px]] | ||
+ | |||
+ | |||
+ | === mqtt2redis_d.py === | ||
+ | |||
+ | I dati MQTT vengono letti dal programma "mqtt2redis_d.py" che deve sempre essere in esecuzione (ho gia` preparato anche un "init.d", che tengo ancora nella "cgi-bin"), questi li manipola inserendoli se non presenti, in due "chiavi" nel database (noSQL) Redis, la prima, e` per identificare il segnale: | ||
+ | |||
+ | '''TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID''' | ||
+ | |||
+ | la seconda e` quella dei valori: | ||
+ | |||
+ | '''TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori''' | ||
+ | |||
+ | valori che sono accodati ad ogni arrivo con l'aggiunta della data e ora, predisposti per una generazione di output in formato "csv". | ||
+ | |||
+ | == ''IMPORTANTE'' == | ||
+ | |||
+ | ''Quello che segue non e` aggiornato di pari passo con l'aggiornamento del software e quant'altro necessario.'' | ||
+ | |||
+ | ''Durante l'uso, nelle pagine di configurazione e modifica compaiono delle descrizioni che sono piu` veritiere/aggiornate, perche` scritte durante la stesura e/o modifica del software.'' | ||
+ | |||
+ | == Segnali == | ||
+ | |||
+ | Una volta pervenuto il primo valore di un segnale, e` possibile configurarlo inserendo alcuni dati che non sono presenti nella comunicazione MQTT: | ||
+ | |||
+ | ;Descrizione | ||
+ | :Meglio se breve, perche` usata anche nei riferimenti dei grafici, non solo per gli allarmi (per esempio: "ST1 Cucina" per sensore temperatura in cucina) | ||
+ | ;UM (Unita` di misura) | ||
+ | ;TempoRitardo | ||
+ | :Ancora non usata | ||
+ | ;RangeValori | ||
+ | :Specificare il range dei valori nel formato 0,100 | ||
+ | :Utile per sonde che (per esempio) lavorano da 0 a 100 gradi | ||
+ | :Genera avviso/allarme se minore di o maggiore di | ||
+ | ;ValoreMin | ||
+ | :Avviso se valore e` inferiore a quello impostato | ||
+ | ;ValoreMax | ||
+ | :Aavviso se valore e` superiore a quello impostato | ||
+ | ;ValoreOn | ||
+ | :Previsto per i segnali analogici o negati | ||
+ | :Avviso quando valore uguale a ValoreOn | ||
+ | ;Allarme | ||
+ | :Definire qua i valori che saranno usati come allarmi, per esempio: ValoreOn,ValoreMin | ||
+ | :Se sono impostati, ma non indicati qua, sono emessi dei semplici avvisi | ||
+ | |||
+ | Esempio di una configurazione di sonda temperatura (ovviamente falsa): | ||
+ | |||
+ | [[File:Livello1-KeysHashTempMod Falsa2.png|800px]] | ||
+ | |||
+ | Esempio di una configurazione di sensore di movimento (pir, ovviamente falso): | ||
+ | |||
+ | [[File:Livello1-KeysHashPirMod Falso2.png|800px]] | ||
+ | |||
+ | == Gruppi == | ||
+ | |||
+ | Per realizzare i raggruppamenti ho utilizzato le chiavi Redis di tipo "sets". | ||
+ | |||
+ | Al momento ho pensato ai soli gruppi riguardanti gli allarmi e i grafici (per esempio quelli di due o piu`, sonde di temperatura). | ||
+ | |||
+ | ;Tip | ||
+ | :Puoi benissimo creare un gruppo con un solo sensore. | ||
+ | |||
+ | Al solito, ho pensato ad una chiave univoca d'inserimento dei dati in Redis '''sets:type:ID''' (gruppo:tipo:identificatore). | ||
+ | |||
+ | <div style="column-count:2;-moz-column-count:2;-webkit-column-count:2"> | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Gruppo | ||
+ | | | ||
+ | * sets | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Tipo | ||
+ | | | ||
+ | * alarms | ||
+ | * graph | ||
+ | * ... | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! ID (Identificatore) | ||
+ | | | ||
+ | (definito da utente, esempi:) | ||
+ | * TemperatureBagno | ||
+ | * TemperaturePianoTerra | ||
+ | * luigi | ||
+ | * ... | ||
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | I gruppi sono definiti dall'utente, ed ogni volta che viene creato un nuovo gruppo (deve avere almeno un'utenza altrimenti si autoelimina), viene gia` creato il "Timer" di "campionamento"/"ritardo nuovo allarme", preimpostato a 5 minuti (sono previsti valori da 1 a 60 minuti). | ||
+ | |||
+ | ''La pagina d'inserimento permette di inserire una chiave con un nome qualsiasi, non ho ancora "bloccato" e/o previsto un controllo sull'identificatore assegnato.'' | ||
+ | |||
+ | === sets:*:ID:Config === | ||
+ | |||
+ | <div style="column-count:2;-moz-column-count:2;-webkit-column-count:2"> | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Descrizione | ||
+ | | | ||
+ | Breve (?) descrizione | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Timer | ||
+ | | | ||
+ | * da 1 60 minuti | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Funzionamento | ||
+ | | | ||
+ | * On | ||
+ | * Off | ||
+ | * Auto | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! (Auto) dalle | ||
+ | | | ||
+ | * HH | ||
+ | * MM | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! (Auto) alle | ||
+ | | | ||
+ | * HH | ||
+ | * MM | ||
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | ==== Esempio "graph" ==== | ||
+ | |||
+ | La chiave per questi gruppi e` previsto che sia: '''sets:graph:ID''' | ||
+ | |||
+ | La chiave per il timer di campionamento e` previsto che sia: '''sets:graph:ID:Timer''' (ora e` generata automaticamente) | ||
+ | |||
+ | La chiave per i dati campionati e la generazione del grafico (che sara` in formato csv) e` previsto che sia: '''sets:graph:ID:Valori''' (sara` creata ed aggiornata autonomamente, da un programma in python) | ||
+ | |||
+ | ==== Esempio "alarms" ==== | ||
+ | |||
+ | Al momento come sopra, tranne che il Timer non servira` (o forse si, perche` sono previsti anche grafici dei PIR). | ||
+ | |||
+ | ==== Esempio d'inserimento gruppo ==== | ||
+ | |||
+ | ;MENU | ||
+ | :Aggiungi chiavi "sets" Redis | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-KeysAddSets 1.png | ||
+ | File:Livello1-KeysAddSets 2.png | ||
+ | File:Livello1-KeysAddSets 3.png | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | ;MENU | ||
+ | :Seleziona e Manipola chiavi Redis | ||
+ | ::Nell'immagine e` gia` stato applicato il filtro '''*:graph:*''' | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-KeysModHash 1.png|Spostiamoci verso il basso e selezioniamo la seconda voce di modifica delle chiavi "hash", quella relativa al "Config": | ||
+ | File:Livello1-KeysModHash 2.png | ||
+ | File:Livello1-KeysModHash 3.png|e l'esempio di un allarme: | ||
+ | File:Livello1-KeysModHash 3a.png | ||
+ | </gallery> | ||
+ | |||
+ | ==== Modifica di un gruppo ==== | ||
+ | |||
+ | ;MENU | ||
+ | :Seleziona e Manipola chiavi Redis | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-KeysModSets 2.png | ||
+ | File:Livello1-KeysModSets 3.png|Credo si spieghi da sola ... | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | == Daemons == | ||
+ | |||
+ | Intanto: non sono veri e propri "demoni", sono script che l'utente avvia e ferma al bisogno. | ||
+ | |||
+ | Specialmente quello degli allarmi (che mi sta` rompendo al cellulare da stamattina ;) ), e` da avviare quando uscite di casa, e fermare prima di rientrare. | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-Daemons part1.png | ||
+ | File:Livello1-Daemons part2.png | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | |||
+ | ;MENU | ||
+ | :Manipolazione files Grafici | ||
+ | |||
+ | Non c'e` molto da scrivere, si puo` visualizzarlo (la chiamata e` tramite GET perche` sia possibile tenere il refresh della pagina in automatico, mi sembra di aver previsto 5 minuti), copiarlo con un nome in archivio (la predisposizione e` per un nome con data e ora), eliminare (qualsiasi, anche dall'archivio). | ||
+ | |||
+ | ;Tip | ||
+ | :Salvate il ".csv" PRIMA di eliminare la/e chiave/i dei valori dal database, se volete tenere una qualche 'traccia'. | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-CSV.png | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | == Grafici (files .csv) == | ||
+ | |||
+ | ;MENU | ||
+ | :Manipolazione files Grafici | ||
+ | |||
+ | Non c'e` molto da scrivere, si puo` visualizzarlo (la chiamata e` tramite GET perche` sia possibile tenere il refresh della pagina in automatico, mi sembra di aver previsto 5 minuti), copiarlo con un nome in archivio (la predisposizione e` per un nome con data e ora), eliminare (qualsiasi, anche dall'archivio). | ||
+ | |||
+ | ;TIP | ||
+ | :Salvate il ".csv" PRIMA di eliminare la/e chiave/i dei valori dal database, se volete tenere una qualche 'traccia'. | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-CSV.png | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | == Allarmi == | ||
+ | |||
+ | Per ogni gruppo creato, e` possibile eseguire il controllo allarmi, servono opportune preimpostazioni (configurazioni), poi e` possibile eseguire il software dalla pagina '''Daemons''': | ||
+ | |||
+ | [[File:Livello1-Allarmi-Daemons.png|800px]] | ||
+ | |||
+ | Si puo` notare in esecuzione solo quello relativo ad una falsa sonda di temperatura, relativo ai [[Centralina livello 1/Test allarmi|test eseguiti]]. | ||
+ | |||
+ | L'eseguibile e` "/var/www/cgi-bin/setsalarms_d.py". | ||
+ | |||
+ | === setsalarms_d.py === | ||
+ | |||
+ | Perche` possa "funzionare" servono alcuni requisiti: | ||
+ | *Deve esistere il gruppo ed avere una configurazione (che e` preimpostata alla creazione) | ||
+ | *Il gruppo deve essere "on" o in modalita` "auto" (per default e` "off") | ||
+ | |||
+ | Tutti sono avvisi (li ho chiamati "alert"), alcuni possono e devono invece diventare allarmi ("alarm"). Perche` siano definiti allarmi, devono essere inseriti nella voce "Allarme", presente nella configurazione della sonda (sensore, PIR, o quello che e`). | ||
+ | |||
+ | Tipi di "alert": | ||
+ | ;RangeValori | ||
+ | :Deve essere specificato nella forma [-]Numero,[+-]Numero, una sonda 1wire pe esempio sarebbe: -55,+125 | ||
+ | :;Alert | ||
+ | ::Se il valore letto e` fuori dal range | ||
+ | ;ValoreMin | ||
+ | :Deve essere specificato nella forma [-]Numero | ||
+ | :;Alert/Alarm | ||
+ | ::Se il valore letto e` inferiore | ||
+ | ;ValoreMax | ||
+ | :Deve essere specificato nella forma [-]Numero | ||
+ | :;Alert/Alarm | ||
+ | ::Se il valore letto e` superiore | ||
+ | ;ValoreOn | ||
+ | :0 o 1 | ||
+ | :Al momento e` previsto per sola sensoristica come: finecorsa, PIR, e altri segnali on/off | ||
+ | :;Alert/Alarm | ||
+ | ::Se il valore letto e` uguale | ||
+ | ;Allarme | ||
+ | :Quello che e` allarme e non semplice avviso: | ||
+ | ::ValoreOn | ||
+ | ::ValoreMin | ||
+ | ::ValoreMin,ValoreMax,ValoreOn | ||
+ | ::... | ||
+ | |||
+ | Per un'esempio di configurazione fate riferimento alla pagina [[Centralina livello 1/Test allarmi|Test Allarmi]]. | ||
+ | |||
+ | Il software invia gli avvisi/allarmi alla centralina [[CentRed]], e` questa poi ad occuparsi della trasmissione, discriminando il tipo dalla stringa con cui e` stato inviato. Altre informazioni alla pagina [[CentRed]]. | ||
+ | |||
+ | == Analizza e Modifica Valori == | ||
+ | |||
+ | Ho aggiunto la possibilita` di manipolare i valori memorizzati nel database Redis. | ||
+ | |||
+ | ;MENU | ||
+ | :Seleziona e Manipola chiavi Redis | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-Selezione_Analizza_e_Modifica_Valori.png | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | Sono ammesse solamente chiavi ":Valori", la possibilita` di selezione dipende (al solito) dal filtro attivo nella pagina. | ||
+ | |||
+ | Una volta scelta la chiave e cliccato su "Analizza e Modifica", compare la pagina: | ||
+ | |||
+ | <gallery widths=800px heights=600px> | ||
+ | |||
+ | File:Livello1-Analizza_e_Modifica_Valori.png | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | Dove e` possibile: | ||
+ | * Visualizzare tutti i valori | ||
+ | * Creare il file ".csv" da elaborare successivamente tramite l'apposita pagina | ||
+ | * Eliminare i dati ormai obsoleti (attenzione che non ho filtrato le immissioni, e` possibile anche fare il contrario) | ||
+ | |||
+ | == Tabella dati e valori == | ||
+ | |||
+ | Denominazione dei campi e attibuzione dei valori standard (piu` o meno) | ||
<div style="column-count:2;-moz-column-count:2;-webkit-column-count:2"> | <div style="column-count:2;-moz-column-count:2;-webkit-column-count:2"> | ||
Riga 124: | Riga 633: | ||
* SPI | * SPI | ||
* ... | * ... | ||
+ | | | ||
+ | Al momento l'ho soppresso, il tipo di segnale e` praticamente definito dal valore in entrata (per ora) | ||
|} | |} | ||
Riga 138: | Riga 649: | ||
! PosizioneP | ! PosizioneP | ||
| | | | ||
− | * Piano0 | + | * Piano0 / PianoZero |
− | * Piano1 | + | * Piano1 / PianoUno |
* ... | * ... | ||
|} | |} | ||
Riga 150: | Riga 661: | ||
* Bagno1 | * Bagno1 | ||
* ... | * ... | ||
+ | * Cantina | ||
+ | * EsternoSala | ||
|} | |} | ||
Riga 155: | Riga 668: | ||
! ID (Identificatore, Utenza/ITEM) | ! ID (Identificatore, Utenza/ITEM) | ||
| | | | ||
− | |||
* 1 | * 1 | ||
* 2 | * 2 | ||
Riga 166: | Riga 678: | ||
* (altro ?) | * (altro ?) | ||
* ... | * ... | ||
− | |||
− | + | Convenzioni usate ad oggi: | |
− | + | * STn sonda/sensore temperatura [n = numero] | |
+ | * RHn sonda/sensore umidita` relativa [n = numero] | ||
+ | * ... | ||
| | | | ||
− | + | Definito dall'utente che programma i "remote", ma meglio definire una struttura di base .. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|} | |} | ||
Riga 183: | Riga 690: | ||
! Valori | ! Valori | ||
| | | | ||
− | * TipoIO | + | * TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori |
+ | | | ||
+ | Assegnato automaticamente dal programma | ||
|} | |} | ||
Riga 193: | Riga 702: | ||
* A (assorbimento) | * A (assorbimento) | ||
* ... | * ... | ||
+ | | | ||
+ | Questo e` previsto solo per le segnalazioni/avvisi/allarmi .. | ||
|} | |} | ||
Riga 202: | Riga 713: | ||
* ... | * ... | ||
* 99.000 (max impostabile) | * 99.000 (max impostabile) | ||
+ | | | ||
+ | Al momento non previsto, teoricamente i segnali dovrebbero arrivare gia` "filtrati" dai "remote" | ||
|} | |} | ||
Riga 207: | Riga 720: | ||
! RangeValori | ! RangeValori | ||
| | | | ||
− | * 0- | + | * 0,100 |
+ | * -50,125 | ||
* 0,1 | * 0,1 | ||
+ | | | ||
+ | Da utilizzarsi per definire l'errore e generare una segnalazione di sonda guasta | ||
|} | |} | ||
Riga 216: | Riga 732: | ||
* 10 (temperatura) | * 10 (temperatura) | ||
* 0 (binari/digitali) | * 0 (binari/digitali) | ||
+ | | | ||
+ | Sotto a questo valore dev'essere generato un'allarme | ||
|} | |} | ||
Riga 223: | Riga 741: | ||
* 40 (temperatura) | * 40 (temperatura) | ||
* 1 (binari/digitali) | * 1 (binari/digitali) | ||
+ | | | ||
+ | Sopra a questo valore dev'essere generato un'allarme | ||
|} | |} | ||
Riga 228: | Riga 748: | ||
! ValoreOn | ! ValoreOn | ||
| | | | ||
− | * 1 | + | * 1 (quando attivo a segnale on) |
+ | * 0 (quando attivo a segnale off) | ||
+ | * [Valore] | ||
+ | | | ||
+ | Valore da utilizzare per alert/alarm, e per definire se si tratta di un segnale negato (zero) e trattarlo di conseguenza | ||
|} | |} | ||
Riga 234: | Riga 758: | ||
! Allarme | ! Allarme | ||
| | | | ||
− | * | + | * ValoreOn |
− | * | + | * ValoreMin |
− | * | + | * ValoreMax |
− | * | + | * ValoreOn,ValoreMin |
− | * | + | * ValoreOn,ValoreMax |
− | * | + | * ValoreOn,ValoreMin,ValoreMax |
− | * | + | * ValoreMin,ValoreMax |
+ | | | ||
+ | Quali sono da trattare come allarmi, di default, se impostati, sono trattati come alert | ||
|} | |} | ||
</div> | </div> | ||
<hr/><br/> | <hr/><br/> | ||
− | + | ||
+ | == TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori == | ||
{| class="wikitable" | {| class="wikitable" | ||
Riga 262: | Riga 789: | ||
|} | |} | ||
− | == | + | == Promemoria chiavi, codici e ... == |
− | + | ====== Dati (mqtt) ====== | |
+ | '''{ "ID" : "Identificatore", "Valore" : "0" }''' | ||
− | |||
− | '''TipoIO | + | ====== Topic (mqtt) ====== |
+ | '''TipoIO/PosizioneC/PosizioneP/PosizioneS/Tipo''' | ||
− | |||
− | + | ====== Chiave primaria segnale di livello 1 (redis) ====== | |
+ | '''TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID''' | ||
− | |||
+ | ====== Chiave primaria valori di livello 1 (redis) ====== | ||
'''TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori''' | '''TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori''' | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ====== Chiave primaria gruppi di livello 1 (redis) ====== | |
− | + | ;TYPE | |
+ | :graph | ||
+ | :alarms | ||
+ | '''sets:TYPE:ID''' | ||
− | |||
− | + | ====== Chiave primaria configurazione gruppi di livello 1 (redis) ====== | |
+ | '''sets:TYPE:ID:Config''' | ||
− | |||
− | == | + | ====== Chiave primaria valori gruppi di livello 1 (redis) ====== |
+ | '''sets:TYPE:ID:Valori''' | ||
− | == | + | == Riferimenti == |
− | + | [[Centralina livello 1/Notes|Notes]] | |
− | + | [[Centralina livello 1/Primo avvio|Primo avvio]] | |
− | + | [[Centralina livello 1/Test allarmi|Test allarmi]] | |
− | + | = Devices = | |
− | + | Ad oggi, ho predisposto/preparato: | |
+ | * [[PorTHable]], che invia valori di temperatura | ||
+ | * [[ ESP8266/DS1820toMQTT | DS1820toMQTT ]], sensore/i di temperatura | ||
+ | * [[ ESP8266/PIRtoMQTT | PIRtoMQTT ]], sensore di movimento (PIR) | ||
+ | * [[ ESP8266/SerialToMQTT_Repeater | SerialToMQTT Repeater ]], che funziona da "repeater", ritrasmette i dati ricevuti via seriale al broker MQTT | ||
+ | * [[ Thermo ]], che invia il valore della temperatura (solo di riferimento ad oggi, non le altre sonde) | ||
+ | * [[ ENC28J60-ATMEGA328P-DS18B20 | ENC28J60 + ATMEGA328P + DS18B20 ]], sensore di temperatura in ethernet | ||
+ | * [[ Centralina_livello_1/ATMEGA328P-ESP8266-DHT-Rain | ATMEGA328P + ESP8266 + DHT + Rain]], sensore temperatura/umidita` (dht) e pioggia (rain) | ||
+ | * [[ ESP8266/DHT22toMQTT | DHT22toMQTT ]], sensore di temperatura e umidita` | ||
+ | * [[ Centralina_livello_1/Dev_HTRL_wAE | ATMEGA328P + ESP8266 + DHT + Rain + Photoresistor]], sensore temperatura/umidita` (dht), pioggia (rain) e luminosita` (photoresistor).<br> Nuova e migliorata (?) versione del precedente [[Centralina_livello_1/ATMEGA328P-ESP8266-DHT-Rain | device]] | ||
+ | * [[ Cronotermostato settimanale ]] | ||
+ | * [[ Centralina_livello_1/Centralina_livello_2_PIR | Centralina livello 2 - PIR ]] | ||
− | + | = Tools = | |
− | + | [[Centralina livello 1/telegram bot|Telegram Bot per Centralina livello 1]] | |
− | + | = Problemi e soluzioni ? = | |
− | + | ;Eliminazione file di swap | |
+ | :Non so se sia stato un problema e sia utile | ||
+ | ::[[Raspberry_PI-Raspbian-Personalizzazioni#Disattivazione|Disattivazione file di swap]] | ||
− | + | ;Redis - Errore salvataggio in background | |
+ | :[https://jee-appy.blogspot.it/2016/04/can-not-save-in-background-fork-redis.html Can't save in background: fork: Cannot allocate memory Redis] | ||
+ | :[https://stackoverflow.com/questions/11752544/redis-bgsave-failed-because-fork-cannot-allocate-memory redis bgsave failed because fork Cannot allocate memory] | ||
+ | :[https://stackoverflow.com/questions/19581059/misconf-redis-is-configured-to-save-rdb-snapshots MISCONF Redis is configured to save RDB snapshots] | ||
− | + | ;Redis - Errore avvio del server | |
+ | :Dopo un ripristino del sistema ho avuto dei problemi di permessi al file "dump.rdb" (che ho voluto ricopiare per riprendermi alcune impostazioni), ho reimpostato in "redis:redis" (directory "/var/lib/redis" inclusa) il proprietario e settato i permessi a 660. | ||
− | + | ;I daemon non vengono eseguiti dalle pagine web | |
+ | :Non sono stati corretti i permessi della directory del webserver "/var/www" [[#Level1_.28www.29]] |
Versione attuale delle 14:59, 8 mar 2022
Centralina livello 1 |
Centralina generale (?) gestione segnali |
Repository: https://github.com/raspibo/Livello1 |
Centralina livello 1
- ATTENZIONE
- Tutte le immagini sono puramente indicative, il progetto e` in pieno sviluppo, tutto e` passibile di modifiche, anche sostanziali.
- L'immagine di presentazione si riferisce alla sezione "debug", realizzata con Dokuwiki e (ad oggi) non fa parte del progetto (o si ?)
Prima e sommaria descrizione
Centralina di controllo segnali.
- (Ad oggi)
- Acquisisce segnali, li suddivide in gruppi mono o multi utenza, dei quali: realizza grafici temporali, crea e gestisce allarmi.
Dal campo arrivano i valori della 'sensoristica' sottoforma di "Identificatore Valore", da queste informazioni sono aggiunti i sensori che eventualmente non sono presenti e le relative 'liste' dei valori (sono generate due chiavi, una dell'utenza e l'altra dei valori), altrimenti viene solo accodato il valore nella rispettiva lista (aggiungendo data-ora-minuti-secondi).
Acquisiti i sensori, e` possibile il loro raggruppamento (anche una sola utenza) ed il campionamento dei valori a tempi prestabiliti (generazione grafici tempo/valore).
Sempre previo raggruppamento (sempre "anche di un solo sensore"), e` possibile attivare/disattivare i relativi allarmi, il classico ON/OFF, ma anche un'automatico (che per esempio attivi i sensori del solaio/cantine dalle 20 alle 8, quando e` certo che nessuno si rechi in quegli spazi).
E poi il resto .. che sarebbe di arrivare non solo a leggere/interpretare segnali, ma anche a pilotare utenze (luci, serrande, elettrodomestici, ...)
L'idea e` che tutto questo sia gestibile da:
- interfaccia web
- browser
- cellulare
- linea di comando
- terminali operatore (display+tastiere)
- pulsanti, lampade, selettori, ..
- ...
Hardware e Software
- Hardware
- Versione 1 - Raspberry Pi 3, perche` completa di WiFi e Bluetooth
- Versione 2 (2018) - Raspberry Pi con chiavetta WiFi
- Software
- MQTT Broker (Mosquitto), perche` in grado di dialogare con la maggior parte dei componenti (Arduino, ESP8266, eccetera)
- Redis, perche` servira` un database di appoggio e manipolazione per alcuni dati, e perche` servira` una struttura dati "manipolabile" (dovremo poter aggiungere e togliere "campi:valori" ad una "chiave", e aggiungere/togliere chiavi a delle liste, ecc. ecc.)
- Nginx, non si puo` fare senza web server
- ... e poi non so cos'altro
- Script cgi
- javascript
- ...
Sistema operativo:
$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 11 (bullseye) Release: 11 Codename: bullseye
Setup
Al primo avvio la nuova SD Card visualizza una schermata di "Resizing file system", seguito da un riavvio del sistema.
Al prompt si entra (login) con username pi, password raspberry e si procede ad una configurazione minima del sistema:
sudo su raspi-config
Qualche esempio di cose da fare:
- password
- hostname <centred>
- locale <en>
- timezone <rome>
- keyboard layout <en-US>
- wifi country <it>
ed eventuali (SSH nella ultime release non e` attivo di default):
- 5 Interfacing options
- P2 SSH Enable
Uscendo, il tool (raspi-config) richiede di riavviare il sistema.
Upgrade
sudo su apt-get update apt-get upgrade reboot # se ha aggiornato pacchetti del kernel, o in caso di dubbi
Access Point
Installato/configurato "Raspberry Pi Access Point WEP2", sfruttando il wifi integrato nel Raspberry Pi 3.
Install
Installazione dei pacchetti utili, necessari (e qualcuno inutile):
sudo su apt install nginx fcgiwrap redis-server python3-redis mosquitto ssl-cert php8.0-fpm php8.0-xml python3-pip python3-paho-mqtt python3-pandas python3-cairosvg python3-tinycss python3-cssselect git mosquitto-clients redis-tools pip3 install python-telegram-bot pygal
Nelle precedenti versioni fu installato manualmente anche dokuwiki, utilizzato per segnarsi appunti vari (e un po` di debug), e` facoltativo e non descritto le operazioni necessarie, ma i files di configurazione del web server si.
E` necessario scaricare il repository con i programmi (script python per lo piu`), si puo` fare da normale utente, per esempio:
mkdir git cd git git clone https://github.com/raspibo/Livello1.git cd Livello1
Nginx
Copiare i nuovi files di configurazione dal repository ed eliminare il web server configurato di default:
sudo su cp etc/nginx/sites-available/level1 /etc/nginx/sites-available/ ln -s /etc/nginx/sites-enabled/level1 /etc/nginx/sites-enabled/ #cp etc/nginx/dokuwiki* etc/nginx/fcgiwrap.conf /etc/nginx/ # se installate dokuwiki cp etc/nginx/fcgiwrap.conf /etc/nginx/ rm /etc/nginx/sites-enabled/default
Abbiamo effettuato tutte le operazioni come "root", ma assicuratevi che il proprietario sia corretto, se non lo e`:
sudo su chown root:root -R /etc/nginx/
Potreste gia` riavviare il web server, ma non abbiamo ancora completato, riavvieremo il sistema alla fine di tutto, ma se volete:
sudo sytemctl restart nginx
dovrebbe funzionare.
Level1 (www)
Ho messo tutti i files/script nella directory del web server.
Li copiamo dal repository e settiamo il giusto proprietario:
sudo su cp -vapu var/www/ /var/ chown www-data:www-data -R /var/www/
Serve anche la scrittura in "www":
sudo su chmod 775 /var/www chown :www-data -R /var/www # oppure si poteva eliminare il "/" dal "chown" precedente
- Nota
- I permessi sono 755, quindi i files sono eseguibili da chiunque.
- Potrebbe essere necessario creare la directory "/var/www/archive"
Mosquitto
Copiare il file di configurazione dal repository ed assicurarsi i giusti permessi e proprietario:
sudo su cp etc/mosquitto/conf.d/myadd.conf /etc/mosquitto/conf.d/ chown root:root /etc/mosquitto/conf.d/myadd.conf chmod 644 /etc/mosquitto/conf.d/myadd.conf
Telegram Bot
Scaricare il repository:
cd ~/git git clone hhttps://github.com/raspibo/bot4livello1.git cd bot4livello1
Questo programma fu creato in origine nella directory "/home/pi/project/csv2image2telegram", quindi tutti i riferimenti sono a questa, copiate qua il programma oppure modificate la directory dove necessario ("/etc/rc.local").
Il programma dev'essere esguito al boot di sistema e rimanere sempre in esecuzione.
Avvio
All'avvio del sistema, devono andare in esecuzione alcuni script (quasi "daemons") e rimanere attivi, per questo si deve modificare il file "/etc/rc.local" (lo trovate nel repository git):
- /etc/rc.local
- Ho aggiunto le seguenti righe prima della "exit 0"
# Power On "Level 1" DAEMON_NAME=mqtt2redis_d PID=`ps -e -o pid,cmd | grep "$DAEMON_NAME[.]py" | awk '{ print $1 }'` if [ $PID ] then echo "Non si e\` avviata correttamente Livello 1, oppure mqtt2redis_d e\` gia\` avviato:" echo "Actual PID is: $PID" else echo "Avvio \"mqtt2redis_d\"" #/var/www/cgi-bin/mqtt2redis_init.d.sh start # 20180115 su -c "/var/www/cgi-bin/mqtt2redis_init.d.sh start" pi # .. e un messaggio a centred quando si [ri]avvia redis-cli -h centred hmset msg:alert:level1:$(date +\%Y\%m\%d\%H\%M\%S) type "alert" desc "Centralina level 1 [ri]avviata .." value "on" um "" date "$(date +\%Y/\%m/\%d\ \%H:\%M:\%S)" fi # Start Telegram Bot DAEMON_NAME=bot4livello1 PID=`ps -e -o pid,cmd | grep "$DAEMON_NAME[.]py" | awk '{ print $1 }'` if [ $PID ] then echo "Non si e\` avviato il Telegram Bot, oppure era gia\` avviato:" echo "Actual PID is: $PID" else echo "Avvio Telegram Bot" cd /home/pi/project/csv2image2telegram su pi -c "python3 bot4livello1.py &" # .. e un messaggio a centred quando si [ri]avvia redis-cli -h centred hmset msg:alert:level1:$(date +\%Y\%m\%d\%H\%M\%S) type "alert" desc "Avvio bot4livello1.py" value "on" um "" date "$(date +\%Y/\%m/\%d\ \%H:\%M:\%S)" cd / fi
Inoltre, visto che puo` capitare s'interrompano, specialmente nelle prove di nuovi devices, sono predisposti dei "check orari" che nel caso, li riavviano:
sudo su cp -vapu etc/cron.hourly/mqtt2redis_check /etc/cron.hourly/ cp -vapu etc/cron.hourly/bot4livello1_check /etc/cron.hourly/ # se installerete anche il bot telegram
Ho anche previsto un messaggio settimanale di centralina in funzione tramite crontab dell'utente pi, copiate il file:
sudo su cp -vapu var/spool/cron/crontabs/pi /var/spool/cron/crontabs/ chown root:root /var/spool/cron/crontabs/pi chmod 600 /var/spool/cron/crontabs/pi
oppure aggiungete la linea (col comando "crontab -e"):
0 7 * * 0 redis-cli -h centred hmset msg:redis:alive:$(date +\%Y\%m\%d\%H\%M\%S) type "alert" desc "Messaggio ciclico, centralina $(hostname) in funzione" value "on" um "" date "$(date +\%Y/\%m/\%d\ \%H:\%M:\%S)" > /dev/null
Backup
Oltre ad un "backup" che si occupa di salvare tutti i computer's della rete, ho aggiunto uno script per salvare giornalmente il database redis, come ulteriore sicurezza, i files sono salvati nella directory "/root":
sudo su cp -vapu etc/cron.daily/backupredis /etc/cron.daily/
Rete
Al momento e` previsto che sia tutto sotto WiFi (quella onboard) del Raspberry Pi 3.
Comunque bastera` modificare il firewall per accettare dati dalla ethernet se si rendesse necessario.
Le centrali accessorie, tipo quella di allarme, che deve solo ricevere, non necessariamente dovranno trovarsi nella sottorete gestita da "livello 1".
Descrizione
I 'segnali' arrivano sempre (?) a "MQTT broker", vengono manipolati se necessario, ed inseriti nel database Redis.
Dal database Redis sono di nuovo letti/scritti/modificati/manipolati ed inviati:
- e/o
- in report (testo, grafico, audio, video, ...)
- e/o
- alla centralina di allarme CentRed
- e/o
- reinviati a MQTT broker
- e/o
- inviati ad altre centraline livello 1
- e/o
- ...
Configurazione e Funzionamento
(Sommariamente)
Al primo avvio e` necesssario configurare prima il database Redis da utilizzare, poi quello della centralina avvisi/allarmi (se avete intenzione di ricevere le comunicazioni relative agli allarmi e/o avvisi di malfunzionamenti).
Una volta "letti" i segnali, e` opera dell'utente aggiungere alcune caratteristiche #Segnali, fatto questo si passa alla creazione dei #Gruppi.
Definiti i #Gruppi, si passa ad avviare i servizi necessari #Daemons, che si occupano di generare i grafici Tempo-Valore/i o gestione degli allarmi/anomalie.
Arrivo dati e manipolazione
I dati devono arrivare al broker MQTT nel formato:
{ "ID" : "Identificatore", "Valore" : "0" }
inviati nel topic:
TipoIO/PosizioneC/PosizioneP/PosizioneS/Tipo
Fate riferimento alla #Tabella dati e valori per comprendere meglio il significato.
Nell'immagine, una schermata dei test in corso, a sinistra gli errori di lettura, a destra un listato della "cgi-bin", sotto i falsi dati inviati (mi servono per i test che sto` facendo ;) ), e in fondo i dati ricevuti (veri e falsi).
mqtt2redis_d.py
I dati MQTT vengono letti dal programma "mqtt2redis_d.py" che deve sempre essere in esecuzione (ho gia` preparato anche un "init.d", che tengo ancora nella "cgi-bin"), questi li manipola inserendoli se non presenti, in due "chiavi" nel database (noSQL) Redis, la prima, e` per identificare il segnale:
TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID
la seconda e` quella dei valori:
TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori
valori che sono accodati ad ogni arrivo con l'aggiunta della data e ora, predisposti per una generazione di output in formato "csv".
IMPORTANTE
Quello che segue non e` aggiornato di pari passo con l'aggiornamento del software e quant'altro necessario.
Durante l'uso, nelle pagine di configurazione e modifica compaiono delle descrizioni che sono piu` veritiere/aggiornate, perche` scritte durante la stesura e/o modifica del software.
Segnali
Una volta pervenuto il primo valore di un segnale, e` possibile configurarlo inserendo alcuni dati che non sono presenti nella comunicazione MQTT:
- Descrizione
- Meglio se breve, perche` usata anche nei riferimenti dei grafici, non solo per gli allarmi (per esempio: "ST1 Cucina" per sensore temperatura in cucina)
- UM (Unita` di misura)
- TempoRitardo
- Ancora non usata
- RangeValori
- Specificare il range dei valori nel formato 0,100
- Utile per sonde che (per esempio) lavorano da 0 a 100 gradi
- Genera avviso/allarme se minore di o maggiore di
- ValoreMin
- Avviso se valore e` inferiore a quello impostato
- ValoreMax
- Aavviso se valore e` superiore a quello impostato
- ValoreOn
- Previsto per i segnali analogici o negati
- Avviso quando valore uguale a ValoreOn
- Allarme
- Definire qua i valori che saranno usati come allarmi, per esempio: ValoreOn,ValoreMin
- Se sono impostati, ma non indicati qua, sono emessi dei semplici avvisi
Esempio di una configurazione di sonda temperatura (ovviamente falsa):
Esempio di una configurazione di sensore di movimento (pir, ovviamente falso):
Gruppi
Per realizzare i raggruppamenti ho utilizzato le chiavi Redis di tipo "sets".
Al momento ho pensato ai soli gruppi riguardanti gli allarmi e i grafici (per esempio quelli di due o piu`, sonde di temperatura).
- Tip
- Puoi benissimo creare un gruppo con un solo sensore.
Al solito, ho pensato ad una chiave univoca d'inserimento dei dati in Redis sets:type:ID (gruppo:tipo:identificatore).
Gruppo |
|
---|
Tipo |
|
---|
ID (Identificatore) |
(definito da utente, esempi:)
|
---|
I gruppi sono definiti dall'utente, ed ogni volta che viene creato un nuovo gruppo (deve avere almeno un'utenza altrimenti si autoelimina), viene gia` creato il "Timer" di "campionamento"/"ritardo nuovo allarme", preimpostato a 5 minuti (sono previsti valori da 1 a 60 minuti).
La pagina d'inserimento permette di inserire una chiave con un nome qualsiasi, non ho ancora "bloccato" e/o previsto un controllo sull'identificatore assegnato.
sets:*:ID:Config
Descrizione |
Breve (?) descrizione |
---|
Timer |
|
---|
Funzionamento |
|
---|
(Auto) dalle |
|
---|
(Auto) alle |
|
---|
Esempio "graph"
La chiave per questi gruppi e` previsto che sia: sets:graph:ID
La chiave per il timer di campionamento e` previsto che sia: sets:graph:ID:Timer (ora e` generata automaticamente)
La chiave per i dati campionati e la generazione del grafico (che sara` in formato csv) e` previsto che sia: sets:graph:ID:Valori (sara` creata ed aggiornata autonomamente, da un programma in python)
Esempio "alarms"
Al momento come sopra, tranne che il Timer non servira` (o forse si, perche` sono previsti anche grafici dei PIR).
Esempio d'inserimento gruppo
- MENU
- Aggiungi chiavi "sets" Redis
- MENU
- Seleziona e Manipola chiavi Redis
- Nell'immagine e` gia` stato applicato il filtro *:graph:*
Modifica di un gruppo
- MENU
- Seleziona e Manipola chiavi Redis
Daemons
Intanto: non sono veri e propri "demoni", sono script che l'utente avvia e ferma al bisogno.
Specialmente quello degli allarmi (che mi sta` rompendo al cellulare da stamattina ;) ), e` da avviare quando uscite di casa, e fermare prima di rientrare.
- MENU
- Manipolazione files Grafici
Non c'e` molto da scrivere, si puo` visualizzarlo (la chiamata e` tramite GET perche` sia possibile tenere il refresh della pagina in automatico, mi sembra di aver previsto 5 minuti), copiarlo con un nome in archivio (la predisposizione e` per un nome con data e ora), eliminare (qualsiasi, anche dall'archivio).
- Tip
- Salvate il ".csv" PRIMA di eliminare la/e chiave/i dei valori dal database, se volete tenere una qualche 'traccia'.
Grafici (files .csv)
- MENU
- Manipolazione files Grafici
Non c'e` molto da scrivere, si puo` visualizzarlo (la chiamata e` tramite GET perche` sia possibile tenere il refresh della pagina in automatico, mi sembra di aver previsto 5 minuti), copiarlo con un nome in archivio (la predisposizione e` per un nome con data e ora), eliminare (qualsiasi, anche dall'archivio).
- TIP
- Salvate il ".csv" PRIMA di eliminare la/e chiave/i dei valori dal database, se volete tenere una qualche 'traccia'.
Allarmi
Per ogni gruppo creato, e` possibile eseguire il controllo allarmi, servono opportune preimpostazioni (configurazioni), poi e` possibile eseguire il software dalla pagina Daemons:
Si puo` notare in esecuzione solo quello relativo ad una falsa sonda di temperatura, relativo ai test eseguiti.
L'eseguibile e` "/var/www/cgi-bin/setsalarms_d.py".
setsalarms_d.py
Perche` possa "funzionare" servono alcuni requisiti:
- Deve esistere il gruppo ed avere una configurazione (che e` preimpostata alla creazione)
- Il gruppo deve essere "on" o in modalita` "auto" (per default e` "off")
Tutti sono avvisi (li ho chiamati "alert"), alcuni possono e devono invece diventare allarmi ("alarm"). Perche` siano definiti allarmi, devono essere inseriti nella voce "Allarme", presente nella configurazione della sonda (sensore, PIR, o quello che e`).
Tipi di "alert":
- RangeValori
- Deve essere specificato nella forma [-]Numero,[+-]Numero, una sonda 1wire pe esempio sarebbe: -55,+125
- Alert
- Se il valore letto e` fuori dal range
- ValoreMin
- Deve essere specificato nella forma [-]Numero
- Alert/Alarm
- Se il valore letto e` inferiore
- ValoreMax
- Deve essere specificato nella forma [-]Numero
- Alert/Alarm
- Se il valore letto e` superiore
- ValoreOn
- 0 o 1
- Al momento e` previsto per sola sensoristica come: finecorsa, PIR, e altri segnali on/off
- Alert/Alarm
- Se il valore letto e` uguale
- Allarme
- Quello che e` allarme e non semplice avviso:
- ValoreOn
- ValoreMin
- ValoreMin,ValoreMax,ValoreOn
- ...
Per un'esempio di configurazione fate riferimento alla pagina Test Allarmi.
Il software invia gli avvisi/allarmi alla centralina CentRed, e` questa poi ad occuparsi della trasmissione, discriminando il tipo dalla stringa con cui e` stato inviato. Altre informazioni alla pagina CentRed.
Analizza e Modifica Valori
Ho aggiunto la possibilita` di manipolare i valori memorizzati nel database Redis.
- MENU
- Seleziona e Manipola chiavi Redis
Sono ammesse solamente chiavi ":Valori", la possibilita` di selezione dipende (al solito) dal filtro attivo nella pagina.
Una volta scelta la chiave e cliccato su "Analizza e Modifica", compare la pagina:
Dove e` possibile:
- Visualizzare tutti i valori
- Creare il file ".csv" da elaborare successivamente tramite l'apposita pagina
- Eliminare i dati ormai obsoleti (attenzione che non ho filtrato le immissioni, e` possibile anche fare il contrario)
Tabella dati e valori
Denominazione dei campi e attibuzione dei valori standard (piu` o meno)
Tipo |
|
---|
Descrizione |
Breve (?) descrizione del segnale |
---|
TipoIO |
|
---|
Segnale |
|
Al momento l'ho soppresso, il tipo di segnale e` praticamente definito dal valore in entrata (per ora) |
---|
PosizioneC |
|
---|
PosizioneP |
|
---|
PosizioneS |
|
---|
ID (Identificatore, Utenza/ITEM) |
Convenzioni usate ad oggi:
|
Definito dall'utente che programma i "remote", ma meglio definire una struttura di base .. |
---|
Valori |
|
Assegnato automaticamente dal programma |
---|
UM (Unita` di Misura) |
|
Questo e` previsto solo per le segnalazioni/avvisi/allarmi .. |
---|
TempoRitardo (secondi) |
|
Al momento non previsto, teoricamente i segnali dovrebbero arrivare gia` "filtrati" dai "remote" |
---|
RangeValori |
|
Da utilizzarsi per definire l'errore e generare una segnalazione di sonda guasta |
---|
ValoreMin |
|
Sotto a questo valore dev'essere generato un'allarme |
---|
ValoreMax |
|
Sopra a questo valore dev'essere generato un'allarme |
---|
ValoreOn |
|
Valore da utilizzare per alert/alarm, e per definire se si tratta di un segnale negato (zero) e trattarlo di conseguenza |
---|
Allarme |
|
Quali sono da trattare come allarmi, di default, se impostati, sono trattati come alert |
---|
TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori
Data (e ora) |
|
---|
Valore |
|
---|
Promemoria chiavi, codici e ...
Dati (mqtt)
{ "ID" : "Identificatore", "Valore" : "0" }
Topic (mqtt)
TipoIO/PosizioneC/PosizioneP/PosizioneS/Tipo
Chiave primaria segnale di livello 1 (redis)
TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID
Chiave primaria valori di livello 1 (redis)
TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori
Chiave primaria gruppi di livello 1 (redis)
- TYPE
- graph
- alarms
sets:TYPE:ID
Chiave primaria configurazione gruppi di livello 1 (redis)
sets:TYPE:ID:Config
Chiave primaria valori gruppi di livello 1 (redis)
sets:TYPE:ID:Valori
Riferimenti
Devices
Ad oggi, ho predisposto/preparato:
- PorTHable, che invia valori di temperatura
- DS1820toMQTT , sensore/i di temperatura
- PIRtoMQTT , sensore di movimento (PIR)
- SerialToMQTT Repeater , che funziona da "repeater", ritrasmette i dati ricevuti via seriale al broker MQTT
- Thermo , che invia il valore della temperatura (solo di riferimento ad oggi, non le altre sonde)
- ENC28J60 + ATMEGA328P + DS18B20 , sensore di temperatura in ethernet
- ATMEGA328P + ESP8266 + DHT + Rain, sensore temperatura/umidita` (dht) e pioggia (rain)
- DHT22toMQTT , sensore di temperatura e umidita`
- ATMEGA328P + ESP8266 + DHT + Rain + Photoresistor, sensore temperatura/umidita` (dht), pioggia (rain) e luminosita` (photoresistor).
Nuova e migliorata (?) versione del precedente device - Cronotermostato settimanale
- Centralina livello 2 - PIR
Tools
Telegram Bot per Centralina livello 1
Problemi e soluzioni ?
- Eliminazione file di swap
- Non so se sia stato un problema e sia utile
- Redis - Errore salvataggio in background
- Can't save in background: fork: Cannot allocate memory Redis
- redis bgsave failed because fork Cannot allocate memory
- MISCONF Redis is configured to save RDB snapshots
- Redis - Errore avvio del server
- Dopo un ripristino del sistema ho avuto dei problemi di permessi al file "dump.rdb" (che ho voluto ricopiare per riprendermi alcune impostazioni), ho reimpostato in "redis:redis" (directory "/var/lib/redis" inclusa) il proprietario e settato i permessi a 660.
- I daemon non vengono eseguiti dalle pagine web
- Non sono stati corretti i permessi della directory del webserver "/var/www" #Level1_.28www.29