Scripting
GPS Essentials provides an automation interface called “Scripting”. With scripting, you can write scripts that automate your workflows and run at a later point in time. You can also use scripting to define custom ellipsoids and datums.
GPS Essentials scripts are written in JavaScript. If you are not familiar with JavaScript it is recommended that you at least learn the basics before writing your own scripts. You can still try out the tutorial and make simple modifications to the scripts in the tutorials with little or no knowledge of JavaScript.
All scripts are JavaScript files (.js) in the scripts folder of the storage location you chose in Settings. GPS Essentials provides a simple script editor: open it with Edit Scripts in Settings. You may also use third party script editors or edit scripts on your desktop computer and copy them into the scripts folder to use them.
Every time GPS Essentials starts or you choose Reload in the script editor, all scripts will reload. If there is an error in your scripts, the script editor will show it below the script. You will also see a hint on the start screen, the dashboard and Portable Maps when a script fails; its Edit button opens the script editor.
In the script editor, Add creates a new script, the drop-down list in the toolbar selects a script to edit, and Delete in the menu deletes the selected one right away. Your changes are saved when you switch scripts or leave the screen.
📱 Write your first script
This step-by-step tutorial lets you write your first script that does nothing but shows a message.
Open GPS Essentials
On the start screen, tap on Settings
Tap on “Edit Scripts”
Tap on “Add” (the plus sign)
Enter test as the script name
Tap on the right arrow to create the script. This creates an empty script for you
Tap into the script window to activate the cursor on the last (empty) line
Enter
toast("Hello World!");Choose Reload from the menu to reload scripts. You should see a toast message.
If you have an error in your script, a red error message appears on the bottom of the screen.
📱 Creating custom dashboard buttons
You can define a custom widget and write scripts that run when the user taps on the widget.
Create a new script that contains the following code:
var w = new Widget("addWaypoint"); w.title = "Add Waypoint"; w.description = "Adds a new waypoint at the current location"; w.addButton("tb_add").setTapListener(function() { }); register(w);
What happens in this script? In the first line, we create a new widget for the dashboard. You need to specify a unique string so that the widget can store data. We will come back to this parameter in a later tutorial.
In the next 2 lines, we assign a title and a description to the widget. These values will show up in the add dialog. The next line defines a button in this widget. The first parameter to the function is the name of the icon.
The following icon names can be used: tb_add, tb_arrow_left, tb_arrow_right, tb_bulk, tb_camera, tb_chart, tb_check, tb_contact, tb_edit, tb_export, tb_help, tb_map, tb_more, tb_move, tb_mylocation, tb_navigate, tb_pause, tb_play, tb_remove, tb_search, tb_settings, tb_view, tb_zoom_all, tb_zoom_in, tb_zoom_leg, tb_zoom_out.
The second parameter is a function that will be called when the user taps the button. We’ll add an empty function here to do nothing.
Finally, we have to register the widget with GPS Essentials.
After reloading scripts, open the dashboard and tap on a free space to add a widget. The list should contain our new widget.
📱 Add a waypoint
Let’s add some code to create a waypoint to the previous script.
Open the script file from the previous tutorial.
Insert the following code into the function definition:
var n = new Node(); n.name = "Waypoint"; n.description = "This waypoint was created on user request"; n.iconId = "circle"; n.location = location; waypoints.insert(n); n.save();Choose Reload from the menu of the script editor.
Tap on the new widget on your dashboard.
Check your Waypoints stream for a new waypoint.
📱 Control routing
You can add more buttons to a widget. Notice that there is no overflow, and you have to try and error to find out the maximum number of buttons that work for you.
The following script creates a widget that allows you to pause and control the current route:
var w = new Widget("routing");
w.title = "Routing Control";
w.description = "Starts and stops routing";
w.addButton("tb_arrow_left").setTapListener(function() {
Stream.navigatePrevious();
});
w.addButton("tb_pause").setTapListener(function() {
Stream.stopNavigate();
});
w.addButton("tb_arrow_right").setTapListener(function() {
Stream.navigateNext();
});
register(w);📱 Control tracking
The API supports creation of streams and track control. Here is a widget to start tracking into a new stream and you can also stop tracking:
var w = new Widget("tracking");
w.title = "Tracking Control";
w.description = "Starts and stops tracking";
w.addButton("tb_play").setTapListener(function() {
var t = new Stream();
t.description = "Stream created from the dashboard";
t.save();
t.track();
});
w.addButton("tb_pause").setTapListener(function() {
var tr = Stream.trackingStream();
if (tr == undefined) {
toast("Not tracking");
}
else {
Stream.stopTrack();
toast("Tracking stopped");
}
});
register(w);📱 Custom expressions
Expressions build the fundamental state model in GPS Essentials. For example, the value that GPS Essentials show in the speed widget is the result of evaluating an expressions. Expressions can consume other expressions. GPS Essentials maintains the dependencies of expressions.
You can provide JavaScript that calculates custom expressions like this:
var tts = new Expression("timeToSunset");
tts.setCalculateListener(function(time, sunset) {
return sunset.getTime() - time.getTime();
});
register(tts);When this script runs, the expression timeToSunset will be available in GPS Essentials.
The following expressions are defined:
| Name | Description |
|---|---|
| gps | Provides the current GPS info |
| trackingAngle | Provides the current tracking angle |
| battery | Provides the current battery state |
| gpsStatus | Provides the current GPS status |
| time | Provides the current time |
| current | Provides the current location |
| route | Provides the current route |
| target | Provides the current navigation target |
| remainingDistance | The distance to the end of the current route |
| targetDistance | The distance to the next target |
| targetEasting | The easting value of the current target |
| targetNorthing | The northing of the current target |
| totalDistance | remainingDistance + targetDistance |
| xtd | Cross track distance |
| atg | Altitude to go |
| trackingSpeed | The speed towards the tracking angle |
| trueSpeed | The speed towards the target |
| course | The direction towards the target |
| courseFrom | The direction from the target to the current location (course + 180°) |
| turn | The change of direction |
| speed | The current speed |
| altitude | The current altitude |
| declination | The local declination |
| targetSlope | The slope to the current target |
| ttg | The time to go to the current target |
| totalTtg | The time to go to the end of the route |
| eta | The estimated time of arrival at the current target |
| totalEtg | The estimated time of arrival at the end of the route |
| climb | The vertical velocity |
| sunset | Today’s sunset time |
| sunrise | Today's sunrise time |
| moonset | Today's moonset time |
| moonrise | Today's moonrise time |
The following tutorial shows how to create a widget that shows this expression.
📱 Expression widgets
Beside widgets that show buttons you can also define widgets that show formatted expressions. The following script shows a widget that consumes the timeToSunset expression from the previous tutorial:
var w = new Widget("timeToSunset");
w.title = "Time to Sunset";
w.description = "Shows the time until sunset";
w.setDrawListener(function(fmt, value) {
fmt.timeSpan(value);
});
register(w);📱 Accessing a specific node
You can read specific nodes in a script. For example, the following script shows the distance to a specific node.
The script requires you to know the id of the referring node. To get the node identifier, open the stream that contains the node, tap on the node and open the Properties tab. Scroll to “Key” and note the number after the hash sign.
var node = new Node(115854);
var home = new Expression("distanceToHome");
home.setCalculateListener(function(current) {
return node.location.distanceTo(current);
});
var w = new Widget("distanceToHome");
w.title = "Distance To Home";
w.description = "The current distance to home";
w.setDrawListener(function(fmt, value) {
fmt.distance(value);
});
register(home, w);📱 Calling scripts from Tasker
GPS Essentials provides a service that you can use to call a JavaScript function you defined in GPS Essentials from Tasker. The procedure may work in many other automation apps as well.
- Open Tasker and tap on tasks to create a new task
- Tap on “+” and enter a name for the new task
- Tap “+” to add an action
- Select “System” and then “Send Intent”
- Enter
android.intent.action.RUNas the action - Enter
application/javascriptas the mime type - Enter
javascript:toast('hello')as the data - Enter
com.mictale.gpsessentialsas the package - Enter
com.gpsessentials.RunScriptServiceas the class - Select “Service” as the target
- Tap back twice to save the changes
- Add a profile or scene to trigger the task.
- When you see the toast message, change
toast()to your custom function. - Add your custom function to a script file, place it into the scripts folder and don’t forget to reload scripts in the script editor.