ESP8266 SIP Klingel mit FritzBox

Hi,
ich bin gerade am Versuchen, einem ESP8266 (D1 Mini) beizubringen, über meine Fritzbox 7490 alle Telefone klingeln zu lassen, wenn die Haustürklingel geht - ein bekanntes Projekt mit diversen Anleitungen.

An sich funktioniert alles, wo wie es soll - nur klingelt kein Telefon.

Stattdessen bekomme ich immer wieder folgenden Fehler, sofern es damit zusammenhängt:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Header>
<h:Challenge xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1">
<Status>Unauthenticated</Status>
<Nonce>9B5965CDC2565C53</Nonce>
<Realm>F!Box SOAP-Auth</Realm>
</h:Challenge>
</s:Header>
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring>UPnPError</faultstring>
<detail>
<UPnPError xmlns="urn:dslforum-org:control-1-0">
<errorCode>503</errorCode>
<errorDescription></errorDescription>
</UPnPError>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>

Hat jemand ähnliche Probleme gehabt und diese gelöst bekommen?

Mein Sketch:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <tr064.h>

#define USE_SERIAL Serial
#define KLINGEL 0


ESP8266WiFiMulti WiFiMulti;

const char WIFI_SSID[] = "MEINE_SSID";
const char WIFI_PASSWORD[] = "MEIN_PW";

const char USER[] = "FRITZ_USER";
const char PASSWORD[] = "USER_PASSWORT";
const char FRITZBOX_IP[] = "192.168.1.1";
const int FRITZBOX_PORT = 49000;

TR064 tr064_connection(FRITZBOX_PORT, FRITZBOX_IP, USER, PASSWORD);

const char DEVICE_NAME[] = "Klingel";

const IPAddress STATIC_IP(192, 168, 1, 230);
const IPAddress GATEWAY(192, 168, 1, 1);
const IPAddress SUBNET(255, 255, 255, 0);
const IPAddress DNS(GATEWAY);


void setup() {
  Serial.begin(115200);
  delay(1000);
  WiFi.hostname(DEVICE_NAME);
  WiFi.config(STATIC_IP, SUBNET, GATEWAY, DNS);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  WiFi.mode(WIFI_STA);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println("Verbinde...");
    delay(100);
  }
  tr064_connection.init();
  Serial.println("Verbunden!");
  
  pinMode(KLINGEL, INPUT_PULLUP);

  
}

void loop() {
  
  int klingel_stat = 0;
  klingel_stat = digitalRead(KLINGEL);
  if (klingel_stat == LOW) {
    Serial.println();
    Serial.printf("ANRUF!");
    makecall();
  }

  else {
    //Serial.println();
    //Serial.printf("KEINE Klingel!");
    delay(100);
  }

}

int makecall() {
  String tr064_service = "urn:dslforum-org:service:X_VoIP:1";
  String call_params[][2] = {{"NewX_AVM-DE_PhoneNumber", "**9"}};
  String req[][2] = {{}};
  String params1[][2] = {{}};
  tr064_connection.action(tr064_service, "X_AVM-DE-DialNumber", call_params, 1, req, 0);
    delay(4000);
  tr064_connection.action(tr064_service, "X_AVM-DE_DialHangup", params1, 1, req, 0);
}

Die komplette Ausgabe, wenn “KLINGEL” LOW geht:

ANRUF!action_3
action_1
The auth token is 88f63e0536a95156047059f54cd27182
[HTTP] begin: 192.168.1.1:49000/upnp/control/x_voip



<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Header><h:ClientAuth xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1"><Nonce>9B5965CDC2565C53</Nonce><Auth>88f63e0536a95156047059f54cd27182</Auth><UserID>esp</UserID><Realm>F!Box SOAP-Auth</Realm></h:ClientAuth></s:Header><s:Body><u:X_AVM-DE-DialNumber xmlns:u='urn:dslforum-org:service:X_VoIP:1'><NewX_AVM-DE_PhoneNumber>**9</NewX_AVM-DE_PhoneNumber></u:X_AVM-DE-DialNumber></s:Body></s:Envelope>



[HTTP] POST... SOAPACTION: urn:dslforum-org:service:X_VoIP:1#X_AVM-DE-DialNumber
[HTTP] POST... code: 500







action_3
action_1
The auth token is 88f63e0536a95156047059f54cd27182
[HTTP] begin: 192.168.1.1:49000/upnp/control/x_voip



<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Header><h:ClientAuth xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1"><Nonce>9B5965CDC2565C53</Nonce><Auth>88f63e0536a95156047059f54cd27182</Auth><UserID>esp</UserID><Realm>F!Box SOAP-Auth</Realm></h:ClientAuth></s:Header><s:Body><u:X_AVM-DE_DialHangup xmlns:u='urn:dslforum-org:service:X_VoIP:1'></u:X_AVM-DE_DialHangup></s:Body></s:Envelope>



[HTTP] POST... SOAPACTION: urn:dslforum-org:service:X_VoIP:1#X_AVM-DE_DialHangup
[HTTP] POST... code: 200



<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Header>
<h:NextChallenge xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1">
<Status>Authenticated</Status>
<Nonce>9E0471B8E39471D5</Nonce>
<Realm>F!Box SOAP-Auth</Realm>
</h:NextChallenge>
</s:Header>
<s:Body>
<u:X_AVM-DE_DialHangupResponse xmlns:u="urn:dslforum-org:service:X_VoIP:1"></u:X_AVM-DE_DialHangupResponse>
</s:Body>
</s:Envelope>

Und noch alles, was bis zum “Verbunden!” passiert:
Verbinde...Verbinde...Verbinde...[HTTP] begin: 192.168.1.1:49000/tr64desc. - Pastebin.com (zu viele Zeichen fürs Forum)

  • Fritzbox-Nutzer ist angelegt und funktioniert
  • Anwendungen im Netzwerk werden zugelassen
  • Der ESP8266 hat eine feste IP (192.168.1.230) und UPnP ist erlaubt
  • SIP-Telefon ist erstellt
  • Virtuelles Telefon als Wählhelfer ist erstellt und so eingerichtet

Rundruf mit **9 funktioniert genauso wenig, wie die Direktwahl eines Telefons mit **610.

Ich weiß nicht mehr weiter…keine Ahnung, wo das Problem liegt…hoffentlich, weiß hier jemand eine Lösung.

Gruß,
Jannomag

Deine Fritzbox hat wirklich die IP 192.168.1.1? Standardmäßig hat jede Fritzbox erstmal die 192.168.178.1, bis man es ändert.

Ergänzung, ist der ESP der Fritzbox bekannt? Also taucht er in der Liste der zugelassenen WLAN Geräte auf? Flashe dazu einen normalen Sketch womit der ESP nicht in den Sleepmode geht. Nur mit fester IP zuweisen im eigenen ESP Sketch ist es nicht getan. Da könnte ja jeder kommen und klingeln.

wapjoe: Deine Fritzbox hat wirklich die IP 192.168.1.1? Standardmäßig hat jede Fritzbox erstmal die 192.168.178.1, bis man es ändert.

Ja, hat sie. Mit Absicht so gewählt, da es bei mir immer so war. ipconfig auf meinem PC, der direkt per Kabel verbunden ist, sagt es auch: |500x203

Doc_Arduino: Ergänzung, ist der ESP der Fritzbox bekannt? Also taucht er in der Liste der zugelassenen WLAN Geräte auf? Flashe dazu einen normalen Sketch womit der ESP nicht in den Sleepmode geht. Nur mit fester IP zuweisen im eigenen ESP Sketch ist es nicht getan. Da könnte ja jeder kommen und klingeln.

Ja, tut er:

Mit meinem Sketch geht der ESP eigentlich ja nicht in den Deepsleep...oder?

Erhöhe mal das delay. Es dauert unter Umständen eine Weile bis es klingelt. Als ich es mal bei mir mit der Nummer vom Smartphone getestet hatte musste ich mehr als 10 Sekunden delay nehmen. Bin leider momentan nicht an meinem Rechner.

Gruß Fips

Auch nach 15 Sekunden nix, dann habe ich mal 30 versucht. Auch nix...wenn das dann aber wirklich so lange dauern würde, ist der Postbote ja schon weg :D

Dann liegt das Problem wo anders.

Mal sehen ob ich heute Abend dazukommen den Sketch zu testen.

Gruß Fips

Derfips: Dann liegt das Problem wo anders.

Mal sehen ob ich heute Abend dazukommen den Sketch zu testen.

Gruß Fips

Danke. Interessant finde ich halt, dass scheinbar die Authentifizierung nicht richtig abläuft, obwohl der Sketch genauso bei fast allen Tutorials zu finden ist. Kann mir auch vorstellen, dass AVM irgendwas gepatched hat und es deswegen nicht funktioniert.

Hi,

ich bin noch nicht firm in Sachen ESP, habe aber ein ähnliches Projekt im Hinterkopf. Daher hab ich mich versucht einzulesen, ist eher auf suchen, sehen und vergleichen hinausgelaufen. ;)

  1. Poste bitte einen Link zur vewendeten Lib.
  2. Hast du in der 7490 unter Heimnetz/Netzwerk/Netzwerkeinstellungen die Optionen unter Heimnetzfreigaben "Zugriff für Anwendungen zulassen" und eventuell auch "Statusinformationen über UPnP übertragen" aktiviert? Ggf. musst du die Fritzbox danach neu starten.
  3. Sehe ich das richtig, dass der Anruf an die Fritzbox über einen externen Service im Internet aufgebaut wird? Hier ist einer der Punkte die ich noch nicht so ganz verstehe, daher wenn es nicht anders geht und da nicht der Fehler liegt, bitte ich um Nachsicht! ;)
  4. Hast du den Port 49000 in der 7490 von Extern freigegeben? Internet/Freigaben/Portfreigaben. Ich denke das der externe Service die Fritzbox sonst nicht erreichen könnte, ist aber auch nur ein Schuss ins Blaue...

Btw: kann man mit dem ESP nicht ein IP-Telefon simulieren, welches die Fritzbox direkt anspricht?

Das sind jetzt die Fragen, die ich mir auf die Schnelle gestellt habe, um weiter in die Materie einzusteigen, muss ich mich erstmal einlesen.

Gruß Jörg

wapjoe: 1. Poste bitte einen Link zur vewendeten Lib.

Ist bei den Board-Infos dabei: http://arduino.esp8266.com/stable/package_esp8266com_index.json

wapjoe: 2. Hast du in der 7490 unter Heimnetz/Netzwerk/Netzwerkeinstellungen die Optionen unter Heimnetzfreigaben "Zugriff für Anwendungen zulassen" und eventuell auch "Statusinformationen über UPnP übertragen" aktiviert? Ggf. musst du die Fritzbox danach neu starten.

ja, ja, getan

wapjoe: 3. Sehe ich das richtig, dass der Anruf an die Fritzbox über einen externen Service im Internet aufgebaut wird? Hier ist einer der Punkte die ich noch nicht so ganz verstehe, daher wenn es nicht anders geht und da nicht der Fehler liegt, bitte ich um Nachsicht! ;)

Du meinst die Befehle wie "urn:dslforum-org:service:X_VoIP:1"? Das sind, soweit ich weiß, nur Zeilen, die über das TR064 Protokoll gesendet werden. Entwickler des Protokolls ist das DSL-Forum. Da wird nichts über einen externen Dienst geleitet, das haben die wohl nur eingefügt, um einen Namen zu haben.

wapjoe: 4. Hast du den Port 49000 in der 7490 von Extern freigegeben? Internet/Freigaben/Portfreigaben. Ich denke das der externe Service die Fritzbox sonst nicht erreichen könnte, ist aber auch nur ein Schuss ins Blaue...

Braucht man nicht, da nix extern benötigt wird. Zu mal 49000 nicht SSL Verschlüsselt wäre... Das ist der Port, den die Fritzbox für die Oberfläche / TR064 benutzt. 49443 wäre SSL, aber das kann der ESP nicht, spielt ja aber auch keine Rollte im internen Netzwerk.

wapjoe: Btw: kann man mit dem ESP nicht ein IP-Telefon simulieren, welches die Fritzbox direkt anspricht?

Glaube nicht, da der ESP nur seriell arbeitet. Daher das TR064 Protokoll, über das die Fritzbox Befehle annehmen kann.

Ich hoffe, ich habe nicht kompletten Unfug erzählt. Das sind lediglich die Infos, die ich mir in den letzten Tagen versucht habe anzueignen.

Mit deinem Sketch von oben klingelt bei mir nichts.

Gruß Fips

Hallo,

so mein Guter, hab mein ESP rausgekramt und alles nochmal nachgestellt.
Ohne TR046 und den Kram.

ESP als WLAN Gerät in der Fritzbox bekannt machen. Heißt neues WLAN Gerät zulassen.
Dazu WLAN-Test.ino flashen.
Unter Heimnetz > Netzwerk > Netzwerverbindungen taucht er dann auf.
IP notieren und Name ggf. ändern. Bei mir “ESP-Klingel”.
Haken setzen “immer gleiche IP Adresse zuweisen”

Dann neues WLAN/IP Telefon einrichten.
Unter Telefonie > Telefoniegräte > Button “Neues Geräte einrichten”
Auswahl > Telefon > LAN/WLAN (IP-Telefon) > Name “ESP-Klingel” > Benutzername + PW ausdenken und notieren

Haupttelefonnummer auswählen falls es mehrere gibt > “alle Anrufe annehmen” > bestätigen, fertig

Info: Man muss kein zusätzliches Nutzerkonto unter System in der Fritzbox anlegen.

SIP-Klingel.ino Sketch nehmen

SSID + WLANKEY angeben

sipip ................. Fritzbox IP ggf. anpassen
sipuser + sippasswd ... sind die beim Telefon einrichten ausgedachten Daten.
sipdialnr ............. "**9" ist Rundruf an alle, individuelle Nummern unter Telefonie > Telefoniegräte
sipdialtext ........... ist der Text der auf dem klingelnden Telefondisplay erscheint, bei mir "ESP-Klingel".

Einstellungen unter network params ggf. anpassen.
Hier die bekannte IP des ESP eintragen, dann ist der Verbindungsaufbau schneller

WLAN_Test.ino (574 Bytes)

SIP_Klingel.ino (15.7 KB)

Mein lieber Doc,

schon von mir danke, ich werde das bald mal testen, aber erst mal muss ich meine Schulter schonen. Also da es mich ebenfalls sehr interessiert, folgt danach mein Test mit deinem Sketch. :)

Ich bin auf meiner Suche auch noch auf einen Beitrag von dir gestoßen, mit tr064.

Hallo,

ja, mit der TR064 Variante hatte ich damals angefangen. Funktionierte auch. Nur störte mich der offene TR064 Port. Irgendwann stieß ich auf die neue Variante aus dem microcontroller Forum. Link ist im Sketch enthalten. Man kann alle bis dahin getätigten Fritzbox Einstellungen rückgängig machen und muss nur weniger Neue machen. Probiert es aus. Bin gespannt ob das bei allen klappt.

Danke für den Sketch. Klappt bei mir. Jedoch muss ich mich jetzt erstmal durch dieses große Programm durchwuseln, damit ich es umschreiben kann. Der Reset dauert etwas zu lange bei mir...etwa 10 Sekunden, nachdem der ESP resettet wurde, klingelt es - im besten. Einmal war es sogar länger und zwei mal hat sich der ESP erst nach erneutem Reset verbunden. Daher wollte ich diese Reset-Methode nicht haben. Mal sehen, ob ich es hinbekomme mit einem Pullup-Eingang statt Reset.

Doc_Arduino: Hallo,

ja, mit der TR064 Variante hatte ich damals angefangen. Funktionierte auch. Nur störte mich der offene TR064 Port. Irgendwann stieß ich auf die neue Variante aus dem microcontroller Forum. Link ist im Sketch enthalten. Man kann alle bis dahin getätigten Fritzbox Einstellungen rückgängig machen und muss nur weniger Neue machen. Probiert es aus. Bin gespannt ob das bei allen klappt.

Genial! Hab es eben auf einem nackten D1 Mini getestet, Sketch angepasst, Kurzwahl auf ein einzelnes Telefon gestellt und aufgespielt - prompt klingelte das Telefon! :) :D ;D

Hallo,

@ wapjoe: freut mich. :)

@ Jannomag: soll deiner in den Sleepmode oder nicht? Wenn nein wird er sich im WLAN vielleicht reconnecten können müssen? Falls das Signal abbrechen sollte. Das ist die Zeit die eben dauert. Dafür gibts EventHandler. https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/generic-examples.html Wünsche maximale Erfolge.

Kein Deepsleep, dann könnte es evtl. zu lange dauern. Sinn der Sache ist bei mir, dass ich beim Zocken oder Musik hören das Telefon sehe, wie es leuchtet oder mein SIP Client bimmelt, so schnell wie möglich, bevor der eilige Paketbote wieder wegrennt.

Im Forum, wo du den Code her hast, hat es einer hinbekommen mit:

---setup---
[...]
  WiFi.persistent(true);
  Udp.begin(sipport);
  aSip.Init(sipip, sipport, ip, sipport, sipuser, sippasswd, 15);
  //aSip.Dial(sipdialnr, sipdialtext);
}
int deepSleepDelay=0;  

void loop(void)
{
  int packetSize = Udp.parsePacket();
  if (packetSize>0)
    {
    caSipIn[0]=0;
    packetSize=Udp.read(caSipIn, sizeof(caSipIn));
    if (packetSize>0)
      {       
      caSipIn[packetSize]=0;
      }
    }
    aSip.HandleUdpPacket((packetSize>0) ? caSipIn : 0 );
    if (!aSip.IsBusy() && deepSleepDelay==0)
    deepSleepDelay=millis();
    if (deepSleepDelay && (millis()-deepSleepDelay)>500)
    {}


// 0, da Platine schon fertig...
    if (digitalRead(0)==LOW){
    aSip.Dial("**9", "KLINGEL!");
    }
    
}

Das funktioniert auch. Ich könnte jetzt ja noch im Loop einbauen, dass wenn die Verbindung weg ist, er reconnecten oder sich resetten soll.

Doc_Arduino: Hallo,

@ wapjoe: freut mich. :)

Mich auch, danke! :)

Jetzt muss ich noch rausfinden, wie der Anruf beim Klingeln an der Tür initialisiert werden kann. Aber das eilt nicht und dann noch nicht fertig sein. Geiles Projekt, aber ein anderes wartet vorher. ;)

@ Jonnamag: bitte keinen Softwarereset ala jump 0 machen. Das ist grober Unfug. Wurde im Forum schon einmal weit und breit diskutiert. Maximal wäre der saubere Umweg über den Watchdog denkbar. Halte ich jedoch für unnötig. Der "Connect-Handler" muss das behandeln können.

@ wapjoe: wenn du eine herkömmliche Klingel mit Klingeltrafo hast, haste hier eine Idee dazu. Beide Schaltungen sind identisch. Hat sicherlich einer vom anderen abgeschaut.

https://www.heise.de/select/ct/2017/17/1502995489716437 https://www.reichelt.de/magazin/how-to/smarte-tuerklingel

Dabei fällt mir ein das ich die erste WLAN Klingel mit Raspi laut dem c't Artikel nachgebaut hatte. Das war aber übelster Sackgang. "Tausende" Dateien mussten bearbeitet und die Scripte aufgerufen werden. Dann kam jemand auf die Idee mit dem ESP, aber immer noch mit TR064. Bis irgendwann jemand auf den anderen Trichter kam ohne TR064. Guter Mann. :)