Modul für Nest Protect - Beta verfügbar

Begonnen von Mitch, 12 Mai 2017, 21:16:03

Vorheriges Thema - Nächstes Thema

Mitch

Hallo Zusammen,

das erste Beta Modul ist verfügbar: https://forum.fhem.de/index.php/topic,71881.msg637627.html#msg637627
FHEM im Proxmox Container

Mitch

So, habe mich jetzt selber versucht und mit viel Lesen, Kopieren angefangen.

Nun stehe ich vor dem Problem, wie ich aus dem JSON die Daten raus bekommen.

Wenn ich folgendes mache:
sub
nestprotect_Set($$@)
{
  my ($hash, $name, $cmd) = @_;

  my $list = "update";

  my $json = JSON->new->allow_nonref;

  if( $cmd eq 'update' ) {
        my $output = `AUFRUF VON CURL`;

       my $result = $json->decode($output);
       print Dumper($result);

       Log3 $name, 1, "nestprotect update done";
    return undef;
  }       

  return "Unknown argument $cmd, choose one of $list";
}


Bekomme ich folgendes im Log (ist verkehrt herum, also von unten nach oben):
2017.05.16 11:56:27 1: nestprotect update done
}
                  }
                                                                                }
                                                                                              }
                                                                                                                                                            }
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLsphSlBV5SNg'
                                                                                                                                                              'name' => 'Driveway',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLsphSlBV5SNg' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLkCJj2If5Cgg'
                                                                                                                                                              'name' => 'Downstairs',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLkCJj2If5Cgg' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLRQGIV3EzkYg'
                                                                                                                                                              'name' => 'Family Room',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLRQGIV3EzkYg' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLHdP5uCq0BFQ'
                                                                                                                                                              'name' => 'Office',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLHdP5uCq0BFQ' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLCFiB8N_58aA'
                                                                                                                                                              'name' => 'Basement',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvLCFiB8N_58aA' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvL0QAyCdyzugQ'
                                                                                                                                                              'name' => 'Entryway',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvL0QAyCdyzugQ' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvKytZg_XieD5g'
                                                                                                                                                              'name' => 'Outside',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvKytZg_XieD5g' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvKxXrVNNxxsqw'
                                                                                                                                                              'name' => 'Front Yard',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvKxXrVNNxxsqw' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvK__bLSo2sogg'
                                                                                                                                                              'name' => 'Upstairs',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvK__bLSo2sogg' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvKEKZWtwvMEbA'
                                                                                                                                                              'name' => 'Den',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvKEKZWtwvMEbA' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJxx9YRGw6Ccg'
                                                                                                                                                              'name' => 'Hallway',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJxx9YRGw6Ccg' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJifA15JewUnw'
                                                                                                                                                              'name' => 'Master Bedroom',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJifA15JewUnw' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJesGvetXrhpw'
                                                                                                                                                              'name' => 'Bedroom',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJesGvetXrhpw' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJSQ_DmLkBZ0g'
                                                                                                                                                              'name' => 'Dining Room',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJSQ_DmLkBZ0g' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJDa8Oc0DXjVA'
                                                                                                                                                              'name' => 'Backyard',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvJDa8Oc0DXjVA' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvIVxTsdicxhmw'
                                                                                                                                                              'name' => 'Living Room',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvIVxTsdicxhmw' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvIPtCUKg21e8A'
                                                                                                                                                              'name' => 'Kids Room',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvIPtCUKg21e8A' => {
                                                                                                                                                            },
                                                                                                                                                              'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvIPJuRui1UoPQ'
                                                                                                                                                              'name' => 'Kitchen',
                                                                                                'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvIPJuRui1UoPQ' => {
                                                                                  'wheres' => {
                                                                                  'time_zone' => 'Europe/Berlin',
                                                                                  'structure_id' => 'cAGFUR8BWMnKqvGZJbvkZ1yfb7LDqRqiKoYh_oAUtUBO6A3lfyA00g',
                                                                                                       ],
                                                                                                         'EcGWQj0ttd81RSC0ZyyUvji38A4Bj6n8'
                                                                                  'smoke_co_alarms' => [
                                                                                  'smoke_alarm_state' => 'ok',
                                                                                  'name' => 'Zweigstrasse',
                                                                                  'country_code' => 'DE',
                                                                                  'co_alarm_state' => 'ok',
                                                                                  'away' => 'home',
                    'cAGFUR8BWMnKqvGZJbvkZ1yfb7LDqRqiKoYh_oAUtUBO6A3lfyA00g' => {
  'structures' => {
                },
                  'client_version' => 2
                  'access_token' => 'c.hYwZ8Yddwe3iRXiLBuBcWigWMThMZlPwfwGZbkkzje70mUa6MJJQWer7ItdxqHOzxet8kcE5UbLEBSqBZHbvV2Yggkk7Q07w3g9OhQlb8sfNFZJkDPQuLvjYI2SN23uKmbCaF5kjK8ARZxre',
  'metadata' => {
               },
                                      }
                                                                              }
                                                                                'where_name' => 'Living Room'
                                                                                'where_id' => 'x-temEyTZjFyNsR7u-mlevey9slX8u0rcFnLz8vLFvIVxTsdicxhmw',
                                                                                'ui_color_state' => 'green',
                                                                                'structure_id' => 'cAGFUR8BWMnKqvGZJbvkZ1yfb7LDqRqiKoYh_oAUtUBO6A3lfyA00g',
                                                                                'software_version' => '3.1.2rc1',
                                                                                'smoke_alarm_state' => 'ok',
                                                                                'name_long' => 'Living Room Nest Protect',
                                                                                'name' => 'Living Room',
                                                                                'locale' => 'de-DE',
                                                                                'last_manual_test_time' => '2017-05-12T05:47:43.000Z',
                                                                                'last_connection' => '2017-05-15T11:44:07.326Z',
                                                                                'is_online' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
                                                                                'is_manual_test_active' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
                                                                                'device_id' => 'EcGWQj0ttd81RSC0ZyyUvji38A4Bj6n8',
                                                                                'co_alarm_state' => 'ok',
                                                                                'battery_health' => 'ok',
                                        'EcGWQj0ttd81RSC0ZyyUvji38A4Bj6n8' => {
                 'smoke_co_alarms' => {
  'devices' => {
{


Wen nich folgendes mache:
sub
nestprotect_Set($$@)
{
  my ($hash, $name, $cmd) = @_;

  my $list = "update";

  my $json = JSON->new->allow_nonref;

  if( $cmd eq 'update' ) {
        my $output = `AUFRUF VON CURL`;

       my $result = $json->decode($output);
       return $result;

       Log3 $name, 1, "nestprotect update done";
    return undef;
  }       

  return "Unknown argument $cmd, choose one of $list";
}


Bekomme ich:
HASH(0xa9438f8)

Wie bekomme ich denn die Daten "sauber" aus dem JSON?
FHEM im Proxmox Container

dev0

ZitatWie bekomme ich denn die Daten "sauber" aus dem JSON?
Hast Du doch schon. Die Keys/Values aus dem JSON String hast Du nun in einem Hash (associative array). Wenn Du die Struktur kennst, dann kannst Du Dir die Werte rauspicken, die Du benötigst. zB:

my value = $result->{key1}{key2}{key3};


Wenn Du die Struktur nicht genau kennst, dann kannst Du zB. foreach/while Schleifen nutzen, um die einzelnen keys/values zu verarbeiten. Beispiele findest Du zb. hier:
http://perldoc.perl.org/perlfaq4.html#Data%3a-Hashes-(Associative-Arrays)
https://perlmaven.com/perl-hashes
https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/98_expandJSON.pm

Vielleicht hilt es Dir bei der Einarbeitung...

Mitch

Vielen Dank, das hat mir geholfen.

Nachdem ich erstmal verstehen mußte, wie so ein JSON aufgebaut ist, habe ich es auch hinbekommen.
Wahrscheinlich super kompliziert, aber es geht erstmal und ich bin ja noch am lernen.

Internals:
   NAME       NestWozi
   NR         811
   STATE      active
   TYPE       nestprotect
   Helper:
     Dblog:
       State:
         Mydblog:
           TIME       1494936012.002
           VALUE      update
   Readings:
     2017-05-16 14:55:20   Batteriestatus  ok
     2017-05-16 14:55:20   CO-Status       ok
     2017-05-16 14:55:20   Letzter Kontakt zur Cloud 2017-05-16T10:44:08.025Z
     2017-05-16 14:55:20   Name            Living Room
     2017-05-16 14:55:20   Nest ist online 1
     2017-05-16 14:55:20   Rauch-Status    ok
     2017-05-16 14:55:20   Softwareversion 3.1.2rc1
     2017-05-16 14:55:20   Sprache         de-DE
Attributes:


Jetzt geht es weiter.
Nun muß ich einen Interval einbauen, damit die Daten auch schön aktuell gehalten werden.

Danach möchte ich das ganze "verallgemeinern". Im Moment ist es nur manuell mit meinen Daten (Token, ID, usw.).
Es soll dann per Attribut diese Dinge übergeben werden.

Es ist noch ein laaaaanger Weg.....
FHEM im Proxmox Container

CoolTux

Schau Dir doch an wie andere Module das machen


Stichwort InternalTimer.74_ Hombot.pm macht das zum Beispiel.
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

Mitch

#5
Danke, schau ich mir an.

Eine weitere Frage  :-[

Ich habe folgende Aufruf:
my $output = `curl -s -L -H "Content-Type: application/json" -H "Authorization: Bearer xxxxxx" -X GET "https://developer-api.nest.com/"`;

und möchte den Token als Variable übergeben.
Ich bekomme das aber mit dem "Escapen" nicht hin.

Im Prinzip brauche ich so etwas:
my $output = `curl -s -L -H "Content-Type: application/json" -H "Authorization: Bearer '$token'" -X GET "https://developer-api.nest.com/"`;

Habe schon alle möglichen Anführungszeichen ausprobiert und auch concatenation
my $output = 'curl -s -L -H "Content-Type: application/json" -H "Authorization: Bearer ' . $token . '" -X GET "https://developer-api.nest.com/"';
FHEM im Proxmox Container

amenomade


my $output = qx("curl -s -L -H \"Content-Type: application/json\" -H \"Authorization: Bearer $token\" -X GET \"https://developer-api.nest.com/\"");
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Mitch

das geht leider nicht, das stürzt fhem komplett ab
FHEM im Proxmox Container

amenomade

#8
Bei mir nicht...

Und ohne quotes?
qx(curl -s -L -H \"Content-Type: application/json\" -H \"Authorization: Bearer $token\" -X GET \"https://developer-api.nest.com/\")

Oder so?
my $command='curl -s -L -H \"Content-Type: application/json\" -H \"Authorization: Bearer '. $token.'\" -X GET \"https://developer-api.nest.com/\';
my $output=qx($command);


EDIT: nicht sicher, dass die Anführungszeichen in der erste Variante "escaped" werden müssen
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

CoolTux

Hallo Mitch,

Du bist ja nun schon sehr weit gekommen. Daher ein Tip zu Deinen Readings. Wenn Dein Modul auch mal offiziell werden soll, schaue Dir einmal an wie Readings Namenstechnisch aufgebaut sind.

Meine Empfehlung
Englisch
Immer zusammen.

Bsp: lastCloudeContact
room
onlineState

Und so weiter. Ist nur ein kleiner Tip.
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

amenomade

Und noch ein Tipp: noch besser so: lastCloudContact

;) ;)

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

Mitch

Danke euch, habe die Readings umgebaut.

Leider bekomme ich das mit der Token-Übergabe immer noch nicht hin.
Egal wie ich quote oder escape, mein fhem stürzt immer ab  >:(

Hier mal der aktuelle List:
Internals:
   DEF        60 xxxx
   NAME       NestWozi
   NR         811
   STATE      Status-Rauch: ok - Status-CO: ok - Batterie: ok
   TOKEN      xxxx
   TYPE       nestprotect
   Readings:
     2017-05-17 08:42:56   battery         ok
     2017-05-17 08:42:56   co_status       ok
     2017-05-17 08:42:56   last_seen       2017-05-16T10:44:08.025Z
     2017-05-17 08:42:56   name            Living Room
     2017-05-17 08:42:56   online          1
     2017-05-17 08:42:56   smoke_status    ok
     2017-05-17 08:42:56   softwareversion 3.1.2rc1
     2017-05-17 08:42:56   sprache         de-DE
     2017-05-17 08:42:56   state           okay
Attributes:
   group      Rauchmelder
   room       Zentrale
   stateFormat Status-Rauch: smoke_status - Status-CO: co_status - Batterie: battery
FHEM im Proxmox Container

dev0

Zitat von: Mitch am 17 Mai 2017, 08:45:16
Leider bekomme ich das mit der Token-Übergabe immer noch nicht hin.
Du kannst so etwas auch per telnet oder in der FHEMWEB Eingabezeile testen, in dem Du den Perlausdruck in geschweifte Klammern setzt.

Getestet:

my $command = 'curl -s -L -H "Content-Type: application/json" -H "Authorization: Bearer '. $token.'" -X GET "https://developer-api.nest.com/"'

Mitch

So, nochmal vielen Dank, ich habe es hin bekommen.

Jetzt baue ich noch den Interval ein und dann ist die Beta fertig und wird hier vorgestellt zum testen.
FHEM im Proxmox Container

CoolTux

Es ist immer die eigene Motivation die einen zu Leistungen treibt.

Ich sage einfach mal herzlichen Glückwunsch zu Deinem ersten Modul in Perl geschrieben.
In ein paar Monaten wirst Du das ganze mehr und mehr verstehen und auf die httpUtils umbauen können.

Nimm mich als Beispiel. Vor 2 Jahren hatte ich dank Andre und 2 anderen mit AMAD ganz einfach angefangen. Mit HttpUtils und Intervalabfrage.
Jetzt habe ich einen eigenen Socket Server, baue das ganze gerade auf 2 stufiges Modul mit JSON Protokoll um und schreibe einen Installationsassistanten für Automagic.
Wenn man erstmal Blut geeckt hat macht es riesen Spaß.



Grüße
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