Fritzbox: ESP8266 lässt Telefon klingeln

Hin und wieder möchte man dafür sorgen, dass sich ein ESP8266 deutlich bemerkbar machen kann, wenn irgendwas wichtiges passiert ist.

Meine Idee war, dass man über die Fritzbox das Telefon klingeln lassen könnte.

Leichter gesagt als getan. Viele Ideen musste ich verwerfen:

  • Der ESP führt auf der FritzBox einen Rundruf (**9) durch. Leider habe ich keine Lösung gefunden, dies über den ESP auszulösen.
  • ESP führt einen get-Request durch, dieser startet auf einem Linux-Server einen Voip Anruf und hierbei wird eine Audio-Datei abgespielt. Leider habe ich keine einfache Lösung für eine Umsetzung  unter Linux gefunden. (Ich bin immer noch offen für Vorschläge)

Durch einen Zufall bin ich auf den folgenden Dialog gestoßen:

fritzboxdialtonetest

Mit dieser Funktion kann man ein DECT-Telefon klingeln lassen.

Perfekt … Nur wie kann ich darauf zugreifen?

Nach einigen Suchen im Internet, ein paar Stunden programmieren und testen, war die Funktion endlich fertig.

Wenn ich die Funktion aufruft, meldet sich der ESP8266 mit dem Passwort an der FritzBox an, startet den Klingelton-Test und beendet ihn nach 10 Sekunden wieder.

 

bool send() {
	HTTPClient http;
	  Serial.println("Notify FritzBox");

	// Get Challenge
	http.begin("http://fritz.box/login_sid.lua");
	int retCode = http.GET();
	if (retCode != 200) {
		Serial.println("Get Challengd failed! " + String(retCode));
		return false;
	}
	String result = http.getString();
	String challenge = result.substring(result.indexOf("<Challenge>") + 11,	result.indexOf("<Challenge>") + 19);

	// Calculate Response
	String reponseASCII = challenge + "-" + "INSERT YOUR PWD HERE";
	String responseHEX = "";
	for (unsigned int i = 0; i  < reponseASCII.length(); i++) {
		responseHEX = responseHEX + String(reponseASCII.charAt(i), HEX) + "00";
	}

	MD5Builder md5;
	md5.begin();
	md5.addHexString(responseHEX);
	md5.calculate();

	String response = challenge + "-" + md5.toString();

	// Login and get SID
	http.begin("http://fritz.box/login_sid.lua?user=&response=" + response);
	retCode = http.GET();
	if (retCode != 200) {
		Serial.println("Get Sid failed! " + String(retCode));
		return false;
	}
	result = http.getString();
	String sid = result.substring(result.indexOf("<SID>") + 5,	result.indexOf("<SID>") + 21);

	// Execute Ring Tone Test
	http.begin("http://fritz.box/fon_devices/edit_dect_ring_tone.lua?idx=1&sid=" + sid + "&ring_tone_radio_test=0&start_ringtest=2");
	retCode = http.GET();
	if (retCode != 200) {
		Serial.println("Enable Ring Tone Test failed! " + String(retCode));
		return false;
	}
	result = http.getString();

	
	// Wait 10 sec
	delay(10 * 1000);

	// Stop Ring Tone Test
	http.begin("http://fritz.box/fon_devices/edit_dect_ring_tone.lua?idx=1&sid=" + sid + "&stop_ringtest=1&ringtone&start_ringtest=0");
	retCode = http.GET();
	if (retCode != 200) {
		Serial.println("Stopping Ring Tone Test failed! " + String(retCode));
		return false;
	}
	result = http.getString();

	// Logout
	http.begin("http://fritz.box/login_sid.lua?logout=1&sid=" + sid);
	http.GET();
	result = http.getString();
	http.end();

	return true;
}

Einschränkungen / Anmerkungen:

    • Im Sourcecode muss in Zeile 16 das Passwort geändert werden. (keine Umlaute oder exotische Sonderzeichen. #%$,. und ähnliche sind wahrscheinlich ok)
    • Das Passwort muss für die FritzBox, bevor es gehasht wird, einmal in UTF-16 umgewandelt werden. Da dies auf der ESP8266 nicht so ganz trivial ist, berücksichtige ich nur Zeichen mit ASCII-Werten zwischen 1 und 255. Aus diesem Grund muss ein Passwort genutzt werden, welches keine Umlaute enthält.
    • Der Sourcecode geht davon aus, dass die FritzBox unter http://fritz.box erreichbar ist. (ggf. http://fritz.box/ passend ändern)
    • Es werden nur DECT Telefone unterstützt und nur das erste klingelt. (ggf. idx=1 ändern, damit ein anderes Telefon klingelt.)
    • Mehr zu der genutzten Zugriffsmethode findet sich in diesem Dokument.

 

13 Gedanken zu „Fritzbox: ESP8266 lässt Telefon klingeln“

  1. In meiner Lösung läuft auf einem Unix-Server (Raspi für
    Hausautomatisierung und als VPN-Server) ein kleiner TCP-Server (Perl) als Dienst. Der ESP8266 baut eine Client-Verbindung dazu auf, sendet einen String, empfängt “ok” und legt sich schlafen. Bei Empfang ruft der TCP-Server ein Perl-Script auf, das mit Hilfe von Net::SIP sich als Telefon anmeldet und einen Ruf an ein internes Telefon absetzt (mit Audiodatei).
    Rundruf müsste genauso gehen, habe ich noch nicht probiert.
    Das IP-Telefoniegerät muss man zuvor in der FRITZ!Box mit Anschluss LAN/WLAN angelegt haben. Die Programmierung auf ESP8266 und Raspi steht, jetzt kommt noch die HW-Bastelei (Anschluss an Türklingel)…
    Übrigens, wenn man mehrere ESP8266 einsetzt, kann man im TCP-Server die Absender unterscheiden und unterschiedlichste Dinge bewirken. Ich habe da schon ein paar Ideen 🙂

  2. Hi,

    vielen Dank für das Methode.

    Wo kann ich die Datei: HTTPClient.h finden?

    Mit freundlichen grüßen

  3. Vielen Dank für Deine Info.

    Deine Lösung funktioniert super.

    Ist es auch möglich, das intern Telefon an externe Nummer umzuleiten oder direkt an externe Nummer anrufen?

    Gruß,

    Wang

  4. Hallo Wang,

    leider habe ich noch keine Lösung für den ESP826 hierfür gefunden. Falls du eine Lösung findest, freue ich mich von dir zu hören.

    Gruß

  5. Danke für den Hinweis.

    Schön zu hören, dass es auch Alternativen gibt.
    Muss ich mir bei Gelegenheit mal anschauen.

  6. Die Lösung per TR-64 funktioniert nicht nur per Rundruf, sondern auch auf externe Ziele – eben auf alles, was man per Wahlhilfe erreichen kann. Ein Telephon (das kann auch ein ungenutzter fon-Anschluss sein) wird als “Quelle” der Wahlhilfe verwendet; für das eigentliche Ziel verwendet man am einfachsten einen Kurzwahleintrag des internen Telephonbuchs der Fritzbox. Dort kann man dann bequem das Ziel ändern – ob **9 für Rundruf, gezielt eine Rufgruppe oder einen externen Anruf. Das spart es, die Programmierung des ESP ändern zu müssen, bloß um die Zielnummer zu ändern.
    Das löst also auch das Problem von Wang; der Anruf wird nicht umgeleitet, sondern gleich an die Externe Nummer geführt.

  7. Hi, ich habe den Code als Basis genommen, um die Anmeldung an der Fritz!Box nach vergeblichen Versuchen mit anderen Beispielen zum Laufen zu bekommen. Der Unterschied war die Generierung des md5 Hashes, so passt es.

    Ich habe zu Windows Phone Zeiten selbst eine Windows Universal App geschrieben, um die Schaltsteckdose Fritz!DECT200 anzusteuern. Den Code-Teil nutze ich jetzt (nach Anpassung) zur Abfrage des Status (an/aus) und der Temperatur. Das alles wird dann als zusätzliche “Seite” auf dem Display der ESP8266 Weather Station ausgegeben. Erweitern möchte ich das dann für Status-Abfrage von AVM Heizkörperthermostaten.

    Bei mir gibt es sporadisch Probleme bei der Anmeldung an der Fritz!Box (ich bekomme keine Challenge), ohne dass ich das an irgendwas festmachen könnte. Mal geht es nicht, dann geht es plötzlich wieder stundenlang ohne Probleme – habt Ihr das auch schon mal festgestellt?

    Danke & viele Grüße

    Tim

  8. Danke für den Code, war mir sehr nützlich.
    Für meine Fritz!Box 6490 Cable musste ich allerdings den Code etwas ändern, indem in zwei Befehlen die ‘Unterstriche’ teilweise weggelassen werden mussten.
    Zeile 40:

    http.begin(“http://fritz.box/fon_devices/edit_dect_ring_tone.lua?idx=1&sid=” + sid + “&ring_tone_radio_test=0&startringtest=2”);

    und Zeile 53:

    http.begin(“http://fritz.box/fon_devices/edit_dect_ring_tone.lua?idx=1&sid=” + sid + “&stopringtest=1&ringtone&startringtest=0”);

    Ich weiß nicht ob das für alle Fritzboxen gilt, vielleicht kann es aber für jemanden hilfreich sein.

    RoSchmi (https://github.com/RoSchmi)

Schreibe einen Kommentar

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


The reCAPTCHA verification period has expired. Please reload the page.