Verbindung zu SMTP Server ohne telnet oder nc testen

Um die Verbindung zu einem SMTP Server zu testen um zum Beispiel einen Fehler durch eine Firewall auszuschließen nutze ich normalerweise telnet:

user@host ~ $ telnet mail.example.net 25
Trying 1.2.3.4...
Connected to mail.example.net.
Escape character is '^]'.
220 mail.example.net ESMTP Postfix

Wenn telnet nicht installiert ist geht das auch noch mit netcat:

user@host ~ $ nc mail.example.net 25
220 mail.example.net ESMTP Postfix

Heute hatte ich ein System auf dem beides nicht existierte. Da habe ich eine Methode mit python gefunden die sehr gut funktioniert hat:

user@host ~ $ python
Python 2.7.9 (default, Mar  1 2015, 12:57:24) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> conn=socket.create_connection(('mail.example.net',25))
>>> input=conn.makefile()
>>> print input.readline()
220 mail.example.net ESMTP Postfix

>>> conn.sendall('QUIT')
>>> conn.close()
>>> 

Smarthome? Monitoring? Notifications mit altem Android Handy!

Heute morgen bin ich über die coolste App seit langem gestolpert. Es handelt sich um den Home24-MediaPlayer (Google Play oder direkter Download der APK).

Die App ist nicht etwa ein stupider Media Player wie der Name vermuten würde, sondern eine ziemlich geniale Möglichkeit um Benachrichtigungen zu verschicken. Die App – einmal gestartet – lauscht per HTTP auf Port 50000 und kann per GET Parameter angewiesen werden unterschiedlichste Dinge zu tun. Man kann das Handy vibrieren lassen, eine Nachricht in den Benachrichtigungen anzeigen lassen oder den Bildschirm anschalten.
Einzelne Kommandos können mit einer | getrennt verknüpft werden. Kommandos mit Parametern können per & verknüpft werden. Das angesprochene Beispiel ist:

curl "http://192.168.1.1:50000/statusbar=Hallo Welt|vibrate|screentimeout=3"

Deutlich cooler sind aber die weiteren Funktionen. So ist es zum Beispiel möglich eine auf dem Gerät vorliegende MP3 abzuspielen. Damit kann man mit simplen Mitteln einen Türgong realisieren. Beispiel:

curl "http://192.168.1.1:50000/track=gong.ogg"

Noch besser finde ich die Text-To-Speach Funktion:

curl "http://192.168.1.1:50000/tts=Alarm! Der Einbruchssensor beim Fenster im Schlafzimmer wurde ausgelöst!"

Aber man kann – eine SIM Karte im Gerät vorausgesetzt – auch SMS verschicken. Ganz einfach:

curl "http://192.168.1.1:50000/sms=017612345678&message=Es ist keiner Zuhause, das Schlafzimmerfenster ist offen und es gibt eine Unwetterwarnung vor starkem Gewitter."

Eine Übersicht der Möglichen Befehle gibt es auf der Webseite vom Home24-MediaPlayer.

Der Phantasie sind hier keine Grenzen gesetzt. Benachrichtigungen auf dem Smartphone wenn man Zuhause ist, SMS wenn man nicht Zuhause ist, Türgong über einen angeschlossenen Lautsprecher und so weiter. Und als Sysadmin ist das eine supersimple günstige einfache Möglichkeit auch Benachrichtigungen zu bekommen…. Genial!

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.