Christion T. hat neulich im Beitrag: Beitrag "Türklingel per ESP32 (WLAN, SIP) an Fritzbox" den Code für seine ESP Klingel veröffentlicht. Das hat mich dazu gebracht auch mal wieder etwas in dieser Richtung zu machen. Allerdings benötige ich den Code um per Sip die Fritzbox klingeln zu lassen ausdrücklich nicht in Verbindung mit dem ESPxxx. Bisher mache ich das über einen Asterisk-Server der auf meinem NAS läuft. Nun soll so etwas in den Code meines selbst geschriebenen Servers für die Heimautomation. Allerdings ist Christians Code zu sehr von der ESP Infrastruktur abhängig. Das Anzupassen kommt einer Neuentwicklung gleich. Das habe ich dann gemacht. Im angehängten Code ist eine C++ Classe Sip enthalten die bis auf die Funktionen Sip::SendUdp(), Sip::Random(), Sip::Millis()und Sip::MakeMd5Digest() Plattform unabhängig ist. Entwickelt habe ich das als Windows-Konsolen Programm. Das kann ich aber aus lizensrechtlichen Gründen nicht veröffentlichen. Deshalb hier das ganze als Arduino ino für den Esp8266. Das ist wohl gemerkt kein fertiges Projekt für ahnungslose Bastler. Es ist nur als Demo zu verstehen. Nach dem Reset und Connecten an die Fritzbox wählt der ESP die festgelegte Nummer und legt sich dann nach 15s in den Tiefschlaf. Wer etwas sinnvolles damit machen will, muss den Rest dann noch selbst entwickeln. Ich selbst nutze die Arduino IDE nicht, sondern eine makefile Umgebung wie ich sie heir schon mal beschrieben haben. Beitrag "Re: ESP32 & ESP8266 etc ohne Arduino?" Der gesamte Code der Sip-Klasse kommt ohne dynamischen Speicher aus. Es wird nur ein char Buffer für das Zusammenbauen der UDP Packete benötigt, den ich selbst nicht in der Klasse halte. Zu beachten ist weiterhin, dass sich die Klasse die Konfigurationsdaten die in der init-Funktion übergeben werden nicht buffert, die Pointer müssen deshalb über die Laufzeit gültig bleiben. Bei meiner Fritzbox kommt es oft vor, dass das erste UDP-Packet irgendwie verloren geht. Im Gegensatz zu Christians Code versuche ich das INVITE zu wiederholen wenn die Fritzbox nicht antwortet.
Danke, nachdem auskommentieren/einkommentieren des return-werts in der Sip::Random() Funktion wegen folgendem Fehler :
1 | sipdial.ino: In member function 'uint32_t Sip::Random()': |
2 | |
3 | sipdial:471: error: 'secureRandom' was not declared in this scope |
4 | |
5 | return secureRandom(0x3fffffff); |
6 | |
7 | |
8 | exit status 1 |
9 | 'secureRandom' was not declared in this scope |
funktioniert dein Aduino-Sketch auf meiner NodeMCU. Auch wenn ich noch hier drüber gestolpert bin und der Fehler anscheinend im Fritz!OS 6.83 meiner 7390 immernoch nicht behoben ist... : https://www.heise.de/forum/heise-online/News-Kommentare/AVM-veroeffentlicht-Fritz-OS-6-60/Seit-6-60-keine-Anmeldung-von-SIP-Nebenstelle-moeglich/posting-28864356/show/ Grüße Marc
Marc G. schrieb: > nachdem auskommentieren/einkommentieren des return-werts in der > Sip::Random() Funktion wegen folgendem Fehler : Du solltest mal deine Entwicklungsumgebung aktualisieren. Aktuell ist Arduino ESP bei 2.4. Die Funktion war auch in 2.3 schon drin. Du solltes aber besser nicht das auskommentierte Standard rand() verwenden ohne einen srand() mit einem zufälligen Wert. Anderenfalls erzeugt die rand() Funktion nach jedem Reset die gleichen Zahlen, was bei dieser Anwendung nicht besonders gut ist. Hier die Funktion wie sie in neueren Esp-Arduinos enthalten ist und die Hardware des ESP8266 nutzt:
1 | #define RANDOM_REG32 ESP8266_DREG(0x20E44)
|
2 | long secureRandom(long howbig) { |
3 | if(howbig == 0) { |
4 | return 0; |
5 | }
|
6 | return RANDOM_REG32 % howbig; |
7 | }
|
Marc G. schrieb: > Auch wenn ich noch > hier drüber gestolpert bin und der Fehler anscheinend im Fritz!OS 6.83 > meiner 7390 immernoch nicht behoben ist... : Damit hat mich AVM auch schon zur Weißglut gebracht. Erst gingen kurze Passwörter nicht mehr, in aktuellen Firmware-Versionen auch keine kurzen Usernamen mehr. Es gab mal einen Stand, da musste man alle! Telefongeräte löschen, danach die Fritzbox zwingend neu starten und erst danach konnte man sie wieder einrichten. Das war bei mir zu Hause und bei beiden Fritzboxen in der Firma nachvollziehbar.
Jürgen L. schrieb: > Du solltest mal deine Entwicklungsumgebung aktualisieren. Aktuell ist > Arduino ESP bei 2.4. Die Funktion war auch in 2.3 schon drin. Ja das ist bestimmt der Grund. Es war eine alte Arduino 1.6.8 IDE mit der ESP 2.0 Bibliothek im Einsatz Danke schön Marc
:
Bearbeitet durch User
Vielen Dank für das schön schlanke Programm. Bei mir hat es - nach Anpassen auf meine Umgebung - sofort funktioniert. Ich wußte gar nicht, daß man das SIP-Protokoll auch mit Udp machen kann. Damit geht es m.E. viel einfacher als mit Tcp. Harald
Eigentlich ist bei Sip UDP Standard. Das macht es auch immer etwas komplizier wenn Router dazwischen sind. Das Programm ist deshalb relativ schlank, weil ich nicht versucht habe das Protokoll komplett zu implementieren. Es ist auch nicht angedacht irgendwelche Audio-Daten zu verarbeiten. Allerdings kann man immerhin die Tastencodes des angerufenen Telefons abgreifen wenn man das will.
Vielen Dank für die Demo, es funktioniert bei mir wie geplant. Ich bin relativ unerfahren in der Progarmmierung in C, deswegen bitte ich etwas um Verständnis für mein "Unverständnis" Ich möchte ich einen Sip-Dial bei einem Druck eines Tasters auslösen, der ESP8266 soll anschließend nicht in den DeepSleep fallen sondern auf die nächste Betätigung warten. Hat jemand einen Tipp für mich an welcher Stelle ich die Aktion auf die Tasterbetätigung einfüge? Das ganze muss ja auch im loop funktionieren so dass ständig der Pin abgefragt wird. Obi
Hallo , Ich finde die sip Türklingel echt gut habe aber Probleme , vielleicht kann mir jemand helfen ?. ich würde gerne den klingel Aufruf per void aufrufen beispiel : wenn Taster gedrückt dann 3 Sekunden klingeln. ich hab es versucht zu machen , hab es aber nicht hinbekommen. wenn ich den loop in einen Unterprogramm packe , klingelt es unendlich. leider verstehe ich das Programm nicht. Bitte um Hilfe ! Danke.
Endlich ! Hab ich es hinbekommen , ich habe alle seriellen Debug ausgaben entfernt. abfrage zwei taste , wenn taste gedrückt ---> meldung Kein Deep Standby viel Spass damit Grüße Nicki
Hallo, eine Frage dazu. Die Fritzbox wird hier rein per WLAN kontaktiert? TR064 muss in der Fritzbox nicht aktiviert werden? Oder doch? Danke im voraus.
Der ESP wird hier als IP-Telefoniegerät an der Fritzbox angemeldet. Sonst muss da nichts weiter gemacht werden Marc
Marc G. schrieb: > Der ESP wird hier als IP-Telefoniegerät an der Fritzbox angemeldet. > Sonst muss da nichts weiter gemacht werden Kann das eine Einfallstor für Hacker sein? Siehe Artikel auf Heide.de: https://www.heise.de/newsticker/meldung/Bundesnetzagentur-stoppt-Abzocke-durch-Router-Hacking-4282164.html
Marc G. schrieb: > Der ESP wird hier als IP-Telefoniegerät an der Fritzbox angemeldet. > Sonst muss da nichts weiter gemacht werden > > Marc aha, sehr schön. Weil das Bsp. aus der c't 17/2018 nutzt TR064 und das muss erst aktiviert werden. Mit Raspi c't 17/2017 hatte ich es damals zum laufen bekommen.
:
Bearbeitet durch User
Hallo, tolles Projekt ! Welchen 8266 habt Ihr denn dafür genommen und was als Akku und wie lange hält der ? Und wie lange dauert es, bis vom Klingeln am Tor dann die Telefone klingeln ? Grüße Christian
Hallo, ich bin noch am Überlegen, ob ich das Ganze mit einem Pi oder ESP machen soll. Ich möchte allerdings zwei Klingel (Zweifamilienhaus) unterstützen.# Dazu bräuchte ich dann aber 2 ESPs, oder? Gruß Michael
...noch eine Frage: Wie wird der EPS denn geschaltet ? Nur mit dem klingeltaster an den Akku wird ja nicht reichen oder ? Ich würde den gerne am Tor draussen anbringen, weil die Funkklingel dort funktioniert meist nicht
...ich beantworte meine Fragen mal einfach selber, nachdem ich das ans Laufen bekommen habe: ESP an Akku, Klingeltaster an GND und Reset. Zeit zwischen drücken des Tasters und Anfang Klingeln der Telefone nur ca. 1s !!! Sehr cool !!!
Mir gefällt die hier vorgestellt Lösung sehr gut, zusammen mit der Schaltung aus dem heise-Artikel funktioniert sie nach Eingabe der Zugangsdaten ohne Änderungen auf anhieb. Allerdings hört das klingeln nicht auf, wenn man den ESP komplett vom Strom trennt, ohne das Ende des 15 Sekunden Programmzyklus abzuwarten. Die Fritzbox klingelt allein mit ausgeschaltetem ESP munter weiter. Gibt es dafür eine passende Einstellung in der Fritzbox oder kann man den abgesetzten Befehl anpassen. Ich nutze den Rundruf (const char *sipdialnr = "**9";) als Klingelzeichen. Zum Thema Sicherheit: Man kann in der Fritzbox dem ESP dem Zugang vom oder ins Internet verbieten. Man kann in der SIP-Telefon-Konfiguration in der Fritzbox eine leere/keine Nummer für eingehende Nummern zuweisen und man kann alle ausgehenden Nummern abwählen. Der interne Ruf "**9" funktioniert weiterhin. Damit ist der ESP vor Einflüssen aus der Ferne relativ sicher. Im ESP ist nur das WLAN-Passwort und die Sipzugangsdaten gespeichert. Anders als bei der Heise-Klingel-Anleitung (https://shop.heise.de/katalog/esp-uberallklingel), bei der zusätzlich das kritische Admin-Passwort auf dem ESP unverschlüsselt gespeichert werden muss.
Nochwas: Man kann in der Fritzbox eine "IP-Türsprechanlage" einrichten. Die unterstütz zum einen mehrere Klingeln, zum anderen kann man eine Code festlegen, mit dem sich die Türen öffnen lassen würden. Außerdem ist bereits die Telefonierfunktion in der Standardkonfiguration begrenzt. Leider scheint das unaufhörliche Klingeln bei spontaner Stromunterbrechung ein Problem von SIP oder der Fritzbox zu sein. Auch mit einem Softwarephone, bei dem plötzlich die Netzverbindung getrennt wird, stoppt das Klingeln nicht von allein.
Moin, es funktioniert im Prinzip auf Anhieb! :) Sehr toll, danke für diese Einführung. Was nicht funktioniert, ist der Text den man übergibt. An allen Endgeräten( DECT, ANALOG, WLAN ) erscheint im Display wahlweise die "**621" oder "ESP8266_TEST", in keinem Fall ist die von mir im Code eingegebene Nachricht "TESTER" zu lesen. In deinem Protokoll, stellst du dies so dar: AddSipLine("From: \"%s\" <sip:%s@%s>;tag=%010u", pDialDesc, pSipUser, pSipIp, tagid); Sonst funktioniert ja alles, dennoch frage ich mich -> wieso geht das nicht und wo is der Text geblieben? Ich kann den ja nirgends abfassen, theoretisch könnte/müsste man den ja dann aus Dial entfernen, wenn der eh nichts bringt... Oder übersehe ich da was? Grüße :)
Im DECT-Handteil werden die Namen so angezeigt, wie sie in der Fritzbox hinterlegt sind. Bei dir ist das wahrscheinlich "**621" [kein Name] oder "ESP8266_TEST". Der Sip-Name wird angezeigt, wenn dein Empfangsgerät die Sip-Daten auswertet. Ist bei mir mit einem Soft-Phone (PhoneLite) auf dem PC so, das wie der ESP als SIP-Telefon eingerichtet ist.
Ich habe eine kleine Platine entwickelt die in ein Siedle Haustelefon HT-511 passt. Wer Lust hat, kann die Schaltung gerne nachbauen. Die Schaltung besteht aus einem AC/DC Netzteil das die 12V Wechselspannung in ca. 3,3V Gleichspannung zur Versorgung des ESP8285 ESP-1 Moduls wandelt. Außerdem sitzen zwei AC-Optokoppler auf der Platine zur Abfrage von zwei Klingeltastern (getrennte Eingänge). Aufgrund der besseren Reichweite habe ich ein ESP8285 ESP-1 WLAN Funkmodul verwendet. Die Versorgungsspannung habe ich an die Klemmen b und c des Siedle Haustelefons HT-511 angeschlossen. Den Eingang habe ich parallel an das Läutwerk (Summer) am Siedle Haustelefon HT-511 geklemmt. Den Code habe ich von @Nicki verwendet: https://www.mikrocontroller.net/attachment/371951/sip_klingel_ND.ino Funktioniert prima :-)
Hi, hast du zufällig noch eine Platine übrig? Würde mich sehr interessieren.
Andreas G. schrieb: > Hi, hast du zufällig noch eine Platine übrig? Würde mich sehr > interessieren. Ja, hab ich. Du hast eine Nachricht von mir bekommen. Grüße :)
Ich habe den Code von Nicki erweitert und eine Türöffner-Funktion mit implementiert. Wenn man einen Anruf von der Tür entgegen nimmt, wird das Drücken einer beliebigen Taste am Telefon jetzt erkannt. Im SIP INFO-Paket steht die gedrückte Taste direkt im Klartext. Das Parsen und das Auslösen einer Aktion der Taste wurde im Code hinzugefügt. Im Beispiel verwende ich als Ausgang GPIO14 für den Türöffner und die Taste "6" am Telefon zum Auslösen des Türöffners. Die Einschaltzeit für den Türöffner lässt sich ebenfalls einstellen.
Vielleicht hilft es jemandem - Ich versuche den Sketch auf ESP32 zu portieren (mit beschränktem Vorwissen) und nutze dabei die aktuelle (Mai 2019) Arduino IDE samt den aktuellen ESP32 1.0.1 Libraries. Mir gelang es leider nicht, die originale Zeilen // generate a 30 bit random number uint32_t Sip::Random() { // return ((((uint32_t)rand())&0x7fff)<<15) + ((((uint32_t)rand())&0x7fff)); return secureRandom(0x3fffffff); } gegen den ESP32 kompiliert zu bekommen, denn ich finde keine passende Library, die secureRandom() per #include für den ESP32 nutzbar macht. Der ESP32 hat aber einen HW RND Generator, den man per esp_random(void) nutzt. Und so wird daraus: // generate a 30 bit random number uint32_t Sip::Random() { return esp_random(); } Damit kommt der Compiler jedenfalls klar. Mein Bitte: Kann einer der Wissenden hier bestätigen, dass esp_random() hier richtig eingesetzt ist? Ich freue mich auch über Hinweise, wie ich secureRandom() auf dem ESP32 doch noch ans Fliegen bekomme. Danke vorab - Roger
Beim Portieren des Sketches auf ESP32 scheitere ich mangels C++ Kenntnissen an folgernder Fehlermeldung bezüglich Typkonvertierung. Kann mir da jemand auf die Sprünge helfen? Wo gleiche ich mit dem wenigsten Aufwand und Risiko den Typ an? In der Definition, im Aufruf und welchen Typ nehme ich? Danke, Roger --------------------------------------------------------------------
1 | /Volumes/data/Meine Geräte/Arduino UNO/Roger Test/ESP32_SIP_Tuerklingel/ESP32_SIP_Tuerklingel.ino: In member function 'int Sip::SendUdp()': |
2 | ESP32_SIP_Tuerklingel:439:13: error: invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive] |
3 | Udp.write(pbuf, strlen(pbuf)); |
4 | ^ |
5 | In file included from /Users/roger/Library/Arduino15/packages/esp32/hardware/esp32/1.0.1/libraries/WiFi/src/WiFi.h:39:0, |
6 | from /Volumes/data/Meine Geräte/Arduino UNO/Roger Test/ESP32_SIP_Tuerklingel/ESP32_SIP_Tuerklingel.ino:1: |
7 | /Users/roger/Library/Arduino15/packages/esp32/hardware/esp32/1.0.1/libraries/WiFi/src/WiFiUdp.h:65:10: note: initializing argument 1 of 'virtual size_t WiFiUDP::write(const uint8_t*, size_t)' |
8 | size_t write(const uint8_t *buffer, size_t size); |
9 | ^ |
10 | Mehrere Bibliotheken wurden für "WiFi.h" gefunden |
11 | Benutzt: /Users/roger/Library/Arduino15/packages/esp32/hardware/esp32/1.0.1/libraries/WiFi |
12 | Nicht benutzt: /Applications/Arduino.app/Contents/Java/libraries/WiFi |
13 | Bibliothek WiFi in Version 1.0 im Ordner: /Users/roger/Library/Arduino15/packages/esp32/hardware/esp32/1.0.1/libraries/WiFi wird verwendet |
14 | exit status 1 |
15 | invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive] |
:
Bearbeitet durch User
Das hier könnte funktionieren:
1 | Udp.write((uint8_t *) pbuf, strlen(pbuf)); |
Sauberer wäre es, wenn pbuf vom Typ uint8_t* wäre, aber dann würde der Aufruf von strlen natürlich scheitern ...
Roger Z. schrieb: > // generate a 30 bit random number > uint32_t Sip::Random() > { > // return ((((uint32_t)rand())&0x7fff)<<15) + > ((((uint32_t)rand())&0x7fff)); > return secureRandom(0x3fffffff); > } > wenn nichts hilft dann das auskommentierte benutzen:
1 | return ((((uint32_t)rand())&0x7fff)<<15) + ((((uint32_t)rand())&0x7fff)); |
dann solltest du aber in der setup() folgenden Code anpassen:
1 | ...
|
2 | int i=0; |
3 | for (i=0; i<100; i++) |
4 | {
|
5 | if (WiFi.status() == WL_CONNECTED) |
6 | break; |
7 | delay(100); |
8 | Serial.print("."); |
9 | }
|
10 | ...
|
11 | |
12 | ändern in: |
13 | |
14 | int i=0; |
15 | for (i=0; i<10000; i++) |
16 | {
|
17 | rand(); |
18 | if (WiFi.status() == WL_CONNECTED) |
19 | break; |
20 | delay(1); |
21 | if ((i%100)==0) |
22 | Serial.print("."); |
23 | }
|
Was für ein Random-Wert da am Ende herauskommt ist völlig egal. Nur wenn es immer der gleiche ist kommt die Fritzbox durcheinander. Da rand() nach dem Neustart aber gleiche Werte liefert ist das ein Problem. Mit der Änderung von oben wird der Wert davon abhängig wie lange der WLAN-Connect dauert. Das ist schon mal besser als nichts.
Noch ein Hinweis. Den ESP32 an dieser Stelle zu benutzen mach nur Sinn, wenn der ESP32 nicht! in den Tiefschlaf geht. Die Zeit bis sich der ESP32 nach dem Reset wieder im WLAN befindet ist deutlich länger als beim ESP8622. Für den Fall, dass sich der ESP32 dauerhaft im Betriebsmodus befindet geht das auch mit dem rand() ohne die Sonderbehandlung am Anfang, da dann der Zufallsgenerator nicht jedes mal mit dem Reset neu initialisiert wird.
Hallo, das hört sich alles sehr gut an, ich interessiere mich für deine Platine, hast Du noch eine übrig. Grüße
Aloha Freunde, Ich hab mir das jetzt lauffähig für den ESP32 (In Verbindung mit einen Mikrofon-Modul) umgebogen. Sobald meine 1970er Rappel-Glocke rappelt, reagiert das Mikrofon und der ESP32 wählt **9. Soweit alles bestens. Allerdings lässt der ESP32 so lange Klingeln bis jetzt abhebt. Hat jemand eine Idee, wie man eine Art Timeout einbauen kann, das buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { Udp.begin(sipport); aSip.Init(sipip, sipport, ip, sipport, sipuser, sippasswd, 15); aSip.Dial(sipdialnr, sipdialtext); // Dial digitalWrite(ledPin, HIGH); // Mikrofon schaltet HIGH } else { // nichts machen ... digitalWrite(ledPin, LOW); } zB nach 10-15 Sekunden ESP-Seitig abgebrochen wird?
Um zu sehen wo das bei dir klemmt musst du schon mehr Code posten. Die 15 am Ende von aSip.Init ist die Zeit nach dem aufgelegt wird. Das kann aber nur funktionieren wenn in einer Schleife wie im Originalprogramm weiterhin ständig das aSip.HandleUdpPacket() gerufen wird solange bis aSip.IsBusy() true liefert und darüber hinaus noch ein paar Sekunden. Im Beispiel 2. Ich denke irgenwo da hast du was falsch gemacht.
Beitrag #5941086 wurde vom Autor gelöscht.
temp schrieb: > musst du schon mehr Code posten Stimmt. Ich wusste doch, das ich etwas vergessen habe :-) Habe das Konstrukt gerade vor mir liegen, wenn ich auf das Mikro tippe, geht die LED vom ESP auf HIGH und dial wird eingeleitet. Nur halt das Stoppen klappt (noch) nicht.
Wenn du das Dial auch tausendfach aufrufst brauchst du dich nicht wundern dass deine Fritzbox durcheinander kommt.
1 | //int deepSleepDelay=0;
|
2 | void loop(void) |
3 | {
|
4 | int packetSize = Udp.parsePacket(); |
5 | if (packetSize>0) |
6 | {
|
7 | caSipIn[0]=0; |
8 | packetSize=Udp.read(caSipIn, sizeof(caSipIn)); |
9 | if (packetSize>0) |
10 | {
|
11 | caSipIn[packetSize]=0; |
12 | #ifdef DEBUGLOG
|
13 | IPAddress remoteIp = Udp.remoteIP(); |
14 | Serial.printf("\r\n----- read %i bytes from: %s:%i ----\r\n", (int)packetSize, remoteIp.toString().c_str(), Udp.remotePort()); |
15 | Serial.print(caSipIn); |
16 | Serial.printf("----------------------------------------------------\r\n"); |
17 | #endif
|
18 | }
|
19 | }
|
20 | aSip.HandleUdpPacket((packetSize>0) ? caSipIn : 0 ); |
21 | |
22 | buttonState = digitalRead(buttonPin); |
23 | |
24 | // !!!!!!!! Das ist eine Endlos-Schleife oder mit anderen Worten solange
|
25 | // dein Pin High ist wird das Init und Dial so oft ausgeführt wie der ESP
|
26 | // kann.
|
27 | // Ich hab das mal mit einer statischen Variablen geblockt aber nicht
|
28 | // getestet
|
29 | static int bInDial=0; |
30 | |
31 | if (buttonState == HIGH) |
32 | {
|
33 | digitalWrite(ledPin, HIGH); |
34 | if (!bInDial) |
35 | {
|
36 | Udp.begin(sipport); |
37 | aSip.Init(sipip, sipport, ip, sipport, sipuser, sippasswd, 2); |
38 | aSip.Dial(sipdialnr, sipdialtext); // Dial |
39 | bInDial=1; |
40 | }
|
41 | }
|
42 | else
|
43 | {
|
44 | if (!aSip.IsBusy()) |
45 | bInDial=0; |
46 | |
47 | // nichts
|
48 | digitalWrite(ledPin, LOW); |
49 | }
|
50 | }
|
Geniale Sache! Auf der FritzBox ein weiteres IP-Telefon eingerichtet, die notwendigen Strings in der ino Datei angepasst und in einen WeMos D1 mini geflasht -> funktioniert. So erspart man es sich gleich mit einer runden Himbeere auf Spatzen zu schießen;) Vielen Dank für die ESP Portierung und Implementierung und das Veröffentlichen des Codes. Reset bis Anruf in ca. 1 bis 2s, Top.
Hallo, möchte meinen Türöffner mit einem Rückruf ansteuern, bräuchte dazu noch einen Lösungsansatz. Bin noch ein absoluter Anfänger in C, wäre um jede Hilfe dankbar. Grüße Manuel
Hallo Leute, folgendes Problem: Ich habe eine Klingelschaltung mit dem ESP8266 gebaut. Der klingt sich in mein WLAN ein und klingelt die Telefone an. Das ist das Programm von J.Liegner aus 2018. Eigentlich funktioniert das auch gut. Es gibt nur einen "Haken", wo ich nicht weiter weiss. Die Schaltung wird über einen Reed-Relais mit "Selbsthaltung" aus dem ESP gesteuert. Läuft also so: 1.Klingeltaster wird gedrückt, 2. Das reicht für kurze Zeit zum Start des ESP.. 3. Das Programm läuft an und hält das Reed Relais. 4. Jetzt "klingelt" das Programm meine Telefone an. 5. Nach einer Zeit (bei mir 2 Minuten) fällt nach Inaktivität das Relais ab. Jetzt zum Problem: Es werden etwa 500 Zeilen mit Definitionen des Programms etc. Verbracht, bis das eigentliche Setup kommt, wo ich den Ausgang sinnvoll setzen kann (die Selbsthaltung). Das ist oft zu lang, wenn nur kurz der Klingelknopf gedrückt wird. Wenn ich ganz vorne einen Loop (z.b. Start) einfüge wo ich das mache, fällt das Relais beim Verlassen des loops sofort ab ;( Hat jemand eine Idee? LG Manfred
Hallo Manfred, poste doch einfach mal deinen Source-Code um das ganze zu verstehen.
...eigentlich kommt der Taster ja an Reset, wenn der gedrückt wird, resettet der ESP, klingelt die Telefone an und nach der vordefinierten Zeit geht der in den Deepsleep Modus. Ein Relais brauchst du da nicht...
Moin @Manfred Findest Du Cross-posting toll oder uns, auf der anderen Seite des Universum, so schlimm? Auch hier solltest Du den fragen der Anderen nachkommen - wenn Du Dich so zeigst, wie bei 'uns' - wird Das hier ebenfalls nicht sonderlich gut für Dich ausgehen. Erschwerend kommt hinzu, daß Du hier sogar noch einen fremden Thread kaperst - aber so ist das Volk wohl heute. Ach ja ... Cross-Post auf Arduino.cc https://forum.arduino.cc/index.php?topic=648475.msg4373829#msg4373829
stieneker@web.de schrieb: > Jetzt zum Problem: > Es werden etwa 500 Zeilen mit Definitionen des Programms etc. Verbracht, > bis das eigentliche Setup kommt, wo ich den Ausgang sinnvoll setzen kann > (die Selbsthaltung). Das ist völliger Schwachsinn. Selbst wenn in der C++ Datei ein paar Millionen Zeilen davor stehen hat das überhaupt nichts zu sagen. Was der ESP vor dem setup() macht ist zuerst vom reinen Initalisierunsgcode abhängig der für den ESP nötig ist um überhaupt erst mal bis zur main() Methode zu kommen. Beim ESP gehört (m.W.n) auch dazu den Code aus dem externen Flash erst mal in den RAM zu kopieren. Das kann sicher etwas dauern. Sämtliche C++ Kontruktoren werden auch vor der main() gerufen. Was der Arduino-Code ab main() bis zum setup() macht kannst du in den Arduino Quellen nachlesen. Der her verlinkte Code benötigt jedenfalls weniger als 1µs für die Intitialisiering von einigen wenigen variablen. Eventuell könnte es helfen eine spezielle C++ Klasse zu schreiben in deren Konstruktor der Pin für die Selbsthaltung gesetzt wird. Der GPIO-Port muss dazu sicher auch erst mal initialisiert werde. Und das alles mit der ESP-Api und nicht mit Arduino, das dürfte zu dem Zeitpunkt noch nicht initialisiert sein. Ob das jetzt zeitlich was bringt kriegst du aber nur mit probieren raus. Die Hardware kann dir auch einen Strich durch die Rechnung machen. Der ESP benötigt ja nicht unbedingt kleine Elkos, die müssen auch erst mal ab Tastendruck geladen werden.
Also, wie beschrieben, Reset drücken, ca. 1s später klingeln die Telefone für ca. 15s, bzw. Bis einer abnimmt, dann deepsleep bis zum nächsten Köingelknopf (tatsächlich der Resettaster) drücken. Flutscht wie doof, out of the box aus dem Thread(code)... Grüsse Christian
Klasse Projekt, vielen Dank an Jürgen und alle Beteiligten! Ein Problem habe ich dabei aber: wird die Klingel und damit der Reset mehrmals betätigt innerhalb der 15s, dann klingelt die Fritzbox ewig! Gibts da eine Lösung? Danke und Grüße, Nico
Eventuell den Reset-Pin mit einem GPIO-Pin auf High klemmen. Die Widerstände hängen natürlich von deinem ESP-Board und dessen Reset-Beschaltung ab.
Hi, ich ahbe das original Script genommen und auf einen ESp geflasht. Funktioniert grundsätzlich. Leider klingelt das Ding immer mal ohne das der Taster gedrückt wird. Und ab und zu regaiert es nicht. Nach aab und wieder anstöpseln des Stroms geht es dann erstmal wieder. Hat jemand von euch auch noch dieses Problem? Ich habe es mit dauerstrom, usb netzteil und mit Batteriepack versucht. Danke und Gruß Michael
Hallo Michael, poste mal den Aufbau deiner Schaltung. Gruß Alois
Aufbau der Schaltung.... hmm. Ich bin elektronisch nicht mit viel Wissen bestückt. Falls das folgende nicht reicht, bitte genauer erklären was du brauchst :) Ich habe einfach einen Anpro ESP8266 microcontroller ESP-12E WiFi bestellt, mir Arduino runtergeladen und das Ding geflasht. Der Klingeldraht überbrückt G und D6. Geändert im Script habe ich nur: if (digitalRead(12) == LOW) { //aSip.Dial("**9", "GPIO D6 !"); aSip.Dial("**610", "Klingel Tor"); } wie gesagt geht das eigentlich ganz gut. Nur Ausfälle und Klingeln ohne Tasterdruck ab und zu.
Hallo Michael, mit Klingeldraht meinst Du die 9 - 12 Volt Klingelspannung vom Klingeltaster oder ist der Taster direkt zwischen GND und dem Eingang D6 angeschlossen (potential getrennt)? Gruß Alois
Michael R. schrieb: > if (digitalRead(12) == LOW) { > //aSip.Dial("**9", "GPIO D6 !"); > aSip.Dial("**610", "Klingel Tor"); > } Und das in der loop()? Wundert mich jetzt dass da überhaupt was geht. Aber selbst wenn man wenig Ahnung von Elektronik hat sollte man seinen Kopf einschalten oder es lassen.
Das ist der Original code von Jürgen Liegner. Nur meine Daten eingetragen und die Nummer anstatt dem Sammelruf **9 in meine ganz unten im Script verändert.
1 | /* ====================================================================
|
2 | |
3 | Copyright (c) 2018 Juerge Liegner All rights reserved.
|
4 | |
5 | Redistribution and use in source and binary forms, with or without
|
6 | modification, are permitted provided that the following conditions
|
7 | are met:
|
8 | |
9 | 1. Redistributions of source code must retain the above copyright
|
10 | notice, this list of conditions and the following disclaimer.
|
11 | |
12 | 2. Redistributions in binary form must reproduce the above copyright
|
13 | notice, this list of conditions and the following disclaimer in
|
14 | the documentation and/or other materials provided with the
|
15 | distribution.
|
16 | |
17 | 3. Neither the name of the author(s) nor the names of any contributors
|
18 | may be used to endorse or promote products derived from this software
|
19 | without specific prior written permission.
|
20 | |
21 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND
|
22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
24 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
27 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
28 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
29 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
30 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
31 | SUCH DAMAGE.
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | ====================================================================*/
|
37 | |
38 | #include <ESP8266WiFi.h> |
39 | #include <WiFiUdp.h> |
40 | #define DEBUGLOG
|
41 | |
42 | //------------------------------------------------
|
43 | // configuration with fix ip
|
44 | //------------------------------------------------
|
45 | |
46 | // wlan param
|
47 | const char* ssid = "xxxxxx"; |
48 | const char* password = "xxxxxxxxxxxxxx"; |
49 | |
50 | // sip params
|
51 | const char *sipip = "192.168.178.1"; // IP der FritzBox |
52 | int sipport = 5060; // Port so lassen |
53 | const char *sipuser = "xxxxxxxxxxx"; // Benutzername SIP-Call FritzBox |
54 | const char *sippasswd = "xxxxxxxxxxx"; // Passwort SIP-Call FritzBox |
55 | |
56 | // dial params
|
57 | const char *sipdialnr = "**701";////unten auskomentiert |
58 | const char *sipdialtext = "Türklingel";////unten auskomentiert |
59 | |
60 | // network params
|
61 | const char *ip = "192.168.178.150"; // Eigene IP vom ESP |
62 | const char *gw = "192.168.178.1"; //Gateway |
63 | const char *mask = "255.255.255.0"; //Subnetmask |
64 | const char *dns = "192.168.178.1"; // DNS |
65 | //------------------------------------------------
|
66 | |
67 | //#define DEBUGLOG
|
68 | WiFiUDP Udp; |
69 | |
70 | /////////////////////////////////////////////////////////////////////////////////////////////////////
|
71 | //
|
72 | // hardware and api independent Sip class
|
73 | //
|
74 | /////////////////////////////////////////////////////////////////////////////////////////////////////
|
75 | |
76 | char set = 0; |
77 | |
78 | class Sip |
79 | {
|
80 | char *pbuf; |
81 | size_t lbuf; |
82 | char caRead[256]; |
83 | |
84 | const char *pSipIp; |
85 | int iSipPort; |
86 | const char *pSipUser; |
87 | const char *pSipPassWd; |
88 | const char *pMyIp; |
89 | int iMyPort; |
90 | const char *pDialNr; |
91 | const char *pDialDesc; |
92 | |
93 | uint32_t callid; |
94 | uint32_t tagid; |
95 | uint32_t branchid; |
96 | |
97 | int iAuthCnt; |
98 | uint32_t iRingTime; |
99 | uint32_t iMaxTime; |
100 | int iDialRetries; |
101 | int iLastCSeq; |
102 | void AddSipLine(const char* constFormat , ... ); |
103 | bool AddCopySipLine(const char *p, const char *psearch); |
104 | bool ParseParameter(char *dest, int destlen, const char *name, const char *line, char cq = '\"'); |
105 | bool ParseReturnParams(const char *p); |
106 | int GrepInteger(const char *p, const char *psearch); |
107 | void Ack(const char *pIn); |
108 | void Cancel(int seqn); |
109 | void Bye(int cseq); |
110 | void Ok(const char *pIn); |
111 | void Invite(const char *pIn = 0); |
112 | |
113 | uint32_t Millis(); |
114 | uint32_t Random(); |
115 | int SendUdp(); |
116 | void MakeMd5Digest(char *pOutHex33, char *pIn); |
117 | |
118 | public:
|
119 | Sip(char *pBuf, size_t lBuf); |
120 | void Init(const char *SipIp, int SipPort, const char *MyIp, int MyPort, const char *SipUser, const char *SipPassWd, int MaxDialSec = 10); |
121 | void HandleUdpPacket(const char *p); |
122 | bool Dial(const char *DialNr, const char *DialDesc = ""); |
123 | bool IsBusy() { |
124 | return iRingTime != 0; |
125 | }
|
126 | };
|
127 | |
128 | Sip::Sip(char *pBuf, size_t lBuf) |
129 | {
|
130 | pbuf = pBuf; |
131 | lbuf = lBuf; |
132 | pDialNr = ""; |
133 | pDialDesc = ""; |
134 | }
|
135 | |
136 | bool Sip::Dial(const char *DialNr, const char *DialDesc) |
137 | {
|
138 | if (iRingTime) |
139 | return false; |
140 | |
141 | iDialRetries = 0; |
142 | pDialNr = DialNr; |
143 | pDialDesc = DialDesc; |
144 | Invite(); |
145 | iDialRetries++; |
146 | iRingTime = Millis(); |
147 | return true; |
148 | }
|
149 | |
150 | void Sip::Cancel(int cseq) |
151 | {
|
152 | if (caRead[0] == 0) |
153 | return; |
154 | pbuf[0] = 0; |
155 | AddSipLine("%s sip:%s@%s SIP/2.0", "CANCEL", pDialNr, pSipIp); |
156 | AddSipLine("%s", caRead); |
157 | AddSipLine("CSeq: %i %s", cseq, "CANCEL"); |
158 | AddSipLine("Max-Forwards: 70"); |
159 | AddSipLine("User-Agent: sip-client/0.0.1"); |
160 | AddSipLine("Content-Length: 0"); |
161 | AddSipLine(""); |
162 | SendUdp(); |
163 | }
|
164 | |
165 | void Sip::Bye(int cseq) |
166 | {
|
167 | if (caRead[0] == 0) |
168 | return; |
169 | pbuf[0] = 0; |
170 | AddSipLine("%s sip:%s@%s SIP/2.0", "BYE", pDialNr, pSipIp); |
171 | AddSipLine("%s", caRead); |
172 | AddSipLine("CSeq: %i %s", cseq, "BYE"); |
173 | AddSipLine("Max-Forwards: 70"); |
174 | AddSipLine("User-Agent: sip-client/0.0.1"); |
175 | AddSipLine("Content-Length: 0"); |
176 | AddSipLine(""); |
177 | SendUdp(); |
178 | }
|
179 | |
180 | void Sip::Ack(const char *p) |
181 | {
|
182 | char ca[32]; |
183 | bool b = ParseParameter(ca, (int)sizeof(ca), "To: <", p, '>'); |
184 | if (!b) |
185 | return; |
186 | |
187 | pbuf[0] = 0; |
188 | AddSipLine("ACK %s SIP/2.0", ca); |
189 | AddCopySipLine(p, "Call-ID: "); |
190 | int cseq = GrepInteger(p, "\nCSeq: "); |
191 | AddSipLine("CSeq: %i ACK", cseq); |
192 | AddCopySipLine(p, "From: "); |
193 | AddCopySipLine(p, "Via: "); |
194 | AddCopySipLine(p, "To: "); |
195 | AddSipLine("Content-Length: 0"); |
196 | AddSipLine(""); |
197 | SendUdp(); |
198 | }
|
199 | |
200 | void Sip::Ok(const char *p) |
201 | {
|
202 | pbuf[0] = 0; |
203 | AddSipLine("SIP/2.0 200 OK"); |
204 | AddCopySipLine(p, "Call-ID: "); |
205 | AddCopySipLine(p, "CSeq: "); |
206 | AddCopySipLine(p, "From: "); |
207 | AddCopySipLine(p, "Via: "); |
208 | AddCopySipLine(p, "To: "); |
209 | AddSipLine("Content-Length: 0"); |
210 | AddSipLine(""); |
211 | SendUdp(); |
212 | }
|
213 | |
214 | void Sip::Init(const char *SipIp, int SipPort, const char *MyIp, int MyPort, const char *SipUser, const char *SipPassWd, int MaxDialSec) |
215 | {
|
216 | caRead[0] = 0; |
217 | pbuf[0] = 0; |
218 | pSipIp = SipIp; |
219 | iSipPort = SipPort; |
220 | pSipUser = SipUser; |
221 | pSipPassWd = SipPassWd; |
222 | pMyIp = MyIp; |
223 | iMyPort = MyPort; |
224 | iAuthCnt = 0; |
225 | iRingTime = 0; |
226 | iMaxTime = MaxDialSec * 1000; |
227 | }
|
228 | |
229 | void Sip::AddSipLine(const char* constFormat , ... ) |
230 | {
|
231 | va_list arglist; |
232 | va_start( arglist, constFormat); |
233 | uint16_t l = (uint16_t)strlen(pbuf); |
234 | char *p = pbuf + l; |
235 | vsnprintf(p, lbuf - l, constFormat, arglist ); |
236 | va_end( arglist ); |
237 | l = (uint16_t)strlen(pbuf); |
238 | if (l < (lbuf - 2)) |
239 | {
|
240 | pbuf[l] = '\r'; |
241 | pbuf[l + 1] = '\n'; |
242 | pbuf[l + 2] = 0; |
243 | }
|
244 | }
|
245 | |
246 | // call invite without or with the response from peer
|
247 | void Sip::Invite(const char *p) |
248 | {
|
249 | // prevent loops
|
250 | if (p && iAuthCnt > 3) |
251 | return; |
252 | |
253 | // using caRead for temp. store realm and nonce
|
254 | char *caRealm = caRead; |
255 | char *caNonce = caRead + 128; |
256 | |
257 | char *haResp = 0; |
258 | int cseq = 1; |
259 | if (!p) |
260 | {
|
261 | iAuthCnt = 0; |
262 | if (iDialRetries == 0) |
263 | {
|
264 | callid = Random(); |
265 | tagid = Random(); |
266 | branchid = Random(); |
267 | }
|
268 | }
|
269 | else
|
270 | {
|
271 | cseq = 2; |
272 | if ( ParseParameter(caRealm, 128, " realm=\"", p) |
273 | && ParseParameter(caNonce, 128, " nonce=\"", p)) |
274 | {
|
275 | // using output buffer to build the md5 hashes
|
276 | // store the md5 haResp to end of buffer
|
277 | char *ha1Hex = pbuf; |
278 | char *ha2Hex = pbuf + 33; |
279 | haResp = pbuf + lbuf - 34; |
280 | char *pTemp = pbuf + 66; |
281 | |
282 | snprintf(pTemp, lbuf - 100, "%s:%s:%s", pSipUser, caRealm, pSipPassWd); |
283 | MakeMd5Digest(ha1Hex, pTemp); |
284 | |
285 | snprintf(pTemp, lbuf - 100, "INVITE:sip:%s@%s", pDialNr, pSipIp); |
286 | MakeMd5Digest(ha2Hex, pTemp); |
287 | |
288 | snprintf(pTemp, lbuf - 100, "%s:%s:%s", ha1Hex, caNonce, ha2Hex); |
289 | MakeMd5Digest(haResp, pTemp); |
290 | }
|
291 | else
|
292 | {
|
293 | caRead[0] = 0; |
294 | return; |
295 | }
|
296 | }
|
297 | pbuf[0] = 0; |
298 | AddSipLine("INVITE sip:%s@%s SIP/2.0", pDialNr, pSipIp); |
299 | AddSipLine("Call-ID: %010u@%s", callid, pMyIp); |
300 | AddSipLine("CSeq: %i INVITE", cseq); |
301 | AddSipLine("Max-Forwards: 70"); |
302 | // not needed for fritzbox
|
303 | // AddSipLine("User-Agent: sipdial by jl");
|
304 | AddSipLine("From: \"%s\" <sip:%s@%s>;tag=%010u", pDialDesc, pSipUser, pSipIp, tagid); |
305 | AddSipLine("Via: SIP/2.0/UDP %s:%i;branch=%010u;rport=%i", pMyIp, iMyPort, branchid, iMyPort); |
306 | AddSipLine("To: <sip:%s@%s>", pDialNr, pSipIp); |
307 | AddSipLine("Contact: \"%s\" <sip:%s@%s:%i;transport=udp>", pSipUser, pSipUser, pMyIp, iMyPort); |
308 | if (p) |
309 | {
|
310 | // authentication
|
311 | AddSipLine("Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"sip:%s@%s\", response=\"%s\"", pSipUser, caRealm, caNonce, pDialNr, pSipIp, haResp); |
312 | iAuthCnt++; |
313 | }
|
314 | AddSipLine("Content-Type: application/sdp"); |
315 | // not needed for fritzbox
|
316 | // AddSipLine("Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
317 | AddSipLine("Content-Length: 0"); |
318 | AddSipLine(""); |
319 | caRead[0] = 0; |
320 | SendUdp(); |
321 | }
|
322 | |
323 | // parse parameter value from http formated string
|
324 | bool Sip::ParseParameter(char *dest, int destlen, const char *name, const char *line, char cq) |
325 | {
|
326 | const char *qp; |
327 | const char *r; |
328 | if ((r = strstr(line, name)) != NULL) |
329 | {
|
330 | r = r + strlen(name); |
331 | qp = strchr(r, cq); |
332 | int l = qp - r; |
333 | if (l < destlen) |
334 | {
|
335 | strncpy(dest, r, l); |
336 | dest[l] = 0; |
337 | return true; |
338 | }
|
339 | }
|
340 | return false; |
341 | }
|
342 | |
343 | // search a line in response date (p) and append on
|
344 | // pbuf
|
345 | bool Sip::AddCopySipLine(const char *p, const char *psearch) |
346 | {
|
347 | char *pa = strstr((char*)p, psearch); |
348 | if (pa) |
349 | {
|
350 | char *pe = strstr(pa, "\r"); |
351 | if (pe == 0) |
352 | pe = strstr(pa, "\n"); |
353 | if (pe > pa) |
354 | {
|
355 | char c = *pe; |
356 | *pe = 0; |
357 | AddSipLine("%s", pa); |
358 | *pe = c; |
359 | return true; |
360 | }
|
361 | }
|
362 | return false; |
363 | }
|
364 | |
365 | int Sip::GrepInteger(const char *p, const char *psearch) |
366 | {
|
367 | int param = -1; |
368 | const char *pc = strstr(p, psearch); |
369 | if (pc) |
370 | {
|
371 | param = atoi(pc + strlen(psearch)); |
372 | }
|
373 | return param; |
374 | }
|
375 | |
376 | // copy Call-ID, From, Via and To from response
|
377 | // to caRead
|
378 | // using later for BYE or CANCEL the call
|
379 | bool Sip::ParseReturnParams(const char *p) |
380 | {
|
381 | pbuf[0] = 0; |
382 | AddCopySipLine(p, "Call-ID: "); |
383 | AddCopySipLine(p, "From: "); |
384 | AddCopySipLine(p, "Via: "); |
385 | AddCopySipLine(p, "To: "); |
386 | if (strlen(pbuf) >= 2) |
387 | {
|
388 | strcpy(caRead, pbuf); |
389 | caRead[strlen(caRead) - 2] = 0; |
390 | }
|
391 | return true; |
392 | }
|
393 | |
394 | void Sip::HandleUdpPacket(const char *p) |
395 | {
|
396 | uint32_t iWorkTime = iRingTime ? (Millis() - iRingTime) : 0; |
397 | if (iRingTime && iWorkTime > iMaxTime) |
398 | {
|
399 | // Cancel(3);
|
400 | Bye(3); |
401 | iRingTime = 0; |
402 | }
|
403 | |
404 | if (!p) |
405 | {
|
406 | // max 5 dial retry when loos first invite packet
|
407 | if (iAuthCnt == 0 && iDialRetries < 5 && iWorkTime > (iDialRetries * 200)) |
408 | {
|
409 | iDialRetries++; |
410 | delay(30); |
411 | Invite(); |
412 | }
|
413 | return; |
414 | }
|
415 | |
416 | if (strstr(p, "SIP/2.0 401 Unauthorized") == p) |
417 | {
|
418 | Ack(p); |
419 | // call Invite with response data (p) to build auth md5 hashes
|
420 | Invite(p); |
421 | }
|
422 | else if (strstr(p, "BYE") == p) |
423 | {
|
424 | Ok(p); |
425 | iRingTime = 0; |
426 | }
|
427 | else if (strstr(p, "SIP/2.0 200") == p) // OK |
428 | {
|
429 | ParseReturnParams(p); |
430 | Ack(p); |
431 | }
|
432 | else if ( strstr(p, "SIP/2.0 183 ") == p // Session Progress |
433 | || strstr(p, "SIP/2.0 180 ") == p ) // Ringing |
434 | {
|
435 | ParseReturnParams(p); |
436 | }
|
437 | else if (strstr(p, "SIP/2.0 100 ") == p) // Trying |
438 | {
|
439 | ParseReturnParams(p); |
440 | Ack(p); |
441 | }
|
442 | else if ( strstr(p, "SIP/2.0 486 ") == p // Busy Here |
443 | || strstr(p, "SIP/2.0 603 ") == p // Decline |
444 | || strstr(p, "SIP/2.0 487 ") == p) // Request Terminatet |
445 | {
|
446 | Ack(p); |
447 | iRingTime = 0; |
448 | }
|
449 | else if (strstr(p, "INFO") == p) |
450 | {
|
451 | iLastCSeq = GrepInteger(p, "\nCSeq: "); |
452 | Ok(p); |
453 | }
|
454 | }
|
455 | |
456 | /////////////////////////////////////////////////////////////////////////////////////////////////////
|
457 | //
|
458 | // hardware dependent interface functions
|
459 | //
|
460 | /////////////////////////////////////////////////////////////////////////////////////////////////////
|
461 | |
462 | int Sip::SendUdp() |
463 | {
|
464 | Udp.beginPacket(pSipIp, iSipPort); |
465 | Udp.write(pbuf, strlen(pbuf)); |
466 | Udp.endPacket(); |
467 | return 0; |
468 | }
|
469 | |
470 | // generate a 30 bit random number
|
471 | uint32_t Sip::Random() |
472 | {
|
473 | // return ((((uint32_t)rand())&0x7fff)<<15) + ((((uint32_t)rand())&0x7fff));
|
474 | return secureRandom(0x3fffffff); |
475 | }
|
476 | |
477 | uint32_t Sip::Millis() |
478 | {
|
479 | return (uint32_t)millis() + 1; |
480 | }
|
481 | |
482 | void Sip::MakeMd5Digest(char *pOutHex33, char *pIn) |
483 | {
|
484 | MD5Builder aMd5; |
485 | aMd5.begin(); |
486 | aMd5.add(pIn); |
487 | aMd5.calculate(); |
488 | aMd5.getChars(pOutHex33); |
489 | }
|
490 | |
491 | /////////////////////////////////////////////////////////////////////////////////////////////////////
|
492 | //
|
493 | // Arduino setup() and loop()
|
494 | //
|
495 | /////////////////////////////////////////////////////////////////////////////////////////////////////
|
496 | |
497 | char caSipIn[2048]; |
498 | char caSipOut[2048]; |
499 | Sip aSip(caSipOut, sizeof(caSipOut)); |
500 | |
501 | void setup() |
502 | {
|
503 | WiFi.softAPdisconnect (true); |
504 | pinMode(12, INPUT_PULLUP); |
505 | pinMode(13, INPUT_PULLUP); |
506 | |
507 | IPAddress Ip; |
508 | IPAddress Gw; |
509 | IPAddress Mask; |
510 | IPAddress Dns; |
511 | |
512 | Ip.fromString(ip); |
513 | Gw.fromString(gw); |
514 | Mask.fromString(mask); |
515 | Dns.fromString(dns); |
516 | |
517 | WiFi.config(Ip, Gw, Mask, Dns); |
518 | |
519 | if (String(ssid) != WiFi.SSID()) |
520 | {
|
521 | WiFi.begin(ssid, password); |
522 | }
|
523 | // Verbindung zum router Herstellen
|
524 | int i = 0; |
525 | for (i = 0; i < 100; i++) |
526 | {
|
527 | if (WiFi.status() == WL_CONNECTED) |
528 | break; |
529 | delay(100); |
530 | }
|
531 | |
532 | if (i >= 100) |
533 | {
|
534 | // without connection go to sleep
|
535 | delay(1000); |
536 | }
|
537 | |
538 | WiFi.persistent(true); |
539 | Udp.begin(sipport); |
540 | aSip.Init(sipip, sipport, ip, sipport, sipuser, sippasswd, 15); |
541 | //aSip.Dial(sipdialnr, sipdialtext);
|
542 | }
|
543 | int deepSleepDelay = 0; |
544 | |
545 | void loop(void) |
546 | {
|
547 | int packetSize = Udp.parsePacket(); |
548 | if (packetSize > 0) |
549 | {
|
550 | caSipIn[0] = 0; |
551 | packetSize = Udp.read(caSipIn, sizeof(caSipIn)); |
552 | if (packetSize > 0) |
553 | {
|
554 | caSipIn[packetSize] = 0; |
555 | }
|
556 | }
|
557 | aSip.HandleUdpPacket((packetSize > 0) ? caSipIn : 0 ); |
558 | if (!aSip.IsBusy() && deepSleepDelay == 0) |
559 | deepSleepDelay = millis(); |
560 | if (deepSleepDelay && (millis() - deepSleepDelay) > 500) |
561 | {}
|
562 | |
563 | // Ab Hier ist euer Programm
|
564 | |
565 | |
566 | // GPIO 13 auf minus gezogen wird
|
567 | if (digitalRead(13) == LOW) { |
568 | //aSip.Dial("**9", "GPIO D7 !");
|
569 | aSip.Dial("**701", "Klingel Tuer"); |
570 | }
|
571 | |
572 | if (digitalRead(12) == LOW) { |
573 | //aSip.Dial("**9", "GPIO D6 !");
|
574 | aSip.Dial("**610", "Klingel Tor"); |
575 | }
|
576 | |
577 | |
578 | |
579 | }
|
Danke dir erstmal :)
:
Bearbeitet durch User
Hallo Michael, im loop wird die Abfrage des Digitalen Eingang ständig abgefragt und bei einem Tastendruck die Routine aSip.Dial("**610", "Klingel Tor"); gleich mehrmals aufgerufen (solange der Taster gedrückt wird). Ich vermute das der Stack überläuft und das Programm abstürzt und dann das von Dir beschriebene Phänomen zeigt. Welches ESP Modul hast Du den? Kannst Du ein Link oder ein Bild posten. Ich passe den Source Code für Dich an. Siehe: Beitrag "Re: Sipdial per ESP8266 an Fritzbox" Gruß Alois
:
Bearbeitet durch User
Hi Alois, vielen Dank dafür schonmal im vorraus. Was ich nicht verstehe ist, das niemand anderes dieses Problem hat. ich habe doch im originalcode nichts verändert ausser der Rufnummer...
Wie weit ist der Weg zwischen Taster und ESP bei dir? Wie versorgst Du den ESP?
Alois, Ich habe gerade mal geprüft welches Script ich da habe. es ist wohl doch ein irgendwie geändertes Script, nicht ganz das original. daher haben wohl nicht viele dasselbe Problem. Es wäre trotzdem toll wenn du den Fehler ausbügeln könntest :) Nico, Vom Klingeltaster zum ESP sind es etwa 8m. USB Netzteil bzw. auch Batteriepack.
:
Bearbeitet durch User
Bei 8m Klingeldraht ist es kein Wunder, dass Du Störungen hast! Oder hast Du geschirmtes Kabel benutzt?
Schirm angeschlossen? Und ein verdrilltes Adernpaar benutzt?
:
Bearbeitet durch User
Hallo ich möchte mich auch bei euch bedanken, ich konnte nun meinen unzuverlässigen RPI1 in den verdienten Ruhestand schicken. Weiterer Vorteil, die Telefone klingen quasi instant mit, statt erst mit sekundenlanger Verzögerung.
Hallo Michael, ich habe den Source-Code überarbeitet und etwas übersichtlicher gestaltet. NodemMCU V3: Klingeltaster 1 = GPIO12 (D6) Klingeltaster 2 = GPIO13 (D7) Türöffner = GPIO14 (D5) Wenn ein Klingeltaster gedrückt wird, geht die BUILTIN-LED solange an das Klingeln aktiv ist. Durch Abheben des Telefonhörers und betätigen der Ziffer "5" am Telefon wird der Türöffner für 2 Sekunden ausgelöst. Gruß Alois.
Hallo Michael, und hier ein Bilder von meinem Siedle Haustelefon HT-511 mit eingebauter selbstentwickelter Platine (Format 37.9 x 36.1 mm). ESP-01: Klingeltaster 1 = GPIO02 Klingeltaster 2 = GPIO00 Türöffner = GPIO01 Die Klingeltaster Eingänge sowie der Türöffner Ausgang sind LOW schaltend. Das hat den Hintergrund das die Pins des ESP-01 Moduls nachdem Anlegen der Versorgungsspannung alle erst HIGH aktiv sind. Ich hatte die Schaltung zuvor mit einem NPN Transistor für die Relaisansteuerung aufgebaut. Das hatte aber den Effekt das der Türöffner beim Anlegen der Versorgungsspannung kurzzeitig angesteuert wurde. Auf der Platine befindet sich auch ein 3,3V Step-Down-Abwärtswandler und eine Gleichrichtung. Die Schaltung lässt sich somit mit Gleich- und Wechselspannung versorgen. Gruß Alois.
:
Bearbeitet durch User
Hallo Alois, hast du noch eine von den Platinen die du weitergeben kannst. Natürlich nicht kostenlos. Danke und Grüße Ralf
Hallo Alois, hier noch ein Hinweis, wenn man die ganz alten ESP01 verwendet. Der wollte mit deiner Schaltung erstmal nicht funktionieren. Hier musste der Pin CH_PD mit einem PullUp von 10kOhm auf 3,3V gelegt werden. Jetzt funktioniert es. Vielen Dank für deine Schaltung. :)
Alois N. schrieb: > Hallo Michael, > > ich habe den Source-Code überarbeitet und etwas übersichtlicher > gestaltet. Ich habe zwar keine Einschränkungen bei der Verwendung meines Codes gemacht, finde es aber trotzdem relativ anmassend, wenn du in der sip.h bzw. sip.cpp angibts der Author des Codes zu sein.
Jürgen L. schrieb: > Ich habe zwar keine Einschränkungen bei der Verwendung meines Codes > gemacht, finde es aber trotzdem relativ anmassend, wenn du in der sip.h > bzw. sip.cpp angibts der Author des Codes zu sein. Hallo Jürgen, Sorry, aber das war ein versehen. Ich habe sofort eine Löschanforderung für den Beitrag gestellt. Eigentlich war das nur mein privater Code den ich für meine kleine Siedele Türklingel und -öffner Schaltung auf meinem Rechner hatte. Bei der Anfrage von dem Benutzer Michael habe ich den Source ohne Verweis auf den eigentlichen Autor hier veröffentlicht. Ich kann mich nur bei Dir dafür entschuldigen. Ich wünsche trotz allem einen schönen Sonntag Alois
Hallo Jürgen, Die Mods haben den Anhang aus dem ursprünglichen Beitrag gelöscht und mich gebeten den Source Code erneut mit entsprechender Quellenangabe hochzuladen. Ist das so ok für dich? Gruß Alois
Hallo Zusammen, nach einem Umzug möchte ich von einer "2-Kanal" Klingen auf "3-Kanal" erweitern. Soll heißen bisher waren nur Haustür und Wohnungstür am ESP8266 angeschlossen. Jetzt soll noch das Gartentor dazu kommen. Bisher (bis zum Umzug) war es so, dass unterschieden wurde über den Text "DialDesc" was auf dem DECT Telefon angezeigt werden soll. Jetzt nach der Erweiterung ist mir aufgefallen, dass dies nicht mehr funktioniert. Auch mit der "alten" Version mit 2 Tasten, geht es nun nicht mehr. Auf dem Display erscheint nun immer der Name des Gerätes wie es in der FB eingerichtet ist, nicht mehr wie zuvor "Haustuer" oder "Wohnungstuer" oder wie geplant "Gartentor". Es kommt immer nur "Türklingel" :-( Der INVITE sieht wie folgt aus:
1 | INVITE sip:**777@192.168.2.1 SIP/2.0 |
2 | Call-ID: 0463499949@192.168.3.10 |
3 | CSeq: 1 INVITE |
4 | Max-Forwards: 70 |
5 | From: "Gartentor" <sip:KlingelFritz@192.168.2.1>;tag=0035208885 |
6 | Via: SIP/2.0/UDP 192.168.3.10:5060;branch=0183009575;rport=5060 |
7 | To: <sip:**777@192.168.2.1> |
8 | Contact: "KlingelFritz" <sip:KlingelFritz@192.168.3.10:5060;transport=udp> |
9 | Content-Type: application/sdp |
10 | Content-Length: 0 |
Als FritzOS ist momentan die letzte Laborversion 7.19x istalliert.
In zwischen habe ich mal das Support-Log ausgelesen. Die Invite Message schein korrekt in der FB anzukommen. Selbst nach einem Firmware Downgrade auf 7.12 geht es nicht mehr. Hat jemand ähnliches beobachtet?
1 | 2020-06-09 12:09:50.557 - IN: my=192.168.2.1%14:5060 peer=192.168.3.10 port=5060 UDP, sipiface=none: |
2 | INVITE sip:**777@192.168.2.1 2.0 |
3 | Via: SIP/2.0/UDP 192.168.3.10:5060;branch=0945021135;rport=5060 |
4 | From: "Gartentor" <sip:KlingelFritz@192.168.2.1>;tag=0884057437 |
5 | To: <sip:**777@192.168.2.1> |
6 | Call-ID: 0105783441@192.168.3.10 |
7 | CSeq: 1 INVITE |
8 | Contact: "KlingelFritz" <sip:KlingelFritz@192.168.3.10:5060;transport=udp> |
9 | Max-Forwards: 70 |
10 | Content-Type: application/sdp |
11 | Content-Length: 0 |
:
Bearbeitet durch User
Hallo @Dennis, wenn Du den Original-Code von hier: Beitrag "Re: Sipdial per ESP8266 an Fritzbox" verwendet hast, sollte es eigentlich funktionieren. Auch ich habe eine Fritzbox 7590 mit aktueller Labor-Version: 07.19-78990 und es funktioniert schon seit längerem ohne Probleme. Keine Aufhänger oder Aussetzer. Wirklich genial. Was mir in Deinem Log auffällt ist, das die ESP-Klingel nicht im gleichen IP-Segment hängt, wie deine Fritzbox. 192.168.2.1 -> IP deiner Fritzbox 192.168.3.10 -> IP deiner ESP-Klingel Bei mir hängt alles im gleichen Segment 192.168.178.x Du rufst **777. Ich mache einen Rundruf mit **9
Alois N. schrieb: > Hallo @Dennis, wenn Du den Original-Code von hier: > Beitrag "Re: Sipdial per ESP8266 an Fritzbox" > verwendet hast, sollte es eigentlich funktionieren. > > Auch ich habe eine Fritzbox 7590 mit aktueller Labor-Version: > 07.19-78990 und es funktioniert schon seit längerem ohne Probleme. Keine > Aufhänger oder Aussetzer. Wirklich genial. > Was mir in Deinem Log auffällt ist, das die ESP-Klingel nich zut im > gleichen IP-Segment hängt, wie deine Fritzbox. > > 192.168.2.1 -> IP deiner Fritzbox > 192.168.3.10 -> IP deiner ESP-Klingel > > Bei mir hängt alles im gleichen Segment 192.168.178.x > > Du rufst **777. Ich mache einen Rundruf mit **9 Ja, soweit korrekt! Leider geht es auch nicht mit dem Original Code. Im 192.168.2 sind alle "normalen" IP Geräte wie Router, Repeater, NAS, Drucker, Smartphones und PCs Im .3 er alles SmartHome Geräte, Alexa, Zigbee Gateway, etc. **777 ist ein Gruppenruf, da mit **9 sonst auch das Fax mit klingelt. Im Prinzip geht ja alles, nur das nicht mehr der Text angezeigt wird. Als ob die FB diesen nicht mehr auswertet.
:
Bearbeitet durch User
@Dennis, hast Du die ESP-Klingel einfach mal aus dem Netzwerk gelöscht? HEIMNETZ -> NETZWERK -> Gerät löschen Danach kurzen RESET am ESP machen. Wirkt manchmal Wunder. Die SIP-Einstellungen in der Fritzbox können erhalten bleiben. Der ESP sollte sich erneut am WLAN und der Fritzbox anmelden und wie gewohnt funktionieren. Schau ob sich was am Verhalten ändert.
:
Bearbeitet durch User
Alois N. schrieb: > @Dennis, > > hast Du die ESP-Klingel einfach mal aus dem Netzwerk gelöscht? > HEIMNETZ -> NETZWERK -> Gerät löschen > Danach kurzen RESET am ESP machen. Wirkt manchmal Wunder. > > Die SIP-Einstellungen in der Fritzbox können erhalten bleiben. > Der ESP sollte sich erneut am WLAN und der Fritzbox anmelden und wie > gewohnt funktionieren. > > Schau ob sich was am Verhalten ändert. @Alois Danke für den Tipp! Hat leider nichts geändert.
Guten Morgen, Heute Morgen klingelte es an der Tür und meine Frau sagte "ohh, es geht wieder!"... Das "Problem" scheint sich isoliert auf ein neueres Mobilteil zu beschränken. Das Mittlere ist mein Büro Telefon das bisher meine Referenz war. Vor ca. 3 Monaten gab es Aussetzer im Bluetooth worauf ein FW Update folgte. Es sieht so aus, als ob es danach nicht mehr so richtig will. Trotzdem danke!
Dennis H. schrieb: > Das "Problem" scheint sich isoliert auf ein neueres Mobilteil zu > beschränken. > Das Mittlere ist mein Büro Telefon das bisher meine Referenz war. > Vor ca. 3 Monaten gab es Aussetzer im Bluetooth worauf ein FW Update > folgte. > Es sieht so aus, als ob es danach nicht mehr so richtig will. Hi Dennis, das wäre wenigstens eine Erklärung ich habe inzwischen verschiedene Fritzbox Firmwarestände ausprobiert und konnte dein Phänomen nicht nachstellen. Allerdings verwende ich Original AVM Mobilteile. (1 x FRITZ!Fon MT-F und 3 x FRITZ!Fon C4).
Alois N. schrieb: > Hi Dennis, > > das wäre wenigstens eine Erklärung ich habe inzwischen verschiedene > Fritzbox Firmwarestände ausprobiert und konnte dein Phänomen nicht > nachstellen. Allerdings verwende ich Original AVM Mobilteile. (1 x > FRITZ!Fon MT-F und 3 x FRITZ!Fon C4). Hi Alois, danke, es lässt sich komplett auf das S850HX mit der FW 114.075.06 eingrenzen. Warum und wieso? Keine Ahnung. Mit den 3x C430 DECT Telefonen geht es. Für mich selbst, ordne ich diesem Verhalten jetzt eine niedrige Prio zu und werde es nicht weiter verfolgen, da es im Büro keinen Mehrwert hat zu wissen, wo es klingelt.
Vielleicht hast Du am Telefonanschluss etwas geändert. https://avm.de/service/fritzbox/fritzbox-7490/wissensdatenbank/publication/show/17_Bei-ankommenden-Anrufen-werden-keine-Rufnummern-angezeigt/
Hallo Dennis, bei mir zeigen die Fritz!Fons auch den Namen aus dem Feld "Namen" des IP-Telefons an und nicht den im ESP hinterlegten. LÖSUNGSIDEE: Damit ich jeden Klingelknopf individuell anzeigen kann, nutze ich die Funktion "Türsprechanlage" in der Fritz!Box. Du kannst dann jeder Taste einen individuellen Namen vergeben (Wohnungstür, Tor usw., auch Umlaute funktionieren!). Die vordefinierten Rufnummern für Taste 1 (Rufnummer 11), Taste 2 (Rufnummer 12) usw. trägst du in deinem ESP als Zielrufnummer ein, die bei der entsprechenden Taste gerufen werden soll. BEISPIEL: Für das Tor nutzt du die 12 im ESP als Rufnummer, du trägst in der Fritz!Box bei der Taste 2 die Rufnummer 12 ein und als Klingeltastenname Torklingel. Die Rufsignalisierung an den gewünschten Geräten bzw. Gruppen kannst du im Nachgang jederzeit in der Fritz!Box anpassen, ohne am ESP etwas ändern zu müssen. Der ESP ruft nun die "12" beim Klingeln am Tor und du siehst auf dem Telefondisplay "Torklingel". Die Variante läuft bei mir tadellos.
Hallo Chris, danke für deinen Tipp! Hab es genau so gelöst. :-D Beitrag "Mathfel / Rongtel MR880C2C RE"
Alois N. schrieb: > SipDial.ino (5,1 KB, 92 Downloads) > | Codeansicht Ich habe erfolgreich diesen Code als SIP-Klingel auf einem Wemos D1 mini eingerichtet. Da das meine ersten Versuche mit der Technik sind, frage ich hiermit, ob es möglich ist, diesen Code mit dem Code https://github.com/letscontrolit/ESPEasy zu kombinieren (Verwendung davon 1-Wire Temperatursensoren, Analogeingang mit Umrechnung, Zeitserver, 1 Digitaleingang). Ausgewertet werden soll der Zustand des Digitaleingangs, bei low soll der Sip-Anruf ausgelöst werden und/oder beim Unterschreiten eines festzulegenden Wertes aus der Umrechnung. Mailversand bekomme ich nicht gebacken, weil auch die Auslösefaktoren für mich nicht einstellbar sind (kA). Der Zugriff über einen Browser ist mir wichtig. Kann mir bei der Lösung jemand helfen?
Guten Abend, zunächst einmal herzlichen Dank für das hier vorgestellte hervorragende Projekt und die damit verbundene Arbeit! Mir ist es gelungen, auf einem ESP8266 die Sache ans Laufen zu bringen. Gerne würde ich statt der statischen const char* Festlegung der IP-Adresse im code diese dynamisch - konkret durch Auslesen aus dem Spiffs/LittleFS zur Laufzeit im setup einstellen. Mangels ausreichender c++ Kenntnisse ist mir das nach zwei Tagen leider immer noch nicht gelungen. Vielleicht kann mir jemand dabei behilflich sein, herzlichen Dank! Dirk
Es klappt. Ich habe die Library nach meinen Bedürfnissen angepasst und kann nun die aus dem FS gelesenen credentials übergeb. Nochmal herzlichen Dank an die Bereitstellung dieser tollen Library!
Moin! Ich weiß, dieser Thread ist Aßbach-Uralt, aber für mich aht er noch große relevanz, da ich diese SIP-Implementierung nutze. Ich nutze dies für eine der üblichen "FritzBox-SIP-Türklingeln". Wenn ich eine Ziffer drücke, löse ich eine Aktion aus. Dazu nutze ich die ESP8266Audio Bibliothek von https://github.com/earlephilhower/ESP8266Audio um eine vorprogrammierte Ansage über ein DAC durchzusagen. Gibt es eine Change, eine unidirektionale Audio-Verbindung aufzubauen und über den DAC am ESP auszugeben? Das wäre absolute Sahne. Gruß und Dank!
Beitrag "Re: Sipdial per ESP8266 an Fritzbox" Ist es möglich, einen Auslösewert vom Analogeingang zu programmieren, der beim unterschreiten einen Sipcall auslöst? Wie wäre das zu realisieren? Integriert werden sollte der Code in den des oben genannten Beitrages.
Vielen Dank für dieses tolle Projekt! Ich habe es mit der ESP8266-Arduino Lösung von Alois nachbauen können. So etwas selber zu programmieren würde aber meine Fähigkeiten überschreiten. In dem Beispielcode arbeitet der ESP als SIP-Telefon an der FritzBox. Es kann wählen (Türklingel) und auch einen Tastendruck der Gegenseite auswerten (Türöffner). Meine Frage: Ist der Code so erweiterbar, daß das ESP-SIP-Telefon auch eingehende Anrufe erkennt und durch einen Portpin signalisiert? Ich würde es dann gerne als opto-akustische Zweitklingel verwenden. Ist diese Ergänzung des Projekts auf Basis des ESP8266 möglich? Ich habe leider kein Beispiel für eine Lösung gefunden. Gruß Erni
Erni schrieb: > Ist der Code so erweiterbar, daß > das ESP-SIP-Telefon auch eingehende Anrufe > erkennt und durch einen Portpin signalisiert? Klar, per REGISTER an der Telefonanlage anmelden (und regelmässig auffrischen) und eingehende INVITEs verarbeiten. Solange Du keinen Ton brauchst, ist das noch überschaubar.
Oh, das klingt einfach :-) Das Anmelden an die Telefonanlage (Fritz) müsste in dem bisherigen Code ja schon vorhanden sein. Dort vermutlich ohne das Auffrischen, da die Verbindung nur kurz besteht. Also muß hier über ein Zeitintervall gearbeitet werden. Die Invites werde ich mir mal genauer anschauen, habe wohl gesehen, daß der Öffner-Befehl auch darüber arbeitet. Einen Signalton brauche ich nicht, es reicht die Aktivierung eines Port-Pins (wie beim Tür-Öffner). Vielen Dank für die Auskunft!
Erni schrieb: > Das Anmelden an die Telefonanlage (Fritz) müsste in dem > bisherigen Code ja schon vorhanden sein. Nein, REGISTER ist im Code nicht vorhanden, für ausgehende Verbindungen schickt man nur INVITEs, ggf. mit Authentifizierung. Das Thema wird in Kapitel 10 von RFC3261 beschrieben. Erni schrieb: > Einen Signalton brauche ich nicht Lokal einen zu erzeugen, wäre kein Problem, aber das Handling von SIP-Audiodaten ist deutlich komplexer als die nackte Signalisierung.
OK! Vielen Dank für den Hinweis! Ich werde es versuchen, vielleicht bekomme ich es hin. Gruß Erni
Moin, kurze Frage ist das Problem gelöst? ich bin grade genau auf der suche nach so etwas. Per Anruf auf Sipnummer einen LED Lampe im Silo als Signal zu haben. meine Klingel ist eine AB Nebenstelle und kann/macht einen Rundruf, so könnte auch die SIP Nebenstelle angerufen werden und die Lampe als Signal fungieren. Gruß Paul
Moin Paul, habe das Problem leider noch nicht gelöst. Das, was in der RFC3261 beschrieben steht ist sehr schwere Kost für mich... Viel Erfolg! Erni
Beitrag #6770449 wurde von einem Moderator gelöscht.
ramu schrieb im Beitrag #6770449: > Im Standardfall bekomme > ich folgende Meldung Das ist völlig normal. INVITE ohne Authentication hinschicken, 401 oder 407 mitsamt Challenge zurückbekommen, dann nochmal ein INVITE mit passender Response schicken.
Hallo, kennt deine Fritzbox denn schon den ESP? Sprich wurden neue WLAN Geräte zugelassen? Nach Bekanntmachung Beider die Funktion wieder sperren. Tipp: Zeige niemals im Internet deine Fritzbox Logindaten! Gib einem Mod Bescheid er das korrigieren soll.
Veit D. schrieb: > Tipp: Zeige niemals im Internet deine Fritzbox Logindaten! > Gib einem Mod Bescheid er das korrigieren soll. Was soll er da korrigieren lassen? Das ist eine Challenge ohne Response, also zufällige Daten ohne Nutzwert.
Ich weiß schon was ich korrigoieren soll, ist mir leider erst nach dem Upload aufgefallen.. Wie erreiche ich einen Mod? Der ESP ist im Netz bekannt und ich kann auch drauf zugreifen... Ich dachte, wenn 401 zurückkommt, würde in sip.ccp ein erneutes invite aufgerufen? Bin etwas ratlos, wo genau ich was aufrufen sollte... Und ist es richtig, dass ich am Anfang nicht wählen kann, solage die Paketgröße = 0 ist?
Ich frage mich nur wie man auf die bescheuerte Idee kommen kann in der Loop() einer Arduino Umgebung ein Delay(1000) einzubauen...
ramu schrieb: > Ich dachte, wenn 401 zurückkommt, würde in sip.ccp ein erneutes invite > aufgerufen? Bin etwas ratlos, wo genau ich was aufrufen sollte... Ein vollständiges Logfile (statt nur des 401 von der Fritzbox) würde evtl. etwas aussagen.
Hmmm schrieb: > Ein vollständiges Logfile (statt nur des 401 von der Fritzbox) würde > evtl. etwas aussagen. Aber erst nach dem das Delay(1000) raus ist. Der Code geht nicht davon aus nur alle Sekunde mal ein UDP Packet verarbeiten zu können.
Hmmm hat recht, hab das delay rausgenommen und vor allen Dingen auch die wiederholenden inits... Jetzt klapps gut, nachdem ich den Taster zum Wählen noch entprellt habe, da beim Einschalten des Kamerastreams manchmal die Zustandsabfrage des Pins nicht richtig funktionierte... Danke Euch!
ramu schrieb: > Ich weiß schon was ich korrigieren soll, ist mir leider erst nach dem > Upload aufgefallen. Wie erreiche ich einen Mod? Entweder findest du zufällig in einem Thread einen User mit Moderatorqualifikation im Zusatz. Oder du schreibst eine E-Mail an webmaster@mikrocontroller.net mit deinem Anliegen und Link zum Beitrag.
Hmmm schrieb: > Erni schrieb: >> Ist der Code so erweiterbar, daß >> das ESP-SIP-Telefon auch eingehende Anrufe >> erkennt und durch einen Portpin signalisiert? > > Klar, per REGISTER an der Telefonanlage anmelden (und regelmässig > auffrischen) und eingehende INVITEs verarbeiten. > > Solange Du keinen Ton brauchst, ist das noch überschaubar. Hallo, ich würde mich auch für eine derartige Lösung interessieren, aber habe leider nicht das dafür notwendige Wissen um das programmiertechnisch selbst zu lösen. Wäre echt toll, wenn jemand mir hier etwas mit dem entsprechenden Code unter die Arme greifen könnte, falls das nicht Zuviel verlangt ist. Danke! Freundliche Grüße Patrick
Hallo Patrick, ich habe für mich eine andere Lösung gefunden, um eingehende Anrufe zu signalisieren. Die Fritzbox stellt einen CallMonitor zur Verfügung, der mit der Telefon-Tasteneingabe #96*5* aktiviert und mit #96*4* deaktiviert werden kann. Der ESP baut eine WLAN-Verbindung zum Port 1012 der Fritzbox auf und wertet die angezeigten Zeichenketten aus. Enthält ein String die Zeichenfolge "RING;" wird der Portpin gesetzt und bei "CONNECT;" zurückgesetzt. Es kann auch die Nummer des eingehenden Anrufs ausgewertet werden. Den Callmonitor kann man auch mit Putty/KiTTY beobachten (Telnet Port 1012). Gruß Erni
Hallo Erni, Ja, den Callmonitor kenne ich. Hab damit und einem Arduino UNO schon vor Jahren meinen ersten Türöffner gebaut. Der UNO hat auf eine spezielle Telefonnummer „gelauscht“, wenn diese angerufen wurde, hat er für 4 Sekunden ein Relais geschaltet, welches meinen Türöffner betätigt hat. So konnte ich mit meinem Handy die Haustür öffnen. Jetzt habe ich aber mehr damit vor und das macht notwendig, dass aus dem ESP der Sip-Client läuft und ständig an der FritzBox angemeldet ist. Am liebsten wäre mir, wenn der ESP nicht nur auf Anrufe regieren könnte, sondern entweder Texte auswerten, die zusammen mit dem Anruf von einem anderen ESP per SIP gesendet werden oder den Anruf annimmt und auf Tastenbefehle reagiert. Möglich ist das doch bestimmt, ich weiß leider nicht wie ich das bewerkstelligen soll. Kenne mich leider zuwenig mit der Materie aus. Gruß Patrick
Hi, genau so eine Platine hätte ich auch gerne. Vielleicht ist ja noch eine übrig? Viele Grüße Frank
@Alois Hi, die Sip.h Datei enthält zwei include Anweisungen die bei mir Compilerfehler erzeugen.
1 | #include "arduino.h" |
1 | #include <WifiUdp.h> |
nach Änderung der Dateinamen auf:
1 | #include "Arduino.h" |
1 | #include <WiFiUdp.h> |
läuft der Compiler ohne Fehler durch. Tippfehler oder gibt es tatsächlich die verschiedenen Dateien? Gruß Berndt
berndt schrieb: > Tippfehler oder gibt es tatsächlich die verschiedenen Dateien? Eher eine Nachlässigkeit, die unter Windows zufällig funktioniert, da hier das Filesystem nicht zwischen Groß-/Kleinschreibung unterscheidet.
Frank M. schrieb: > die unter Windows zufällig funktioniert Handklatsch vor die Stirn, zu lange nicht mehr benutzt :-) Gruß Berndt
Vielen Dank für dieses tolle Projekt! Ich benutze Elastix. Das System funktioniert, aber ich konnte es nicht mit "5" auslösen. Könntest du helfen
Orkun schrieb: > Bu harika proje için teşekkürler! > elastix kullanıyorum. Sistem çalışıyor ama yapamadım > "5" ile tetikleyin. yardım edebilir misin
Moin, ich bin am überlegen das ganze ein wenig zu erweitern und bei Homeassistant mit zu integrieren um bei Abwesenheit z.B. eine Push-Nachricht zu generieren. Hat jemand eine Idee, wie man das hinbekommen könnte?
Hallo Andreas, hast du schon was hinbekommen? Beitrag "Re: Sipdial per ESP8266 an Fritzbox" Ich würde ebenfalls noch gerne eine Nachricht per MQTT erhalten wollen. Kenne mich aber mit C nicht so gut aus. Möchte alles gerne auf einem ESP 01S laufen lassen. Gruß Jürgen
Hey, ich nutze erfolgreich das Script von Nicki. Allerdings dauert das Klingelzeichen ca. 3-4 Sekunden. Gibt es Möglichkeiten der schnelleren Signalisierung am DECT Telefon? Der Postbost/ Paketbote ist bei uns sehr flott unterwegs.....
Hatte das identische Problem mit den 3-4 Sekunden. Einfach folgendes ergänzen ... // WiFiManager for remote WiFi configuration #include <WiFiManager.h> dann folgendes im void setup() entfernen ... delay(10); WiFi.disconnect(true); delay(10); WiFi.mode(WIFI_STA); delay(10); Serial.print("\r\n\r\n"); Serial.printf("Connecting to %s\r\n", SSID); IPAddress Ip; IPAddress Gw; IPAddress Mask; IPAddress Dns; Ip.fromString(ip); Gw.fromString(gw); Mask.fromString(mask); Dns.fromString(dns); WiFi.config(Ip, Gw, Mask, Dns); if (String(SSID) != WiFi.SSID()) { Serial.print("Wifi begin...\r\n"); WiFi.begin(SSID, WLANKEY); } int i = 0; for (i = 0; i < 100; i++) { if (WiFi.status() == WL_CONNECTED) break; delay(100); Serial.print("."); } if (i >= 100) { // without connection go to sleep delay(500); ESP.deepSleep(0); } WiFi.persistent(true); ipTest = WiFi.localIP().toChar(); Serial.printf("\r\nWiFi connected to: %s\r\n", WiFi.localIP().toString().c_str()); und durch folgendes ersetzen ... void setup() { Serial.begin(115200); //WiFiManager WiFiManager wifiManager; wifiManager.autoConnect("Klingel", "passwort");
Die ESP Arduino Version >3.00 verhalten sich anders als die 2er. Das mit dem WiFiManager bläht das alles noch mehr auf, dem müsste man dann auch feste Ip Einstellungen geben, sonst hängt auch noch das DHCP mit dazwischen. Ich hab das mal mit einer 3.02er Version probiert und festgestellt dass da ein voller WLAN-Scan gemacht wird. Bei mir hat diese Änderung wieder für schnellen Connect gesorgt:
1 | WiFi.config(Ip,Gw,Mask,Dns); |
2 | WiFi.persistent(true); |
3 | |
4 | if (String(ssid) != WiFi.SSID()) |
5 | {
|
6 | Serial.println("Wifi begin...\n"); |
7 | WiFi.begin(ssid, password); |
8 | }
|
9 | else
|
10 | WiFi.begin(); |
Hallo zusammen, das ganze ist ohne Frage ein geiles Projekt und ich habe es in der letzten Zeit nach und nach ein wenig erweitert. Es kam ja mittlerweile hier auch schon die Frage auf nach MQTT, deswegen schmeiße ich mal meine Version hier zur freien Verfügung dazu. Gruß Christian
Mit Homeassitant kenne ich mich leider nicht aus. Ich hab den IO-Broker im Einsatz. Das funktioniert aber mit Sicherheit auch irgendwie. PS. Bevor es mir jemand aufs Brot schmiert: Die WiFi-Daten im Screenshot sind natürlich nicht die regulären ;-).
Christian schrieb: > letzten Zeit nach und nach ein wenig erweitert. Es kam ja mittlerweile > hier auch schon die Frage auf nach MQTT, deswegen schmeiße ich mal meine > Version hier zur freien Verfügung dazu. > Christian Hallo Christian, ich hatte im Beitrag "Re: Sipdial per ESP8266 an Fritzbox" eine Frage, die sich mit deinem Projekt fast deckt. Läßt sich der Code von ESPEasy auch integrieren, bzw durch Befehlszeilen auf anderen Modulen die Eingänge schalten, das die Rufe ausgelöst werden? Mir gefällt an deinem Projekt, das alles über die Oberfläche einstellbar ist.
Christian, wie kann ich die IOs am besten konfigurieren? Ich nutze den ESP-01S und habe eigentlich nur einen Klingeltaster an GPIO0.
Beitrag #7426850 wurde vom Autor gelöscht.
Jens D. schrieb: > Christian schrieb: >> letzten Zeit nach und nach ein wenig erweitert. Es kam ja mittlerweile >> hier auch schon die Frage auf nach MQTT, deswegen schmeiße ich mal meine >> Version hier zur freien Verfügung dazu. >> Christian > Hallo Christian, ich hatte im > Beitrag "Re: Sipdial per ESP8266 an Fritzbox" eine Frage, die > sich mit deinem Projekt fast deckt. > Läßt sich der Code von ESPEasy auch integrieren, bzw durch Befehlszeilen > auf anderen Modulen die Eingänge schalten, das die Rufe ausgelöst > werden? > Mir gefällt an deinem Projekt, das alles über die Oberfläche einstellbar > ist. Hallo Jens, ich hoffe, ich hab das richtig verstanden: Du hast also zwei ESP-Module, eins mit ESP-Easy und eins mit der SIP-Dial Firmware und ESP-Easy soll auf dem anderen Modul den SIP-Call auslösen? ESP-Easy kann soweit ich weiß HTTP-Requests versenden. Ich hab mal eine Version angehängt, bei der ein SIP-Call über ein HTTP (Post) Request ausgelöst werden kann (http://xxx.xxx.xxx.xxx/dial). Gruß Christian
Habt ihr mit der fritzbox und dem esp8266 auch probleme? Ueber meine 5490 ist der esp zeitweise einfach nicht erreichbar, oder es dauert sehr lange. Dasselbe mit einem xiaomi router funktioniert tadellos. Das problem ist zwar bekannt, lösung gibts aber nicht.
Christian schrieb: > Du hast also zwei ESP-Module, eins mit ESP-Easy und eins mit der > SIP-Dial Firmware und ESP-Easy soll auf dem anderen Modul den SIP-Call > auslösen? Das ist momentan so. Ich würde aber gerne das Sip-Modul in das ESP-Easy-Modul integrieren. Mir fehlt dazu das Wissen. Ich habe eine Hystereseauswertung von Sensorwerten, da soll beim Unterschreiten eines festgelegten Wertes (ein GPIO definiert) ein Sipdial ausgelöst werden. @moriz996 Bei mir tritt das Problemchen mit der WLan Verbindung seit dem Update auf 7.5 auch auf. Es half bisher nur, einen Kanal <10 zu setzen und bei Bedarf die Fritte neu zu starten.
Christian schrieb: > Du hast also zwei ESP-Module, eins mit ESP-Easy und eins mit der > SIP-Dial Firmware und ESP-Easy soll auf dem anderen Modul den SIP-Call > auslösen? > ESP-Easy kann soweit ich weiß HTTP-Requests versenden. Ich erhalte folgende Fehlermeldung:
1 | C:\Users\*****\Documents\Arduino\Sketch sip dial\SipDial\ESP8266HTTPUpdateServer-impl.h: In lambda function: |
2 | |
3 | ESP8266HTTPUpdateServer-impl.h:110:36: error: 'FS_end' was not declared in this scope; did you mean 'va_end'? |
4 | |
5 | 110 | size_t fsSize = ((size_t)FS_end - (size_t)FS_start); |
6 | |
7 | | ^~~~~~ |
8 | |
9 | | va_end |
10 | |
11 | ESP8266HTTPUpdateServer-impl.h:110:53: error: 'FS_start' was not declared in this scope; did you mean 'va_start'? |
12 | |
13 | 110 | size_t fsSize = ((size_t)FS_end - (size_t)FS_start); |
14 | |
15 | | ^~~~~~~~ |
16 | |
17 | | va_start |
18 | |
19 | Mehrere Bibliotheken wurden für "PubSubClient.h" gefunden |
20 | |
21 | Benutzt: C:\Users\*****\Documents\Arduino\libraries\PubSubClient |
22 | |
23 | Nicht benutzt: C:\Users\*****\Documents\Arduino\libraries\SipDial |
24 | |
25 | exit status 1 |
26 | |
27 | 'FS_end' was not declared in this scope; did you mean 'va_end'? |
Bei mir läuft der Compiler ohne Fehler durch. Benutzt du die neueste Arduino Core-Version 3.1.2? Wenn ja, weiss ich auch nicht was da los ist. Versuchs mal mit der angehängten Version. Die ist ohne den Webupdater, der ja scheinbar das Problem verursacht.
Hi Zusammen, ich wollte mal das Script von Christian (12.05.23 & 01.08.23) ausprobieren und habe es auch geschafft zu kompilieren und auf meine NodeMCU zu flashen. Leider passiert danach garnichts. Da ich im Script keine Option für die Änderung der Parameter von WiFi, MQTT, SIP gefunden hatte, dachte ich, dass vielleicht ein eigener AP entsteht, über dessen Website ich die Parameter ändern kann. Aber nichts passiert... Kann mir da bitte jemand weiterhelfen?
config.h
1 | #define JUMPER_PIN 12
|
SipDial.ino
1 | if ((JUMPER_PIN) == LOW) { // Wenn Jumper gesetzt ist, startet der ESP im AP-Modus |
ist doch ganz einfach, oder?
Jens D. schrieb: > Mehrere Bibliotheken wurden für "PubSubClient.h" gefunden Ich habe bei mir die Dateien PubSubClient.h und PubSubClient.cpp aus dem Projektverzeichnis gelöscht. Dann wird die über den Library Manager installierte Lib verwendet. > 'FS_end' was not declared in this scope; did you mean 'va_end'?[/c] In der Datei ESP8266HTTPUpdateServer-impl die folgende Zeile size_t fsSize = ((size_t)FS_end - (size_t)FS_start); // TODO: original code doesn't compile durch diese Zeile ersetzen, dann klappt es bei mir: const size_t fsSize = FS_PHYS_SIZE; Siehe dazu hier: https://github.com/esp8266/Arduino/blob/a348833a817244ab7e3c65c78ad5fb3276bb6f35/cores/esp8266/flash_hal.h#L80 Bisher habe ich den Code nur übersetzt, aber noch nie geladen! Michael
:
Bearbeitet durch User
Adi B. schrieb: > config.h >
1 | #define JUMPER_PIN 12
|
> > SipDial.ino >
1 | if ((JUMPER_PIN) == LOW) { // Wenn Jumper gesetzt ist, startet der |
2 | > ESP im AP-Modus |
> > ist doch ganz einfach, oder? Du hast Recht! Wer liest ist klar im Vorteil! Vielen Dank für die schnelle Hilfe!
tolle Idee das mit der Sipdial Türklingel. Danke an Autor und Mitentwickler. Zwar passiert es selten doch es kann vorkommen das man sich aussperrt. Für speziell diesen Zweck habe ich lange Zeit eine Öffnerschaltung benutzt die per bestimmten Morsecode mit der Türklingel den Türöffner betätigt. Könnte man diese Funktion auch in den Code des 8266 implementieren das wenn man per Handy die Fritzbox anruft plus Zusatzcode diese dann den Türöffner betätigt? Kann den teuren Schlüsseldienst ersparen. Oder man kann die Kinder schon von Ferne reinlassen, wenn man sich verabredet aber verspätet hat usw.
:
Bearbeitet durch User
Klaus B. schrieb: > wenn man per Handy die Fritzbox anruft Es geht auch einfacher: Du wählst dich per VPN mit dem Handy in dein internes Netzwerk ein, rufst die IP von SipDial auf und betätigst den dort bereits vorhandenen Türöffner Knopf
Hallo, ich nutze die ESP-Klingel von J.Liegner jetzt schon seit mehreren Jahren und bin begeistert. Heute ist mir die Idee zu einer anderen Umsetzung mit der SIP-Funktion gekommen, und zwar habe ich für unser automatisiertes Hoftor ein GSM-Modul genutzt. Leider ist mal wieder die SIM-Karte wegen 'nichtNutzung' gesperrt und gelöscht worden. Nun möchte ich über die SIP-Nummer anrufen und das Hoftor auffahren lassen, wenn die anrufende Nummer mit den definierten zugelassenen Nummern übereinstimmt. Da ich von Programmierung überhaupt keine Ahnung habe würde ich mich über eure Hilfe sehr freuen. Grüße sendet Andre Z.
Andre Z. schrieb: > Nun möchte ich über die > SIP-Nummer anrufen und das Hoftor auffahren lassen, wenn die anrufende > Nummer mit den definierten zugelassenen Nummern übereinstimmt. Dafür müsste der bestehende Code um REGISTER-Funktionalität (mitsamt regelmässiger Auffrischung) erweitert werden, das ist nicht ganz so trivial wie ausgehende Anrufe.
Hmm schade, weitere Möglichkeit wäre den Callmonitor der Fritzbox nutzen. Aber falls sich doch jemand dafür begeistert das Projekt umzusetzen, bin ich bestimmt nicht der einzige dankbare Nutzer. Thema ist auf jeden Fall aboniert.
Moin kurze Rückmeldung, meine Torsteuerung funktioniert jetzt. Ich stelle nur kurz vor was ich gemacht habe, falls jemand dasselbe Problem hat. Umgesetzt wurde die Torsteuerung in NodeRed mit dem Fritzbox-Node Callmonitor und einem TasmotaSchalter welcher die OrginalTorsteuerung betätigt. Im Anhang der NodeRed-Flow als .nfo
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.