26.04.2016
Es ist praktisch, jederzeit abrufen zu können, wie warm es gerade in einem Raum ist oder wie hoch die Luftfeuchtigkeit ist. Doch manchmal möchte man nicht nur den aktuellen Wert sehen, sondern auch einen Verlauf der letzten Tage, Wochen und sogar Monate. Um dies zu realisieren, wird eine Datenbank benötigt, in die regelmäßig die Werte geschrieben werden. Dann können diese jederzeit einfach per URL-Aufruf abgefragt werden. Wie man so eine Datenbank einrichtet und die Werte eintragen lässt, erfährst du hier. Um dem Tutorial folgen zu können, benötigst du einen fertig eingerichteten Raspberry Pi und solltest außerdem das RaZberry Modul auf deinem Raspberry Pi installiert haben.
Um die Werte zu messen, benötigt man natürlich auch einen Sensor. Ich benutze den folgenden, da er nicht nur die Temperatur angibt, sondern auch die Luftfeuchtigkeit & Helligkeit, und weil er gleichzeitig als Bewegungsmelder fungiert.
http://[IP-ADRESSE]/database/phpliteadmin.php
http://[IP DEINES RASPBERRY]:8083/smarthome/
http://[IP DEINES RASPBERRY]:8083/smarthome/
<?php
function getSensorData($room, $val, $show_einheit, $db){
$ipAddress = $_SERVER['SERVER_ADDR'];
if($val == null){ //Alle Werte werden abgefragt
//Räume laden
if($room == "all"){
$results = $db->prepare("SELECT * FROM 'ROOMS'");
$results->execute();
}
else{
$results = $db->prepare("SELECT * FROM 'ROOMS' WHERE LOCATION == :room");
$results->execute(array('room' => $room));
}
//Ausgabearray erzeugen
$values = array();
//Alle Räume durchlaufen
foreach($results->fetchAll(PDO::FETCH_ASSOC) as $row){
//Wertearray erzeugen
$value_array = array();
//Sensoren im aktuellen Raum laden
$ergebnisse = $db->prepare("SELECT * FROM 'ZWAVE_SENSOREN' WHERE RAUM == :location");
$ergebnisse->execute(array('location' => $row['LOCATION']));
//Alle Sensoren im Raum durchlaufen
foreach($ergebnisse->fetchAll(PDO::FETCH_ASSOC) as $reihe){
//Wert für jeden Sensor zusammen mit Sensorart in Wertearray schreiben
$value = array('shortform' => $reihe['SHORTFORM'], 'sensorart' => $reihe['SENSORART'], 'wert' => getSensorData($reihe['RAUM'], $reihe['SENSORART'], 1, $db));
array_push($value_array, $value);
}
//Daten für aktuellen Raum in Ausgabearray schreiben
$value_item = array('name' => $row['NAME'], 'location' => $row['LOCATION'], 'value_array' => $value_array);
array_push($values, $value_item);
}
//JSON-Objekt zurückgeben
return json_encode(array('values' => $values));
}
else{ //Ein spezieller Wert wird abgefragt
//ID des gesuchten Sensors im gesuchten Raum ermitteln
$id = getZwaveId($room, $val, $db);
if($id !== "N/A"){
//Z-Wave API aufrufen
$link = "http://".$ipAddress.":8083/ZAutomation/api/v1/devices/".$id;
//curl mit URL initialisieren
$cURL = curl_init($link);
//Port setzen
curl_setopt($cURL, CURLOPT_PORT, 8083);
//Ausgabe einstellen
curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
//Abfrage ausführen
$result = curl_exec($cURL);
//wert je nach Wunsch mit/ohne Einheit ausgeben
$array = json_decode($result, true);
if($show_einheit == "1"){
return $array['data']['metrics']['level']." ".$array['data']['metrics']['scaleTitle'];
}
else{
return $array['data']['metrics']['level'];
}
}
else return "N/A"; //Sensor-ID nicht gefunden?
}
}
function getZwaveId($room, $val, $db){
//Z-Wave ID des gesuchten Sensors im gesuchten Raum laden
$query = $db->prepare("SELECT * FROM 'ZWAVE_SENSOREN' WHERE RAUM == :room AND SENSORART == :sensorart");
$query->execute(array('room' => $room, 'sensorart' => $val));
//ID zurückgeben, wenn gefunden
if($result = $query->fetch(PDO::FETCH_ASSOC)){
return $result['ID'];
}
else return "N/A"; //ID nicht gefunden?
}
?>
<?php
//Datenbankverbindung herstellen
$SQLITEdb = "database/data.sqlite";
$db = new PDO("sqlite:".$SQLITEdb);
include "getSensorData.php";
$validUser = validateUser($_POST['username'], $_POST['password'], $db);
if($validUser){
switch($_POST['action']){
case "getsensordata":
echo getSensorData($_POST['room'], $_POST['value'], $_POST['showeinheit'], $db);
break;
}
}
function validateUser($username, $password, $db){
//wird noch implementiert
return true;
}
?>
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sqlite3 as lite #Für die Datenbankverbindung
import datetime #Um Datum und Uhrzeit zu ermitteln
import urllib #Um die URL aufzurufen
import httplib #Um die URL aufzurufen
import sys #Um Kommandozeilenargumente zu lesen
#Um die IP-Adresse zu ermitteln
import socket
import fcntl
import struct
now = datetime.datetime.now()
con = lite.connect('/var/www/html/database/data.sqlite')
#Nutzerdaten, da API im weiteren Verlauf der Tutorials noch geschützt werden
username = 'client'
password = 'clientpassword'
#IP-Adresse des Servers feststellen und zurückgeben
#Parameter: ifname - 'wlan0' falls per WLAN verbunden und 'eth0' falls per LAN verbunden
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
#Daten aus Datenbank laden
def getData():
with con:
cur = con.cursor()
cur.execute("SELECT * FROM ZWAVE_SENSOREN")
return cur.fetchall()
#Sensorwerte abfragen und Wert in Datenbank schreiben
#Parameter:
#room: Raum, in dem der Wert gesucht werden soll
#sensor: Art des zu suchenden Sensors
def saveSensorData(room, sensor, ip):
#entsprechenden Sensorwert abfragen
params = urllib.urlencode({'action': 'getsensordata', 'room': room, 'value': sensor, 'username': username, 'password': password})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn = httplib.HTTPConnection(ip)
conn.request("POST", "/api.php", params, headers)
response = conn.getresponse()
sensorwert = response.read()
conn.close()
#Datum und Uhrzeit ermitteln
uhrzeit = now.strftime("%d.%m.%y %H:%M") #Datum und Uhrzeit im Format TT.MM.JJ HH:MM
#Daten in Datenbank schreiben
cur = con.cursor()
cur.execute("INSERT INTO SENSOR_DATA (ROOM, VALUE, SENSORART, DATETIME) VALUES ('"+room+"','"+sensorwert+"','"+sensor+"','"+uhrzeit+"')")
con.commit()
#Für jeden Sensor in jedem Raum den Wert in die Datenbank schreiben
for data in getData():
saveSensorData(data[0], data[1], get_ip_address(sys.argv[1])) #data[0] enthält den KEY des Raumes und data[1] die Art des Sensors
Damit die Sensorwerte automatisiert regelmäßig in die Datenbank geschrieben werden, muss auf dem Raspberry ein Cronjob angelegt werden. Dieser ruft den angegebenen Befehl in angegebenen Zeitabständen auf (bei mir: alle 3 Stunden). Um einen solchen Cronjob anzulegen, musst du in die Kommandozeile den folgenden Befehl eingeben:
crontab -e
* * * * * Befehl
0 0,3,6,9,12,15,18,21 * * * sudo python /var/www/html/python/saveSensorData.py [VERBINDUNGSART]
sudo reboot
Dieser Beitrag hat dir gefallen?
Dann abonniere doch unseren Newsletter!