2013-04-05 136 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)