Szenen anlegen im Smarthome


17.05.2016  |  Smarthome Server, Tutorial

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:

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
In der Tabelle 'SCENES' kannst du später deine Szenen anlegen.
Dort gibst du unter dem Punkt "Create new table on database data.sqlite" bei Name "SCENES" und bei "Number of Fields" die Zahl 3 ein. Anschließend klickst du auf "Go", um zum Definitions-Bildschirm zu gelangen. Dort werden die Felder folgendermaßen definiert:
  • 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
Die 3 Felder sind 'NAME', 'ROOM' und 'ACTIONS'.
Dann schließt du die Definition der Tabelle mit einem klick auf "Create" ab.

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&uuml;llt ist oder keine Bedingung angegeben, f&uuml;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&uuml;ft die &uuml;bergebene Bedingung auf Wahrheit und gibt dementsprechend true/false zur&uuml;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 &uuml;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&uuml;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 &Uuml;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&uuml;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

Über den Autor


Sascha Huber

Hallo, ich bin Sascha, der Gründer von Smarthome Blogger.

Mit einer Leidenschaft für Technologie und einem Hintergrund als Software Engineer habe ich 2016 Smarthome Blogger gegründet. Mein Ziel war es schon immer, innovative Lösungen zu entdecken, die unser Leben einfacher und intelligenter gestalten können. In meinem beruflichen Leben arbeite ich täglich mit Software und Technik, aber auch in meiner Freizeit bin ich stets auf der Suche nach neuen technischen Spielereien und Möglichkeiten, mein Zuhause zu automatisieren und zu verbessern.

Auf Smarthome Blogger teile ich mein Wissen, meine Erfahrungen und meine Begeisterung für alles rund um das Thema Smarthome.



Dieser Beitrag hat dir gefallen?

Dann abonniere doch unseren Newsletter!