¿Nos ayudas a pagar el Hosting?

Compartir en facebook Compartir en google+ Compartir en twitter Compartir en pinterest Compartir en linkedin

Registro de datos de series de tiempo y generación de gráficos

Publicado en Diciembre de 2017

Cuando empecé con el tema de las sondas y sensores se me planteó la necesidad de almacenar los datos y mostrarlos de manera legible. Buscando, encontré una herramienta diseñada exclusivamente para eso: Registro de datos de alto rendimiento para datos de series de tiempo y generación de gráficos. RRDtool.

Gráfico generado con RDDtool
Gráfico generado con RDDtool

Empezar a mostrar gráficos con esta herramiente parece difícil... y lo es. Empezar es bastante lioso, pero vamos a ver si consigo explicar, al menos, como empezar. Una vez que se entiende, es muy fácil sacar gráficos de varios sensores a la vez.

Lo primero que necesitamos es crear un archivo que nos servirá para almacenar los datos. Con la función create de RRDtool configuramos nuevos archivos Round Robin Database (RRD). El archivo que se crea es como si fuera una base de datos, pero en un único archivo que en el momento de generarlo, se crea a tamaño completo y se rellena con datos * DESCONOCIDOS * (a menos que se hayan especificado uno o más archivos RRD de origen y que tengan datos adecuados para "completar previamente" el nuevo archivo RRD, pero esto es otra película. Quedémonos con que el archivo no crecerá).

Primero instalamos los paquetes necesarios, pensando en utilizar Python como interfaz para RRDtool:

sudo apt-get install rrdtool python-rrdtool

Para crear un nuevo fichero de base de datos, vemos un ejemplo y lo explicamos:

rrdtool create temperatura.rrd --step 300 \
  DS:temp:GAUGE:600:-273:5000 \
  RRA:AVERAGE:0.5:1:1200 \
  RRA:MIN:0.5:12:2400 \
  RRA:MAX:0.5:12:2400 \
  RRA:AVERAGE:0.5:12:2400

Esto crea un fichero RRD (Round Robin Database) llamado temperatura.rrd que acepta un valor de temperatura cada 300 segundos (--step). El nombre del valor es temp y si no se suministran datos nuevos durante más de 600 segundos, la temperatura se almacena como * DESCONOCIDO *. El valor mínimo aceptable es -273 y el máximo es 5.000.

Los RRA (Round Robin Archives) casi se pueden considerar vistas, y definen las diferentes maneras en que podemos almacenar y recuperar datos. El primero almacena las temperaturas suministradas durante 100 horas (1.200 * 300 segundos definidos en --step = 100 horas). El segundo RRA almacena la temperatura mínima registrada en cada hora (12 * 300 segundos = 1 hora), durante 100 días (2.400 horas). El tercero y el cuarto RRA hacen lo mismo para la temperatura máxima y promedio, respectivamente.

He usado el proyecto del sensor de temperatura para obtener los datos. Primero creamos el archivo que almacenará los datos:

rrdtool create temperatura.rrd --step 300 \
  DS:temp0:GAUGE:1200:-40:80 \
  RRA:AVERAGE:0.5:1:960 \
  RRA:MIN:0.5:96:3600 \
  RRA:MAX:0.5:96:3600 \
  RRA:AVERAGE:0.5:96:3600

Tendremos un nuevo archivo llamado temperatura.rrd y el mío tiene un tamaño aproximado de 95MB. Después creamos un archivo en Python que obtiene los datos de la(s) sonda(s), los almacena en variables y genera un gráfico, todo en el mismo archivo:

sudo nano gettemp.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import re, os, rrdtool, time

# function: leer y analizar el archivo de datos del sensor
def read_sensor(path):
  value = "U"
  try:
    f = open(path, "r")
    line = f.readline()
    if re.match(r"([0-9a-f]{2} ){9}: crc=[0-9a-f]{2} YES", line):
      line = f.readline()
      m = re.match(r"([0-9a-f]{2} ){9}t=([+-]?[0-9]+)", line)
      if m:
        value = str(float(m.group(2)) / 1000.0)
    f.close()
  except (IOError), e:
    print time.strftime("%x %X"), "Error de lectura", path, ": ", e
  return value

# define la ruta al sensor 1-wire
# CAMBIAR LA RUTA 28-031770cda8ff 
pathes = (
  '/sys/bus/w1/devices/28-031770cda8ff/w1_slave',
)

# leer datos del/los sensor/es
data = 'N'
for path in pathes:
  data += ':'
  data += read_sensor(path)
  time.sleep(1)

# insertar datos en round-robin-database
rrdtool.update(
  "%s/temperatura.rrd" % (os.path.dirname(os.path.abspath(__file__))),
  data)

# genera el gráfico en el directorio www para publicarlo en web
rrdtool.graph('/var/www/html/mygraph.png',
              '--border', '4',
              '--imgformat', 'PNG',
              '--width', '540',
              '--height', '300',
              '--start', "now - 1 day",
              '--end', "-1",
              '--vertical-label', 'Grados Centígrados',
              '--title', 'Temperatura',
              '--lower-limit', '0',
              'DEF:temp0=/home/orangepi/ds18b20/temperatura.rrd:temp0:AVERAGE',
              'LINE3:temp0#000000',
              'AREA:temp0#00ff00:Exterior',
              'GPRINT:temp0:LAST:Última temperatura\: %2.1lf C')

Varias cosas a explicar. El archivo está preparado para que se puedan definir todos los sensores que se quieran, sólo habrá que añadirlos en el parámetro pathes = separados por comas. Importante poner el nombre de tu sensor (28-xxxxxxx), en este caso sólo leerá uno. También he puesto las rutas completas para evitar errores: rrdtool.graph('/var/www/html/mygraph.png', y 'DEF:temp0=/home/orangepi/ds18b20/temperatura.rrd:temp0:AVERAGE',. El gráfico mostrará los datos de la última semana '--start', "now - 1 week", '--end', "-1",. En mi caso quiero tener sólo una imagen para publicarla vía web así que la imagen se sobreescribe, pero si quieres guardar más puedes cambiar el nombre usando fechas o algo así. Hay que tener en cuenta, que como tenemos todos los datos almacenados en la base de datos, podremos generar estos gráficos en cualquier momento con un rango de fechas. El resto es más o menos auto explicativo, tamaño y formato de la imagen, etiquetas, título, color de la línea... En fin, juega con este archivo para obtener otros resultados. El mío es este:

Gráfico generado con RDDtool
Gráfico generado con RDDtool

Deberás llamar al archivo para que se ejecute cada x tiempo. En el crontab añade la siguiente línea:

# lanzar cada 5 minutos
*/5 * * * * root python /home/orangepi/ds18b20/gettemp.py

Se pueden hacer cosas tan curradas como estas:

Gráfico generado con RDDtool Gráfico generado con RDDtool Gráfico generado con RDDtool Gráfico generado con RDDtool Gráfico generado con RDDtool

Espero que te haya sido de utilidad, no dudes en escribir un comentario si ves algún error o si puedo ayudarte.


Utiliza este espacio si quieres añadir algún comentario adicional o si tienes alguna duda.
No olvides añadir tu distribución y tu placa.

Todos los comentarios serán validados antes de su publicación.

Nombre*

Email* Nunca será publicado ni compartido

Comentario*



Copyright © 2016. Todos los derechos reservados | Diseño JaviPSantos

Solicitamos su permiso para obtener datos estadísticos de su navegación en esta web, en cumplimiento del Real Decreto-ley 13/2012. Si continúa navegando consideramos que acepta el uso de cookies.

OK | Más información