Statistiche sul fotovoltaico

Pannelli fotovoltaici
Pannelli fotovoltaici

Al giorno d’oggi è sempre più frequente vedere nei tetti delle case impianti fotovoltaici per la produzione di energia elettrica. La diminuzione dei costi di produzione e lo sviluppo tecnologico stanno portando alla creazione di impianti sempre più moderni e all’avanguardia, ed in un mondo sempre più smart l’informatica non poteva di certo stare fuori da un ambiente in continuo sviluppo come questo.

Ogni impianto fotovoltaico, oltre ai pannelli sul tetto ed i vari cavi, possiede un inverter che si occupa di “convertire” la corrente continua prodotta dai pannelli in corrente alternata adatta ad essere immessa nella rete di distribuzione.
Ed è proprio l’inverter il cuore pulsante di ogni impianto, apparecchi che al giorno d’oggi sono diventati, oltre alla parte per così dire “di potenza”, dei veri e propri computer, molti dei quali con porte di comunicazione seriale o perfino schede ethernet.

Nell’impianto a casa dei miei genitori è stato installato un inverter modello S3000 prodotto dalla casa svizzera SolarMax. Questo modello può erogare una potenza istantanea massima di 2750 Watt e possiede una porta ethernet con connettore RJ45 sul fondo per essere interfacciata con altri dispositivi della casa produttrice oppure per essere interrogato con dei software ufficiali prodotti dalla stessa SolarMax (disponibili per Linux, Mac, Windows e perfino per Android).

SolarMax S3000
SolarMax S3000

Grazie alle preziose informazioni raccolte in questo post, dove è accuratamente spiegato il protocollo di comunicazione tra l’inverter ed i vari software, ho potuto realizzare un piccolo demone scritto in linguaggio C (smlgr, disponibile in GPLv2 su GitHub) che si occupa di interrogare l’inverter circa ogni 10 secondi per poi memorizzare i dati in un database MySQL. Il demone è molto leggero e consuma pochissima RAM. Dipende solo dalle librerie MySQL ed è possibile compilarlo ed installarlo perfino a bordo di un router.
Dopo che i dati sono memorizzati su database possono essere interpretati semplicemente con una serie di pagine in PHP (anche questo progetto è disponibile su GitHub).

Per realizzare il tutto ci sono voluti circa 2 giorni.
Il primo problema da risolvere è stato collegare l’inverter alla LAN interna. Tutti gli apparati di rete (Modem, Router e AccessPoint) stanno al piano di sopra, mentre l’inverter è stato installato nel garage. Si potrebbe potuto passare un cavo di rete nell’impianto elettrico, ma per ora ho deciso di utilizzare un link WiFi usando una Fonera 2100 con firmware OpenWRT configurato per lavorare in modalità client (e non Access Point) così da agganciarsi al già esistente segnale WiFi della casa e collegare la sua porta ethernet alla LAN.

Fonera serial interface
Fonera serial interface
Flashing Fonera with OpenWRT
Flashing Fonera with OpenWRT

A causa dell’hardware della fonera non è possibile configurare in bridge le due interfacce di rete (via cavo e wifi), quindi ho dovuto configurare la fonera per abilitare il forwarding tra le due interfacce ed ho dovuto aggiungere una route statica nel router domestico.
Inoltre la Fonera è famosa per essere un apparecchio che scalda parecchio, specialmente in periodi caldi dell’anno.
Per ovviare a questo problema ho forato il coperchio superiore della fonera ed ho installato una vecchia ventola per CPU alimentandola a 5 Volt invece che a 12, così da farla girare molto più lentamente, facendo meno rumore e durando più a lungo, e garantire un flusso d’aria continuo.

Fonera Wi-Fi client
Fonera Wi-Fi client

Una volta collegato l’inverter alla LAN ho iniziato a realizzare il demone scrivendo in C le varie funzioni. Non ho ancora raggiunto una versione stabile, però posso già dire che il sistema funziona e memorizza i dati sul database, e sopratutto il continua a funzionare sia nel caso un cui il database dovesse andare off-line, sia nelle ore notturne in cui inverter si spegne e non risponde più alle richieste del socket.

La cosa più difficile è stato gestire le stringhe di comunicazione ed implementare quindi il protocollo creato dalla SolarMax. Grazie alle utilissime informazioni del post son riuscito a scrivere una funzione che mi prepara la stringa da inviare all’inverter per interrogarlo ed una funzione per parsare la risposta.

Ogni stringa è chiusa tra parentesi grafe ed è divisa in 3 sezioni separate da un simbolo di pipe (|).
La prima a sinistra contiene nell’ordine l’indirizzo del “mittente”, quello del “destinatario” e la lunghezza del messaggio. FB identifica il computer, mentre 01 è il numero dell’inverter configurabile nel menù dell’inverter stesso, ed utile nel caso in cui nell’impianto siano presenti più di un inverter.
In questo caso 32 è la lunghezza in bytes dell’intero messaggio comprese le parentesi grafe, espressa in numero esadecimale. La lunghezza sarà quindi sempre pari a 13 + lunghezza della query + 6.
La seconda parte inizia sempre con “64:” ed è seguita dalla query.
Nella terza ed ultima parte è presente il checksum della stringa. Su questa parte ho perso un po’ di tempo, ma alla fine ho capito che si tratta della somma di tutti i valori ASCII dell’intera stringa limitata a 16 bits, cosa che si può facilmente ottenere con l’operatore modulo, ed espressa sempre in esadecimale aggiungendo zeri fino ad ottenere 4 cifre. Il checksum va calcolato in tutti i caratteri a partire da “FB” fino all’ultima pipe compresa (escludendo quindi la prima parentesi grafa). La stringa deve essere formattata correttamente, ed i valori di lunghezza e checksum devono essere corretti, altrimenti l’inverter non risponderà.

Inviando la stringa così formattata si riceve in risposta una stringa simile, con in più i valori sempre espressi in esadecimale.
Si può notare che i valori di “mittente” e “destinatario” del messaggio ora sono giustamente invertiti, che il valore della lunghezza è superiore rispetto a prima (ora contiene anche i valori), e che il checksum è differente. Tutti i parametri sono riproposti nello stesso ordine dell’interrogazione, e ciascuno è seguito da un segno = e dal corrispondente valore.
Tralasciando la parte iniziale e finale, ho splittato la stringa in più parametri usando il carattere ; come separatore, e su ciascuna porzione ho usato il segno = per separare i parametri dai valori. In questo modo ho creato una lista circolare di argomenti da usare per costruire la query SQL per la memorizzazione dei dati.
Il demone come prima cosa crea e connette il socket, poi invia i dati. Quando riceve la risposta, la interpreta e salva le informazioni sul database. Alla fine chiude la connessione al DB, chiude il socket e rimane in sleep per 10 secondi. Il tutto è racchiuso in un ciclo while infinito.
Tutte queste operazioni sono sequenziali. Se una fallisce, le successive non vengono eseguite. In questo modo mi assicuro che se l’inverter non risponde (spento oppure non c’è connessione) il demone non crasha e continua il suo ciclo finché non ritorna raggiungibile. Idem per il database, dove la connessione viene ogni volta aperta e chiusa. Se l’inverter funziona ma il database non risponde i dati vengono scartati senza interrompere il funzionamento del demone.

Nel database MySQL occorre creare una tabella che contenga un campo per ogni parametro richiesto, infatti il demone salva nel database i valori chiamandoli con lo stesso nome dei parametri. È necessario inoltre aggiungere un campo che contenga il timestamp in cui è stata fatta l’interrogazione.
Questo è un esempio di query SQL eseguita dal demone:

Al momento della creazione della tabella, i campi relativi ai valori sono stati creati di tipo INT. In questo modo è possibile esprimere i valori da inserire usando direttamente la notazione esadecimale e quindi inserendo i valori così come sono stati inviati dall’inverter, semplicemente aggiungendo all’inizio la stringa “0x”.

smlgr working
smlgr working

Per l’interpretazione dei dati è possibile usare in qualsiasi sistema che può interfacciarsi con il database MySQL.
Ho creato un piccolo sito internet scritto in PHP e jQuery che mi visualizza in tempo reale l’andamendo della produzione. Avendo i dati sul DB ed avendo un refresh di circa 10 secondi è possibile fare un’analisi sulla produzione di energia sia sulla base oraria, sia giornaliera, ma anche a lungo termine.

Tutta l’infrastruttura gira a bordo di una Raspberry Pi model B, e consuma pochissima CPU e poca RAM.

smlgr Web Interface
smlgr Web Interface