Traffic with Google Maps in Domoticz

Moderator: leecollings

Post Reply
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Traffic with Google Maps in Domoticz

Post by woody4165 »

Hi

just found that I can check the traffic with Google Maps.
I tried out the fantastic script with Waze, but don't know why, in my case, the result I get is always very far from the reality (sometimes half the time I get using the Waze App on Android).

So I would like to try Google Maps.

I found some info here, you need to get a Google API key for free and you have a daily limimation on using it (if I remember well something like 1000).
https://developers.google.com/maps/docu ... Parameters


I tried using the first and simple http, https://maps.googleapis.com/maps/api/di ... zzzzzzzzzz and I got a result like this.

Code: Select all

{
   "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "zzzzzz",
         "types" : [ "route" ]
      },
      {
         "geocoder_status" : "OK",
         "place_id" : "aaaaaaaaa",
         "types" : [ "street_address" ]
      }
   ],
   "routes" : [
      {
         "bounds" : {
            "northeast" : {
               "lat" : xxxxxx,
               "lng" : yyyyyy
            },
            "southwest" : {
               "lat" : xxxxxx,
               "lng" : yyyyyy
            }
         },
         "copyrights" : "Map data ©2016 Google",
         "legs" : [
            {
               "distance" : {
                  "text" : "12,7 km",
                  "value" : 12736
               },
               "duration" : {
                  "text" : "18 min",
                  "value" : 1105
               },
               "end_address" : "xxxxxx",
               "end_location" : {
                  "lat" : xxxxx,
                  "lng" : yyyyyy
               },
               "start_address" : xxxxxx",
               "start_location" : {
                  "lat" : xxxxxx,
                  "lng" : yyyyyy
                  .....
I haven't report all the file, but just the first part, since the total distance and duration are already shown without the needs of a calculation.
And it seems to me more real.

What I don't know is how to get it from a lua script.

Any suggestion?

Thanks
Vittorio
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Traffic with Google Maps in Domoticz

Post by Westcott »

Hi Vittorio,
Thanks for posting, this could keep me occupied for hours.
Getting a key is particularly easy if you are already a registered Google user.
Reading the data with Lua is 'straightforward', this creates a table of your data -

Code: Select all

commandArray = {}

key     = 'your-api-key'
jsonurl = 'https://maps.googleapis.com/maps/api/directions/json?origin=xxxxxx,yyyyy&destination=xxxxx,yyyyy&key='..key
jsondata    = assert(io.popen(jsonurl))
jsondevices = jsondata:read('*all')
jsondata:close()
JSON = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
data = JSON:decode(jsondevices)
-- Read from the data table, and add to devices
return commandArray
Have a look at this Wiki to see the principal in action -
https://www.domoticz.com/wiki/Real-time ... Lux_sensor...
Last edited by Westcott on Thursday 07 April 2016 12:53, edited 1 time in total.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

Thanks for your reply and piece of code.

This code is very similar to the one found in the Waze traffic script.

What I'm not able to do is to extract the two values I am interested in that are distance/text and duration/text from my previous message.

I know it's maybe OT, since is not related to Domoticz, but to Lua language.

I tried to follow the link, but I get "There is currently no text in this page. You can search for this page title in other pages, search the related logs, or edit this page.".
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Traffic with Google Maps in Domoticz

Post by Westcott »

Ah, the link above misses the final '.'
There's 3 of them...
It shows how to read from the data table using the names in the returned result.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

ok, thanks, I'll take a look into it and try to use it.
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

I'm trying to do it starting from the example, but I'm doing something wrong.

This is the file to read:

Code: Select all

   "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "xxxxxxx",
         "types" : [ "route" ]
      },
      {
         "geocoder_status" : "OK",
         "place_id" : "xxxxxxxxx",
         "types" : [ "street_address" ]
      }
   ],
   "routes" : [
      {
         "bounds" : {
            "northeast" : {
               "lat" : xxxxx,
               "lng" : xxxxxx
            },
            "southwest" : {
               "lat" : xxxx,
               "lng" : xxxxxx
            }
         },
         "copyrights" : "Map data ©2016 Google",
         "legs" : [
            {
               "distance" : {
                  "text" : "12.7 km",
                  "value" : 12736
               },
               "duration" : {
                  "text" : "18 mins",
                  "value" : 1105
               },
                 ........
 
and here is the full script code

Code: Select all

commandArray={}

json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

local distance = " "
local duration = " "

key     = 'aaaaaaaaaaaaa'
local jsondata    = assert(io.popen('curl https://maps.googleapis.com/maps/api/directions/json?origin=xxxxxx,yyyyyy&destination=xxxxxx,yyyyyy&key=xxxxxx'))
local jsondevices = jsondata:read('*all')
jsondata:close()
local gmaps = json:decode(jsondevices)

-- Read from the data table, and add to devices
          local distance = gmaps.routes.legs.distance.text
          local duration = gmaps.routes.legs.duration.text

print(duration)
print(distance)

return commandArray
I tried the curl string in a browser and I get it correctly.

I think, based on the example in the Wiki, that I should read routes/legs/distance/text

so I do

Code: Select all

local distance = gmaps.routes.legs.distance.text
and this is where I get error

Code: Select all

2016-04-07 15:12:08.007 Error: EventSystem: in test_gmaps: [string "---------------------------------..."]:24: attempt to index field 'legs' (a nil value)
The gmaps.routes.legs.distance.text should be different?

Thanks
Last edited by woody4165 on Thursday 07 April 2016 18:18, edited 1 time in total.
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Traffic with Google Maps in Domoticz

Post by Westcott »

Very strange - printing 'jsondevices' gives -
{
"error_message" : "Invalid request. Missing the 'destination' parameter.",
"routes" : [],
"status" : "INVALID_REQUEST"
}
Printing the URL and copying it to a browser it works OK.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

Found this exactly for same Google maps API.

http://stackoverflow.com/questions/3053 ... n-paramete

But don't understand the answer... :-(
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Traffic with Google Maps in Domoticz

Post by Westcott »

Yes I found it also.
It means adding some double quotes around the URL -

Code: Select all

key     = 'key'
jsonurl = 'curl "https://maps.googleapis.com/maps/api/directions/json?destination=41.765307,12.3677014&origin=41.8234588,12.4437439&key='..key..'"'
jsondata = assert(io.popen(jsonurl))
This makes the query run, but the returned data is now too long for a string.
I'm looking into that.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

Probably I found the issue.

The file returned contains this string:

Code: Select all

"html_instructions" : "Head \u003cb\u003esoutheast\u003c/b\u003e on \u003cb\u003eVia Madras\u003c/b\u003e toward \u003cb\u003eVia Calcutta\u003c/b\u003e",
                     "polyline" : {
                        "points" : "ssg~Fkl}jA`B}B"
                        
I think that the "points" : "ssg~Fkl}jA`B}B" is the issue. I contains some braces!!!

Infact if I print the jsondevices, I can see the log until here:

Code: Select all

"html_instructions" : "Head \u003cb\u003esoutheast\u003c/b\u003e on \u003cb\u003eVia Madras\u003c/b\u003e toward \u003cb\u003eVia Calcutta\u003c/b\u003e",
"polyline" : {
The fact is that I don't know how to "bypass" this...
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Traffic with Google Maps in Domoticz

Post by Westcott »

Well, I think I've cracked it, try-

Code: Select all

          local distance = data.routes[1].legs[1].distance.text
          local duration = data.routes[1].legs[1].duration.text
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

It's WORKING!!!

Thanks.

What was the cause?
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Traffic with Google Maps in Domoticz

Post by Westcott »

It must be because the Google Json data allows for multiple routes, each with multiple legs.
We had to select route 1, leg 1.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
User avatar
remb0
Posts: 499
Joined: Thursday 11 July 2013 22:21
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: The Netherlands
Contact:

Re: Traffic with Google Maps in Domoticz

Post by remb0 »

Can you add this to the wiki as alternative for waze?
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

I have prepared a "clean" script, considering that I have very poor knowledge of programming.

And I don't know how to update the wiki, so if someone can make it for me, I will appreciate it, since this is not the right place to ask for help on how to update it...

What is needed is a "Google Maps APIs for Web" and you can get it at https://developers.google.com/maps/web/

You need to know the starting point and destination coordinates (in the Google Map web page just set your itinerary and you will see the coordinates in the url).

You can modify when to go in to the calculation loop, for me only during weekdays and only between 7AM and 9AM.

It takes out from the generated data, decoded with Json, the total duration, you can have it as text (duration) or as a number (mins) and the total distance, only as text.

I'm returning text in my idx device, using duration.

Code: Select all

---------------------------------
-- Script to calculate duration and distance between two points using Google Maps
-- Autor : woody4165 based on Neutrino Traffic with Waze
-- Date : 9 April 2016 
-- Need a text device (using duration) or an integer (using mins)
---------------------------------
commandArray={}

    time = os.date("*t")
    day = tonumber(os.date("%w"))
    
    idx = 'nn'
    -- If a weekday and time between 7AM and 9AM
    if ((day > 0 and day < 6) and (time.hour > 6 and time.hour < 10)) then
    
        -- Every 10 minutes
        if((time.min % 10)==0) then
    
            --import JSON.lua library
            json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
    
            -- variables --
            -- Coordinates starting point
            fromx="xx.xxxxxxx"
            fromy="yy.yyyyyyy"
            -- Coordinates destination point
            tox="xx.xxxxxxx"
            toy="yy.yyyyyyy"
            -- Google Api Key
            key     = 'zzzzzzzzzzzzzzzzzzzzzz'

            -- get data from Google Maps and decode it in gmaps
            local jsondata    = assert(io.popen('curl "https://maps.googleapis.com/maps/api/directions/json?origin='..fromx..','..fromy..'&destination='..tox..','..toy..'&key='..key..'"'))
            local jsondevices = jsondata:read('*all')
            jsondata:close()
            local gmaps = json:decode(jsondevices)
    
            -- Read from the data table, and extract duration and distance in text
            distance = gmaps.routes[1].legs[1].distance.text
            duration = gmaps.routes[1].legs[1].duration.text
    
            -- mins is only the number part of duration (for evaulation purpose or to return a number in a number device)
            for minutes in string.gmatch(duration, "%d+") do mins = tonumber(minutes) end
    
            -- return a text to the device (eg. 12 mins)
            commandArray[1]={['UpdateDevice'] =idx..'|0|' .. tostring(duration)}
        end
    
    end

return commandArray
What I'm missing is this.
I would like to receive a Telegram message with the traffic, but since the script is executed more than once every 10 minutes, I get something like 6-8 messages one after the other on the tenth minutes.

I was not able to find a way to avoid this, so I gave up.

Thanks!
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
jvdz
Posts: 2265
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: Traffic with Google Maps in Domoticz

Post by jvdz »

What have you named this script? script_device_xxxx.lua or script_time_xxxx.lua?
Should be the latter.

Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

I have this script in Setup->More Options->Events, is not saved as a file, but of course it can be done like this.

I have understood the script_device_xxxx function, but how it works the script_time_xxxx ?
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
jvdz
Posts: 2265
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: Traffic with Google Maps in Domoticz

Post by jvdz »

Ok, so you use the internal editor. What have you selected ? LUA & All?
That should be LUA & Time.

Jos
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
woody4165
Posts: 476
Joined: Monday 14 March 2016 13:55
Target OS: Linux
Domoticz version: beta
Location: Rome, Italy
Contact:

Re: Traffic with Google Maps in Domoticz

Post by woody4165 »

Thanks!!

I haven't noticed this, and now it's working perfectly, one message every 10 minutes.

I have changed also two things I noticed in the script.

I've added the parameter &departure_time=now to the curl so it's sure it takes the actual duration.

I've modified the duration in duration_in_traffic since this is the real value that consider also the actual traffic.

So now the script is:

Code: Select all

---------------------------------
-- Script to calculate duration and distance between two points using Google Maps
-- Autor : woody4165 based on Neutrino Traffic with Waze
-- Date : 9 April 2016 
-- Need a text device (using duration) or an integer (using mins)
---------------------------------
commandArray={}

    time = os.date("*t")
    day = tonumber(os.date("%w"))
    
    idx = 'nn'
    -- If a weekday and time between 7AM and 9AM
    if ((day > 0 and day < 6) and (time.hour > 6 and time.hour < 10)) then
    
        -- Every 10 minutes
        if((time.min % 10)==0) then
    
            --import JSON.lua library
            json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
    
            -- variables --
            -- Coordinates starting point
            fromx="xx.xxxxxxx"
            fromy="yy.yyyyyyy"
            -- Coordinates destination point
            tox="xx.xxxxxxx"
            toy="yy.yyyyyyy"
            -- Google Api Key
            key     = 'zzzzzzzzzzzzzzzzzzzzzz'

            -- get data from Google Maps and decode it in gmaps
            local jsondata    = assert(io.popen('curl "https://maps.googleapis.com/maps/api/directions/json?origin='..fromx..','..fromy..'&destination='..tox..','..toy..'&departure_time=now&key='..key..'"'))
            local jsondevices = jsondata:read('*all')
            jsondata:close()
            local gmaps = json:decode(jsondevices)
    
            -- Read from the data table, and extract duration and distance in text
            distance = gmaps.routes[1].legs[1].distance.text
            duration = gmaps.routes[1].legs[1].duration_in_traffic.text
    
            -- mins is only the number part of duration (for evaulation purpose or to return a number in a number device)
            for minutes in string.gmatch(duration, "%d+") do mins = tonumber(minutes) end
    
                -- send a Telegram message with status update (replace xxxxxxx with chatid and yyyyyyyyy with bot key)
                -- In case you don't want to receive Telegram message, just remove or comment next two lines
            message = mins..'  mins to go to office at  '..time.hour..':'..time.min..' !!!'
            os.execute('curl --data chat_id=xxxxxxxxxx--data-urlencode "text='..message..'"  "https://api.telegram.org/botyyyyyyyyyyyyyyyyy/sendMessage" ')

    
            -- return a text to the device (eg. 12 mins)
            commandArray[1]={['UpdateDevice'] =idx..'|0|' .. tostring(duration)}
        end
    
    end

return commandArray
Cubietruck - Linux cubietruck 4.13.16 (Debian GNU/Linux 8 (jessie)) + Domoticz + RFLink, Xiaomi Gateway, Owl USB, Yeelight Color and B/W, ESP8266, Broadlink RM2, Netatmo Thermostat
User avatar
G3rard
Posts: 669
Joined: Wednesday 04 March 2015 22:15
Target OS: -
Domoticz version: No
Location: The Netherlands
Contact:

Traffic with Google Maps in Domoticz

Post by G3rard »

Thanks all for sharing these scripts. Works a lot better then using Waze.
Not using Domoticz anymore
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest