2013-04-05 72 views
2

已解决,添加的解决方案进一步下降 我一直试图从热传感器的输出创建一个PyRRD图,我已连接到我的Raspberry Pi,但没有运气得到实际数据显示在图表(但创建了png文件)。我不确定这是否是正确的方法,但是这个代码每秒都会吐出温度,所以while循环至少可以工作。Python(PyRRD)和RRD 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)

+2

给你+1让你10;) – Anuj 2013-04-08 19:02:22

回答

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中被更新。

http://oss.oetiker.ch/rrdtool/doc/rrdfetch.en.html

+0

谢谢您的回复!我以什么方式困惑?它正在创建和更新.rrd文件,它直接获取值(而不是尝试将float发送到数据库等),但不创建图形。 编辑:我不知道是否所有的价值beeing添加到数据库,但。是否有任何“简单”的方法来检查这一点,我试过myRRD.info(),但不知道要寻找什么。 – MufflerEU 2013-04-05 17:34:46

+0

使用可以使用“rrdtool fetch ”http://oss.oetiker.ch/rrdtool/doc/rrdfetch.en.html – Anuj 2013-04-05 17:46:34

+0

是的,这给了我所有的输入作为NaN。我认为这与我无法将步骤设置为所需的时间间隔有关。我找不到用PyRRD做的任何方法...... – MufflerEU 2013-04-05 18:15:19

0

创造一个像你RRD文件时我已经在“步”设置忌用。

它在创建RRD文件时进行设置:

myRRD = RRD(filename, step=5, ds=dataSources, rra=roundRobinArchives, start=datetime.fromtimestamp(time.time()), step=60) 
myRRD.create() 

不是在数据源就像我首先想到的......

我发现在文件示例5的解决方案。提供PyRRD

1

PY这里是另一种方式来攫取的温度值,然后更新您的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)