Anwesenheitserkennung für Smarthome mit der Fritz!Box via TR-064

Wer sich mit dem Kontext SmartHome beschäftigt, der hat früher oder später immer die Frage: Wie erkenne ich möglichst automatisiert, ob jemand zuhause ist oder nicht? Am einfachsten geht das mit dem Smartphone. Das hat man in der Regel bei sich. Der am häufigsten anzutreffende Ansatz ist dieses in regelmäßigen Abständen anzupingen und auf der Basis den Anwesenheitsstatus zu definieren.

Da ich mein Smartphone aber nicht anpingen kann fällt die Lösung für mich flach. Ich habe aber eine Fritz!Box und mein Handy bezieht darüber per DHCP eine IP-Adresse. In der Fritz!Box ist auch sichtbar, ob das Gerät aktiv oder nicht aktiv ist.

Die Fritz!Box hat eine Schnittstelle für Anwendungen basierend auf TR-064. Der Zugriff darauf muss in dem Webinterface unter

  • Heimnetz ->
  • Heimnetzübersicht ->
  • Netzwerkeinstellungen ->
  • Zugriff für Anwendungen zulassen

freigeschaltet werden. Anschließend kann via SOAP mit der Fritz!Box kommuniziert und unter anderem auch der Status eines angeschlossenen Gerätes ermittelt werden. Dafür muss man nur die MAC-Adresse kennen.

Die Antwort der Fritz!Box sieht dann zum Beispiel so aus:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:GetSpecificHostEntryResponse xmlns:u="urn:dslforum-org:service:Hosts:1">
      <NewIPAddress>11.22.33.44</NewIPAddress>
      <NewAddressSource>DHCP</NewAddressSource>
      <NewLeaseTimeRemaining>0</NewLeaseTimeRemaining>
      <NewInterfaceType>802.11</NewInterfaceType>
      <NewActive>1</NewActive>
      <NewHostName>mySmartphoneDevice</NewHostName>
    </u:GetSpecificHostEntryResponse>
  </s:Body>
</s:Envelope>

Für die Hausautomatisierung setze ich Homematic mit einer CCU2 ein. Dort habe ich eine Systemvariable definiert und über die XML API kann diese auch per GET aktualisiert werden. Dafür muss man nur die sogenannte ise_id der Variable kennen, die findet man unter der folgenden URL: http://ccu2/config/xmlapi/sysvarlist.cgi

Die Anfrage an die Fritz!Box und das anschließende setzen der Systemvariable in der CCU2 habe ich in PHP wie folgt gelöst:

<?php 
 
// Array of MAC addresses and coresponndig ise_id on ccu2
$check[] = array('mac' => 'AA:BB:CC:DD:EE:FF', 'ise_id' => '1234');
$check[] = array('mac' => '11:22:33:44:55:66', 'ise_id' => '4321');
 
 
for ($j = 0; $j < count($check); $j++) {
 
	$soapUrl = "http://fritz.box:49000/upnp/control/hosts";
 
	$xml_post_string = '<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" >
  <s:Body>
    <u:GetSpecificHostEntry xmlns:u="urn:dslforum-org:service:Hosts:1">
      <NewMACAddress>' . $check[$j]['mac'] . '</NewMACAddress>
    </u:GetSpecificHostEntry>
  </s:Body>
</s:Envelope>';
 
	$headers = array(
		"Content-type: text/xml;charset="utf-8"",
		"Accept: text/xml",
		"Cache-Control: no-cache",
		"Pragma: no-cache",
		"SoapAction:urn:dslforum-org:service:Hosts:1#GetSpecificHostEntry",
		"Content-length: ".strlen($xml_post_string),
        ); 
 
 
 
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $soapUrl);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_TIMEOUT, 10);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
 
	$response = curl_exec($ch); 
	curl_close($ch);
 
	$parser = simplexml_load_string($response);
	$parser->registerXPathNamespace("a", "urn:dslforum-org:service:Hosts:1");
 
	$NewActive_h = $parser->xpath('//NewActive/text()');
	$NewActive =  $NewActive_h[0]->__toString();
 
	if ($NewActive == 1) {
		$result = file_get_contents("http://ccu2/config/xmlapi/statechange.cgi?ise_id=" . $check[$j]['ise_id'] . "&new_value=true");
	}
	else {
		$result = file_get_contents("http://ccu2/config/xmlapi/statechange.cgi?ise_id=" . $check[$j]['ise_id'] . "&new_value=false");
	}
}
?>

Als Cronjob laufen lassen irgendwo, zum Beispiel auf einem Raspberry Pi, und schon hat man eine korrekte Systemvariable in der CCU2 auf dessen Basis man dann weitere Dinge machen kann.

prego

/me... prego!

2 Gedanken zu „Anwesenheitserkennung für Smarthome mit der Fritz!Box via TR-064“

  1. Hallo Prego,

    gegen
    PHP Parse error: syntax error, unexpected ‚utf‘ (T_STRING), expecting ‚)‘ in bla/bla/bla/check_presence.php on line 22

    „Content-type: text/xml;charset=“utf-8″“,
    hilft
    „Content-type: text/xml;charset=“utf-8″“,

    Danke für Dein Script. Es läuft und macht spaß.

    VG
    Alex M.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.