Arduino-TR-064-SOAP-Library icon indicating copy to clipboard operation
Arduino-TR-064-SOAP-Library copied to clipboard

Working example and a question

Open Roehrenkramladen opened this issue 4 years ago • 13 comments

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

Roehrenkramladen avatar Dec 28 '20 21:12 Roehrenkramladen

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 <Arduino.h>
#if defined(ESP8266)
	//Imports for ESP8266
	#include <ESP8266WiFi.h>
	#include <ESP8266WiFiMulti.h>
	#include <ESP8266HTTPClient.h>
	ESP8266WiFiMulti WiFiMulti;
#elif defined(ESP32)
	//Imports for ESP32
	#include <WiFi.h>
	#include <WiFiMulti.h>
	#include <HTTPClient.h>
	WiFiMulti WiFiMulti;
#endif

#include <tr064.h>


// 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);
		}
	}
}

Aypac avatar Dec 29 '20 22:12 Aypac

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!

Roehrenkramladen avatar Dec 30 '20 11:12 Roehrenkramladen

Ok, kannst du auch den entsprechenden Code posten?

Aypac avatar Dec 30 '20 11:12 Aypac

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.

Aypac avatar Dec 30 '20 11:12 Aypac

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 <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <tr064.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>

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
}

Roehrenkramladen avatar Dec 30 '20 11:12 Roehrenkramladen

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

Aypac avatar Jan 06 '21 18:01 Aypac

Moin Roehrenkramladen, hast du mal versucht die Zeile auszulassen?

Aypac avatar Jan 17 '21 12:01 Aypac

@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 avatar Jan 17 '21 23:01 Aypac

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

Aypac avatar Jan 17 '21 23:01 Aypac

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?

Aypac avatar Jul 27 '22 08:07 Aypac

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 (.......) }`

spekulatius-fb avatar Sep 30 '22 12:09 spekulatius-fb

if i may.

Constructors:

TR064 connection(FRITZBOX_PORT, FRITZBOX_IP, 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(); } }

saak2820 avatar Nov 11 '22 10:11 saak2820

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

Aypac avatar Nov 14 '22 11:11 Aypac