Registro de datos de series de tiempo y generación de gráficos
Publicado en Diciembre de 2017Cuando 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.
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:
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:
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.
Copyright © 2024 desde 2016. Todos los derechos reservados | Diseño JaviPSantos