已解决,进一步向下添加解决方案 我一直在尝试使用PyRRD从我连接到Raspberry Pi的热传感器的输出创建一个图形,但没有运气获得实际数据显示在图形中(但是创建了png文件)。我不确定这是否是正确的方法,但这段代码每秒吐出温度,所以while循环至少起作用。
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)
我一直在试验,在RRD手册和初学者教程中阅读ALOT,但我无法做到这一点。我对#Graph-making部分中的rpn-stuff非常不确定。请帮我 :) 如果还有更好的方法,请告诉我!
解决方案(对我的问题):丢弃PyRRD并尝试rrdtools自己的python实现。 http://oss.oetiker.ch/rrdtool/prog/rrdpython.en.html
我在程序之外创建了数据库,并在终端(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 \
然后我删除了连接到PyRRD的所有代码,并添加了一些导入行和一行用于rrdtool更新。更清洁,现在我可以创建我的图表:D 这是“最终”代码:
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)
我还没有在代码中创建图表,但可以在过去2小时内将其打印出来:
rrdtool graph temp120.png --end now --start end-7200s --width 400 \
DEF:ds0a=dailyTemp.rrd:temp:AVERAGE \
图表结果(正在进行中):一旦我获得所需的声誉(10)
,就添加图片答案 0 :(得分:1)
这是获取温度值然后更新RRD的另一种方法......
#!/usr/bin/python
# reads 1-wire DS18B20 temperature sensors and outputs options for rrdupdate
import os
import glob
import rrdtool
sensors = ( {'aab8': { # last four characters of sensor ID
'DS': 'DSName1', # DS name in rrd
'value': 0
},
'5cc3': {
'DS': 'DSName2',
'value': 0
},
'9ce0': {
'DS': 'DSName3',
'value': 0
}
} )
RRD='/path/to/my.rrd'
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')
DS_list = ""
value_list = "N:"
for index, sensor in enumerate(device_folder):
for k, v in sensors.items():
if sensor[-4:] == k:
f = open(sensor + '/w1_slave', 'r')
lines = f.readlines()
f.close()
if lines[0].strip()[-3:] == 'YES':
v['value'] = float(lines[1][lines[1].find('t=')+2:])/1000.0
DS_list += v['DS'] + ':'
value_list += str(v['value']) + ':'
DS_list = DS_list[:-1]
value_list = value_list[:-1]
rrdtool.update(RRD, '--template', DS_list, value_list)
答案 1 :(得分:0)
看起来你和rrdtool混淆了。 我建议你先使用rrdtool手动生成图形。一旦你理解了它的功能,你就可以转移到pyrrd。
这些网址包含关于rrd的非常好的文档
http://oss.oetiker.ch/rrdtool/doc/index.en.html
如果您已经生成了rrd,请使用以下网址并尝试手动生成图表。
http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html
由于您提到空png文件已生成,请确保数据正确地更新为rrd。使用rrdtool fetch来确定是否在rrd中更新了任何实际数据。
答案 2 :(得分:0)
我已经挂了" step"在创建像你这样的rrd文件时进行设置。
创建RRD文件时必须进行设置:
myRRD = RRD(filename, step=5, ds=dataSources, rra=roundRobinArchives, start=datetime.fromtimestamp(time.time()), step=60)
myRRD.create()
不像我最初想的那样在数据源中......
我在PyRRD提供的example5.py文件中找到了解决方案