CCU abfragen mit Arduino

Allgemeines zur HomeMatic Haussteuerung

Moderator: Co-Administratoren

Antworten
svenp
Beiträge: 630
Registriert: 11.12.2012, 14:24
Hat sich bedankt: 3 Mal
Danksagung erhalten: 4 Mal

CCU abfragen mit Arduino

Beitrag von svenp » 15.09.2017, 17:38

Hallo, ich stehe gerade auf dem Schlauch.
Ich möchte mit Arduino einen Wert aus der CCU auslesen.

Wenn ich folgenden Befehl im Webbrowser eingebe:

Code: Alles auswählen

http://192.168.1.90:8181/xy.exe?antwort=dom.GetObject(CUxD.CUX4000001:2.STATE).State()
Bekomme ich folgenden Output:

Code: Alles auswählen

<xml><exec>/xy.exe</exec><sessionId/><httpUserAgent>User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0</httpUserAgent><antwort>true</antwort></xml>
Wenn ich nun das gleiche per Arduino versuche:

Code: Alles auswählen

 WiFiClient client; // Webclient initialisieren
  if (!client.connect(host, 8181)) { // mit dem CCU-Port 8181 verbinden
    delay(100);
    return;
  client.println("GET /xy.exe?antwort=dom.GetObject('CUxD.CUX4000001:4.STATE').State()"); // Daten an CCU melden
while(client.available()){
zeile = client.readString();
Serial.println(zeile);
  }
Bekomme ich folgende Meldung:

Code: Alles auswählen

Antwort von CCU Zeile->:HTTP/1.1 200 OK
Server: ise GmbH HTTP-Server v2.0
Accept-Ranges: bytes
Cache-Control: no-store, no-cache
Content-Type: text/xml
Content-Length: 109
Date: Fri, 15 Sep 2017 17:29:35 GMT
Leider fehlt hier der xml Output.

Kann mir jemand sagen was ich falsch mache?

svenp
Beiträge: 630
Registriert: 11.12.2012, 14:24
Hat sich bedankt: 3 Mal
Danksagung erhalten: 4 Mal

Re: CCU abfragen mit Arduino

Beitrag von svenp » 16.09.2017, 12:55

Hallo, so ich habe für mich eine Lösung gefunden.
Keine Ahnung ob das nun besonders elegant ist oder wie man das besser machen kann.
Ich habe nun viel mit yield() und delay(xxx) probiert und einige sketche im Web gelesen.
Meine derzeitige Lösung ist folgende:

Code: Alles auswählen

 WiFiClient client; // Webclient initialisieren
  if (!client.connect(host, 8181)) { // mit dem CCU-Port 8181 verbinden
    smeldung("  Fehler: Verbindung zur CCU konnte nicht aufgebaut werden");
     delay(100);
    return;
  }
 client.print(befehl + " Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  yield();
  String zeile = "";
  while(client.available() == 0 ){ // Antwort der CCU zeilenweise auslesen
    i ++;
    //zeile = client.readStringUntil('\n'); // Zeitstempel der CCU ausfiltern und merken
    zeile = client.readString(); // Zeitstempel der CCU ausfiltern und merken
    //yield();
    smeldung("Antwort von CCU Zeile->:" + String(i) + ":"  + zeile);
    break;
Wichtig ist die Rote Erweiterung, sonst fehlt die eigentliche XML Zeit.
client.print(befehl + " Host: " + host + "\r\n" + "Connection: close\r\n\r\n");

Mit der while Zeile bin ich auch noch etwas unzufrieden, eigentlich wird diese auch nicht wirklich benötigt da die CCU nur eine Zeile zurück liefert deshalb auch der break und die Schleife zu verlassen.

Die Rückgabe der CCU sieht nun wie folgt aus:

Code: Alles auswählen

HTTP/1.1 200 OK
Server: ise GmbH HTTP-Server v2.0
Accept-Ranges: bytes
Cache-Control: no-store, no-cache
Content-Type: text/xml
Content-Length: 109
Date: Sat, 16 Sep 2017 12:54:04 GMT

<xml><exec>/xy.exe</exec><sessionId></sessionId><httpUserAgent></httpUserAgent><antwort>false</antwort></xml>

bernd33-1
Beiträge: 1
Registriert: 12.11.2017, 10:10

Re: CCU abfragen mit Arduino

Beitrag von bernd33-1 » 12.11.2017, 10:42

Hi,

ich bin zwar auch kein Experte aber hier mal ein Erklärungsansatz.

Wenn du mit einem Browser eine GET Anfrage an einen WEB-Server sendest dann erwartet der Web-Server eine paar Parameter. Genau genommen diese:

GET /index.php?suche=anfragemethoden+formular HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: image/gif, image/jpeg, */*
Connection: close
<EINE LEERZEILE>

Du hast geschrieben, dass du in einen Browser folgende Zeile eintippen kannst und alles geht:
http://192.168.1.90:8181/xy.exe?antwort ... ATE).State()

Ist klar, weil der Browser ja die oben genannten Parameter korrekt an den Web-Server sendet (der Webserver ist in unserem Fall übrigens die CCU).

Ok, in deinem Arduino Programm hast du zuerst folgendes gemacht:

client.connect(host, 8181);
client.println("GET /xy.exe?antwort=dom.GetObject('CUxD.CUX4000001:4.STATE').State()");
client.stop();

Damit sendet der Arduino aber nur : GET /xy.exe?antwort=dom.GetObject('CUxD.CUX4000001:4.STATE').State() an den Web-Server der CCU. Alles Andere, was der Web-Server eigentlich auch noch erwartet, wird nicht gesendet.

In deinem 2. Post hast du es dann mit folgender Zeile hin bekommen:
client.print(befehl + " Host: " + host + "\r\n" + "Connection: close\r\n\r\n");

Man sieht schon, dass du hier die Benötigten Infos reingepackt hast. Man kann es noch etwas lesbarer schreiben ("host" ist die IP der CCU):
client.connect(host, 8181);
client.println ("GET /xy.exe?antwort=dom.GetObject('CUxD.CUX4000001:4.STATE').State() HTTP/1.1");
client.println ("Host: 192.168.0.10"); <-Das ist die IP MEINER CCU. Muss man an die eigene anpassen.
client.println("Connection: close");
client.println();

Ich hab deine Zeile hierbei nur in mehrere Zeilen zerlegt. Man sieht auch, das die \r\n verschwunden sind. \r\n bedeutet nur "neue leere Zeile" und das Kommando client.println macht das automatisch.
Dann hab ich in der ersten Zeile noch ein HTTP/1.1 angehängt. Achso.... und das "Connection: close" nicht vergessen. Einige denken, dass der Befehl client.close() das machen würde. Tut er aber nicht :-) Und ganz am schluss kommt dann noch eine Leerzeile. Und damit geht es dann.

Ich selbst hab meine Arduinos früher so wie du mit der CCU reden lassen. Das hat eine ganze Zeit lang gut funktioniert. Aber seit dem letzten Firmwareupdate der CCU hat das nichtmehr zuverlässig funktioniert. Daher muss jetzt die "korrekte" kommunikation in das Arduinoprogramm.

Hier ist das mit dem HTTP GEP, POST usw. gut erklärt:
https://wiki.selfhtml.org/wiki/HTTP/Anfragemethoden

Und hier ist ein Arduino Beispielprogramm, in dem man sieht wie die GET-Geschichte im Arduino programiert wird:
https://www.arduino.cc/en/Tutorial/WebClient

GRüße und schönen Sonntag, Bernd

Antworten

Zurück zu „HomeMatic allgemein“