Tutorial Raspberry Pi - Graficar la temperatura de la CPU con Node.js y Highcharts
¡Hola! Hoy vengo a enseñaros un proyecto en el que estoy trabajando. He llegado al punto en el que prefiero enseñaros cómo hacerlo antes que mostraros el proyecto cuando acabe todo (que también lo haré). Hace poco, nuestro compañero AlexCorvis publicó una entrada sobre Xively y Raspberry Pi, una manera de ver estadísticas y el estado de nuestra Raspberry Pi en Internet, es decir, el Internet de las cosas. Esto no vale sólo para Raspberry Pi, pero como sabemos que os gusta, lo aplicamos a ello.
Hace ya varios meses estábamos trabajando en Geeky Theory en un proyecto bastante más grande que esto que os voy a enseñar ahora. Este tutorial es una mínima parte de lo que tenemos, pero no se puede documentar todo el código línea a línea, como comprenderéis.
El objetivo es graficar la temperatura del SoC (System on a Chip) de la Raspberry Pi para poder verla desde un navegador. Esto lo haremos con node.js y Highcharts.
El resultado debería ser algo parecido a esto:
Voy a contaros mi planteamiento principal para llevar a cabo esto con el menor consumo de recursos por parte de la Raspberry Pi. En Linux, podemos ver por ejemplo, la temperatura en miligrados en un archivo haciendo simplemente esto:cat /sys/class/thermal/thermal_zone0/temp
Muy sencillo, ¿no? Pues lo que pensé hacer es poner un watchdog que me controlara cuándo cambiaba el fichero para que cuando lo hiciese, coger su contenido y meterlo en la gráfica. Problema: el archivo cambiaba de contenido pero veías sus propiedades y la última hora de modificación era la hora en la que había encendido el ordenador. ¿Cómo puede modificarse un archivo sin modificarse? Aún sigo sin entenderlo, así que si algún linuxero experto lo sabe... ¡Por favor que me lo diga!
Bueno, pues viendo el fracaso de esto, fuí a lo fácil: cada X tiempo ejecuto un comando para saber la temperatura y grafico lo que me devuelva. Haciendo esto, la Raspberry Pi funciona bastante bien. No se calienta ni se queda atascada y va el navegador bastante fluido.
Después de este rollo, voy a enseñaros lo que tenéis que hacer para acabar realizando este tutorial:
1. Instalar un servidor Web en la Raspberry Pi
Esto lo podéis hacer siguiente tutorial: Instalar servidor Web Raspberry Pi
Si no tenéis Raspberry Pi pero lo queréis hacer en cualquier Linux, podéis seguir este: Instalar servidor Web Linux
2. Instalar node.js y npm en la Raspberry Pi
Simplemente introduciremos los siguientes comandos:
sudo apt-get install nodejs npmEs lo mismo para cualquier Linux. Recordad que al final la Rasberry Pi con Raspbian es a grandes rasgos un Debian.
3. Crearemos la carpeta del proyecto
mkdir /var/www/Raspberry-Pi-StatusNavegamos hacia ella: cd /var/www/Raspberry-Pi-Status
4. Instalar Socket.io
Ejecutamos el siguiente comando: npm install socket.io
5. Creamos el archivo que ejecutará el servidor
Lo llamaremos server.js y estará dentro de la carpeta js, ya que está programado en Javascript. ¡Hay que ser ordenado con los ficheros de código! mkdir jscd jsnano server.js
No explicaré el código paso a paso porque está visto en los tutoriales de node.js de Geeky Theory. Voy diciendo lo que hago en los comentarios:
/** * Autor: Mario Pérez Esteso * Web: geekytheory.com */ var app = require('http').createServer(handler), io = require('socket.io').listen(app), fs = require('fs'), sys = require('util'), exec = require('child_process').exec, child; //Escuchamos en el puerto 8000 app.listen(8000); //Si todo va bien al abrir el navegador, cargaremos el archivo index.html function handler(req, res) { fs.readFile(__dirname+'/../index.html', function(err, data) { if (err) { //Si hay error, mandaremos un mensaje de error 500 console.log(err); res.writeHead(500); return res.end('Error loading index.html'); } res.writeHead(200); res.end(data); }); } //Cuando abramos el navegador estableceremos una conexión con socket.io. //Cada 5 segundos mandaremos a la gráfica un nuevo valor. io.sockets.on('connection', function(socket) { setInterval(function(){ child = exec("cat /sys/class/thermal/thermal_zone0/temp", function (error, stdout, stderr) { if (error !== null) { console.log('exec error: ' + error); } else { //Es necesario mandar el tiempo (eje X) y un valor de temperatura (eje Y). var date = new Date().getTime(); var temp = parseFloat(stdout)/1000; socket.emit('temperatureUpdate', date, temp); } });}, 5000); });
Ya tenemos creada la parte de servidor. ¡Node.js mola mucho!
6. Creamos el archivo que ejecutará el cliente
Ahora vamos a mostrar en nuestro navegador los datos que recibimos de la Raspberry Pi. Para ello, utilizaremos Highcharts, como ya he mencionado anteriormente. Como estábamos en la carpeta js dentro de la ruta absoluta /var/www/Raspberry-Pi-Status/js, navegamos a la carpeta status. Introducimos el siguiente comando:
cd ..o también podemos ejecutar el siguiente, da igual: cd /var/www/Raspberry-Pi-Status
Ahora creamos el archivo index.html:
nano index.htmlSu contenido es el siguiente. Tened en cuenta que la IP de mi Raspberry Pi es la 192.168.1.9. Vosotros poned la vuestra: <!DOCTYPE html> <!-- Autor: Mario Pérez Esteso <mario@geekytheory.com> Web: geekytheory.com --> <html> <head> <meta charset="utf-8" name="viewport" content="width=device-width" /> <title> Raspberry Pi Status </title> <!-- Importo el módulo socket.io que tengo en el proyecto --> <script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <!-- Importo el archivo Javascript de Highcharts directamente desde su servidor --> <script src="http://code.highcharts.com/highcharts.js"></script> </head> <body> <!-- Creo el div donde tendré la gráfica. Le digo que ocupe todo el ancho de la pantalla y 400px de alto --> <div id="chart" style="width:100%; height:400px;"></div> <!-- Comienza el Javascript --> <script> // Creo un WebSocket. ¡Poned la IP de vuestra Raspberry Pi! var socket = io.connect('http://192.168.1.9:8000'); // Creo un nuevo objeto 'Chart' var chart; chart = new Highcharts.Chart({ chart: { renderTo: 'chart', defaultSeriesType: 'spline', events: { load: function() { // Cada vez que reciba un valor desde el socket, lo meto en la gráfica socket.on('temperatureUpdate', function (time, data) { var series = chart.series[0]; series.addPoint([time, data]); }); } } }, rangeSelector : { selected : 100 }, title: { text: 'CPU Temperature Raspberry Pi' }, xAxis: { type: 'datetime', tickPixelInterval: 150, maxZoom: 20 * 1000 }, yAxis: { minPadding: 0.2, maxPadding: 0.2, title: { text: 'Temperature ºC', margin: 80 } }, series: [{ name: 'Temperature', data: [] }] }); </script> </body> </html>Finalmente, queda ejecutar el código.
7. Ejecución del código
Ejecutamos el siguiente comando: nodejs js/server.jsy tras esto abrimos el navegador en la dirección de la Raspberry Pi: http://192.168.1.9:8000 en mi caso.
Como siempre, podéis ver todo el código en GitHub. Haced fork, starreadlo,... ¡Lo que queráis!
A vuestro servicio ;) ¡Un saludo! Fuente imagen cabecera: readwrite.com