Manchmal möchte man nicht nur einen einzigen Befehl ausführen, sondern eine ganze Gruppe von Befehlen. Bei einem DVD-Abend z.B. möchte man mit einem Klick die Lichter auschalten, das Media Center starten, und eventuell die Heizung auf eine bestimmte Temperatur regeln. Das Zauberwort heißt "Szene". Mit Szenen werden Befehlsketten zu einem einzigen Befehl zusammengefasst, um häufig zusammen ausgeführte Befehle zu vereinen. In diesem Tutorial erfährt du, wie du ganz einfach in deinem Smarthome-System Szenen anlegen kannst.
Was wird benötigt?
Um diesem Tutorial folgen zu können solltest du folgendes besitzen: Außerdem solltest du bereits folgenden Tutorials dieser Website gefolgt sein:- Raspberry Pi einrichten
- Funksteckdosen mit Raspberry Pi schalten
- Datenbank anlegen & verwalten
- Funksteckdosen per Internet schalten
- RaZberry Modul auf Raspberry installieren
- Datenbank: Sensorwerte speichern
Was wird in diesem Tutorial gemacht?
In diesem Tutorial werden folgende Dinge getan:- Eine Tabelle für die Szenen anlegen
- Ein Script erstellen, das die Befehle der ausgeführten Szene verarbeitet
- Ein Script erstellen, um Szenen anlegen zu können
- Ein Script erstellen, um vorhandene Szenen abzufragen (wird für später erstellte Smarthome App benötigt)
Tabelle für Szene in Datenbank erstellen
Um die Tabelle zu erstellen, öffnest du in deinem Browser folgende URL:http://[IP DES RASPBERRY]/database/phpliteadmin.php
- NAME (Text): Dies ist der Name der Szene (dieser wird auch in der später erstellten App angezeigt)
- ROOM (Text): Im Feld "ROOM" wird der Raum gespeichert, bei dem die Szene in der später erstellten App angezeigt wird
- ACTIONS (Text): Hier werden die Aktionen dieser Regel im JSON-Format abgespeichert
Script für die Steuerung erstellen
Nun erstellst du per FTP im Hauptverzeichnis deines Servers einen Ordner mit dem Namen "scenes". Anschließend wechselst du in diesen Ordner und erstellst du eine Datei namens "runScene.php". Diese Datei ist für die Ausführung der Szenen zuständig. Öffne diese Datei und füge den folgenden Quellcode ein.<?php
function runScene($room, $scene, $db){
//Szenen aus Datenbank laden
$results = $db->prepare("SELECT * FROM 'SCENES' WHERE ROOM == :room AND NAME == :scene");
$results->execute(array('room' => $room, 'scene' => $scene));
foreach($results->fetchAll(PDO::FETCH_ASSOC) as $row){
$array = json_decode($row['ACTIONS'], true);
foreach($array['actions'] as $action)
{
//Wenn Bedingung erfüllt ist oder keine Bedingung angegeben, führe Befehl aus
if($action['if']==null || conditionTrue($action['if'])){
//Verarbeitung der Aktion anhand des Aktionstyps (Schalter, Heizung, etc.)
switch($action['type']){
case 'switch':
setModes($action['location'], $action['device'], $action['value'], $db);
break;
case 'heizung':
//Heizungssteuerung wird noch implementiert
break;
}
}
}
}
return "ok";
}
//Prüft die übergebene Bedingung auf Wahrheit und gibt dementsprechend true/false zurück
function conditionTrue($condition){
switch($condition['type']){
//Sensorwert abfragen
case 'sensor':
$value = getData($condition['room'], $condition['sensorart'], '', $db);
break;
//Schalter abfragen
case 'switch':
$value = getModes($condition['room'], $condition['device'], $db);
break;
}
//vergleicht den abgefragten Wert mit dem übergebenen Wert
switch($condition['comparator']){
case '<':
return ($value < $condition['value']);
case '<=':
case '=<':
return ($value <= $condition['value']);
case '>':
return ($value > $condition['value']);
case '>=':
case '=>':
return ($value >= $condition['value']);
case '==':
case '=':
return ($value == $condition['value']);
default:
return false;
}
}
?>
Erklärung des Scripts
Das Script fragt zuerst die Befehlskette im JSON-Format ab, die der Szene zugewiesen ist, prüft, ob die zugewiesene Bedingung erfüllt ist und führt anschließend die entsprechenden Befehle anhand der zugewiesenen Typen aus (momentan wird nur der Typ "switch" unterstützt, damit lassen sich Szenen für Funksteckdosen erstellen - weitere Befehlstypen werden im weiteren Verlauf dieser Tutorialreihe implementiert, z.b. Steckdosen, Befehle fürs Media Center, etc). Die Methode conditionTrue($condition) prüft, ob die vorhandene Bedingung für eine Aktion erfüllt ist oder nicht. Momentan implementierte Bedingungen sind (weitere folgen in Zukunft):- bestimmter Sensorwert größer (oder gleich) als angegebener Grenzwert
- bestimmter Sensorwert kleiner (oder gleich) als angegebener Grenzwert
- bestimmter Sensorwert gleich dem angegebenen Grenzwert
- Bestimmtes Gerät AN bzw. AUS
Script, um Szenen anlegen zu können
Nun erstellst du im Ordner "scenes" eine weitere Datei namens "createScene.php". Mit dieser Datei kannst du später neue Szenen anlegen.In das Script fügst du nun folgenden Code ein:<?php
function createScene($devices, $rooms, $types, $values, $conditions, $room, $name, $db){
//Prüfen, ob alle Arrays ($devices, $rooms, $types, $modes) gleich viele Elemente haben, gibt andernfalls Fehlermeldung aus
if(sizeOf($devices) < sizeOf($rooms) ||
sizeOf($rooms) < sizeOf($types) ||
sizeOf($types) < sizeOf($values) ||
sizeOf($values) < sizeOf($devices)){
exit("error");
}
$scene = array();
//Die Übergabe-Arrays in ein einziges Array zusammensetzen
for($counter = 0; $counter < sizeOf($devices); $counter++){
$action_item = array('device' => $devices[$counter], 'location' => $rooms[$counter], 'value' => $values[$counter], 'type' => $types[$counter], 'if' => $conditions[$counter]);
array_push($scene, $action_item);
}
//Array als JSON-Objekt ausgeben
header('Content-type: application/json');
$action_string = json_encode(array('actions' => $scene));
//Prüfen, ob $room leer ist, wenn ja Default-Wert setzen
if($room == ''){
$room = 'NONE';
}
//Szene in Datenbank schreiben
$statement = $db->prepare("INSERT INTO SCENES(NAME, ROOM, ACTIONS)VALUES(?,?,?)");
$statement->execute(array($name ,$room, $action_string));
return "ok";
}
?>
Erklärung des Scripts
Als Parameter werden die einzelnen Befehle der Szene als Arrays übergeben. Das Skript setzt aus den einzelnen Arrays nun ein JSON-Objekt zusammen, das anschließend zusammen mit dem Namen der Szene und dem zugewiesenen Raum in die Datenbank geschrieben wird. Wenn die einzelnen Arrays der Übergabe nicht gleich lang sind, also unvollständig, bricht das Skript ab und gibt "error" zurück. Läuft das Skript hingegen vollständig und erfolgreich ab, so wird "ok" zurückgegeben.Script, um vorhandene Szenen abzufragen
Als letztes muss du eine Datei mit dem Namen "getScenes.php" im Ordner "scenes" erstellen. Diese Datei gibt bei Aufruf alle zugehörigen Szenen eines Raumes zurück. Den folgenden Code fügs du anschließend in das Script ein:<?php
function getScenes($room, $db){
//Szenen aus Datenbank laden
//INFO: Es werden alle Szenen abgefragt, die entweder dem Raum des Parameters $room oder dem Raum 'NONE' zugewiesen sind
$results = $db->prepare("SELECT * FROM 'SCENES' WHERE ROOM == :room OR ROOM == 'NONE'");
$results->execute(array('room' => $room));
$scenes = array();
//Namen aller gefundenen Szenen in Array schreiben
foreach($results->fetchAll(PDO::FETCH_ASSOC) as $row){
$scene_item = array('name' => $row['NAME'], 'room' => $row['ROOM'], 'actions' => $row['ACTIONS']);
array_push($scenes, $scene_item);
}
//Array als JSON-Objekt ausgeben
header('Content-type: application/json');
return json_encode(array('scenes' => $scenes));
}
?>
Erklärung des Scripts
Das Script fragt bei Aufruf die Datenbank nach allen Szenen ab, die dem übergebenen Raum (oder keinem Raum) zugewiesen sind und gibt dann ein JSON-Objekt zurück, in dem alle Szenen dieser Suche mit dem Namen und dem zugewiesenen Raum aufgelistet sind.Benutzung der Skripte
Um Szenen abfragen, ausführen oder anlegen zu können wird eine Schnittstelle benötigt. Diese Schnittstelle wird vor Programmierung der Android-App angelegt. Wenn du Schwierigkeiten oder Fragen hast, kannst du mir gerne einen Kommentar hinterlassen.Das Video zum Tutorial
Dieser Beitrag hat dir gefallen?
Dann abonniere doch unseren Newsletter!