Centralina livello 1

Da raspibo.
Livello1-Debug.png

Centralina livello 1
Centralina generale (?) gestione segnali
Repository: https://github.com/raspibo/Livello1

Indice

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:

  1. interfaccia web
    • browser
    • cellulare
  2. linea di comando
  3. terminali operatore (display+tastiere)
  4. pulsanti, lampade, selettori, ..
  5. ...

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
...

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-get install nginx fcgiwrap redis-server python3-redis mosquitto paho-mqtt ssl-cert php-fpm php7.0-xml python3-pip python3-pandas python3-cairosvg python3-cssselect git mosquitto-clients apt-file mc redis-tools aria2
pip3 install paho-mqtt python-telegram-bot pygal tinycss

E` stato 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/
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"

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

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).

Level1 201604170814.png


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):

Livello1-KeysHashTempMod Falsa2.png

Esempio di una configurazione di sensore di movimento (pir, ovviamente falso):

Livello1-KeysHashPirMod Falso2.png

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
  • sets
Tipo
  • alarms
  • graph
  • ...
ID (Identificatore)

(definito da utente, esempi:)

  • TemperatureBagno
  • TemperaturePianoTerra
  • luigi
  • ...

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
  • da 1 60 minuti
Funzionamento
  • On
  • Off
  • Auto
(Auto) dalle
  • HH
  • MM
(Auto) alle
  • HH
  • MM

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:

Livello1-Allarmi-Daemons.png

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
  • Temperatura
  • PIR
  • Finecorsa
  • Proximity
  • Livello
  • Rele`
  • Termostato
  • Valvola
  • Motore
  • ...
Descrizione

Breve (?) descrizione del segnale

TipoIO
  • I (Input/Ingresso)
  • O (Output/Uscita)
Segnale
  • Analogico
  • Digitale
  • Testo
  • I2C
  • SPI
  • ...

Al momento l'ho soppresso, il tipo di segnale e` praticamente definito dal valore in entrata (per ora)

PosizioneC
  • Casa
  • Garage
  • Giardino
  • ...
PosizioneP
  • Piano0 / PianoZero
  • Piano1 / PianoUno
  • ...
PosizioneS
  • Cucina1
  • Camera2
  • Bagno1
  • ...
  • Cantina
  • EsternoSala
ID (Identificatore, Utenza/ITEM)
  • 1
  • 2
  • 3
  • ..
  • Up
  • Down
  • Left
  • Right
  • (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 ..

Valori
  • TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori

Assegnato automaticamente dal programma

UM (Unita` di Misura)
  • °C
  • V (tensione)
  • A (assorbimento)
  • ...

Questo e` previsto solo per le segnalazioni/avvisi/allarmi ..

TempoRitardo (secondi)
  • 0.000
  • 1.002
  • ...
  • 99.000 (max impostabile)

Al momento non previsto, teoricamente i segnali dovrebbero arrivare gia` "filtrati" dai "remote"

RangeValori
  • 0,100
  • -50,125
  • 0,1

Da utilizzarsi per definire l'errore e generare una segnalazione di sonda guasta

ValoreMin
  • 10 (temperatura)
  • 0 (binari/digitali)

Sotto a questo valore dev'essere generato un'allarme

ValoreMax
  • 40 (temperatura)
  • 1 (binari/digitali)

Sopra a questo valore dev'essere generato un'allarme

ValoreOn
  • 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

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



TipoIO:PosizioneC:PosizioneP:PosizioneS:Tipo:ID:Valori

Data (e ora)
  • 2016/03/13 20:40:08
Valore
  • 0
  • 1
  • 13
  • ...

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

Notes

Primo avvio

Test allarmi

Devices

Ad oggi, ho predisposto/preparato:

Tools

Telegram Bot per Centralina livello 1

Problemi e soluzioni ?

Eliminazione file di swap
Non so se sia stato un problema e sia utile
Disattivazione file di swap
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
Strumenti personali
Namespace

Varianti
Azioni
Navigazione
Strumenti