[73_GardenaSmartBridge, 74_GardenaSmartDevice] - Module für Gardena Smart System

Begonnen von CoolTux, 05 August 2017, 23:17:06

Vorheriges Thema - Nächstes Thema

CoolTux

Zitat von: Det20 am 27 Februar 2020, 15:33:18
Ich tippe arg doll drauf, dass sich die URL vom C&C Server geändert hat, zusammen mit dem Aufbau der Anmeldung.

Frage mich nur wieso die anderen nicht das Problem haben.
Es hat ja auch mal bei Dir funktioniert oder?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Det20


CoolTux

Dann bekommen die anderen früher oder später auch die Probleme.
Ich weiß leider nur nicht wie der Aufbau jeweils sein muss. Kenne mit mit Java nicht aus um abschauen zu können.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Det20

Ich bin zwar nicht in C zu Hause, aber grundsätzlich verstehe ich den Code (von der Gardena Seite). Habe versucht, den mit PHP nachzubauen, hat leider nicht geklappt.

Hier steht die Reihenfolge (https://developer.1689.cloud/apis/GARDENA+smart+system+API#/readme) mit CURL, weiter unten mit Python. Den API Key habe ich mir schon besorgt (man muss sich mit seinem Gardena-Account einloggen und den beantragen). Habe den auch mit übergeben, das hat dann aber irgendwie nicht geklappt ("Authentification failed"). Und im Teil "Swagger" taucht irgendwie nur der Rasenmäher aus, kein Water-Control. Verstehe die Logik nicht ...

Auf jeden Fall sind dies die neuen URL's, wenn die Doku aktuell und wirklich von Gardena ist. Die wollen aber andere Parameter und einen anderen JSON Aufbau als die von dir verwendete API.


AUTHENTICATION_HOST = 'https://api.authentication.husqvarnagroup.dev'
SMART_HOST = 'https://api.smart.gardena.dev'


Wollte das mit Änderungen mit Deinem Modul versuchen, aber irgendwie bin ich zu blöd. Reload hat die Änderungen nicht geladen und ich musste dauernd FHEM neu starten. Das dauert bei mir aber immer 1-2 Minuten, weshalb alles ewig lange gedauert hat; und eben auch nicht funktioniert hat. Habe es dann versucht so nachzubauen, wie es Firefox hat (F12 = Entwicklertools und gedebuggt), das hat ebenfalls nicht geklappt, weil die anscheinend abfangen, ob der Aufruf von einer Gardena Seite kommt.

Gardena Smart lässt sich zwar über IFTTT ansteuern, aber leider nur mit Google Home, muss also sagen "Ok Google, mach die Zisterne leer". Bringt mir nachts automatisiert also rein garnichts.

CoolTux

Ich habe mir das jetzt mal in Ruhe angeschaut. Im Grunde läuft das ganze auf ein komplett neues Modul hinaus. Zu mindest das Bridgemodul. Das Devicemodul kann man sicherlich so belassen mit Ausnahme der JSON zu Reading Sache.

Aber aktuell habe ich leider keine Zeit dafür.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net


CoolTux

Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Det20

Ok, habe versucht es so einfach wie möglich zu halten.

=== Update ===
Dieser PHP Code funktioniert, hier die Reihenfolge. BaseURL ist immer "https://smart.gardena.com/v1"

1. Anmelden (Methode POST)
URL ist "https://smart.gardena.com/v1/auth/token"
Post-Params: {"data":{"type":"token","attributes":{"username":"'.$Username.'","password":"'.$Password.'","client_id":"smartgarden-jwt-client"}}}

Ergebnis enthält JSON, hier sind ['data']['id'], ['data']['attributes']['provider'] und ['data']['attributes']['user_id']; interessant.
Provider ($Bearer_Prov) und id ($Bearer) müssen im weiteren Verlauf immer im HTTP Header mitgegeben werden.

2. Locations lesen (Methode GET)
URL ist "https://smart.gardena.com/v1/locations?locationId=null&user_id=$userID" ($userID aus Schritt 1)

Im HTTP Header wird benötigt ($Bearer und $Bearer_Prov aus Schritt 1):

- Content-Type: application/json
- Authorization: Bearer $Bearer
- Authorization-Provider: $Bearer_Prov

Ergebnis enthält JSON mit den Devices, zB. ['locations']['0']['id'] und ['locations']['0']['devices'][0]

3. Beispiel Schalten vom Water-Control (Methode PUT)

URL ist "https://smart.gardena.com/v1/devices?locationId=$locationid" ($locationidaus Schritt 2)

Im HTTP Header wird benötigt ($Bearer und $Bearer_Prov aus Schritt 1):

- Content-Type: application/json
- Authorization: Bearer $Bearer
- Authorization-Provider: $Bearer_Prov

Post-Params (für "stop"): {"properties":{"name":"watering_timer_1","value":{"duration":0,"state":"idle","valve_id":1}}}
Post-Params (für "start 1 Min"): {"properties":{"name":"watering_timer_1","value":{"duration":60,"state":"manual","valve_id":1}}}

===


<?
  $Username = 'foo@foo';
  $Password = 'foo';
  $RootURL  = 'https://smart.gardena.com/v1';
  $ClientID = 'smartgarden-jwt-client'; // gegen einen eigen API Key von hier austauschen: https://developer.1689.cloud/apps
 
  //
  // Anmelden mit POST, um Bearer zu bekommen
  //
  $payload = '{"data":{"type":"token","attributes":{"username":"'.$Username.'","password":"'.$Password.'","client_id":"'.$ClientID.'"}}}';
  $url     = $RootURL.'/auth/token';
 
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8'));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $result = curl_exec($ch);
  $code   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);
  var_dump('Login HTTP-Code '.$code.' : '.$result);

  // ... UserID, Bearer auslesen
  $data        = json_decode($result, true);
  $Bearer      = $data['data']['id'];
  $Bearer_Prov = $data['data']['attributes']['provider'];
  $userID      = $data['data']['attributes']['user_id'];
 
 
  // User-Daten auslesen
  $url = $RootURL.'/auth/users/'.$userID;
  $ch  = curl_init($url);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
                                             'Authorization: Bearer '.$Bearer,
                                             'Authorization-Provider: '.$Bearer_Prov));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $result = curl_exec($ch);
  $code   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);
  echo '<br><br>';
  var_dump('User-Data HTTP-Code '.$code.' : '.$result);
 
  $data      = json_decode($result, true);
  $FirstName = $data['data']['attributes']['first_name'];
  $LastName  = $data['data']['attributes']['last_name'];
  $RegProv   = $data['data']['attributes']['registration_provider'];
 
 
  // Locations lesen mit GET
  $url = $RootURL.'/locations?locationId=null&user_id='.$userID;
  $ch  = curl_init($url);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
                                             'Authorization: Bearer '.$Bearer,
                                             'Authorization-Provider: '.$Bearer_Prov));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $result = curl_exec($ch);
  $code   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);
  echo '<br><br>';
  var_dump('Locations HTTP-Code '.$code.' : '.$result);


  // ... und Devices auslesen
  $data       = json_decode($result, true);
  $LocationID = $data['locations']['0']['id'];
  $Gateway    = $data['locations']['0']['devices'][0]; // GW
  $WaterCtl   = $data['locations']['0']['devices'][1]; // WC
 
 
  // Verfügbare Geräte auslesen
  $url     = $RootURL.'/devices?locationId='.$LocationID;
  $ch  = curl_init($url);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
                                             'Authorization: Bearer '.$Bearer,
                                             'Authorization-Provider: '.$Bearer_Prov));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $result = curl_exec($ch);
  $code   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);
  echo '<br><br>';
  var_dump('Device-Info HTTP-Code '.$code.' : '.$result);


  // 5 Minuten anschalten mit POST
  $payload_start = '{"properties":{"name":"watering_timer_1","value":{"duration":300,"state":"manual","valve_id":1}}}';
  $payload_stop  = '{"properties":{"name":"watering_timer_1","value":{"duration":0,"state":"idle","valve_id":1}}}';
  $url           = $RootURL.'/devices/'.$WaterCtl.'/abilities/watering/properties/watering_timer_1?locationId='.$LocationID;
   
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_stop);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
                                             'Authorization: Bearer '.$Bearer,
                                             'Authorization-Provider: '.$Bearer_Prov));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $result = curl_exec($ch);
  $code   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);
  echo '<br><br>';
  var_dump('Set-Command-Info HTTP-Code '.$code.' : '.$result);
?>

Det20

Kurzes Update: Ich habe mir spontan die Gardena Smart Pumpe (Hauswasserwerk) geholt. Die wird vom Modul korrekt erkannt und auch eingebunden, allerdings werden so gut wie keine Daten aktualisiert, lediglich "device_info-last_time_online", "radio-state" und "radio-quality". Habe mein PHP entsprechend angepasst, ist das zweite Device:


    $data     = json_decode($result, true);
    $Status   = $data['devices'][1]['abilities']['5']['properties'][0]['value']['state'];
    $ToGo     = $data['devices'][1]['abilities']['5']['properties'][0]['value']['duration'];
    //
    $Status2  = $data['devices'][2]['abilities']['3']['properties'][1]['value']; // Status
    $Pressure = $data['devices'][2]['abilities']['4']['properties'][0]['value']; // Akt Druck
    $Liter    = $data['devices'][2]['abilities']['5']['properties'][2]['value']; // m³ Seit Start
    $Liter    = $Liter / 0.0010000;                                              // In Liter

Gruvol

Hallo,
Ich habe seit dem Update des Gardena Gerätes die gleichen Probleme wie Det20. Es handelt sich auch um den Waterboy.

Gruß
Gruvol

Det20


CoolTux

Danke für Info. Aktuell kann ich leider nichts tun.
Wer sich im Stande sieht kann es gerne versuchen. Ich kann auch unterstützen bei Bedarf.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Gruvol

Hi,
Ich reagiere auf den Füllstand und schalte das Gerät für eine Stunde an und wartet auf den nächsten Trigger.

Gruß
Gruvol

Det20


bigcheese

Sileno Roboter: seit der neuen Firmware wird anscheinend der Timer anders berechnet - falls ich ihm den OverrideTimer mit wie bisher 1440 sende, fährt er nur noch 24 minuten :)
d.h. entweder müsste der slider angepasst werden in der max-Werte von 74_GardenaSmartDevice oder man schickt über einen anderen schalter eine höhere zeitspanne :)

gruss,
bigcheese