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

qtffmpeg

Nuovo progettino per realizzare una piccola GUI che consenta di convertire qualsiasi file audio in formato MP3 o WAV.
Molto semplice, ma sopratutto multi-piattaforma.
Lavori in corso e sorgenti disponibili su http://github.com/sardylan/qtffmpeg

Installare Linux su RaspberryPi con SD di qualsiasi dimensione

In questo esempio mostro come installare in una qualsiasi SD una distribuzione per la RaspberryPi, senza dover eseguire procedure per per l’espansione delle partizioni e con la possibilità di organizzare le partizioni come si vuole.
Gli esempi sono fatti con la Raspbian (2013-05-25-wheezy-raspbian.zip)

Partizionare (fdisk, parted, cfdisk) la scheda SD e creare due partizioni:

  1. primaria, 64MB, FAT32 LBA (codice 0x0c)
  2. primaria, tutto lo spazio rimanente, Linux (codice 0×83)

Formattare la prima con mkdosfs (FAT32):

Formattare la seconda con mkfs (ext3 o ext4):

Ora è neccessario montare l’immagine su delle directories temporanee per copiare i dati.
Estrarre il file ZIP e verificare gli offset con fdisk:

Nella colonna “Start” abbiamo i valori per montare le partizioni con l’offset.
Creiamo due directories temporanee:

Montiamo le partizioni dell’immagine:

Creiamo la directory per la scheda SD e montiamo le due partizioni:

Copiamo tutti i files del sistema operativo:

Copiamo tutti i files della partizione di boot:

Ora verifichiamo con vim il contenuto del file in /mnt/boot/etc/fstab:

Nella RPi, il device della scheda SD si chiamerà /dev/mmcblk0. Verificate che il tipo di filesystem corrisponda con quello da voi scelto, in questo caso ext4, ed aggiungete eventuali righe per ogni partizioni che avete creato.
Ora smontate tutte le partizioni:

Rimuovete la scheda dal PC e collegatela alla RPi, e tutto dovrebbe andare.

Icecast + MySQL Stats

Icecast è ormai considerato uno dei migliore software per realizzare un server di relay per flussi audio in streaming basato su formati e codice Open Source. Non solo è stato uno dei primi a supportare più flussi su un unico server, ma può essere usato anche con flussi audio/video basati su formati OGG.

Per quanto riguarda le statistiche di ascolto, il software di per se fornisce già alcuni dati come il numero di ascoltatori attuali per ogni flusso e quello del picco massimo, e consente di ottenere informazioni maggiori usando soluzioni esterne, come parser i files di log oppure software esterni che interrogano periodicamente il server.

Faccio parte del Team di UnicaRadio, la webradio degli Studenti dell’Università di Cagliari. Lavorando nell’ambiente ho capito l’importanza di un dato come il tempo medio di permanenza degli ascoltatori. Dopo aver valutato diverse soluzioni e provato diversi software, ho deciso di implementare la cosa lavorando direttamente sul codice sorgente, così da ottenere data ed ora di connessione e disconnessione di ogni singolo ascoltatore.

L’uso di un database esterno mi è sembrata la migliore soluzione, sia per l’inserimento dei dati da parte di Icecast, sia per la consultazione delle statistiche ottenute che può essere implementata anche con un semplice sito internet PHP+HTML.

Ho creato un repository su GitHub, raggiungibile all’indirizzo https://github.com/sardylan/icecast-mysql nel quale a breve riporterò tutte le modifiche che ho fatto fin’ora al sorgente originale.

Stay Tuned…

strlen e puntatori a NULL

Oggi ho scoperto una cosa molto importante sulla strlen() in linguaggio C.
Utilizzo questa funzione in quasi tutte le operazioni che riguardano le stringhe, ma non mi è mai capitato un caso in cui viene richiamata passando un puntatore a NULL come parametro di ingresso.
E non intendo un puntatore ad una stringa vuota (il cui unico elemento è un carattere di NULL), ma proprio un puntatore che in effetti non punta da nessuna parte.
Mentre testavo le nuove modifiche al codice di icecast (che pubblicherò non appena saranno stabili) ottenevo una serie di Segmentation Fault, e grazie a GDB ho scoperto e risolto il problema implementando una nuova funzione:

Nel mio caso, la strlen serve per preparare una query SQL, quindi il problema di un puntatore a NULL può essere risolto considerandolo come una stringa vuota.
In ogni caso si può risolvere la cosa con un semplice if.

Anche la funzione strcpy ha un comportament simile. Alla fine ho gestito la cosa con un if a monte.

Benvenuti

Benvenuti.

Come potete vedere, dopo tanto tempo mi son deciso a dare un aspetto decente al mio sito personale. Dopo aver testato Joomla (vecchie versioni), provato Drupal e dopo aver perfino creato un CMS partendo da zero, ho finalmente preso la decisione finale di installare WordPress.
Questo significa che avrò finalmente un blog serio, con una grafica “decente” e sopratutto facile da usare.

Argomenti e contenuti saranno quelli di sempre, ovvero un po’ di tutto. Guide, notizie, foto, e tanto altro, ma sopratutto tanta tanta roba inutile…