Dann füge ich hier den Code ein. Folgende PHP-Datei liegt als index in /var/www/, die lädt automatisch die erzeugten Bilder und aktualisiert sich nach fünf Minuten.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"[url=http://www.w3.org/TR/html4/loose.dtd]http://www.w3.org/TR/html4/loose.dtd[/url]">
<html>
<head>
<title>Temperaturen</title>
<meta http-equiv="refresh" content="300; url=../index.php">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-15">
<meta name="content-language" content="de">
</head>
<body>
<h1 align="center">Temperaturen</h1>
<?php
// Zeilenumbruch für html-code erstellen
define('CRLF',"\r\n");
// Find all files in that folder
$files = glob('./temperature/*.png');
// Do a natural case insensitive sort, usually 1.jpg and 10.jpg would come next to each other with a regular sort
natcasesort($files);
// Display images
foreach($files as $file) {
echo ' <p align="center"><img src="' . $file . '" alt="' . $file . '"></p>'.CRLF;
}
?>
</body>
</html>
Display More
Im Unterordner /var/www/temperature/ liegt das Script, welches alle fünf Minuten als Cronjob ausgeführt wird. Das Script ist für Python3 und stellt meinen ersten Versuch mit Python dar, Verbesserungsvorschläge sind willkommen! Ich habe meine Kommentare, auch was ich irgendwann noch hinzufügen will, mal drin gelassen. Ich hoffe es hilft.
- Es wird, sofern noch nicht vorhanden, eine Datenbank für die angegebene Anzahl Sensoren erstellt.
- Da ich manchmal Probleme beim Auslesen der Sensoren hatte (trat immer bei Last auf dem USB-Bus auf, zB wenn ein Paket heruntergeladen wird), werden diese bei Lesefehlern bis zu drei Mal ausgelesen, bis der CRC ok ist oder der Wert "U"nknown an die Datenbank gegeben wird.
- Die RRD erwartet alle fünf Minuten neue Daten.
- Das Intervall gibt den Zeitraum in Stunden an, für den die Grafiken erstellt werden.
- Bei mehr oder weniger als vier Sensoren müssen die Zeilen bei rrd_graph angepasst werden.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
import sys
import subprocess
max_sensors = 10 # Maximum number of sensors that might be connected.
# 1-10 possible, 0 or any other number for autodetection.
# The database will then be created with the number of
# sensors connected.
connected_sensors = 0 # sensors actually connected, enter anything, will be changed
# anyway
sensors = {"sensor0" : "not connected ", \
"sensor1" : "not connected ", \
"sensor2" : "not connected ", \
"sensor3" : "not connected ", \
"sensor4" : "not connected ", \
"sensor5" : "not connected ", \
"sensor6" : "not connected ", \
"sensor7" : "not connected ", \
"sensor8" : "not connected ", \
"sensor9" : "not connected "
}
temperature = {"sensor0" : "U", \
"sensor1" : "U", \
"sensor2" : "U", \
"sensor3" : "U", \
"sensor4" : "U", \
"sensor5" : "U", \
"sensor6" : "U", \
"sensor7" : "U", \
"sensor8" : "U", \
"sensor9" : "U"
}
# check if modules loaded?
# lsmod?
# check if max_sensors is sensible
if max_sensors in range(1, 11):
print("maximum of", max_sensors, "sensors set in config")
f = open("/sys/devices/w1_bus_master1/w1_master_slave_count")
connected_sensors = f.read()[:-1]
f.close()
print(connected_sensors, "sensors found", "\n")
else:
print("detecting sensors ...")
f = open("/sys/devices/w1_bus_master1/w1_master_slave_count")
connected_sensors = f.read()[:-1]
if len(connected_sensors) == 0:
sys.exit("no devices connected", "\n")
else:
print(connected_sensors, "sensors found", "\n")
max_sensors = connected_sensors
f.close()
# check for rrd, create rrd if needed
rrd_name = "/var/www/temperature/temp" + str(max_sensors) + "sensorsmax.rrd"
if os.path.exists(rrd_name) == True:
pass # insert check if database is ok
else:
print("database", rrd_name, "not found")
rrd_create_options = "--start now --step 300 --no-overwrite"
rrd_create_sensors = ""
for i in range(0, int(max_sensors)):
rrd_create_sensors += "DS:sensor" + str(i) + ":GAUGE:600:-40:125 "
rrd_create_rra = "RRA:AVERAGE:0.5:1:1200 " \
"RRA:MIN:0.5:12:100 " \
"RRA:MAX:0.5:12:100 " \
"RRA:AVERAGE:0.5:12:1000 " \
"RRA:AVERAGE:0.5:6:1000 " \
"RRA:AVERAGE:0.5:24:1000 " \
"RRA:AVERAGE:0.5:288:1000 "
rrd_create = "rrdtool create " + str(rrd_name) + " " + str(rrd_create_options) + " " + str(rrd_create_sensors) + " " + str(rrd_create_rra)
print("creating database for", max_sensors, "sensors")
subprocess.call(rrd_create, shell=True)
# detect sensorIDs
f = open("/sys/devices/w1_bus_master1/w1_master_slaves")
for i in range(0, int(connected_sensors)):
sensor_id = f.readline()[:-1]
if len(sensor_id) == 0:
break
sensor_number = "sensor" + str(i)
sensors[sensor_number] = sensor_id
f.close()
# read sensors
temp_string = "N"
for i in range(0, int(connected_sensors)):
sensor_number = "sensor" + str(i)
sensor_id = sensors[sensor_number]
attempt = 0
while (attempt < 3):
f = open("/sys/bus/w1/devices/w1_bus_master1/" + sensor_id + "/w1_slave")
while True:
temp = f.read()
if len(temp) == 0:
break
crc = temp.split("\n")[0].split(" ")[11]
if crc != "YES":
attempt += 1
print(sensor_number, sensor_id, "attempt", attempt, "to read sensor: failed. retrying ...")
else:
tempvalue = temp.split("\n")[1].split(" ")[9]
sensor_temp = round((float(tempvalue[2:]) / 1000), 1)
temperature[sensor_number] = sensor_temp
attempt = 4
f.close()
if (attempt == 3): # set temp to "U"nknown if reading failed three times
print(sensor_number, sensor_id, "attempt", attempt, "to read sensor: failed. stopped trying.")
sensor_temp = "U"
temperature[sensor_number] = sensor_temp
if (attempt == 4): # need to add comparison to last value from database
temp_string += ":" + str(sensor_temp)
# handle sensors that are set in config but are not connected
if int(connected_sensors) < int(max_sensors):
for i in range(int(connected_sensors), int(max_sensors)):
sensor_number = "sensor" + str(i)
temp_string += ":" + str(temperature[sensor_number])
# update rrdtool database
rrdupd = "rrdtool update " + rrd_name + " " + temp_string
subprocess.call(rrdupd, shell=True)
# print values as long as database is not fully implemented
print("\n")
print("Sensor | Sensor-ID | Temperature")
print("--------+-----------------+------------")
for i in range(0, int(max_sensors)):
sensor_number = "sensor" + str(i)
if temperature[sensor_number] == "U":
pass
else:
print(sensor_number, "|", sensors[sensor_number], "|", temperature[sensor_number], "°C")
print("\n")
# generate graphs
interval = ["1", "6", "12", "36", "168", "744", "8760", "24000"]
for span in interval:
span_s = int(span) * 3600
rrd_graph1 = "rrdtool graph /var/www/temperature/temp" + str(span) + "h.png -w 650 -h 240 -a PNG " \
"--slope-mode --title=\'Temperatur -" + str(span) + "h\' --start -"
rrd_graph2 = " --vertical-label \'Grad Celsius\' "
rrd_graph3 = "\'DEF:probe1=" + str(rrd_name) + ":sensor0:AVERAGE\' " \
"\'DEF:probe2=" + str(rrd_name) + ":sensor1:AVERAGE\' " \
"\'DEF:probe3=" + str(rrd_name) + ":sensor2:AVERAGE\' "
rrd_graph4 = "\'LINE1:probe1#ff0000:Kellerfenster\: " + str(temperature["sensor0"]) + "°C\' " \
"\'LINE2:probe2#0000ff:Innen\: " + str(temperature["sensor1"]) + "°C\' " \
"\'LINE3:probe3#ffff00:Innen2\: " +str(temperature["sensor2"]) + "°C\' "
rrd_graph = rrd_graph1 + str(span_s) + rrd_graph2 + rrd_graph3 + rrd_graph4
subprocess.call(rrd_graph, shell=True)
Display More