Page 4 of 7

Re: Traffic with Google Maps in Domoticz

Posted: Friday 15 April 2016 19:58
by Westcott
Hi Assenzuid,
Let me be the first to ask -
can you please post your script script_time_googletravel.lua
Thanks.

Re: Traffic with Google Maps in Domoticz

Posted: Friday 15 April 2016 20:11
by jvdz
Could it be that the variable mins isn't initialized when the this for fails causing the setting of message fail with this error?

Code: Select all

		-- 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..' !!!'
Jos

Re: Traffic with Google Maps in Domoticz

Posted: Friday 15 April 2016 21:09
by assenzuid
@Westcott.

My script:

Code: Select all

---------------------------------
--Script to calculate duration and distance between two points using Google Maps
--Author   : woody4165 based on Neutrino Traffic with Waze, updated by G3rard
--Date     : 9 April 2016 
---------------------------------
commandArray = {}

time = os.date("*t")
day = tonumber(os.date("%w"))

--idx of devices for capturing the travel minutes in both direction
idxhomework='135'
idxworkhome='136'
--usual traveltime (mins)
usualtimehomework = 30
usualtimeworkhome = 30
--coordinates home
fromx="52.992753"
fromy="6.564228"
--coordinates work
tox="53.219383"
toy="6.566502"
--Google Api Key
key='XXXXXXXXXXXXX-MY-Google-API-KEY'

--determine workday (Mo-Fri)
if (day > 0 and day < 6) then
    werkweek=true; weekend=false
else
    werkweek=false; weekend=true
end

--determine time (7:00-9:00, 16:00-19:00)
if ((time.hour > 6 and time.hour < 9) or (time.hour == 9 and time.min < 1)) then
    ochtend=true; middag=false
elseif ((time.hour > 15 and time.hour < 19) or (time.hour == 19 and time.min < 1)) then
    ochtend=false; middag=true
else
    ochtend=false; middag=false
end

--calculate traveltime
function traveltime(fromx,fromy,tox,toy)
    --import JSON.lua library
    json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

    -- 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
    return mins
end

--weekday (Mo-Fri) and time between 7:00-9:00
if (werkweek and ochtend) then
    --every 15 minutes
    if((time.min % 30)==0) then
        homework=traveltime(fromx,fromy,tox,toy)
        message=tostring(homework)..' minuten naar kantoor | '..("%02d:%02d"):format(time.hour, time.min)
      print(message)
      --send message if traveltime is longer than usual
      if(homework > usualtimehomework) then
          commandArray['SendNotification']=message
      end
        --return a text to the device (eg. 12 mins)
        commandArray[1]={['UpdateDevice'] =idxhomework..'|0|' .. tostring(homework)}
    end
end

--weekday (Mo-Thu) and time between 16:00-19:00
if (werkweek and middag) then
    --every 15 minutes
    if((time.min % 30)==0) then
        workhome=traveltime(tox,toy,fromx,fromy)
        message=tostring(workhome)..' minuten naar huis | '..("%02d:%02d"):format(time.hour, time.min)
      print(message)
      --send message if traveltime is longer than usual
      if(workhome > usualtimeworkhome) then
          commandArray['SendNotification']=message
      end
        --return a text to the device (eg. 12 mins)
        commandArray[2]={['UpdateDevice'] =idxworkhome..'|0|' .. tostring(workhome)}
    end
end

return commandArray

return commandArray

Re: Traffic with Google Maps in Domoticz

Posted: Friday 15 April 2016 21:26
by Westcott
So line 54 is -
distance = gmaps.routes[1].legs[1].distance.text
This suggests that incomplete route info was returned.
Perhaps the script needs to check that the returned "status" is "OK" before proceeding.
Can you try printing the url (line 48) and running it in a browser?

Re: Traffic with Google Maps in Domoticz

Posted: Friday 15 April 2016 21:58
by assenzuid
The error message is:

{
"error_message" : "Browser API keys cannot have referer restrictions when used with this API.",
"routes" : [],
"status" : "REQUEST_DENIED"
}

Looks like something wrong with my Google API

Re: Traffic with Google Maps in Domoticz

Posted: Friday 15 April 2016 22:08
by assenzuid
assenzuid wrote:I get below error.

2016-04-15 19:00:00.749 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_googletravel.lua: /home/pi/domoticz/scripts/lua/script_time_googletravel.lua:54: attempt to index field '?' (a nil value)
2016-04-15 19:00:01.531 Error: EventSystem: in script_time_googletravel: [string "--------------------------------- ..."]:54: attempt to index field '?' (a nil value)
Solved.

Wrong API, now enabled Google Maps Directions API and the url at line 48 is working.
Now to figure out how to check if it's working correctly.

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 16:10
by woody4165
I'm thinking to use a dummy switch with timers to activate the script, because I see it's called every minute.
Probably I'm still new to Domoticz, but how can I let the switch call the script and run repeatedly while the switch is On?

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 19:25
by G3rard
All time scripts are called every minute. That is no problem. Moreover the calculation of the traveltime will only take place every 30 minutes in the time frame that is put in the script. So the "heavy" part of the script will not run every minute.

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 19:46
by G3rard
I have made an icon for the custom sensor. The zip file is attached in this post.
traveltime.jpg
traveltime.jpg (15.63 KiB) Viewed 4497 times
reistijd.zip
(18.7 KiB) Downloaded 289 times

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 19:49
by woody4165
Well done and very nice. How can I change it?

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 20:00
by G3rard
Go to Setup, More Options, Custom Icons and add the zip file. Then you can edit the switch and change the icon.

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 20:39
by woody4165
Don't know why, but I can't edit the Custom Switch. All the others I can.
I tried to create also a new one, but it's the same.
I'm on beta 3.5065

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 20:48
by G3rard
Make sure you have choosen a Custom Sensor at Create Custom Sensors and not a Text sensor.

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 20:51
by woody4165
Absolutely.

Image



PS: Tried with another browser than Chrome and it worked.
In Chrome I tried also to clean cache. Strange it works with all the other Devices.

Re: Traffic with Google Maps in Domoticz

Posted: Saturday 16 April 2016 21:00
by G3rard
I am on 3.5070 so that could be the difference.

Edit: was a cache issue.

Re: Traffic with Google Maps in Domoticz

Posted: Sunday 17 April 2016 10:07
by bran2000
woody4165 wrote:One more thing I've found regarding the google map api.

The travel time is being calculated on a certain route and it may vary depending on the traffic.
So if you want to know on which route is being calculated the travel time, just get this value:

Code: Select all

    summary = gmaps.routes[1].summary
And you will know on which route has been calculated.
Now I'm using the Custom Device to get travel time, and to get also logs, and I resumed the Dummy Text device to show the message that I have already built to send it via Telegram, adding just the summary variable.

Code: Select all

        message=tostring(homework)..'min to go to office at '..("%02d:%02d"):format(time.hour, time.min)..' route '..tostring(summary)
and modified/added

Code: Select all

-- modified, added [1] after commandArray
commandArray[1]={['UpdateDevice'] =idxhomework..'|0|' .. tostring(homework)} 
-- addedd
commandArray[2]={['UpdateDevice'] =idxroute..'|0|' .. tostring(message)}  
Nice!
ok Thanks i'll try this settings when you'll post a new script with all of this.
Thanks anyway !

Re: Traffic with Google Maps in Domoticz

Posted: Sunday 17 April 2016 13:27
by woody4165
Here is my latest script:

Code: Select all

---------------------------------
--Script to calculate duration and distance between two points using Google Maps
--Author   : woody4165 based on Neutrino Traffic with Waze, updated by G3rard
--Date     : 9 April 2016 
---------------------------------
commandArray={}

time = os.date("*t")
day = tonumber(os.date("%w"))

--idx of devices for capturing the travel minutes in both direction
idxtraffic='xx'
idxroute='xx'
--usual traveltime (mins)
usualtimehomework = 25
usualtimeworkhome = 25
-- Coordinates starting point
fromx="xx.xxxxx"
fromy="xx.xxxx"
-- Coordinates destination point
tox="xx.xxxx"
toy="xx.xxxx"
--Google Api Key
key='xxxxxxxxxxx'

--determine workday (Mo-Fri)
if (day > 0 and day < 6) then
    week=true; weekend=false
else
    week=false; weekend=true
end

--determine time (7:00-9:00, 16:00-19:00)
if ((time.hour > 6 and time.hour < 9) or (time.hour == 9 and time.min < 1)) then
    mattina=true; sera=false
elseif ((time.hour > 15 and time.hour < 19) or (time.hour == 19 and time.min < 1)) then
    mattina=false; sera=true
else
    mattina=false; sera=false
end


--calculate traveltime
function traveltime(fromx,fromy,tox,toy)
    --import JSON.lua library
    json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

    -- 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
    summary = gmaps.routes[1].summary
    mins=0
    -- 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 mins
end

--weekday (Mo-Fri) and time between 7:00-9:00
if (week and mattina) then
    --every 15 minutes
    if((time.min % 15)==0) then
        traffic=traveltime(fromx,fromy,tox,toy)
        message=tostring(traffic)..'min per andare in ufficio alle '..("%02d:%02d"):format(time.hour, time.min)..' percorso '..tostring(summary)
      print(message)
      --send message if traveltime is longer than usual
      if(traffic > usualtimehomework) then
        os.execute('curl --data chat_id=xxxxxxxx --data-urlencode "text='..message..'"  "https://api.telegram.org/botxxxxxxxxxxxxx/sendMessage" ')
--          commandArray['SendNotification']=message
      end
        --return a text to the device (eg. 12 mins)
        commandArray[1]={['UpdateDevice'] =idxtraffic..'|0|' .. tostring(traffic)}
        commandArray[2]={['UpdateDevice'] =idxroute..'|0|' .. tostring(message)}
    end

--weekday (Mo-Thu) and time between 16:00-19:00
elseif (week and sera) then
    --every 15 minutes
    if((time.min % 15)==0) then
        traffic=traveltime(tox,toy,fromx,fromy)
        message=tostring(traffic)..'min per andare a casa alle '..("%02d:%02d"):format(time.hour, time.min)..' percorso '..tostring(summary)
      print(message)
      --send message if traveltime is longer than usual
--      if(traffic > usualtimeworkhome) then
--        os.execute('curl --data chat_id=xxxxxx --data-urlencode "text='..message..'"  "https://api.telegram.org/botxxxxxxxxx/sendMessage" ')
--          commandArray['SendNotification']=message
--      end
        --return a text to the device (eg. 12 mins)
        commandArray[1]={['UpdateDevice'] =idxtraffic..'|0|' .. tostring(traffic)}
        commandArray[2]={['UpdateDevice'] =idxroute..'|0|' .. tostring(message)}

    end
else
    -- set device to 0 to prevent device get the last value after working hour
    zero=0
    commandArray[1]={['UpdateDevice'] =idxtraffic..'|0|' .. tostring(zero)}
    commandArray[2]={['UpdateDevice'] =idxroute..'|0|' .. tostring(zero)}
end

return commandArray

Re: Traffic with Google Maps in Domoticz

Posted: Sunday 17 April 2016 17:51
by bran2000
Thanks, i'll tell you tomorrow but i'm still with the stable version.

Re: Traffic with Google Maps in Domoticz

Posted: Monday 18 April 2016 10:18
by bran2000
Hi, i tried your new script !
it's working but the instructions about the traffic is in italian ?
anyway it can be in French for example ?

Re: Traffic with Google Maps in Domoticz

Posted: Monday 18 April 2016 10:52
by EBOOZ
There's a bug when the time exceeds one hour.

Google API output:
Image

Sensors in Domoticz:
Image

Log in Domoticz:
Image

I couldn't find a solution yet. If anyone else has an idea? Much appreciated!