Hello,
Il y a de cela une paire d'années, j'avais utilisé les rrdtools pour
monitorer une station météo Lacrosse ws2300.
Il y a belle lurette que cette station ne marche plus, et je suis en train
d'en refaire une from scratch¹. Et je voudrais ré-utiliser ce que j'avais
fait à l'époque.
Le hic, c'est qu'il me manque la partie création de la base RRD :o/ Est-ce
que quelqu'un saurait me dire comment il faut que je la définisse, à
partir du script de remplissage et de création des graphes joints ?
Merci d'avance !
¹
https://www.logre.eu/wiki/Anemometer
--
Frédéric
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import os.path
import stat
import tempfile
import shutil
import rrdtool
RRD_FILENAME = "/var/lib/rrdtool/weather.rrd"
GRAPH_PATH = "/var/www/ws2300/images"
WIDTH = "400"
HEIGHT = "175"
def rrdUpdate(data):
""" Envoie les données à la base RRD.
"""
unixDate = time.mktime(time.strptime(str(data['timestamp']), "%Y%m%d%H%M%S"))
if data['temp_in'] >= 69.9:
data['temp_in'] = "U"
if data['temp_out'] >= 69.9:
data['temp_out'] = "U"
if data['dewpoint'] >= 69.9:
data['dewpoint'] = "U"
if data['wind_chill'] >= 69.9:
data['wind_chill'] = "U"
if data['rel_hum_in'] <= 19 or data['rel_hum_in'] >= 96:
data['rel_hum_in'] = "U"
if data['rel_hum_out'] <= 19 or data['rel_hum_out'] >= 96:
data['rel_hum_out'] = "U"
if data['windspeed'] >= 150:
data['windspeed'] = "U"
values = "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s" % (int(unixDate), \
data['temp_in'], \
data['temp_out'], \
data['dewpoint'], \
data['wind_chill'], \
data['rel_hum_in'], \
data['rel_hum_out'], \
data['rel_pressure'], \
data['windspeed'], \
data['wind_angle'], \
data['rain_1h'])
#print values
rrdtool.update(rrdBaseName, values)
def makeTempGraph(graphName, periode, title):
""" Génère un graph rrd pour la température.
"""
rrdtool.graph(graphName,
"--imgformat", "PNG",
"--width", WIDTH,
"--height", HEIGHT,
"--start", "end-%s" % periode,
"--title", "Température - %s" % title,
"--vertical-label", "température (°C)",
"--base", "1000",
"DEF:ti_avg=%s:temp_in:AVERAGE" % RRD_FILENAME,
"DEF:to_avg=%s:temp_out:AVERAGE" % RRD_FILENAME,
"DEF:dp_avg=%s:dew_point:AVERAGE" % RRD_FILENAME,
"DEF:wc_avg=%s:wind_chill:AVERAGE" % RRD_FILENAME,
"LINE2:ti_avg#00AA00:Intérieure",
"LINE2:wc_avg#FF00FF:Resentie",
"LINE2:to_avg#FF0000:Extérieure",
"LINE2:dp_avg#0000FF:Point de rosée",
"HRULE:-5#8080FF",
"HRULE:30#FF8080"
)
def makeHumGraph(graphName, periode, title):
""" Génère un graph rrd pour l'humidité.
"""
rrdtool.graph(graphName,
"--imgformat", "PNG",
"--width", WIDTH,
"--height", HEIGHT,
"--start", "end-%s" % periode,
"--title", "Humidité - %s" % title,
"--vertical-label", "taux (%)",
"--base", "1000",
"--lower-limit", "20",
"--upper-limit", "95",
"--rigid",
"DEF:hi_avg=%s:rel_hum_in:AVERAGE" % RRD_FILENAME,
"DEF:ho_avg=%s:rel_hum_out:AVERAGE" % RRD_FILENAME,
"LINE2:hi_avg#00AA00:Intérieure",
"LINE2:ho_avg#FF0000:Extérieure",
"HRULE:30#8080FF",
"HRULE:80#FF8080"
)
def makePressureGraph(graphName, periode, title):
""" Génère un graph rrd pour la pression.
"""
rrdtool.graph(graphName,
"--imgformat", "PNG",
"--width", WIDTH,
"--height", HEIGHT,
"--start", "end-%s" % periode,
"--title", "Pression atmosphérique - %s" % title,
"--vertical-label", "pression (hPa)",
"--base", "1000",
"--lower-limit", "1000",
"--upper-limit", "1035",
"--alt-y-grid",
"--units-exponent", "1",
"--rigid",
"DEF:p_avg=%s:rel_pressure:AVERAGE" % RRD_FILENAME,
"LINE2:p_avg#00AA00",
"HRULE:1010#8080FF",
"HRULE:1020#FF8080"
)
def makeWindGraph(graphName, periode, title):
""" Génère un graph rrd pour le vent.
"""
rrdtool.graph(graphName,
"--imgformat", "PNG",
"--width", WIDTH,
"--height", HEIGHT,
"--start", "end-%s" % periode,
"--title", "Vent, vitesse et direction - %s" % title,
"--vertical-label", "vitesse (km/h)",
"--base", "1000",
"--lower-limit", "-3.5",
"--upper-limit", "30",
"--rigid",
"DEF:ws_avg=%s:windspeed:AVERAGE" % RRD_FILENAME,
"DEF:ws_max=%s:windspeed:MAX" % RRD_FILENAME,
"DEF:ws_min=%s:windspeed:MIN" % RRD_FILENAME,
"DEF:wa=%s:wind_angle:AVERAGE" % RRD_FILENAME,
"CDEF:min2max=ws_max,ws_min,-",
"CDEF:N=wa,22,GE,wa,wa,338,+,IF,337,362,LIMIT,360,/,FLOOR,3,-",
"CDEF:NE=wa,22,68,LIMIT,360,/,FLOOR,3,-",
"CDEF:E=wa,67,113,LIMIT,360,/,FLOOR,3,-",
"CDEF:SE=wa,112,158,LIMIT,360,/,FLOOR,3,-",
"CDEF:S=wa,157,203,LIMIT,360,/,FLOOR,3,-",
"CDEF:SO=wa,202,238,LIMIT,360,/,FLOOR,3,-",
"CDEF:O=wa,237,293,LIMIT,360,/,FLOOR,3,-",
"CDEF:NO=wa,292,338,LIMIT,360,/,FLOOR,3,-",
"AREA:ws_min#FFFFFF",
"STACK:min2max#22FF22",
"LINE2:ws_avg#00AA00",
"AREA:N#FF0000:N ",
"AREA:NE#FF8800:NE ",
"AREA:E#F0F000:E ",
"AREA:SE#C0F000:SE ",
"AREA:S#00F0F0:S ",
"AREA:SO#0000FF:SO ",
"AREA:O#A000FF:O ",
"AREA:NO#FF00FF:NO ",
"HRULE:5#8888FF",
"HRULE:20#FF8888"
)
def makeRainGraph(graphName, periode, title):
""" Génère un graph rrd pour la pluie.
"""
rrdtool.graph(graphName,
"--imgformat", "PNG",
"--width", WIDTH,
"--height", HEIGHT,
"--start", "end-%s" % periode,
"--title", "Pluie - %s" % title,
"--vertical-label", "précipitations (mm)",
"--base", "1000",
"--lower-limit", "0",
"--upper-limit", "5",
"--rigid",
"DEF:r_avg=%s:rain_1h:AVERAGE" % RRD_FILENAME,
"LINE2:r_avg#00AA00",
"HRULE:1#8080FF",
"HRULE:3#FF8080"
)
if __name__ == "__main__":
while True:
t = time.time()
# Mise à jour base RRD
config = ws2300.loadConfig()
table = config['MYSQL']['table']
request = "SELECT * FROM %s ORDER BY timestamp DESC LIMIT 1" % table
data = ws2300.collect(request, fetch='one')
try:
rrdUpdate(data)
except rrdtool.error, s:
print s
# Génèration des graphes
for periode, graphName, title in (("30hours", "1d", "jour"),
("8days", "1w", "semaine"),
("32days", "1m", "mois"),
("13months", "1y", "année")
):
fd, path = tempfile.mkstemp(".png", "weather_")
makeTempGraph(path, periode, title)
dst = os.path.join(GRAPH_PATH, "temp-%s.png" % graphName)
shutil.move(path, dst)
os.chmod(dst, stat.S_IRGRP+stat.S_IROTH),
fd, path = tempfile.mkstemp(".png", "weather_")
makeHumGraph(path, periode, title)
dst = os.path.join(GRAPH_PATH, "hum-%s.png" % graphName)
shutil.move(path, dst)
os.chmod(dst, stat.S_IRGRP+stat.S_IROTH),
fd, path = tempfile.mkstemp(".png", "weather_")
makePressureGraph(path, periode, title)
dst = os.path.join(GRAPH_PATH, "pressure-%s.png" % graphName)
shutil.move(path, dst)
os.chmod(dst, stat.S_IRGRP+stat.S_IROTH),
fd, path = tempfile.mkstemp(".png", "weather_")
makeWindGraph(path, periode, title)
dst = os.path.join(GRAPH_PATH, "wind-%s.png" % graphName)
shutil.move(path, dst)
os.chmod(dst, stat.S_IRGRP+stat.S_IROTH),
fd, path = tempfile.mkstemp(".png", "weather_")
makeRainGraph(path, periode, title)
dst = os.path.join(GRAPH_PATH, "rain-%s.png" % graphName)
shutil.move(path, dst)
os.chmod(dst, stat.S_IRGRP+stat.S_IROTH),
# Attend la prochaine période (5min)
time.sleep(5*60 - (time.time() - t))