Tutorial Raspberry Pi - Graficar la temperatura de la CPU con Node.js y Highcharts

Consigue gratis tu cuenta

Crea una API REST con Node.js y MongoDB

En este curso vas a aprender a crear una API REST con Node.js y MongoDB, además de crear un entorno de desarrollo con Docker y Docker Compose.

Comenzar ahora

InternetofThings

¡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:

Raspberry Pi xively node js highchartsVoy 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 npm
Es 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-Status
Navegamos 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 js
cd js
nano 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.html
Su 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.js
y tras esto abrimos el navegador en la dirección de la Raspberry Pi: http://192.168.1.9:8000 en mi caso. Raspberry Pi xively node js highcharts Como siempre, podéis ver todo el código en GitHub. Haced fork, starreadlo,... ¡Lo que queráis!

 jenktocat

    A vuestro servicio ;) ¡Un saludo! Fuente imagen cabecera: readwrite.com

¿Quieres seguir aprendiendo?