SOLVED, ADDED SOLUTION FURTHER DOWN
I've been trying to create a graph with PyRRD from the output of a thermal sensor I have connected to my Raspberry Pi, but with no luck getting the actual data to show up in the graph (but the png-file is created). I'm not sure if this is the right way to do it, but this code spits out the temperature every second, so the while loop works at least.
import os
import glob
import time
import subprocess
# RDD-imports
from pyrrd.graph import DEF, CDEF, VDEF
from pyrrd.graph import LINE, AREA, GPRINT
from pyrrd.graph import ColorAttributes, Graph
from pyrrd.rrd import DataSource, RRA, RRD
# Sensor-stuff
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
# RRD-stuff
startTime = int(time.time())
filename = 'temptest.rrd'
dataSources = []
rras = []
dataSource = DataSource(dsName='temp', dsType='DERIVE', heartbeat=5)
dataSources.append(dataSource)
rra1 = RRA(cf='AVERAGE', xff=0.5, steps=1, rows=5)
rra2 = RRA(cf='AVERAGE', xff=0.5, steps=6, rows=10)
rras.extend([rra1, rra2])
myRRD = RRD(filename, ds=dataSources, rra=rras, start=startTime)
myRRD.create()
# Graph-making
graphfile = 'tempgraf.png'
def1 = DEF(rrdfile=myRRD.filename, vname='mytemp', dsName=dataSource.name)
# Data going into green field
cdef1 = CDEF(vname='temp', rpn='%s,3600,*' % def1.vname)
# Line for max value
line1 = LINE(value=30, color='#990000', legend='Max temp allowed')
# Green area
area1 = AREA(defObj=cdef1, color='#006600', legend='Temp')
def read_temp_raw():
catdata = subprocess.Popen(['cat',device_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,err = catdata.communicate()
out_decode = out.decode('utf-8')
lines = out_decode.split('\n')
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
myRRD.bufferValue(int(time.time()), int(temp_c))
myRRD.update()
return temp_c
while True:
print(read_temp())
g = Graph(graphfile, start=startTime, end=int(time.time()), vertical_label='Temp(c)')
g.data.extend([def1, cdef1, line1, area1])
g.write()
time.sleep(1)
I have been experimenting around, reading ALOT in the RRD manual and tutorial for beginners but i just can't get this right. I'm very unsure about the rpn-stuff in the #Graph-making part. Please help me :)
Also if there is a better way to do this, please tell me!
SOLUTION (to my problem): Dropped PyRRD and tried out rrdtools own python implementation. http://oss.oetiker.ch/rrdtool/prog/rrdpython.en.html
I created the database outside of the program and set the Step correctly like this in terminal (Linux):
rrdtool create dailyTemp.rrd --step 5 \
DS:temp:GAUGE:10:-100:200 \
RRA:AVERAGE:0.5:1:2880 RRA:MAX:0.9:1:2880 \
I then dropped all code connected to PyRRD and just added some import lines and ONE row for rrdtool update. MUCH cleaner and now i can create my graphs :D
Here is the "final" code:
import os
import glob
import time
import subprocess
import sys
sys.path.append('/usr/local/lib/python2.7/site-packages/')
import rrdtool, tempfile
# Sensor-stuff
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
# RRD-stuff, not specific
startTime = int(time.time())
def read_temp_raw():
catdata = subprocess.Popen(['cat',device_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,err = catdata.communicate()
out_decode = out.decode('utf-8')
lines = out_decode.split('\n')
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
print(int(temp_c))
print(int(time.time()))
rrdtool.update('dailyTemp.rrd','N:' + `temp_c`)
return temp_c
while True:
print(read_temp())
time.sleep(5)
I have not implemented the graph creating into the code yet but can print it out the readings for the last 2 hours with:
rrdtool graph temp120.png --end now --start end-7200s --width 400 \
DEF:ds0a=dailyTemp.rrd:temp:AVERAGE \
Graph result (work in progress): Adding picture as soon as i got the needed reputation (10)