Google Charts, CSV e grafici in tempo reale

grafico con google chartsNel poco tempo concessomi dalla sessione estiva, mi sono interrogato circa la possibilità di disporre sul blog di un grafico aggiornato in tempo reale (o quasi, a me basta ogni ora) con la temperatura del Raspberry. La cosa sembra abbastanza inutile (ed in effetti lo penso anche io >:( ) , ma l'applicazione è a solo fine di apprendimento: potrebbe diventare interessante qualora ci fosse qualcosa di più significativo da graficare (ad esempio se usassi il raspi come un datalogger in remoto).

Schema generale applicazione

Quello che voglio fare è: leggere la temperatura interna del processore del Raspberry (come già fatto varie volte), associarci data e ora e caricare il tutto su un grafico in una pagina del blog. Di per se non è difficile, ma richiede più di qualche passaggio:

1. Leggo la temperatura e la salvo assieme all'ora in un file csv (semplice e facile da gestire!)

2. Automatizzo questa operazione, facendola ripetere ogni ora

3. Dopo l'esecuzione, automatizzo il caricamento sul mio spazio web (sempre ogni ora, anche questo già fatto)

4. Con qualche riga di PHP visualizzo un grafico con i dati raccolti (grazie a Google Charts, comodo e completo)

Dettagli dell'operazione

Il listato che crea il file csv è in python:

 import subprocess
import csv
import sys
import operator
from time import localtime, strftime

t = subprocess.check_output(["/opt/vc/bin/vcgencmd","measure_temp"])
a = str(t)
h = a[5:9]
s = strftime("%H:%M %D", localtime())

temperature = h.encode("utf-8")
time = s.encode("utf-8")
newtemp = [time,temperature]

fcsv = open("temperaturegraph.csv", "a")
wrobj = csv.writer(fcsv)
wrobj.writerow(newtemp)
fcsv.close()

Si comincia con i soliti comandi per importare le librerie necessarie, seguiti da 4 righe che leggono la temperatura del processore, che viene salvata in una stringa. Tale formato non è però accettato dalla libreria csv e va quindi trasformato in una serie di byte, con l'istruzione encode. stessa cosa per la stringa contente l'ora. Le due possono quindi essere salvate in una lista che viene caricata nel file grazie all'istruzione wrobj.writerow.

Bisogna quindi automatizzare l'esecuzione di questo listato ed il caricamento sul server; basta digitare nella shell il comando crontab -e  ed inserire le seguenti righe:

* */1 * * * python /home/pi/tempraspicsv.py
* */1 * * * curl -T temperaturegraph.csv ftp://host.server.org/ --user username:password

caricamento csv per google charts

Ora non resta che scrivere qualche riga di PHP che legga il file CSV e crei il grafico corrispondente. Inizialmente avevo pensato di servirmi di qualche libreria free (PHPgraphib se non vado errando), poi ho scoperto Google Charts. Non necessariamente più semplice, ma offre molti più esempi e supporto (indispensabili visto che non ho intenzione di mettermi a studiare anche PHP)... e poi i grafici sono mooolto più belli e personalizzabili! Il listato è qui di seguito:

 <?php
# Open the File.
if (($handle = fopen("temperaturegraph.csv", "r")) !== FALSE)
{
# Set the parent multidimensional array key to 0.
$nn             = 1;
$csvarray[0][0] = "Ora";
$csvarray[0][1] = "Temperatura";
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
# Count the total keys in the row.
$c = count($data);
# Populate the multidimensional array.
for ($x = 0; $x < $c; $x++)
{
if ($x == 0)
{
$csvarray[$nn][$x] = $data[$x];
}
else
{
$csvarray[$nn][$x] = (int) $data[$x]; #forzo ad integer
}

}
$csvarray[$nn][1] = (int) $csvarray[$nn][1];
$nn++;
}
# Close the File.
fclose($handle);
}
# Print the contents of the multidimensional array.
?>
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
<?php

$js_array = json_encode($csvarray);
echo "var javascript_array = " . $js_array . ";\n";
?>
function drawChart() {
var data = google.visualization.arrayToDataTable(javascript_array);

var options = {
title: 'Raspberry Temperature'
};

var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body> <div id="chart_div" style="width: 650px; height: 400px;"></div>
</body>
</html>

La prima parte si occupa di leggere il file csv e riordinare i record che vengono poi passati, sotto forma di array multidimensionale, alla funzione che si occupa di generare il grafico vero e proprio, la seconda parte (racchiusa tra i tag <html>).

Dove scrivere tutte queste righe in PHP?  In un file con estensione PHP, che va poi richiamato nella pagina del blog con il tag iframe:

<iframe src="http://www.tobpic.altervista.org/temperature_graph.php" height="500" width="700"></iframe>

Il risultato è questa pagina! 🙂