Commit 3f775720 authored by julric's avatar julric

added changes for AirPi

parent 383ca5ad
#This file takes in inputs from a variety of sensor files, and outputs information to a variety of services
import sys
sys.dont_write_bytecode = True
import RPi.GPIO as GPIO
import ConfigParser
import time
import datetime
import inspect
import os
os.chdir("/srv/airpi")
from sys import exit
from sensors import sensor
from outputs import output
def get_subclasses(mod,cls):
for name, obj in inspect.getmembers(mod):
if hasattr(obj, "__bases__") and cls in obj.__bases__:
return obj
if not os.path.isfile('sensors.cfg'):
print "Unable to access config file: sensors.cfg"
exit(1)
sensorConfig = ConfigParser.SafeConfigParser()
sensorConfig.read('sensors.cfg')
sensorNames = sensorConfig.sections()
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) #Use BCM GPIO numbers.
sensorPlugins = []
for i in sensorNames:
try:
try:
filename = sensorConfig.get(i,"filename")
except Exception:
print("Error: no filename config option found for sensor plugin " + i)
raise
try:
enabled = sensorConfig.getboolean(i,"enabled")
except Exception:
enabled = True
#if enabled, load the plugin
if enabled:
try:
mod = __import__('sensors.'+filename,fromlist=['a']) #Why does this work?
except Exception:
print("Error: could not import sensor module " + filename)
raise
try:
sensorClass = get_subclasses(mod,sensor.Sensor)
if sensorClass == None:
raise AttributeError
except Exception:
print("Error: could not find a subclass of sensor.Sensor in module " + filename)
raise
try:
reqd = sensorClass.requiredData
except Exception:
reqd = []
try:
opt = sensorClass.optionalData
except Exception:
opt = []
pluginData = {}
class MissingField(Exception): pass
for requiredField in reqd:
if sensorConfig.has_option(i,requiredField):
pluginData[requiredField]=sensorConfig.get(i,requiredField)
else:
print "Error: Missing required field '" + requiredField + "' for sensor plugin " + i
raise MissingField
for optionalField in opt:
if sensorConfig.has_option(i,optionalField):
pluginData[optionalField]=sensorConfig.get(i,optionalField)
instClass = sensorClass(pluginData)
sensorPlugins.append(instClass)
# do not log everything
# print ("Success: Loaded sensor plugin " + i)
except Exception as e: #add specific exception for missing module
print("Error: Did not import sensor plugin " + i )
raise e
if not os.path.isfile("outputs.cfg"):
print "Unable to access config file: outputs.cfg"
outputConfig = ConfigParser.SafeConfigParser()
outputConfig.read("outputs.cfg")
outputNames = outputConfig.sections()
outputPlugins = []
for i in outputNames:
try:
try:
filename = outputConfig.get(i,"filename")
except Exception:
print("Error: no filename config option found for output plugin " + i)
raise
try:
enabled = outputConfig.getboolean(i,"enabled")
except Exception:
enabled = True
#if enabled, load the plugin
if enabled:
try:
mod = __import__('outputs.'+filename,fromlist=['a']) #Why does this work?
except Exception:
print("Error: could not import output module " + filename)
raise
try:
outputClass = get_subclasses(mod,output.Output)
if outputClass == None:
raise AttributeError
except Exception:
print("Error: could not find a subclass of output.Output in module " + filename)
raise
try:
reqd = outputClass.requiredData
except Exception:
reqd = []
try:
opt = outputClass.optionalData
except Exception:
opt = []
if outputConfig.has_option(i,"async"):
async = outputConfig.getbool(i,"async")
else:
async = False
pluginData = {}
class MissingField(Exception): pass
for requiredField in reqd:
if outputConfig.has_option(i,requiredField):
pluginData[requiredField]=outputConfig.get(i,requiredField)
else:
print "Error: Missing required field '" + requiredField + "' for output plugin " + i
raise MissingField
for optionalField in opt:
if outputConfig.has_option(i,optionalField):
pluginData[optionalField]=outputConfig.get(i,optionalField)
instClass = outputClass(pluginData)
instClass.async = async
outputPlugins.append(instClass)
# do not log everything
# print ("Success: Loaded output plugin " + i)
except Exception as e: #add specific exception for missing module
print("Error: Did not import output plugin " + i )
raise e
if not os.path.isfile("settings.cfg"):
print "Unable to access config file: settings.cfg"
mainConfig = ConfigParser.SafeConfigParser()
mainConfig.read("settings.cfg")
lastUpdated = 0
# wait 5 seconds for DHT22
time.sleep(5)
#delayTime = mainConfig.getfloat("Main","uploadDelay")
redPin = mainConfig.getint("Main","redPin")
greenPin = mainConfig.getint("Main","greenPin")
GPIO.setup(redPin,GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(greenPin,GPIO.OUT,initial=GPIO.LOW)
data = []
# get current time
ts = time.time()
st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
#Collect the data from each sensor
for i in sensorPlugins:
dataDict = {}
val = i.getVal()
if val==None: #this means it has no data to upload.
continue
dataDict["value"] = i.getVal()
dataDict["unit"] = i.valUnit
dataDict["symbol"] = i.valSymbol
dataDict["name"] = i.valName
dataDict["sensor"] = i.sensorName
data.append(dataDict)
working = True
for i in outputPlugins:
working = working and i.outputData(data)
if working:
print "Uploaded successfully (" + st + ")"
GPIO.output(greenPin,GPIO.HIGH)
else:
print "Failed to upload"
GPIO.output(redPin,GPIO.HIGH)
time.sleep(1)
GPIO.output(greenPin,GPIO.LOW)
GPIO.output(redPin,GPIO.LOW)
[Print]
filename=print
enabled=on
enabled=off
[Xively]
filename=xively
enabled=off
APIKey=zC0Qfeii9nDAU3eUXr902Kj6YCnMacTpFVhyiJPOQodOh0Jx
FeedID=1454336002
[MySQL]
filename=sql
enabled=off
[Log]
filename=log
enabled=off
[RRD]
filename=rrd
enabled=on
APIKey=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
FeedID=XXXXXXXXXX
rrd_file=rrd/data_airpi.rrd
import output
import datetime
class Log(output.Output):
requiredData = []
optionalData = []
def __init__(self,data):
pass
def outputData(self,dataPoints):
f = open('sensors.log', 'a')
logline = '{"time":"'
logline += str(datetime.datetime.now())
logline += '",'
for i in dataPoints:
logline += '"' + i["name"] + '"' + ":" + '"' + str(i["value"]) + '",'
logline += "}\n"
print(logline)
f.write(logline)
f.close()
return True
import output
import datetime
import rrdtool
from rrdtool import update as rrd_update
class rrd(output.Output):
requiredData = ["rrd_file"]
optionalData = []
def __init__(self,data):
self.rrd_file=data["rrd_file"]
def outputData(self,dataPoints):
rrd_value = "N"
if [i for i, x in enumerate(dataPoints) if x["name"] == "TemperatureBMP" and x["sensor"] == "BMP085"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "TemperatureBMP" and x["sensor"] == "BMP085"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
if [i for i, x in enumerate(dataPoints) if x["name"] == "TemperatureDHT" and x["sensor"] == "DHT22"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "TemperatureDHT" and x["sensor"] == "DHT22"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
if [i for i, x in enumerate(dataPoints) if x["name"] == "Pressure" and x["sensor"] == "BMP085"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "Pressure" and x["sensor"] == "BMP085"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
if [i for i, x in enumerate(dataPoints) if x["name"] == "Relative_Humidity" and x["sensor"] == "DHT22"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "Relative_Humidity" and x["sensor"] == "DHT22"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
if [i for i, x in enumerate(dataPoints) if x["name"] == "Light_Level" and x["sensor"] == "LDR"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "Light_Level" and x["sensor"] == "LDR"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
if [i for i, x in enumerate(dataPoints) if x["name"] == "Nitrogen_Dioxide" and x["sensor"] == "MiCS-2710"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "Nitrogen_Dioxide" and x["sensor"] == "MiCS-2710"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
if [i for i, x in enumerate(dataPoints) if x["name"] == "Carbon_Monoxide" and x["sensor"] == "MiCS-5525"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "Carbon_Monoxide" and x["sensor"] == "MiCS-5525"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
if [i for i, x in enumerate(dataPoints) if x["name"] == "Volume" and x["sensor"] == "ABM_713_RC"]:
array_index = [i for i, x in enumerate(dataPoints) if x["name"] == "Volume" and x["sensor"] == "ABM_713_RC"][0]
rrd_value = rrd_value + ":" + str(int(round(dataPoints[array_index]["value"])))
else:
rrd_value = rrd_value + ":U"
# print rrd_value
ret = rrd_update(self.rrd_file, rrd_value);
return True
\ No newline at end of file
import output
import datetime
import MySQLdb
class sql(output.Output):
requiredData = []
optionalData = []
def __init__(self,data):
pass
def outputData(self,dataPoints):
conn = MySQLdb.connect(host= "127.0.0.1", user="airpi", passwd="airpi", db="airpi")
x = conn.cursor()
sql = "INSERT INTO obs ( Station, Datetime"
for i in dataPoints:
sql = sql + ", " + i["name"]
sql = sql + " ) values ( \"julric\", \"" + str(datetime.datetime.now()) + "\""
for i in dataPoints:
sql = sql + ", " + str(i["value"])
sql = sql + " ) ;"
# print ( sql )
x.execute ( sql )
conn.commit()
conn.close()
return True
\ No newline at end of file
#! /bin/bash
RRDTOOL="/usr/bin/rrdtool"
RRD_DB="/srv/airpi/data_airpi.rrd"
GRAPH_PATH="/srv/flukso/graph"
# hour
$RRDTOOL graph $GRAPH_PATH/airpi-temp-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Temperatur (°C)' \
DEF:temp=$RRD_DB:tempbmp:AVERAGE \
DEF:tempmin=$RRD_DB:tempbmp:MIN \
DEF:tempmax=$RRD_DB:tempbmp:MAX \
AREA:temp#FF4141 \
LINE1:temp#bf3434:"<big>Temperatur (BMP085)</big> " \
VDEF:temp_min=temp,MINIMUM \
'GPRINT:temp_min:<b>Minimum</b>\: %5.0lf °C ' \
VDEF:temp_average=temp,AVERAGE \
'GPRINT:temp_average:<b>Durchschnitt</b>\: %5.0lf °C ' \
VDEF:temp_max=temp,MAXIMUM \
'GPRINT:temp_max:<b>Maximum</b>\: %5.0lf °C ' \
> /dev/null
# hour
$RRDTOOL graph $GRAPH_PATH/airpi-press-hour.png -a PNG --width=800 --height=300 --lower-limit 0 \
--start -1h --pango-markup --vertical-label 'Druck (hPa)' --units-exponent 0 --slope-mode \
DEF:press=$RRD_DB:press:AVERAGE \
DEF:pressmin=$RRD_DB:press:MIN \
DEF:pressmax=$RRD_DB:press:MAX \
AREA:press#FF4141 \
LINE1:press#bf3434:"<big>Druck</big> " \
VDEF:press_min=press,MINIMUM \
'GPRINT:press_min:<b>Minimum</b>\: %5.0lf hPa ' \
VDEF:press_average=press,AVERAGE \
'GPRINT:press_average:<b>Durchschnitt</b>\: %5.0lf hPa ' \
VDEF:press_max=press,MAXIMUM \
'GPRINT:press_max:<b>Maximum</b>\: %5.0lf hPa ' \
> /dev/null
# day
#$RRDTOOL graph $GRAPH_PATH/flukso-day.png -a PNG --width=800 --height=300 --lower-limit 0 \
#--start -1d --end -5min --pango-markup --x-grid HOUR:1:HOUR:6:HOUR:2:0:%H:%M --grid-dash 1:0 \
#--vertical-label 'Stromverbrauch (Watt)' --units-exponent 0 --slope-mode \
# week
#$RRDTOOL graph $GRAPH_PATH/flukso-week.png -a PNG --width=800 --height=300 --lower-limit 0 \
#--start -1w --end -5min --pango-markup --x-grid DAY:1:WEEK:1:DAY:1:86400:%d.%b --grid-dash 1:0 \
#--vertical-label 'Stromverbrauch (Watt)' --units-exponent 0 --slope-mode \
# month
#$RRDTOOL graph $GRAPH_PATH/flukso-month.png -a PNG --width=800 --height=300 --lower-limit 0 \
#--start -1m --end -5min --pango-markup --vertical-label 'Stromverbrauch (Watt)' --units-exponent 0 --slope-mode \
# year
#$RRDTOOL graph $GRAPH_PATH/flukso-year.png -a PNG --width=800 --height=300 --lower-limit 0 --upper-limit 1000 \
#--start -1y --end -5min --pango-markup --vertical-label 'Stromverbrauch (Watt)' --units-exponent 0 --slope-mode \
#! /bin/bash
RRDTOOL="/usr/bin/rrdtool"
RRD_DB="/srv/airpi/data_airpi.rrd"
GRAPH_PATH="/srv/flukso/graph"
$RRDTOOL graph $GRAPH_PATH/airpi-tempbmp-day.png -a PNG --width=800 --height=300 \
--start -1d --pango-markup --vertical-label 'Temperatur (°C)' --lower-limit 0 \
DEF:temp=$RRD_DB:tempbmp:AVERAGE \
DEF:tempmin=$RRD_DB:tempbmp:MIN \
DEF:tempmax=$RRD_DB:tempbmp:MAX \
AREA:temp#acc6fb \
LINE1:temp#4f5a72:"<big>Temperatur (BMP085)</big> " \
VDEF:temp_min=temp,MINIMUM \
'GPRINT:temp_min:<b>Minimum</b>\: %5.0lf °C ' \
VDEF:temp_average=temp,AVERAGE \
'GPRINT:temp_average:<b>Durchschnitt</b>\: %5.0lf °C ' \
VDEF:temp_max=temp,MAXIMUM \
'GPRINT:temp_max:<b>Maximum</b>\: %5.0lf °C ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-tempdht-day.png -a PNG --width=800 --height=300 \
--start -1d --pango-markup --vertical-label 'Temperatur (°C)' --lower-limit 0 \
DEF:temp=$RRD_DB:tempdht:AVERAGE \
DEF:tempmin=$RRD_DB:tempdht:MIN \
DEF:tempmax=$RRD_DB:tempdht:MAX \
AREA:temp#acc6fb \
LINE1:temp#4f5a72:"<big>Temperatur (DHT22)</big> " \
VDEF:temp_min=temp,MINIMUM \
'GPRINT:temp_min:<b>Minimum</b>\: %5.0lf °C ' \
VDEF:temp_average=temp,AVERAGE \
'GPRINT:temp_average:<b>Durchschnitt</b>\: %5.0lf °C ' \
VDEF:temp_max=temp,MAXIMUM \
'GPRINT:temp_max:<b>Maximum</b>\: %5.0lf °C ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-press-day.png -a PNG --width=800 --height=300 --lower-limit 940 \
--start -1d --pango-markup --vertical-label 'Druck (hPa)' --upper-limit 1060 --rigid --units-exponent 0 \
DEF:press=$RRD_DB:press:AVERAGE \
DEF:pressmin=$RRD_DB:press:MIN \
DEF:pressmax=$RRD_DB:press:MAX \
AREA:press#acc6fb \
LINE1:press#4f5a72:"<big>Druck (BMP085)</big> " \
VDEF:press_min=press,MINIMUM \
'GPRINT:press_min:<b>Minimum</b>\: %5.0lf hPa ' \
VDEF:press_average=press,AVERAGE \
'GPRINT:press_average:<b>Durchschnitt</b>\: %5.0lf hPa ' \
VDEF:press_max=press,MAXIMUM \
'GPRINT:press_max:<b>Maximum</b>\: %5.0lf hPa ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-humi-day.png -a PNG --width=800 --height=300 \
--start -1d --pango-markup --vertical-label 'Luftfeuchtigkeit (%)' --lower-limit 0 --upper-limit 100 \
DEF:humi=$RRD_DB:humi:AVERAGE \
DEF:humimin=$RRD_DB:humi:MIN \
DEF:humimax=$RRD_DB:humi:MAX \
AREA:humi#acc6fb \
LINE1:humi#4f5a72:"<big>Luftfeuchtigkeit (DHT22)</big> " \
VDEF:humi_min=humi,MINIMUM \
'GPRINT:humi_min:<b>Minimum</b>\: %5.0lf %% ' \
VDEF:humi_average=humi,AVERAGE \
'GPRINT:humi_average:<b>Durchschnitt</b>\: %5.0lf %% ' \
VDEF:humi_max=humi,MAXIMUM \
'GPRINT:humi_max:<b>Maximum</b>\: %5.0lf %% ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-light-day.png -a PNG --width=800 --height=300 \
--start -1d --pango-markup --vertical-label 'Helligkeit (%)' --lower-limit 0 --upper-limit 110 \
DEF:light=$RRD_DB:light:AVERAGE \
DEF:lightmax=$RRD_DB:light:MAX \
CDEF:scaled_light=light,10250000,/ \
CDEF:light_inverse=1,scaled_light,- \
CDEF:light_percent=light_inverse,100,* \
AREA:light_percent#acc6fb \
LINE1:light_percent#4f5a72:"<big>Helligkeit (LDR)</big> " \
VDEF:light_min=light_percent,MINIMUM \
'GPRINT:light_min:<b>Minimum</b>\: %5.0lf %% ' \
VDEF:light_average=light_percent,AVERAGE \
'GPRINT:light_average:<b>Durchschnitt</b>\: %5.0lf %% ' \
VDEF:light_max=light_percent,MAXIMUM \
'GPRINT:light_max:<b>Maximum</b>\: %5.0lf %% ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-no2-day.png -a PNG --width=800 --height=300 \
--start -1d --pango-markup --vertical-label 'Stickstoffdioxid' \
DEF:no2=$RRD_DB:no2:AVERAGE \
DEF:no2min=$RRD_DB:no2:MIN \
DEF:no2max=$RRD_DB:no2:MAX \
AREA:no2#acc6fb \
LINE1:no2#4f5a72:"<big>Stickstoffdioxid (MiCS-2710)</big> " \
VDEF:no2_min=no2,MINIMUM \
'GPRINT:no2_min:<b>Minimum</b>\: %5.0lf ' \
VDEF:no2_average=no2,AVERAGE \
'GPRINT:no2_average:<b>Durchschnitt</b>\: %5.0lf ' \
VDEF:no2_max=no2,MAXIMUM \
'GPRINT:no2_max:<b>Maximum</b>\: %5.0lf ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-co-day.png -a PNG --width=800 --height=300 \
--start -1d --pango-markup --vertical-label 'Kohlenstoffmonoxid' \
DEF:co=$RRD_DB:co:AVERAGE \
DEF:comin=$RRD_DB:co:MIN \
DEF:comax=$RRD_DB:co:MAX \
AREA:co#acc6fb \
LINE1:co#4f5a72:"<big>Kohlenstoffmonoxid (MiCS-5525)</big> " \
VDEF:co_min=co,MINIMUM \
'GPRINT:co_min:<b>Minimum</b>\: %5.0lf ' \
VDEF:co_average=co,AVERAGE \
'GPRINT:co_average:<b>Durchschnitt</b>\: %5.0lf ' \
VDEF:co_max=co,MAXIMUM \
'GPRINT:co_max:<b>Maximum</b>\: %5.0lf ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-vol-day.png -a PNG --width=800 --height=300 \
--start -1d --pango-markup --vertical-label 'Lautstärke' \
DEF:vol=$RRD_DB:vol:AVERAGE \
DEF:volmin=$RRD_DB:vol:MIN \
DEF:volmax=$RRD_DB:vol:MAX \
AREA:vol#acc6fb \
LINE1:vol#4f5a72:"<big>Lautstärke (ABM_713_RC)</big> " \
VDEF:vol_min=vol,MINIMUM \
'GPRINT:vol_min:<b>Minimum</b>\: %5.0lf ' \
VDEF:vol_average=vol,AVERAGE \
'GPRINT:vol_average:<b>Durchschnitt</b>\: %5.0lf ' \
VDEF:vol_max=vol,MAXIMUM \
'GPRINT:vol_max:<b>Maximum</b>\: %5.0lf ' \
> /dev/null
#! /bin/bash
RRDTOOL="/usr/bin/rrdtool"
RRD_DB="/srv/airpi/data_airpi.rrd"
GRAPH_PATH="/srv/flukso/graph"
$RRDTOOL graph $GRAPH_PATH/airpi-tempbmp-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Temperatur (°C)' \
DEF:temp=$RRD_DB:tempbmp:AVERAGE \
DEF:tempmin=$RRD_DB:tempbmp:MIN \
DEF:tempmax=$RRD_DB:tempbmp:MAX \
AREA:temp#acc6fb \
LINE1:temp#4f5a72:"<big>Temperatur (BMP085)</big> " \
VDEF:temp_min=tempmin,MINIMUM \
'GPRINT:temp_min:<b>Minimum</b>\: %5.0lf °C ' \
VDEF:temp_average=temp,AVERAGE \
'GPRINT:temp_average:<b>Durchschnitt</b>\: %5.0lf °C ' \
VDEF:temp_max=tempmax,MAXIMUM \
'GPRINT:temp_max:<b>Maximum</b>\: %5.0lf °C ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-tempdht-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Temperatur (°C)' \
DEF:temp=$RRD_DB:tempdht:AVERAGE \
DEF:tempmin=$RRD_DB:tempdht:MIN \
DEF:tempmax=$RRD_DB:tempdht:MAX \
AREA:temp#acc6fb \
LINE1:temp#4f5a72:"<big>Temperatur (DHT22)</big> " \
VDEF:temp_min=temp,MINIMUM \
'GPRINT:temp_min:<b>Minimum</b>\: %5.0lf °C ' \
VDEF:temp_average=temp,AVERAGE \
'GPRINT:temp_average:<b>Durchschnitt</b>\: %5.0lf °C ' \
VDEF:temp_max=temp,MAXIMUM \
'GPRINT:temp_max:<b>Maximum</b>\: %5.0lf °C ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-press-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Druck (hPa)' \
DEF:press=$RRD_DB:press:AVERAGE \
DEF:pressmin=$RRD_DB:press:MIN \
DEF:pressmax=$RRD_DB:press:MAX \
AREA:press#acc6fb \
LINE1:press#4f5a72:"<big>Druck (BMP085)</big> " \
VDEF:press_min=press,MINIMUM \
'GPRINT:press_min:<b>Minimum</b>\: %5.0lf hPa ' \
VDEF:press_average=press,AVERAGE \
'GPRINT:press_average:<b>Durchschnitt</b>\: %5.0lf hPa ' \
VDEF:press_max=press,MAXIMUM \
'GPRINT:press_max:<b>Maximum</b>\: %5.0lf hPa ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-humi-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Luftfeuchtigkeit (%)' \
DEF:humi=$RRD_DB:humi:AVERAGE \
DEF:humimin=$RRD_DB:humi:MIN \
DEF:humimax=$RRD_DB:humi:MAX \
AREA:humi#acc6fb \
LINE1:humi#4f5a72:"<big>Luftfeuchtigkeit (DHT22)</big> " \
VDEF:humi_min=humi,MINIMUM \
'GPRINT:humi_min:<b>Minimum</b>\: %5.0lf %% ' \
VDEF:humi_average=humi,AVERAGE \
'GPRINT:humi_average:<b>Durchschnitt</b>\: %5.0lf %% ' \
VDEF:humi_max=humi,MAXIMUM \
'GPRINT:humi_max:<b>Maximum</b>\: %5.0lf %% ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-light-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Helligkeit' \
DEF:light=$RRD_DB:light:AVERAGE \
DEF:lightmin=$RRD_DB:light:MIN \
DEF:lightmax=$RRD_DB:light:MAX \
AREA:light#acc6fb \
LINE1:light#4f5a72:"<big>Helligkeit (LDR)</big> " \
VDEF:light_min=light,MINIMUM \
'GPRINT:light_min:<b>Minimum</b>\: %5.0lf ' \
VDEF:light_average=light,AVERAGE \
'GPRINT:light_average:<b>Durchschnitt</b>\: %5.0lf ' \
VDEF:light_max=light,MAXIMUM \
'GPRINT:light_max:<b>Maximum</b>\: %5.0lf ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-no2-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Stickstoffdioxid' \
DEF:no2=$RRD_DB:no2:AVERAGE \
DEF:no2min=$RRD_DB:no2:MIN \
DEF:no2max=$RRD_DB:no2:MAX \
AREA:no2#acc6fb \
LINE1:no2#4f5a72:"<big>Stickstoffdioxid (MiCS-2710)</big> " \
VDEF:no2_min=no2,MINIMUM \
'GPRINT:no2_min:<b>Minimum</b>\: %5.0lf ' \
VDEF:no2_average=no2,AVERAGE \
'GPRINT:no2_average:<b>Durchschnitt</b>\: %5.0lf ' \
VDEF:no2_max=no2,MAXIMUM \
'GPRINT:no2_max:<b>Maximum</b>\: %5.0lf ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-co-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Kohlenstoffmonoxid' \
DEF:co=$RRD_DB:co:AVERAGE \
DEF:comin=$RRD_DB:co:MIN \
DEF:comax=$RRD_DB:co:MAX \
AREA:co#acc6fb \
LINE1:co#4f5a72:"<big>Kohlenstoffmonoxid (MiCS-5525)</big> " \
VDEF:co_min=co,MINIMUM \
'GPRINT:co_min:<b>Minimum</b>\: %5.0lf ' \
VDEF:co_average=co,AVERAGE \
'GPRINT:co_average:<b>Durchschnitt</b>\: %5.0lf ' \
VDEF:co_max=co,MAXIMUM \
'GPRINT:co_max:<b>Maximum</b>\: %5.0lf ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-vol-hour.png -a PNG --width=800 --height=300 \
--start -1h --pango-markup --vertical-label 'Lautstärke' \
DEF:vol=$RRD_DB:vol:AVERAGE \
DEF:volmin=$RRD_DB:vol:MIN \
DEF:volmax=$RRD_DB:vol:MAX \
AREA:vol#acc6fb \
LINE1:vol#4f5a72:"<big>Lautstärke (ABM_713_RC)</big> " \
VDEF:vol_min=vol,MINIMUM \
'GPRINT:vol_min:<b>Minimum</b>\: %5.0lf ' \
VDEF:vol_average=vol,AVERAGE \
'GPRINT:vol_average:<b>Durchschnitt</b>\: %5.0lf ' \
VDEF:vol_max=vol,MAXIMUM \
'GPRINT:vol_max:<b>Maximum</b>\: %5.0lf ' \
> /dev/null
#! /bin/bash
RRDTOOL="/usr/bin/rrdtool"
RRD_DB="/srv/airpi/data_airpi.rrd"
GRAPH_PATH="/srv/flukso/graph"
$RRDTOOL graph $GRAPH_PATH/airpi-tempbmp-month.png -a PNG --width=800 --height=300 \
--start -1m --pango-markup --vertical-label 'Temperatur (°C)' --upper-limit 40 --lower-limit 0 \
DEF:temp=$RRD_DB:tempbmp:AVERAGE \
DEF:tempmin=$RRD_DB:tempbmp:MIN \
DEF:tempmax=$RRD_DB:tempbmp:MAX \
AREA:temp#acc6fb \
LINE1:temp#4f5a72:"<big>Temperatur (BMP085)</big> " \
VDEF:temp_min=temp,MINIMUM \
'GPRINT:temp_min:<b>Minimum</b>\: %5.0lf °C ' \
VDEF:temp_average=temp,AVERAGE \
'GPRINT:temp_average:<b>Durchschnitt</b>\: %5.0lf °C ' \
VDEF:temp_max=temp,MAXIMUM \
'GPRINT:temp_max:<b>Maximum</b>\: %5.0lf °C ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-tempdht-month.png -a PNG --width=800 --height=300 \
--start -1m --pango-markup --vertical-label 'Temperatur (°C)' --upper-limit 40 --lower-limit 0 \
DEF:temp=$RRD_DB:tempdht:AVERAGE \
DEF:tempmin=$RRD_DB:tempdht:MIN \
DEF:tempmax=$RRD_DB:tempdht:MAX \
AREA:temp#acc6fb \
LINE1:temp#4f5a72:"<big>Temperatur (DHT22)</big> " \
VDEF:temp_min=temp,MINIMUM \
'GPRINT:temp_min:<b>Minimum</b>\: %5.0lf °C ' \
VDEF:temp_average=temp,AVERAGE \
'GPRINT:temp_average:<b>Durchschnitt</b>\: %5.0lf °C ' \
VDEF:temp_max=temp,MAXIMUM \
'GPRINT:temp_max:<b>Maximum</b>\: %5.0lf °C ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-press-month.png -a PNG --width=800 --height=300 --lower-limit 940 \
--start -1m --pango-markup --vertical-label 'Druck (hPa)' --upper-limit 1060 --rigid --units-exponent 0 \
DEF:press=$RRD_DB:press:AVERAGE \
DEF:pressmin=$RRD_DB:press:MIN \
DEF:pressmax=$RRD_DB:press:MAX \
AREA:press#acc6fb \
LINE1:press#4f5a72:"<big>Druck (BMP085)</big> " \
VDEF:press_min=press,MINIMUM \
'GPRINT:press_min:<b>Minimum</b>\: %5.0lf hPa ' \
VDEF:press_average=press,AVERAGE \
'GPRINT:press_average:<b>Durchschnitt</b>\: %5.0lf hPa ' \
VDEF:press_max=press,MAXIMUM \
'GPRINT:press_max:<b>Maximum</b>\: %5.0lf hPa ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-humi-month.png -a PNG --width=800 --height=300 \
--start -1m --pango-markup --vertical-label 'Luftfeuchtigkeit (%)' --lower-limit 0 --upper-limit 100 \
DEF:humi=$RRD_DB:humi:AVERAGE \
DEF:humimin=$RRD_DB:humi:MIN \
DEF:humimax=$RRD_DB:humi:MAX \
AREA:humi#acc6fb \
LINE1:humi#4f5a72:"<big>Luftfeuchtigkeit (DHT22)</big> " \
VDEF:humi_min=humi,MINIMUM \
'GPRINT:humi_min:<b>Minimum</b>\: %5.0lf %% ' \
VDEF:humi_average=humi,AVERAGE \
'GPRINT:humi_average:<b>Durchschnitt</b>\: %5.0lf %% ' \
VDEF:humi_max=humi,MAXIMUM \
'GPRINT:humi_max:<b>Maximum</b>\: %5.0lf %% ' \
> /dev/null
$RRDTOOL graph $GRAPH_PATH/airpi-light-month.png -a PNG --width=800 --height=300 \
--start -1m --pango-markup --vertical-label 'Helligkeit (%)' --lower-limit 0 --upper-limit 110 \
DEF:light=$RRD_DB:light:AVERAGE \