Gateways ins Smarthome einbinden

Teile diesen Beitrag

Im Artikel “RaZberry Modul auf Raspberry installieren” habe ich dir gezeigt, wie du deinen Raspberry Pi als Z-Wave Zentrale einsetzen kannst. Im heutigen Tutorial wird die Unterstützung für externe Smarthome Zentralen implementiert, damit du auch dein vorhandenes Z-Wave System von deinem Raspberry aus steuern kannst. Doch auch wenn du Z-Wave lokal auf deinem Smarthome-Raspberry eingerichtet hast, solltest du diesem Tutorial folgen, da in Zukunft auch andere Smarthome-Systeme unterstützt werden und die folgenden Tutorials teilweise darauf aufbauen.

Datenbank anpassen

Als erstes wird der Datenbank eine neue Tabelle hinzugefügt, in der die Daten der externen Smarthome-Zentralen gespeichert sind. Dazu rufst du mit deinem Browser die Adresse “http://[IP DEINES RASPBERRY]/database/phpliteadmin.php” auf und klickst im mittleren Bereich auf “Create new table on database ‘data.sqlite'”. Hier gibst du nun als Name “GATEWAYS” und als Anzahl der Felder 5 ein und klickst auf “Go”.

So wird die Tabelle Gateways definiert.

So wird die Tabelle Gateways definiert.

Die Felder der Tabelle sind NAME, IP, PORT, USERNAME und PASSWORD. Bis auf “PORT” sind alle Felder vom Typ “TEXT”, “PORT” ist vom Typ “INTEGER”. Das Feld “NAME” ist der Primärschlüssel und “NAME” und “PORT” dürfen nicht null sein. Der Defaultwert des Feldes “IP” ist “localhost” und der des Feldes “PORT” ist “80”.

Skript zur Unterstützung von externen Zentralen

Anschließend muss noch das Skript zur Abfrage und der Verwaltung der externen Smarthome-Zentralen implementiert werden. Dazu verbindest du dich per FTP mit deinem Server, erstellst im Serverhauptverzeichnis den Ordner “manager” und darin die Datei “gatewayManager.php”, die du dann öffnest. In dieser Datei werden nun die folgenden Methoden angelegt. Die Methode addEditGateway() erstellt ein neues oder aktualisiert ein vorhandenes Gateway, je nachdem, ob der Parameter $key leer ist, oder nicht. Gateways können mit der Methode deleteGateway() gelöscht werden. Mit den Methoden getGateway() und getGatewayData() lassen sich die Daten eines bestimmten Gateways abfragen, wobei sich die Rückgabe der Methoden leicht unterscheidet. Die ins System eingebundenen Gateways lassen sich mit getGateways() und die Typen der verfügbaren Gateways, die noch nicht eingebunden wurden, mit getGatewayTypes() abfragen. Speichere das Skript anschließend und lade die Änderungen auf den Server hoch.

<?php

/**
*Erstellt ein neues Gateway bzw. aktualisiert das Gateway mit dem Key $key
*/
function addEditGateway($key, $ip, $port, $usr, $psw, $changepw, $db){
	if(!hasPermission("admin", $db)){
		return "noadmin";
	}
	
	$paramArray = array("name" => $key, "ip" => $ip, "port" => $port, "usr" => $usr);
	
	if($changepw === "true"){
		$paramArray['psw'] = $psw;
		
		//Gateway bearbeiten bzw. hinzufügen
		$updateQuery = $db->prepare("UPDATE OR IGNORE 'GATEWAYS' SET IP = :ip, PORT = :port, USERNAME = :usr, PASSWORD = :psw WHERE NAME = :name;");
	
		$insertQuery = $db->prepare("INSERT OR IGNORE INTO 'GATEWAYS' (NAME, IP, PORT, USERNAME, PASSWORD) VALUES (:name, :ip, :port, :usr, :psw);");
	}
	else{
		//Gateway bearbeiten bzw. hinzufügen
		$updateQuery = $db->prepare("UPDATE OR IGNORE 'GATEWAYS' SET IP = :ip, PORT = :port, USERNAME = :usr WHERE NAME = :name;");
	
		$insertQuery = $db->prepare("INSERT OR IGNORE INTO 'GATEWAYS' (NAME, IP, PORT, USERNAME) VALUES (:name, :ip, :port, :usr);");
	}
	
	$updateQuery->execute($paramArray);
	$insertQuery->execute($paramArray);
	
	if($updateQuery == true && $insertQuery == true) return "ok";
	else return "error";
}

/**
*Löscht das Gateway mit dem Key $key
*/
function deleteGateway($key, $db){
	if(!hasPermission("admin", $db)){
		return "noadmin";
	}
	
	$result = $db->prepare("DELETE FROM GATEWAYS WHERE NAME == :key");
	$result->execute(array("key" => $key));
	
	if($result == true){
		return "ok";
	}
	else return "error";
}

/**
*Gibt alle Daten eines bestimmten Gateways zurück
*/
function getGateway($key, $db){
	$results = $db->prepare("SELECT * FROM 'GATEWAYS' WHERE NAME == :key");
	$results->execute(array('key' => $key));
	
	//Alle Server durchlaufen
	foreach($results->fetchAll(PDO::FETCH_ASSOC) as $row){
		return $row;
	}
}

/**
*Gibt Namen, IP, Port und Nutzername eines bestimmten Gateways zurück
*/
function getGatewayData($key, $db){
	if(!hasPermission("admin", $db)){
		return "noadmin";
	}
	
	$results = $db->prepare("SELECT * FROM 'GATEWAYS' WHERE NAME == :key");
	$results->execute(array('key' => $key));
	
	//Alle Server durchlaufen
	foreach($results->fetchAll(PDO::FETCH_ASSOC) as $row){
		return json_encode(array("gatewaydata" => array("name" => $row['NAME'], "ip" => $row['IP'], "port" => $row['PORT'],
		"username" => $row['USERNAME'])));
	}
}

/**
*Gibt die zum System hinzugefügten Gateways zurück
*/
function getGateways($db){
	if(!hasPermission("admin", $db)){
		return "noadmin";
	}
	
	$results = $db->prepare("SELECT * FROM 'GATEWAYS'");
	$results->execute();
	
	$gateways = array();
	
	//Alle Server durchlaufen
	foreach($results->fetchAll(PDO::FETCH_ASSOC) as $row){
		array_push($gateways, array("name" => $row['NAME'], "ip" => $row['IP'], "port" => $row['PORT'], "username" => $row['USERNAME']));
	}
	
	return json_encode(array("gateways" => $gateways, "gatewaytypes" => getGatewayTypes($db)));
}

/**
*Gibt die Gatewaytypen zurück, die noch nicht zum System hinzugefügt wurden
*/
function getGatewayTypes($db){
	if(!hasPermission("admin", $db)){
		return "noadmin";
	}
	
	$gatewayTypes = array("Z-Wave");
	
	$query = $db->prepare("SELECT NAME FROM GATEWAYS");
	$query->execute();
	
	foreach($query->fetchAll() as $row){
		$index = array_search($row['NAME'], $gatewayTypes);
		if($index !== FALSE){
			unset($gatewayTypes[$index]);
		}
	}
	
	return array_values($gatewayTypes);
}

?>

Schnittstelle bearbeiten

Als letztes muss noch die Schnittstelle bearbeitet werden. Dazu öffnest du die Datei “api.php” im Serverhauptverzeichnis. Hier fügst du in Zeile 26 einen include-Befehl für die Datei “gatewayManager.php” hinzu und erstellst die neuen Fälle für die Methoden (Zeilen 83 – 94). Speichere das Skript anschließend und lade die Änderungen auf den Server hoch.

<?php
 
//Datenbankverbindung herstellen
$SQLITEdb = "database/data.sqlite";
$db = new PDO("sqlite:".$SQLITEdb);
 
//Funksteckdosen
include "getModes.php";
include "setModes.php";
   
//Andere
include "getRooms.php";
include "getSensorData.php";
include "getSystemInfo.php";
include "getRoomData.php";
include "getGraphData.php";
include "events.php";
include "permissions.php";
 
//Szenen
include "scenes/getScenes.php";
include "scenes/runScene.php";
include "scenes/createScene.php";
 
//Diese Zeile wurde hinzugefügt
include "manager/gatewayManager.php";
 
$validUser = validateUser($_POST['username'], $_POST['password'], $db);
 
if($validUser){
    switch($_POST['action']){
        case "getrooms":
            echo getRooms($db);
            break;
        case "getevents":
            echo getEvents($_POST['username'], $_POST['type'], $_POST['limit'], $_POST['offset'], $db);
            break;
        case "geteventtypes":
            echo getEventTypes($db);
            break;
        case "addevent":
            echo addEvent($_POST['type'], $_POST['text'], $db);
            break;
        case "getunseenevents":
            echo getUnseenEvents($_POST['username'], $db);
            break;
        case "getpermissions":
            echo getPermissions($_POST['user'], $db);
            break;
        case "setpermissions":
            echo setPermissions($_POST['user'], $_POST['permissions'], $db);
            break;
        case "getgraphdata":
            echo getGraphData($_POST['type'], $_POST['id'], $_POST['von'], $_POST['bis'], $db);
            break;
        case "getroomdata":
            echo getRoomData($_POST['room'], $db);
            break;
        case "getmodes":
            echo getModes($_POST['room'], $_POST['type'], $_POST['device'], $db);
            break;
        case "setmodes":
            echo setModes($_POST['room'], $_POST['type'], $_POST['device'], $_POST['zustand'], $db);
            break;
        case "getsensordata":
            echo getSensorData($_POST['room'], $_POST['type'], $_POST['id'], $_POST['showeinheit'], $db);
            break;
        case "runscene":
            echo runScene($_POST['room'], $_POST['name'], $db);
            break;
        case "createscene":
            echo createScene($_POST['devices'], $_POST['rooms'], $_POST['types'], $_POST['values'],
                $_POST['conditions'], $_POST['room'], $_POST['name'], $db);
            break;
        case "getscenes":
            echo getScenes($_POST['room'], $db);
            break;
        case "getsysteminfo":
            echo getSystemInfo();
            break;
         
        //Diese Cases wurden hinzugefügt
        case "deletegateway":
            echo deleteGateway($_POST['key'], $db);
            break;
        case "getgateways":
            echo getGateways($db);
            break;
        case "getgatewaydata":
            echo getGatewayData($_POST['type'], $db);
            break;
        case "addeditgateway":
            echo addEditGateway($_POST['type'], $_POST['ip'], $_POST['port'], $_POST['usr'], $_POST['psw'], $_POST['changepw'], $db);
            break;
    }
}
 
function validateUser($username, $password, $db){
    //Wird noch implementiert
     
    return true;
}
 
function hasPermission($action, $db){
    $permissions = getPermissions($_POST['username'], $db);
    $permissions = json_decode($permissions, true)['permissions'];
     
    return (in_array($action, $permissions) || in_array("admin", $permissions));
}

?>

Bei Fragen oder Problemen kannst du mir einen Kommentar hinterlassen.

Teile diesen Beitrag
, , , , ,
Vorheriger Beitrag
Smarthome App #9: Anpassung an Systemänderungen & Login-Daten speichern
Nächster Beitrag
Smarthome App #10: Modularisierung der App

Ähnliche Beiträge

Menü

Wir nutzen Cookies, um dir passende Inhalte zu präsentieren und dein Surfvergnügen zu optimieren, aktivieren Cookies aber erst, wenn du auf akzeptieren klickst. Weitere Informationen

Wir benutzen Google Analytics, um zu ermitteln, welche Inhalte unsere Besucher sehen wollen und welche nicht. Eingebettete YouTube-Videos helfen dir mittels Cookies nur die Videos zu sehen, die du sehen willst.

Schließen