Wecken je nach Verkehrslage z.B. durch Abfrage von google maps (o.ä.)

Begonnen von schlupp, 13 Februar 2014, 00:02:34

Vorheriges Thema - Nächstes Thema

betateilchen

Ok, Crashkurs "Perl & JSON für Anfänger"


use strict;
use warnings;
use JSON qw( decode_json );

my $json = '{
        "name": "Bob",
        "sex": "Male",
        "address": {
                "city": "San Jose",
                "state": "California"
        },
        "friends":
                [
                        {
                                "name": "Alice",
                                "age": "20"
                        },
                        {
                                "name": "Laura",
                                "age": "23"
                        },
                        {
                                "name": "Daniel",
                                "age": "30"
                        }
                ]
}';

my $decoded = decode_json($json);

# city ist ein einzelnes JSON object.
print "City = " . $decoded->{'address'}{'city'} . "\n";

# friends ist ein JSON Array (erkennbar an den eckigen Klammern)

my @friends = @{ $decoded->{'friends'} };
foreach my $f ( @friends ) {
  print $f->{"name"} . "\n";
}


Du kannst Dir den Code in eine Datei test.pl kopieren und
dann mit perl test.pl ausführen, um folgendes Ergebnis zu bekommen.



City = San Jose
Alice
Laura
Daniel



Die Transferleistung auf den Antworttext von Google überlasse ich aber Dir.
Wenn Du das hinbekommst, hast Du das Prinzip verstanden.

Viel Erfolg!
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

StefanStrobel

define TI HTTPMOD https://maps.google.de/maps?saddr=hamburg&daddr=oberhausen&hl=de 60
attr TI readingsName1 Stunden
attr TI readingsName2 Minuten
attr TI readingsRegex1 ([\d]+) Stunden
attr TI readingsRegex2 ([\d]+) Minuten

ist zwar nicht so elegant wie über die API und per JSON, scheint aber auf die erste mögliche Route zu matchen.

Gruss
   Stefan

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

nocomment

Das ganze hier ist echt ne gute Idee für nen Modul :)

Denke viele würden sich über etwas derartiges freuen.

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

StefanStrobel

und noch ne Variante mit HTTPMOD auf die API:

define TI2 HTTPMOD http://maps.googleapis.com/maps/api/distancematrix/json?origins=st.poelten|&destinations=Vienna|&mode=driving&language=de-DE&sensor=false 120
attr TI2 readingsName1 Time
attr TI2 readingsRegex1 duration.*\n.*"text" : "([^"]+)"

sucht nach duration in einer Zeile und nach dem Wert zwischen "" nach "text" :  in der Folgezeile.

netbus

Super, so funktioniert es.
Da meine Abfrage zu global war kamen mehrere alternative Ergebnisse wo man mit regex nicht weiter kam.
Mit dieser präzisen URL http://maps.googleapis.com/maps/api/distancematrix/json?origins=st.poelten|&destinations=Vienna|&mode=driving&language=de-DE&sensor=false 120
kann dein Modul mit Regex den Minuten Wert extrahieren.
Ich verwende als Regex (?=\d{2} Minuten).{2}
Damit werden nur die Zahlen gematched.

Paul

@Betateilchen

Habe mal probiert Deine Aufgabe zu lösen. Kann es aber nicht testen, da ich nur ein
Anwender bin und -ich weiss du schüttelst Dich jetzt- nur Windows und Fritzbox user bin und ich nicht weiß
wie und wo ich diesen Perlcode in Fhem einbinden kann ( Json ist auf meiner Fritte)


use strict;
use warnings;
use JSON qw( decode_json );

my $json = '{
   "destination_addresses" : [ "Wien, Österreich" ],
   "origin_addresses" : [ "Sankt Pölten, Österreich" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "64,4 km",
                  "value" : 64375
               },
               "duration" : {
                  "text" : "49 Minuten",
                  "value" : 2964
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}';
my $decoded = decode_json($json);

print "Die Fahrzeit nach " . $decoded->{'origin_addresses'} .  "beträgt  ";

my @duration = @{ $decoded->{'duration'} };
foreach my $f ( @duration ) {
  print $f->{"text"} . "\n";
}

Cubietruck, HM-USB, CUL, FS20, FHT, HUE, Keymatic

schlupp

Ich sehe hier noch folgendes Problem: Sowie ich verstanden habe liefert die JSON Abfrage über googles distancematrix API nur die Standard-Fahrzeit, nicht jedoch die aktuelle Fahrzeit nach Verkehrslage zurück - die ist nicht besonders interessant, da statisch.
Wir brauchen vielleicht eher die directions API?:
https://developers.google.com/maps/documentation/directions/?hl=de#DirectionsRequests

"value" scheint der interessantere Wert zu sein (Zeit in Sekunden) - dann erspart man sich das parsen des "text" in Stunden, Minuten.



Paul

@schupp

Ich brauche beides nicht, wollte nur mal sehen ob ich nach Anweisung auch perl kann.   ;D

Stimmt value ist der interessantere ,

aber "Die Fahrzeit nach .... beträgt .... Minuten" sieht schöner aus.
Cubietruck, HM-USB, CUL, FS20, FHT, HUE, Keymatic

Rince

Das wird zunehmend spannend hier. Gerade im morgentlichen Berufsverkehr kann es durchaus so sein, dass 20 Minuten früher oder später aufbrechen einen signifikanten Einfluss auf die Fahrzeit hat.
Wenn man sowas im 5 oder 10 Minuten Rythmus abfragen könnte, wäre das schon praktisch.
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

Hans Franz

#26
Moin,

angeregt durch betateilchens Beispiel:
{fahrzeit("Bremen","Hamburg")}


use JSON qw( decode_json );
use LWP::UserAgent;
sub
fahrzeit($$)
{
    my($start,$destination) = @_;
    my $ua = LWP::UserAgent->new();
    my $response = $ua -> get ("http://maps.googleapis.com/maps/api/directions/json?origin=$start&destination=$destination&sensor=false");
    my $json = $response->content();
    my $decoded = decode_json($json);
    my @legs = @{ $decoded->{'routes'}[0]{'legs'} };
    my $distance_meters = 0;
    my $time_duration = 0;
    foreach my $leg (@legs) {
        $distance_meters = $leg->{'distance'}{'text'};
        $time_duration = sprintf('%.2f',($leg->{'duration'}{'value'})/60);
        }
    my $ret = "Die Fahrt von $start nach $destination ist $distance_meters lang und dauert $time_duration Minuten";
    return $ret;
}


Es geht auch als Einzeiler sagt Google. ;)

Gruß
Hans
Raspi
CUL, Nano-CUL
FHT8V, FHT80B, S300TH
WM1000WZ, ELRO
LW12, LD382,DS18B20

TeeVau

Interessante Sache.
Allerdings habe ich gerade festgestellt, dass auch bei Benutzung von directions nicht die Zeit nach aktueller Verkehrslage ausgegeben wird.
Habe es getestet mit der Strecke Wohnung -> Firma. Google Maps sagt normal 45 Minuten, bei aktueller Verkehrslage 56.
Die Directions Ausgabe sagt immer 45 Minuten.
FHEM 5.8 dev (virtualisiert) / FBF 7390 (CUL 868MHz V 1.51 / panStick (AVR1))
FS20: fs20di,fs20pira,fs20sm8,fs20st2,fs20tfk,fs20ue1,fs20ws1
panStamp (AVR1): RGB Multi von ext23, 1W-DSxxxx, I/O Sketch, Spritzpumpe
Multimedia: Panasonic TV (VIERA), Kodi, Yamaha RX-V781, LMS
Sonstiges: XiaomiFlowerSen

mi.ke

Dann such doch nach "aktueller Verkehrslage"


define TI HTTPMOD https://maps.google.de/maps?saddr=xxxxxxxxxxxxxxx&daddr=xxxxxxxxxxxx&hl=de 360
attr TI readingsName1 Standard
attr TI readingsName2 Verkehr
attr TI readingsRegex1 ([\d]+) Minuten
attr TI readingsRegex2 (Bei aktueller Verkehrslage: ([\d]+) Minuten

Cheers
mi.ke
FHEM 5.9 | RPi4 + 5 x RPi(Z) + FB7590 + FB 6890 LTE via LAN und WAN (VPN) verbunden.
2 x CUL868 + 3 x RFXTRX(e) + 6 x HMwLanGW + 4 x z2tGw + 5 x LGW + 2 x IRBlast + CO2 +++
FS20, FHT, FMS, Elro(mod), CM160, Revolt, LGTV, STV, AVR, withings, HM-sec-*, HM-CC-RT-DN, AMAD, PCA301, arlo, Aqara

TeeVau

Hatte nicht das Modul verwendet, sondern das Beispiel der API Abfrage.
Die API Rückt die Verkehrsdaten aber nur raus, wenn man ein Zertifikat hat, was google gegen Einwurf von Scheinen rausgibt :-)

HTTPMOD gucke ich mir mal an, habe gesehen dass es jetzt im svn ist :-)
FHEM 5.8 dev (virtualisiert) / FBF 7390 (CUL 868MHz V 1.51 / panStick (AVR1))
FS20: fs20di,fs20pira,fs20sm8,fs20st2,fs20tfk,fs20ue1,fs20ws1
panStamp (AVR1): RGB Multi von ext23, 1W-DSxxxx, I/O Sketch, Spritzpumpe
Multimedia: Panasonic TV (VIERA), Kodi, Yamaha RX-V781, LMS
Sonstiges: XiaomiFlowerSen