Miele 3rd party API in FHEM einbinden

Begonnen von xerion, 16 Januar 2019, 22:26:52

Vorheriges Thema - Nächstes Thema

amenomade

Dans probier mal mit "Content-Type: text" oder "Content-Type:" (leer)
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

xerion

Bei den beiden Varianten bekomme ich:
HTTP/1.1 500 Internal Server Error
Date: Sat, 19 Jan 2019 10:40:35 GMT
Content-Type: text/html
Content-Length: 186
Connection: close
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
Strict-Transport-Security: max-age=15724800; includeSubDomains

<html>
<head><title>500 Internal Server Error</title></head>
<body bgcolor="white">
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx</center>
</body>
</html>
Ich würde mich  freuen, wenn du meinen Einladungscode für Tibber, der Stromanbieter, der dir hilft, deinen Stromverbrauch zu verstehen und zu reduzieren, nutzt: https://invite.tibber.com/5fc08jbs. So bekommen wir beide 50 Euro und 100 % Ökostrom / https://geld-fuer-eauto.de/ref/334561880

amenomade

Vielleicht kannst Du mir jetzt helfen: ich schaffe es nicht, mit Postman die Geräteliste zu erreichen, und kriege immer "Autentication failed", obwohl ich ein oauth2 Token generieren lassen habe... Wie hast Du es geschafft?
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

xerion

Erzeugt habe ich den Token mit Postman über "Get New Access Token" unter den Reiter Authorization:
siehe "Get Token.jpg
Danach die entsprechenden Daten eingeben:
siehe Token Value.jpg
Den Type nicht als "OAuth 2.0" stehen lassen, sonder auf "Bearer Token" umstellen und unter "Token" den erhaltenen Token eintragen.
siehe Token.jpg
Dann solltest du die Daten im JSON Format erhalten.
siehe JSON.jpg

Ich würde mich  freuen, wenn du meinen Einladungscode für Tibber, der Stromanbieter, der dir hilft, deinen Stromverbrauch zu verstehen und zu reduzieren, nutzt: https://invite.tibber.com/5fc08jbs. So bekommen wir beide 50 Euro und 100 % Ökostrom / https://geld-fuer-eauto.de/ref/334561880

amenomade

Genauso habe ich auch gemacht, und beim GET /v1/devices/ kriege ich immer Authentication failed...
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

amenomade

Zur Sicherheit, habe ich noch meinen Miele Trockner (nicht Smart, aber zumindest macht es ein Gerät in der Liste) registriert.
Geht immer noch nicht.

Ich habe aber gesehen, dass ich auch die Antwort 415 kriege, wenn ich irgendwelche Content-Type hinzufüge. Dann muss ich ein bisschen gucken, wie man bei HTTPMOD dieses Content-type urlencode vermeiden kann.

Ansonsten, wird es schwierig, dir weiter zu helfen, wenn ich nicht selbst experimentieren kann. Sorry.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

xerion

Das ist ja seltsam. Könnte natürlich daran liegen, dass kein Gerät vorhanden ist was mit der Cloud verbunden ist, kann ich aber auch nicht sicher sagen.
Wie kommen wir dann weiter kommen?
Ich würde mich  freuen, wenn du meinen Einladungscode für Tibber, der Stromanbieter, der dir hilft, deinen Stromverbrauch zu verstehen und zu reduzieren, nutzt: https://invite.tibber.com/5fc08jbs. So bekommen wir beide 50 Euro und 100 % Ökostrom / https://geld-fuer-eauto.de/ref/334561880

amenomade

Also... man kann ein bisschen weiter mit dem "get devices" und dem bestehenden Token experimentieren, aber blind werde ich das Verfahren zur Erneuerung des Tokens nicht hinkriegen.

Ich melde mich.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

amenomade

Also: mit allen möglichen Content-Type kriege ich entweder "415 - unsupported media type" oder "500 - internal server error". Aber mit Content-Type: application/json bekomme ich mit meinem nicht funktionierenden Token "401 - unauthorized"

Dann vermute ich, es ist so richtig.
Hier meine Definition:

defmod Miele_API3 HTTPMOD https://api.mcs3.miele.com/v1/devices/?language=de 0
attr Miele_API3 enableControlSet 1
attr Miele_API3 requestHeader01 Authorization: Bearer DE_zzzzzz
attr Miele_API3 requestHeader02 Content-Type: application/json
attr Miele_API3 verbose 5


Dann manuell auslesen mit set Miele_API3 reread.
Versuch mal bitte (kreiere bitte ein neues sauberes Device, deswegen habe ich es Miele_API3 genannt)
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

xerion

Du bist perfekt! Vielen Vielen Dank. :)
Das wars jetzt bekomme ich die Daten, nur noch extraxtAllJSON aktiviert und schon waren alle Werte in den Readings.
Haben wir denn noch eine Möglichkeit, den Token automatisch zu refreshen und dann zu übergeben?
Ich würde mich  freuen, wenn du meinen Einladungscode für Tibber, der Stromanbieter, der dir hilft, deinen Stromverbrauch zu verstehen und zu reduzieren, nutzt: https://invite.tibber.com/5fc08jbs. So bekommen wir beide 50 Euro und 100 % Ökostrom / https://geld-fuer-eauto.de/ref/334561880

amenomade

#25
Zitat von: xerion am 20 Januar 2019, 13:42:16
Haben wir denn noch eine Möglichkeit, den Token automatisch zu refreshen und dann zu übergeben?
Das ist bestimmt möglich. Wird aber mühsam, wenn ich nicht selbst experimentieren kann. Prinzipiell geht das so:
- reAuthRegex Unauthorized|Authentication failed => um zu wissen, wenn der Token nicht mehr funktioniert
- mit sid1 attribute, GET /thirdparty/login/
- mit sid2 attribute, POST /oauth/auth mit user/passwort, und "code" fangen
- mit sid3 attribute, POST /thirdparty/token und Token fangen


Alternativ gibt es auch anscheinend eine Möglichkeit, Tokens zu erneuern... (Refresh Token flow)

So was in der Art. Es ist aber sehr theoretisch ;) Ich werde mal gucken, was ich kann: Grunsätzlich kann ich schon Tokens generieren lassen (zumindest mit Postman), auch wenn die nicht funktionieren...
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

amenomade

#26
Also... Da mein Token nie funktioniert, wird logischerweise bei mir bei jedem "set reread" der Token wieder erneuert, aber am Ende habe ich auch logischerweise immer noch Unauthorized. Aber grundsätzlich wird mein Token ordentlich erneuert und die Request01 wird durch request01Header mit dem neuen Token gerufen !

defmod Miele_API3 HTTPMOD https://api.mcs3.miele.com/v1/devices/?language=de 0
attr Miele_API3 enableControlSet 1
attr Miele_API3 reAuthRegex Unauthorized
attr Miele_API3 requestHeader01 Authorization: Bearer $sid
attr Miele_API3 requestHeader02 Content-Type: application/json
attr Miele_API3 sid1URL https://api.mcs3.miele.com/thirdparty/login/?response_type=code&state=login&client_id=zzzzzMeinClientID&scope=&redirect_uri=https%3A%2F%2Fapi.mcs3.miele.com%2Fthirdparty%2Flogin%2F
attr Miele_API3 sid2Data email=zzzzzMeinEmail&password=zzzzzMeinPasswort&redirect_uri=https%3A%2F%2Fapi.mcs3.miele.com%2Fthirdparty%2Flogin%2F&state=login&response_type=code&client_id=zzzzzMeinClientID&vgInformationSelector=de-DE
attr Miele_API3 sid2IdRegex (?s)code=(DE_[0-9a-f]+)
attr Miele_API3 sid2IgnoreRedirects 1
attr Miele_API3 sid2URL https://api.mcs3.miele.com/oauth/auth
attr Miele_API3 sid3Data grant_type=authorization_code&code=$sid&redirect_uri=https%3A%2F%2Fapi.mcs3.miele.com%2Fthirdparty%2Flogin%2F&client_id=zzzzzMeinClientID&client_secret=zzzzzMeinClientSecret
attr Miele_API3 sid3IdJSON access_token
attr Miele_API3 sid3URL https://api.mcs3.miele.com/thirdparty/token/
attr Miele_API3 verbose 5


Natürlich, alle zzzzzMein.* Parameter durch deine ersetzen.

Für den ersten Test ist $sid noch nicht bekannt, dann sollte er die Erneuerung anfordern. Der neue Token wird dann im Internal "sid" gespeichert.

Wenn weitere Erneuerungstests benötigt werden, dann solltest Du reAuthRegex auf irgendwas setzen, was mit dem erfolgreichen Aufruf der /v1/devices Seite stimmt, damit er die Erneuerung zwingt. Z.B. deine Devicenummer 000149130299 vom ersten Post. Wenn letztendlich alles geht, dann wieder auf Unauthorized... bis Du evtl. feststellst, dass beim abgelaufenden Token eine andere Fehlermledung kommt (laut Swagger Doku sollte es aber nicht sein). Dann ggf. einfach auf Unauthorized|andereMeldung setzen.

Wenn es nicht geht, dann wie immer die verbose 5 log und ein "list" deines HTTPMOD. (Vorsicht, viel zu anonymisieren)
Wenn Fragen zur Verständnis, gerne hier posten.
Danach können wir vielleicht mit der PUT Methode anfangen, wobei ich nicht weiss, ob HTTPMOD das kann ;)

EDIT: tatsächlich kann HTTPMOD (bzw. HttpUtils) nur GET und POST. Da bleiben nur alternative Methoden per perl Code...
EDIT2: die HTTPMOD Geschichte ist aber für dein Projekt nicht komplett umsonst, da Du schon mit {InternalVal("Miele_API3","sid","")} den Token holen kannst, und mit {fhem "set Miele_API3 reread";} eine Möglichkeit hast, um den zu erneueren.


Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

xerion

Wow. Das hat auch wieder funktioniert. Besten Dank. Wenn wir jetzt noch die PUT Geschichte hinbekommen wäre es perfekt.
Aber wie du schon sagt, das wird wohl mit HTTPMOD nicht gehen. Habe im Forum schon einen zweiten Eintrag gefunden der auch was über PUT umsetzen möchte, aber dort steht die Antwort noch aus. https://forum.fhem.de/index.php/topic,92178.msg846886.html#msg846886
Momentan sende ich das einfach mit einem Python Skript, aber dort wechselt sich ja nicht der nicht der Token automatisch.
Wäre vielleicht was über cURL möglich, so das man den Token dann als Variable übergeben kann?
Ich würde mich  freuen, wenn du meinen Einladungscode für Tibber, der Stromanbieter, der dir hilft, deinen Stromverbrauch zu verstehen und zu reduzieren, nutzt: https://invite.tibber.com/5fc08jbs. So bekommen wir beide 50 Euro und 100 % Ökostrom / https://geld-fuer-eauto.de/ref/334561880

amenomade

Ich habe ein bisschen wegen PUT überlegt. Es sollte einfach mit curl funktionieren, da kriegst Du aber keine Rückantwort zurück, wenn Du es non-blocking möchtest. Deswegen müsste man zuerst durch ein reread sicherstellen, dass der Token noch gültig ist.

Etwas in der Art (nicht getestet)

{ fhem "set Miele_API3 reread";
if (ReadingsVal("Miele_API3", "status", 0)==4) { #laut put preconditions in der Doku
   system("curl -X PUT \"https://api.mcs3.miele.com/v1/devices/000149130299/actions\" -H  \"accept: */*\" -H  \"Content-Type: application/json\" -H \"Authorization: Bearer ".InternalVal("Miele_API3","sid", "")."\" -d '{\"processAction\":1}' &")
  }
}
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

amenomade

#29
Hab ein bisschen weiter experimentiert. Sowas könnte funktionieren:

In 99_myUtils:
sub mieleStart() {
  my $befehl = "curl -X PUT 'https://api.mcs3.miele.com/v1/devices/000149130299/actions' -H 'accept: */*' -H 'Content-Type: application/json' -H 'Authorization: Bearer ";
  $befehl .= InternalVal("Miele_API3","sid", "");
  $befehl .= "' -d '{\"processAction\":1}' &";
  Log 3,$befehl;
  system("$befehl");
  return 0;
}


Und dann in einem notify auf deinem PV-Anlage, oder ein DOIF oder hier ein at:
defmod atcurl at *01:00 set Miele_API3 reread;; sleep 10;; { mieleStart() }

Wie gesagt, reread um sicher zu stellen, dass der Token OK ist, dann 10 Sekunden (non blocking) warten, um sicher zu sein, dass der HTTPMOD fertig ist, und dann das PUT (das & am Ende, um zu forken, damit es auch non blocking wird)

Dann könnte man noch ein reread reinpacken, um den Status zu aktualisieren...
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus