Aypac / Arduino-TR-064-SOAP-Library

Arduino library for the TR-064 protocol, most commonly used by the Fritz!Box router API
Other
63 stars 21 forks source link

Working example and a question #36

Open Roehrenkramladen opened 3 years ago

Roehrenkramladen commented 3 years ago

Hallo,

I used your library to build my wifi bell. Thanks for the publication! I have documented everything here including the hardware: http://www.roehrenkramladen.de/Tuerklingel-V2/TK-FB-V2-1.html I use the wifi manager to configure the wifi data. I could also query the TR064 data (user & password) with the wifi manager, but it doesn't work because the parameters for the Fritzbox user are transferred in the main area. Does anyone know a solution? Thank you in advance for your answers!

thanks

Aypac commented 3 years ago

Hi Roehrenkramladen, interesting documentation, love the considerations you took, like using the relay :) Using the Wifi configurator is also a nice touch I wanted to do for quite a while. I would love if you could commit it as a push request here on Github if you can.

For your problem: I'm not 100% sure if I get it right. So what I think you are asking is if there is a way not not hard-code the user-info to the Fritz!Box, but have it added just like the Wifi password in your case.

The only thing that prevents you from this, is that the line

TR064 connection(PORT, IP, fuser, fpass);

is in the definition area right now, instead of the main loop. But you can just move that to the main loop, so something like (pseudocode):

Click to show pseudocode ``` #include #if defined(ESP8266) //Imports for ESP8266 #include #include #include ESP8266WiFiMulti WiFiMulti; #elif defined(ESP32) //Imports for ESP32 #include #include #include WiFiMulti WiFiMulti; #endif #include // Flash BUTTON - you can connect a separate button to this pin or an opto-coupler // for example: use a resistor and an opto-coupler to connect to a doorbell #define BUTTON 0 void setup() { Serial.begin(115200); // Port as input pinMode(BUTTON, INPUT); // Set up webhost for wifi conig // ... } void loop() { if connection_not_set_up { // Wait for webinterface input (wifi and/or router settings) // Setup WIFI connection // Maybe: Wait for webinterface input (router settings) ensureWIFIConnection() // TR-064 connection TR064 connection(PORT, IP, fuser, fpass); } int button_state = digitalRead(BUTTON); if (digitalRead(BUTTON) == LOW) { if (Serial) { Serial.println(); Serial.printf("Button pressed"); } callWahlhilfe(); // callDect(); // char* status=getStatus(); delay(20000); } else { if (Serial) { Serial.println(); Serial.printf("Button not pressed"); } delay(50); } } void callWahlhilfe() { ensureWIFIConnection(); String params[][2] = {{"NewX_AVM-DE_PhoneNumber", "**799"}}; String req[][2] = {{}}; connection.action("urn:dslforum-org:service:X_VoIP:1", "X_AVM-DE_DialNumber", params, 1, req, 0); } void callDect() { ensureWIFIConnection(); String params[][2] = {{"NewAIN", "12345 0123456"}, {"NewSwitchState", "TOGGLE"}}; connection.action("urn:dslforum-org:service:X_AVM-DE_Homeauto:1", "SetSwitch", params, 2); } String getStatus() { String paramsb[][2] = {{"NewAIN", "12345 0123456"}}; String reqb[][2] = {{"NewDeviceId", ""}, {"NewSwitchState", ""}}; connection.action("urn:dslforum-org:service:X_AVM-DE_Homeauto:1", "GetSpecificDeviceInfos", paramsb, 1, reqb, 2); return reqb[1][1]; } /** * Makes sure there is a WIFI connection and waits until it is (re-)established. */ void ensureWIFIConnection() { if ((WiFiMulti.run() != WL_CONNECTED)) { WiFiMulti.addAP(wifi_ssid, wifi_password); while ((WiFiMulti.run() != WL_CONNECTED)) { delay(100); } } } ```
Roehrenkramladen commented 3 years ago

Hallo,

ich habe deinen Vorschlag mal getestet. Leider funktioniert es nicht. Der ESP8266 stürzt ab. Der Login ins Wifi funktioniert, wenn er aber die TR064 Verbindung startet stürzt die Software ab. Auslöser ist der "init Prozess". Der blockiert den ESP8266 zu lange, der löst dann WDT (Wachdog Timeout) aus. Führt man das ganze aus wenn im Hintergrund des ESP noch keine Verbindung aktiv funktioniert es einwand frei. D.h. TR064 connection(PORT, IP, fuser, fpass); muss ausgeführt werden bevor die Wifi Verbindung steht. Deshalb steht sie in den Beispielen im "Definition Bereich".

Der seriell Monitor gibt dann folgendes aus. (Click to expand) ``` *WM: AutoConnect *WM: Connecting as wifi client... *WM: Status: *WM: 6 *WM: Using last saved values, should be faster *WM: Connection result: *WM: 3 *WM: IP Address: *WM: 192.168.178.70 Verbunden mit dem WLAN. *WM: freeing allocated params! User exception (panic/abort/assert) --------------- CUT HERE FOR EXCEPTION DECODER --------------- WDT Soft reset Panic core_esp8266_main.cpp:133 __yield stack>>> ctx: cont sp: 3ffef5c0 end: 40215b4a offset: 0000 3ffef5c0: 007a1200 2e4a16ad 00000000 000005b4 3ffef5d0: 000000fe 00000000 00000000 00000000 3ffef5e0: 00000000 00000000 00000000 3ffeeeb0 3ffef5f0: 00000000 00000860 40100288 000005b4 3ffef600: 3fff45a4 3fff1014 3fff1014 4020ada2 3ffef610: 000e5131 00000000 3fff121c 4020adff 3ffef620: 3fff45a4 3fff1014 00000079 4020a669 3ffef630: 3fff45a4 3fff1014 3fff1014 4020908b 3ffef640: 00000000 00000000 00000094 402090cb 3ffef650: 3fff45a4 3fff0c1c 00000000 00003294 3ffef660: 3fff0c1c 00002ce0 3fff45a4 4020ec98 3ffef670: 3fff0c1c 00002ce0 3fff45a4 4020d830 3ffef680: 000005b4 000005b4 00000001 3ffef700 3ffef690: 00000790 000005b4 000000f2 40100773 3ffef6a0: 3fff0c1c 3fff0c1c 3ffef700 3ffef700 3ffef6b0: 3fff0c1c 3fff0c1c 3ffef700 4020d8b7 3ffef6c0: 00000000 3fff0c1c 3fff0c2c 402095 ```

Danke!

Aypac commented 3 years ago

Ok, kannst du auch den entsprechenden Code posten?

Aypac commented 3 years ago

Welches Debug-Level benutzt du?

Also ich wüsste keinen Grund, warum die TR-064 Verbindung zuerst aufgebaut werden müsste. Aber falls das wirklich so ist (wäre dann interessant warum), dann könntest du halt auch einfach die Fragen umkehren (also erst Router-Einstellungen und dann WIFI). Dann ist nur das Problem, dass du dem Nutzer nicht mitteilen kannst, wenn er sich bei den Router Einstellungen vertippt hat.

Roehrenkramladen commented 3 years ago

Hallo,

anbei der Code der den Absturz auslöst,. ,Der Befehl in Zeile 90 tr064_connection.init(); löst den Absturz aus.

Click to expand ``` /* Wifi Türklingel Version 2.0 28.12.2020 (c)Hans Borngräber Einstellungen FritzBox siehe seperate Doku IDE 1.8.13 Historie: 17.10.2019 Integration Batterie Überwachung an Port A0 06.08.2020 Wifi Daten können Online eingetragen werden per Wifi Manager 28.12.2020 Debug_level auf NONE gesetzt, in TR064.cpp. Ergibt stabileren Betrieb bei langsamen WLAN. */ #include #include #include #include #include #include #include WiFiServer server(80); // web server port number auf 80 setzen String USER = "*****"; // Fritzbox - Benutzer <-- muss angepasst werden auf eigene Werte String PASSWORD = "*****"; // Fritzbox - Passwort <-- muss angepasst werden auf eigene Werte String FRITZBOX_IP = "192.168.178.1"; // Fritzbox IP-Adresse <-- muss angepasst werden auf eigene Werte int FRITZBOX_PORT = 49000; // TR064 - Standard Port //TR064 tr064_connection(FRITZBOX_PORT, FRITZBOX_IP, USER, PASSWORD); // An der Fritz-Box anmelden int Messbereich = 6; // Messbereich 6V, über Spannungsteiler eingestellt. int Messport = A0; // Port A0 Analog Eingang int WLAN = 4; // Port D2 WLAN LED int TR064_LED = 5; // Port D1 TR064 LED int DipSW1 = 13; // Port D7 Dip-Switch 1 int DipSW2 = 12; // Port D6 Dip-Switch 2 int DipSW3 = 14; // Port D5 Dip-Switch 3 int Configsw = 16; // Port D0 Config-Switch int Configled = 0; // Port D3 Config-Led //--------------------------------------------------------------------------------------------------------------------------------------- void setup() { pinMode (Configsw, INPUT); // Config Taste pinMode (DipSW1, INPUT); // Dip-Switch 1 pinMode (DipSW2, INPUT); // Dip-Switch 2 pinMode (DipSW3, INPUT); // Dip-Switch 3 Serial.begin(74880); // Geschwindigkeit serielle Schnittstelle 74880 Baud. Standard WEMOS D1. pinMode (Configled, OUTPUT); // Config LED digitalWrite (Configled, HIGH); // Config LED aus pinMode(WLAN, OUTPUT); // WLAN LED digitalWrite(WLAN, HIGH); // WLAN LED aus pinMode(TR064_LED, OUTPUT); // TR064_LED LED digitalWrite(TR064_LED, HIGH); // TR064_LED LED aus WiFiManager wifiManager; // WiFiManager digitalWrite (Configled, LOW); // Config LED ein if (digitalRead(Configsw) == LOW) { // Configuration löschen wenn Configtaste gedrückt wifiManager.resetSettings(); Serial.println ("***************************"); // --------- Debug Meldung Serial.println ("Konfigurations Modus aktiv."); // --------- Debug Meldung digitalWrite (Configled, LOW); // Config LED ein } wifiManager.autoConnect("Wifi-Klingel"); // SSID und Passwort werden aus dem eeprom gelesen. Kommt keine Verbindung damit zustande wird // ein Accesspoint gestartet. Die Schleife läuft solange bis Parameter eingetragen wurden. digitalWrite (Configled, HIGH); // Config LED aus Serial.println("Verbunden mit dem WLAN."); // --------- Debug Meldung digitalWrite(WLAN, LOW); // Wifi Verbindung hergestellt. WLAN LED ein server.begin(); } //--------------------------------------------------------------------------------------------------------------------------------------- void loop() { int (verz) = 0; // Variable für DipSwitch Wert int (Klingelzeit) = 2000; // Variable für Klingelzeit = 2 sec. if (digitalRead(DipSW1) == HIGH) { // DipSwitch 1 auslesen wenn 1 dann verz +1 verz = 1; } if (digitalRead(DipSW2) == HIGH) { // DipSwitch 2 auslesen wenn 1 dann verz +2 verz = verz + 2; } if (digitalRead(DipSW3) == HIGH) { // DipSwitch 3 auslesen wenn 1 dann verz +4 verz = verz + 4; } Klingelzeit = Klingelzeit * verz; // Klingelzeit mit DipSwitch Wert multiplizieren TR064 tr064_connection(FRITZBOX_PORT, FRITZBOX_IP, USER, PASSWORD); // An der Fritz-Box Anmeldedaten tr064_connection.init(); // TR064 Verbindung herstellen Serial.println("---------------------------"); // --------- Debug Meldung Serial.print("Klingelzeit: "); // --------- Debug Meldung Serial.println(Klingelzeit, DEC); // --------- Debug Meldung if (Klingelzeit > 0) { // Wenn Klingelzeit > 0 wird ein Call abgesetzt Serial.println ("************************ TR064 Action **************************"); String tr064_service = "urn:dslforum-org:service:X_VoIP:1"; // Betriebsart Voice over IP einschalten String call_params[][2] = {{"NewX_AVM-DE_PhoneNumber", "**9"}}; // Die Telefonnummer **9 ist der Fritzbox-Rundruf. tr064_connection.action(tr064_service, "X_AVM-DE_DialNumber", call_params, 1); // Ruf absetzen digitalWrite(TR064_LED, LOW); // TR064_LED LED ein delay(Klingelzeit); // Eingestellte Zeit klingeln tr064_connection.action(tr064_service, "X_AVM-DE_DialHangup"); // Telefon auflegen. Ruf beendet digitalWrite(TR064_LED, HIGH); // TR064_LED LED aus } else { for (int i = 1; i <= 5; i++) { // Blinkschleife wenn Klingelzeit = 0. Wird 5x durchlaufen digitalWrite(TR064_LED, LOW); // TR064_LED LED ein delay(200); // Blinkzeit ein 200ms digitalWrite(TR064_LED, HIGH); // TR064_LED LED aus delay(200); // Blinkzeit aus 200ms } } int Batteriespg = analogRead(Messport); // Batteriespannung messen, an Port A0 float Spannung = Batteriespg * ( Messbereich / 1023.0); // Spannung ausrechnen Serial.print ("Messwert: "); // --------- Debug Meldung Serial.println (Spannung); // --------- Debug Meldung if (Spannung > 4.3) { // Wenn gemessene Spannung größer 4,3V, 2 rote LED blinken lassen Serial.println("Batteriespannung OK"); // --------- Debug Meldung for (int i = 1; i <= 5; i++) { // Blinkschleife digitalWrite(TR064_LED, LOW); // LED TR064_LED ein digitalWrite(WLAN, LOW); // LED WLAN LED ein delay(100); // Blinkzeit ein 100ms digitalWrite(TR064_LED, HIGH); // LED TR064_LED aus digitalWrite(WLAN, HIGH); // LED WLAN LED aus delay(200); // Blinkzeit aus 200ms } } Serial.println ("Gehe jetzt schlafen"); // --------- Debug Meldung ESP.deepSleep(0); // Powersafe Modus ein. Aufwachen mit Reset } ```
Aypac commented 3 years ago

If you are using the latest version of the library, you should be able to simply leave that line out, maybe try that.

Aypac commented 3 years ago

Moin Roehrenkramladen, hast du mal versucht die Zeile auszulassen?

Aypac commented 3 years ago

@Roehrenkramladen said in #36

Hallo,

habe es probiert, ohne Init kommt keine TR064 Verbindung zustande. Die Plazierung der Logindaten im Header ist kontraproduktiv. Das verhindert die Übergabe von Daten durch eine Eingabe. Man ist immer auf die hardcodierten Daten angewiesen.
Aypac commented 3 years ago

Ok, bist du sicher, dass du die neuste Version der Bibliothek benutzt?

Aypac commented 1 year ago

Hi/Moin @Roehrenkramladen, I just merged an important bug-fix. Can you see if it works for you now, using version 1.2.1? Or did you solve it in the meantime? How?

Ich habe gerade einen Bugfix gemerged, kannst du testen ob es mit der neuen Version (1.2.1) funktioniert? Oder hast Du es in der Zwischenzeit anderweitig gelöst? Wie?

spekulatius-fb commented 1 year ago

Hi @Aypac, I was facing the same issue that was brought up by @Roehrenkramladen when building an Sketch for ESP8266.

Even with the new library 1.2.1 the following code will not work for me:

`... char FritzBoxIp = "192.168.178.1; char Password = "TestUser"; char* User = "Password"; ...

void loop() { TR064 connection(FRITZBOX_PORT, FritzBoxIp, User, Password);
connection.init();
... connection.action (.......) } `

But I got it working like this: `... char FritzBoxIp = "192.168.178.1; char Password = "TestUser"; char* User = "Password";

TR064 connection; ...

void loop() { connection.setServer(FRITZBOX_PORT, FritzBoxIp, User, Password);
connection.init();
... connection.action (.......) }`

saak2820 commented 1 year ago

if i may.

Constructors:

TR064 connection(FRITZBOX_PORT, FRITZBOXIP, USER, PASSWORD);
Or TR064 connection;
// you will need to set the Parameter later with connection.setServer(…)_

These are the calls to the constructors. You get an instance of the TR064 class. This call should be done only once (dont put this in loop()) and is in the configuration under the variables, because "connection" is the variable of the TR064.

Methods:

connection.setServer(FRITZBOX_PORT, FRITZBOX_IP, USER, PASSWORD);
Set the Parameter if you use the empty Constructor.

init() **The init() method establishes the connection to the FritzBox. Necessary for this is a network connection.

state() With if(connection.state()<0) the connection to the FritzBox can be checked and if necessary restored by calling init() again.**

Examples:


String USER = ""; String PASSWORD = ""; String FRITZBOX_IP = "192.168.178.1"; int FRITZBOX_PORT = 49000;

TR064 tr064_connection(FRITZBOX_PORT, FRITZBOX_IP, USER, PASSWORD); void setup(){

}

void loop() { if(connection.state()<0){
connection.init(); } }


String USER = ""; String PASSWORD = ""; String FRITZBOX_IP = "192.168.178.1"; int FRITZBOX_PORT = 49000;

TR064 tr064_connection; void setup(){ connection.setServer(FRITZBOX_PORT, FRITZBOX_IP, USER, PASSWORD);
}

void loop() { if(connection.state()<0){
connection.init(); } }

Aypac commented 1 year ago

Thanks @saak2820 ! Did it solve your problem @spekulatius-fb ?