[Tutorial domotica] Sonoff + Python = punto luce intelligente

La possibilità di incrementare le prestazioni dell’interruttore wifi economico Sonoff della iTead grazie al firmware della Tasmota che, tra l’altro, lo svincolano dall’uso tramite App proprietaria, mi ha fatto venire l’idea di far accendere al Raspberry Pi nella mia stanza un punto luce in maniera automatica e magari intelligente (è la domotica baby!)

  • Livello di difficoltà: medio/basso
  • Costoestremamente ridotto (~10 €)

Ingredienti:

  • Sonoff Basic (acquistabile su Amazon.it)
  • saldatore e cavetti prototipazione
  • conoscenza di Python
  • spina elettrica maschio
  • spina elettrica femmina
  • filo elettrico bipolare q.b.
  • server controllo (es. Raspberry Pi)

Procedimento:

  • Innanzitutto occorre programmare il Sonoff con il firmware Tasmota. Per farlo ci sono diversi metodi, tutti magnificamente descritti nella relativa Wiki. Per conto mio non ho avuto fortuna con l’installazione via OTA: il mio interruttore montava un firmware di fabbrica troppo recente, risultato incompatibile con questa modalità di upload. Scartato il metodo via adattatore USB/TTL (che non trovo più nel cassetto e per il quale avevo trovato quest’ottima guida in italiano) mi sono arrangiato via Arduino Uno (e un saldatore) che ho sfruttato per trasferire il nuovo firmware dal PC al Sonoff, seguendo questa chiarissima guida in italiano. Cmq in caso si può fare affidamento sulla community di smanettoni che potete trovare in questo Forum o in questo canale Discord. Infine per chi proprio non se la sente, consiglio di farsi un giro su Ebay e di acquistare un dispositivo già pronto e funzionante con firmware Tasmota pre-installato.
  • Collegamenti elettrici. Ho utilizzato un cavo bipolare tipo H03VVH2 2×0,75mm, una spina elettrica maschio per il collegamento alla rete elettrica e una spina elettrica femmina per il collegamento al punto luce. Ovviamente la lunghezza dei cavi deve essere predisposta secondo necessità.
    ATTENZIONE CON LA CORRENTE 220V NON SI SCHERZA!!!
  • Il software di controllo. Il firmware Tasmota consente già di programmare (tramite la funzione timer) l’orario di accensione e di spegnimento del carico collegato all’interruttore, ma io voglio qualcosa di più intelligente.
    Voglio che il punto luce si accenda in mia presenza e al verificarsi di precise condizioni. Quindi ho creato uno script in Python (che ho chiamato myTwilight) che gira avviato via crontab sul Raspberry Pi. Lo script completo è disponibile sulla mia pagina Github e fa le seguenti cose:


    • Controlla che il Sonoff sia effettivamente operativo:

      • def pingSonoff(): ##Test ping SonOff
            var = os.popen("ping sonoff -c 1").read()
            l = var.index('received')
            l = l-2
            if var[l] == '1':
                return 'ON'
            else:
                return 'OFF'
        

      Ho assegnato l’hostname ‘sonoff’ al mio interruttore così da non essere costretto, per contattarlo, a ricordare il suo indirizzo IP.


    • Controlla via API l’ora del crepuscolo del giorno preciso (calcolata sulle coordinate geografiche della mia stanza);

      • def tramonto(lat, lng): ##Orario calcolato secondo GMT (senza ora legale/ora solare)
            request = requests.get("http://api.sunrise-sunset.org/json?lat="+lat+"&lng="+lng+"&formatted=0")
            return datetime.strptime(str(request.json()['results']['sunset'][11:16]), '%H:%M')
        

      Le coordinate geografiche della stanza le ho ottenute facilmente via Google Maps,  e la richiesta all’API del sito “sunrise-sunset.org” è gratuito e molto semplice da utilizzare, purtroppo il valore orario restituito è calcolato sull’ora GMT. Ho quindi dovuto calcolare l’offset dell’ora legale con una richiesta ad un’altra API di “worldtimeapi.org”:

      • def oralegale(): ##controllo ora legale
            request = requests.get("http://worldtimeapi.org/api/timezone/Europe/Rome")
            utc_offset = str(request.json()['utc_offset'])
            return int(utc_offset[2])
        

      E quindi l’ora del tramonto risulta essere così determinata (richiamando le suddette funzioni):

      • tramonto = tramonto(lat, lng)
        ora_tramonto = str(int(str(tramonto)[11:13])+oralegale())+':'+str(tramonto)[14:16]
        

    • Controlla la situazione meteo (indice copertura delle nuvole e quindi situazione luminosa);

      • def clima(lat, lng, api_key):
            url = "https://api.darksky.net/forecast/"+api_key+"/"+lat+","+lng+"?units=si&lang=it&exclude=daily,hourly,alerts,minutely"
            request = requests.get(url)
            print "Situazione clima: " + request.json()['currently']['summary']
            cloud = request.json()['currently']['cloudCover'] # controllo indice copertura cielo (da 0 a 1, da sereno a molto coperto)
            if  cloud > 0.50:
                if cloud > 0.75: 
                    return -600 # molto coperto
                else:
                    return -300 # coperto
            else:
                if cloud < 0.25:
                    return 0    # sereno
                else:
                    return 750  # molto sereno
        

      La suddetta funzione si è resa necessaria perché voglio che il punto luce si accenda anticipando l’ora del tramonto di qualche minuto nel caso il cielo risulti essere particolarmente coperto e quindi la stanza sia particolarmente buia, piuttosto che rimandare l’accensione di qualche minuto in caso di cielo sereno. Il sito “darksky.net” mette a disposizione via API (gratuitamente fino al limite di 1000 richieste giornaliere) diversi parametri meteorologici calcolati sulla base delle coordinate geografiche tra le quali l’indice ‘cloudCover’ che da 0 a 1 mostra lo statodella nuvolosità del cielo.


    • Controlla se sono presente nella stanza (quindi controlla se almeno uno dei due pc che solitamente utilizzo risultano accesi);

      • def ping(): ##Check presenza (attraverso ping PC e Laptop)
            var1 = os.popen("ping 192.168.1.124 -c 1").read()
            l1 = var1.index('received')
            l1 = l1-2
            if var1[l1] == '1':
                stato1 = 'OK'
            else:
                stato1 = 'NO'	
            var2 = os.popen("ping 192.168.1.111 -c 1").read()
            l2 = var2.index('received')
            l2 = l2-2
            if var2[l2] == '1':
                stato2 = 'OK'
            else:
                stato2 = 'NO'	
            if stato1 == 'OK' or stato2 == 'OK':
                return 'OK'
            else:
                return 'NO'
        

      Anche in questo caso utilizzo il ping per verificare se uno dei due PC che di solito utilizzo risultano accesi, determinando così l’effettiva mia presenza in stanza.


    • La funzione ‘main’ controlla se tutte le condizioni sono soddisfatte:

      • def main(ora, delay):
            diff = int((max(ora) - min(ora)).total_seconds())
            if ora[1] > ora[0] and diff >= delay:
                if pingSonoff() == 'ON':
                    if ping() == 'OK':
                        print 'Accendo Sonoff'
                        powerOn()
                    else:
                        print 'Sole tramontato, ma non rilevo presenza attiva...'
                else:
                    print 'Sole tramontato, ma Sonoff non operativo...'
            else:
                print 'Ancora troppo presto...'
        

      Ovviamente nel caso in cui non sussistano le condizioni il programma prosegue con questo loop:

      • while count <24:
            print str(count)+' - Check: '+strftime("%d-%m-%Y %H:%M:%S", localtime())
            adesso = datetime.strptime(strftime("%H:%M", gmtime()), '%H:%M')
            ora = [tramonto,adesso]
            delay = clima(lat, lng)
            main(ora, delay)
            print '\n'
            count += 1
            time.sleep(750) #loop ogni 15'
        

      Il programma procede quindi per un numero massimo di 24 volte, a distanza di 15 minuti, a controllare le condizioni impostate. Facendo partire il programma alle 16:00 il numero di loop è sufficiente per coprire i possibili scenari.


    • … e nel caso accende il punto luce eccitando il relé del Sonoff:

      •  
        def powerOn(): ##attivazione Sonoff
            r = requests.get("http://sonoff/cm?cmnd=Power%20ON")
            print(r.content)
            sys.exit()
        
    • Una volta provveduto ad accendere il punto luce lo script Python ha terminato la sua funzione quindi viene terminato.

Considerazioni finali:

  • Con poca spesa e un po’ di ingegno ho centrato il mio obiettivo: avere un interruttore intelligente in grado di accendere un punto luce al verificarsi di determinate condizioni (presenza, orario e luminosità).
  • Una peculiarità del Sonoff Basic è quella di consumare veramente poco (circa 0,70-0,80W o qualcosina in più quando il relè è eccitato), inoltre è possibile ridurne ‘sensibilmente’ i consumi impostando il valore Sleep del firmware Tasmota da 50 a 200 espresso in millisecondi. Inoltre ho spento le funzionalità MQTT che di fatto non utilizzo (tramite il comando PowerRetain)..
  • Sempre via console ho disattivato l’accensione del led presente sul Sonoff (comando LedPower e LedState) che quindi ora lampeggia brevemente solo al momento in cui si connette alla rete elettrica segnalando la ricerca della connessione Wifi.
  • La presenza del bottoncino sulla parte alta della copertura di plastica del Sonoff mi consente di accendere e di spegnere manualmente il punto luce.
  • Una prossima versione del programma di controllo, a cui sto già pensando, prevede di modificare il rilevamento di presenza integrando funzionalità via bluetooth (in questo caso andrei a rilevare o meno la connessione con il mio smartphone).
  • Ho già pensato/realizzato un’integrazione con il client Telegram che è già in esecuzione sul mio Raspberry Pi così da ricevere comunicazioni sul funzionamento del Sonoff.
  • Lo script Python completo è disponibile sulla mia pagina Github insieme agli altri progetti.
  • Ho già ordinato un Sonoff Dual (quindi in grado di comandare due uscite) da collegare alla tapparella motorizzata che si abbasserà e si alzerà a seconda delle condizioni da me impostate…

Raspberry Pi – Come spegnere (tutti) i LED

PROBLEMA

Possedendo un Raspberry Pi (modello B+) che rimane acceso in continuazione e ahimè posizionato in camera da letto, allo scopo di diminuire il disturbo luminoso notturno e il consumo di corrente, mi sono chiesto se era possibile spegnere tutti i led del dispositivo, sia i due frontali, quello rosso (PWR – power) e quello verde (ACTSD card) che i due posteriori, quello verde (LNKEthernet) e quello giallo (100 – Ethernet).

SOLUZIONE

1 – Collegandomi via SSH al Raspberry Pi ho dato i seguenti due comandi con i quali mi sono occupato di spegnere i due led frontali:

sudo -s

echo 0 >/sys/class/leds/led0/brightness #Spegne led PWR

echo 0 >/sys/class/leds/led1/brightness #Spegne led ACT

(ovviamente per accendere i led occorrerà sostituire la parte iniziale del comando con “echo 1”)

2 – Per quanto riguarda lo spegnimento dei due led posti sul connettore RJ45 è un’altro paio di maniche, per fortuna ho trovato in rete questo programmino amatoriale (llctl) che si è occupato ella faccenda.

Una volta scaricato e trasferito sul Raspberry pi, procedere con i seguenti comandi:

tar xf llctl.tgz

make

sudo ./llctl f0 l0 d0

(per riaccendere i led modificare i parametri finali con “f1 l1 d1”)


Ho quindi creato il seguente script per schedulare con CRONTAB lo spegnimento dei led ad ogni avvio del Raspberry Pi:

ledOFF.sh

echo spengo led
sudo -s << SCRIPT
echo 0 >/sys/class/leds/led0/brightness #Spegne led PWR
echo 0 >/sys/class/leds/led1/brightness #Spegne led ACT
./leds/llctl f0 l0 d0
tvservice --off
SCRIPT

P.S.:

  • Mi è sembrato di capire che la suddetta procedura funziona anche con gli altri modelli di Raspberry Pi;
  • Nello script ho aggiunto il comando tvservice –off per spegnere l’HDMI (che non uso).

 

[Hack] Raspberry Pi email print server

Problema: Ho la necessita di stampare e/o far stampare documenti quando sono fuori casa. Purtroppo ho l’abitudine di tenere spenta la stampante sulla scrivania e non ho modo di accenderla da remoto. La tempistica di stampa non è importante, non mi importa quando i documenti saranno stampati, ma che i documenti vengano effettivamente stampati.

Soluzione: L’idea è di inviare i documenti da stampare via email a una casella appositamente creata per lo scopo. Il Raspberry Pi (serverino che fa tanti altri lavori ed è quindi sempre acceso) provvederà periodicamente a controllare la posta (diciamo ogni 20 minuti durante la giornata), a salvare gli allegati su una chiavetta USB e a stamparli quando la stampante risulterà effettivamente disponibile.

Ingredienti:
– Raspberry Pi (nel mio caso un model B+);
– pendrive USB;
– account email ad hoc;
– python;
– libreria imaplib;
– stampante.

Procedimento: Continua a leggere

[Progetto-Arduino] Telecomando ON/OFF con controllo di prossimità – (VI.BE.TV)

Secondo progetto con Arduino Uno (link precedente progettoArduino+Bluetooth+Relè+Lampadina) utilizzando il sensore ad ultrasuoni HC-SR04 e un led IR che mi sono appena arrivati.

VIBETV

childTVNon so quanti di voi abbiano il problema dei bambini che guardano la Tv avvicinandosi troppo allo schermo.
Ai voglia continuare a ripetere di allontanarsi, non c’è niente da fare. Sembra che Peppa Pig & Co. debbano essere guardati appiccicati al video, altrimenti non c’è gusto, anche sotto la minaccia di spegnere la televisione.
Mi è venuta quindi l’idea di monitorare con Arduino la distanza dello spettatore ed eventualmente spegnere la tv se si è troppo vicini allo schermo…

how-watching-tv-and-adult-media-affects-children-039-s-health-21A che distanza bisogna posizionare il televisore?
Occorre tener conto della risoluzione: gli HD e i Full HD vanno guardati a distanze diverse, anche se hanno la stessa grandezza.
Teniamo inoltre presente che 1 pollice (1”) equivale a 2,54 cm.

Per i televisori HD la formula è: (POLLICI x 2,54) x 2,30.
Quindi se dobbiamo calcolare la distanza di un televisore 46” HD dovremo calcolare: (46 x 2,54) x 2,30 ovvero 268,70 (2 m e 69 cm circa).

Per un televisore Full HD la formula è: (POLLICI x 2,54) x 1,50.
Quindi se dobbiamo calcolare la distanza di un televisore 46” Full HD dovremo calcolare: (46 x 2,54) x 1,50 ovvero 175,20 (1 m e 75 cm circa).


Il progetto:
logo-arduino_byZirconetIl dispositivo è davanti al televisore, posto sullo stesso ripiano.
L’inizializzazione è verificabile dall’accensione dei tre led (in sequenza: rosso, giallo e poi verde) e dal suono del buzzer che avverte che il dispositivo è attivo.
Il modulo ad ultrasuoni misura la distanza dell’ostacolo davanti al dispositivo (lo spettatore). Sono contemplate tre distanze limite a 200cm (segnalata dall’accensione del led verde), 130cm (led giallo) e 80cm (led rosso).
Il codice da inviare alla TV lho ricavato
Per evitare misurazioni ridondanti, se la distanza è > 200cm la misurazione avviene ogni 5 secondi, che scendono a 2 secondi a < 130cm e un solo secondo sotto gli 80cm. ArduinoUnoSmd450pxA distanze inferiori alla soglia degli 80cm il sistema rileva un allarme (segnalazione acustica tramite buzzer) e dopo 10 rilevamenti consecutivi provvede ad inviare via infrarossi il segnale di spegnimento alla televisione (invio segnale OFF). ledA questo punto verrà inviato un segnale di accensione alla tv quanto non si rileveranno più allarmi ovvero l’ostacolo (lo spettatore) non si sarà adeguatamente allontanato (distanza > 80cm, invio segnale ON).
Ho anche predisposto la comunicazione seriale per monitorare via seriale quanto misurato durante la fase di test.


Lista componenti hardware utilizzati per questo progetto:
– Arduino Uno;
– modulo sensore HC-SR04;
– IR led 38Khz;
– led rosso;
– led giallo;
– led verde;
– buzzer piezo;
– breadboard;
– resistenze 330Ω;
– resistenza 150Ω;
– cavi e cavetti vari. Continua a leggere

[Tutorial-Arduino] Arduino+Bluetooth+Relè+Lampadina (parte 3/3) – L’App

In questo post andremo ad analizzare in dettaglio l’App che ho realizzato con la piattaforma online App Inventor 2 per il mio primo progetto con Arduino ovvero comandare con uno smartphone l’accensione/spegnimento di una lampadina via Bluetooth. Nella prima parte abbiamo visto la parte hardware e le relative connessioni, mentre nella seconda la realizzazione dello Sketch caricato sull’Arduino.

Premetto che per poter utilizzare App Inventor 2, la piattaforma realizzata e messa a disposizione del MIT, è necessario registrarsi. E’ comodo registrarsi con il proprio account di Google per avere sott’occhio tutti i progetti realizzati che saranno memorizzati nel lo spazio Cloud messo a disposizione. La registrazione così come l’utilizzo e totalmente gratuito.

App Inventor 2 è uno strumento online che permette in maniera semplice e pratica di dare sfogo alla propria fantasia nel realizzare App per Android senza conoscere il codice di programmazione. La piattaforma è suddivisa in due. In una, quella grafica denominata Designer, si realizzerà l’aspetto grafico dell’App scegliendo i componenti più o meno visibili che vogliamo utilizzare per la nostra applicazione. Nell’altra, denominata Blocks, si andrà a realizzare con una certa semplicità il motore software utilizzando dei pezzettini modulari.

Ecco il funzionamento dell’App che mi occorreva per questo progetto:MIT App Inventor 2

Innanzitutto mi occorreva stabilire la connessione Bluetooth con il modulo HC-06 pertanto ho realizzato un pulsante (utilizzando un ListPicker) tramite la quale scegliere il dispositivo con il quale connettermi tra quelli associati in precedenza e attivi. Alla pressione del tasto ho associato un suono.

Una volta scelto il dispositivo BT il programma stabilisce la connessione seriale che rimane attiva. Al momento dell’attivazione della comunicazione ho associato un suono, quindi il pulsante ListPicker1 scompare e al suo posto compare un pulsante premuto il quale si disattiva la comunicazione con l’HC-06.

A questo punto entrano in gioco due pulsanti, quello di acceso e quello di spento premendo i quali invio via seriale la lettera “H” per HIGH che farà accendere la lampadina oppure “L” per spegnerla. Alla pressione di ciascun pulsante ho associato un suono.

Download App: premi qui

[Tutorial-Arduino] Arduino+Bluetooth+Relè+Lampadina (parte 2/3) – Lo Sketch

ArduinoUnoSmd450pxIn questo post andremo ad analizzare in dettaglio lo Sketch che ho scritto per il mio primo progetto con Arduino ovvero comandare con uno smartphone l’accensione/spegnimento di una lampadina via Bluetooth.

//dichiarazioni
char com;
int ledpin = 8;

void setup() {
pinMode(ledpin, OUTPUT); //dichiarazione dell'OUTPUT
Serial.begin(9600); // inizializzazione seriale
}

void loop() {
if( Serial.available() )
{
com = Serial.read();   } //controllo input da seriale
if( com == 'H')   {
//se riceve 'H' eccita il relè
digitalWrite(ledpin, HIGH);
}
else {
if( com == 'L')
//se riceve 'L' spegne la lampadina
digitalWrite(ledpin, LOW);
}
}

In breve ho dichiarato l’utilizzo del pin 8 quale Output. Arduino ciclicamente andrà a controllare quanto ricevuto via seriale dal modulo Bluetooth e se riceverà la lettera “H” andrà a alzare il livello del pin 8 ed ecciterà il relè accendendo la lampadina, mentre se riceverà una “L” andrà ad abbassare il livello del pin 8 comandando al relè di spegnere la lampadina.


Download dello Sketch: qui il link


Analizziamo in dettaglio le parti del codice dello Sketch: Continua a leggere

[Tutorial-Arduino] Arduino+Bluetooth+Relè+Lampadina (parte 1/3) – L’Hardware

ArduinoUnoSmd450px

Ho recentemente acquistato una scheda Arduino Uno, un modulo di comunicazione Bluetooth e una scheda relè. Con questi ho realizzato il mio primo progetto, giocando con la prototipazione elettronica, con la programmazione dello Sketch poi caricato sull’Arduino, con la comunicazione seriale via Bluetooth e con la programmazione Android per far accendere l’abat-jour che sta solitamente sul comodino premendo un pulsante sullo smartphone.

Questo tutorial è diviso in tre parti:
Arduino+Bluetooth+Relè+Lampadina (parte 1/3) – L’Hardware – Dove troverete il progetto completo con la spiegazione dell’hardware utilizzato e i vari collegamenti.
Arduino+Bluetooth+Relè+Lampadina (parte 2/3) – Lo Sketch
– Dove troverete l’analisi del programma caricato sull’Arduino per questo progetto.
Arduino+Bluetooth+Relè+Lampadina (parte 3/3) – L’App Android – Dove troverete l’analisi del programma realizzato per lo smartphone Android  per il controllo remoto.

Lista componenti hardware utilizzati per questo progetto:
– scheda Arduino Uno;
– scheda relè;
– modulo BT HC-06;
– breadboard;
– cavi e cavetti vari.


Continua a leggere

%d blogger hanno fatto clic su Mi Piace per questo: