This rule template uses the Waze RoutingManager API to query for and calculate the time and distance to drive between two points. My original idea for this template was to get an alert in the mornings so we know when to leave early because there’s yet another accident on the interstate.
The template has four properties:
starting coordinates in “lat,lon” format
ending coordinates in “lat,lon” format
Number:Time Item that will be updated with the current driving time
Number:Length Item that will be updated with the current driving distance
This rule template does not have any triggers or conditions. To avoid hammering the Waze servers this rule remains inert until you further add your own triggers and conditions. I recommend a polling period in minutes at the most and adding conditions so the rule does not run at times when it’s not needed.
If more than one route is desired, create multiple rules using this template, one for each route.
Language: JS Scripting
Dependencies:
JS Scripting add-on installed
Future versions may depend on OHRT
Changelog
Version 0.4
the region property had two options with the same mapping which caused problems, those two options were merged to avoid the problem
Version 0.3
changed to use Waze’s new URLs
minor changes to make URL generation based on region easier
moved code to github
Version 0.2
added property to choose region to avoid Internal Error problems for users outside the US
changed the logger name and added more logging at the debug and trace levels
Obviously that list is not comprehensive across the world, and I’m not sure what region IL is (Israel? Waze was founded as an Israeli company before being purchased by Google).
If you are in the EU try replacing `“RoutingManager/routingRequest” with “row-RoutingManager/routingRequest” in the URL and let me know if that works.
I’ll figure out how to make that part of the URL configurable through a property.
Already does. A new version of the rule template is posted now which has a property to choose the region, logs out the raw JSON at the trace level, and logs our what;'s returned by the server if the parsed JSON doesn’t include what we expect.
I just got done testing it and verifying it works so remove your existing rule and template, add back the template and create a new rule. You should now have a property to choose the region which will change the URL of the request.
For an example of alerting when the travel time gets too long or a different route from usual is see below. I configured the rule template to only run every minute between 07:00 and 07:20.
items.School_CheckTime.postUpdate(time.toZDT());
var usualDistance = Quantity("17.6 mi");
var distanceBuffer = Quantity("0.5 mi");
var usualTime = Quantity("19.1 min");
var timeBuffer = Quantity("5 min");
var notificationId = "schoolDriveTime";
console.debug('Received travel info from Waze');
var arrivalTime = time.toZDT(items.School_TravelTime).toLocalTime();
function getTime(inst) {
let hour = inst.hour();
let meridian = "AM"
if(hour == 12) meridian = 'PM';
if(hour > 12) {
hour -= 12;
meridian = 'PM'
}
return hour + ":" + String(inst.minute()).padStart(2, '0') + " " + meridian;
}
// If route is more than distanceBuffer from the usual route
var differentRoute = items.School_TravelDistance.quantityState.subtract(usualDistance).greaterThan(distanceBuffer);
// If the travel time is more than timeBuffer from the usual route
var longerTime = items.School_TravelTime.quantityState.subtract(usualTime).greaterThan(timeBuffer);
var msg = "As of " + getTime(time.toZDT().toLocalTime());
if(differentRoute) msg += " a different route is suggested by Waze"
else msg += " the usual route is still the best"
msg += " to school and travel duration is "
+ items.School_TravelTime.quantityState.toUnit("min").float.toPrecision(3)
+ " minutes for an arrival time of " + getTime(arrivalTime);
console.info(msg);
items.School_TravelMessage.postUpdate(msg);
if(differentRoute || longerTime) {
actions.notificationBuilder(msg).addUserId('rlkoshak@gmail.com')
.withTitle('Time to leave!')
.withIcon('f7:car-fill')
.withOnClickAction('app:android=com.waze') // untested
.withReferenceId(notificationId)
.send();
cache.private.get(notificationId)?.cancel();
cache.private.put(notificationId, actions.ScriptExecution.createTimer(ruleID, time.toZDT('PT10M'), () => {
actions.notificationBuilder('cancel notification').withReferenceId(notificationId).hide().send();
cache.private.remove(notificationId);
}));
actions.Voice.say(msg, null, "sink:id"); // all speakers group
}
else {
cache.private.get(notificationId)?.cancel();
actions.notificationBuilder('cancel notification').withReferenceId(notificationId).hide().send();
cache.private.remove(notificationId);
}
The School_TravelMessage Item is a String Item I use with Embedded Waze Live Traffic Map Widget as the footer so I can see the travel time and the current traffic conditions in MainUI in the same widget. I use =items.Shcool_TravelMessage.state for the footer property of the widget.
Code has been fixed. It took a little longer because I needed to rework how the URL was generated based on regional settings.
Remove and re-add the template from the add-on store and then regenerate your rule(s) based on the template. Don’t forget to reselect your region when you regnerate becuase I changed what the options turn into meaning you must replace your current setting.
Thank you, @rlkoshak, for offering and updating the rule template. One question: On entering data, it allows region selection. “EU” cannot be chosen, selector instantly moves over to “AU”. Yet, it results in valid data. So is this move intended behaviour?
Found that “region” can be edited to “EU” in rule code afterwards.
It is not intended behavior, and it appears I can reproduce it so I should be able to fix it. Note you now have to be a little careful in how you set it in the code now. Rather than do this relatively complicated mapping between the selection and the actual value Waze uses for each region, I do the mapping in the selector. Both “EU” and “AU” map to row.
Note, editing the region in the configuration section on the code tab doesn’t actually do anything. When editing the region variable in the code of the script action you have to be careful to choose the correct value. For “EU” you need to enter “row”, not “EU”.
The fact that two values map to the same value might be the root of the problem.
For now, selecting either EU or AU will work so the fact that it selects AU when trying to select EU is startling but does not result in a broken rule. I’ll get an update posted once I figure out what the actual problem is.