2022-02-05 04:21:38 +00:00
|
|
|
// Add this script to DroidScript on an android device.
|
2022-02-04 23:24:12 +00:00
|
|
|
// Uses the PuckJS plugin to provide mirroring of the GPS Adv Sports II Bangle app face onto an android device.
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
app.LoadPlugin("PuckJS");
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-09 03:28:04 +00:00
|
|
|
app.SetDebugEnabled(true);
|
2022-02-09 02:25:50 +00:00
|
|
|
|
|
|
|
|
2022-02-09 03:28:04 +00:00
|
|
|
v = '1.52' // Version of this script
|
2022-02-09 02:25:50 +00:00
|
|
|
requiredBangleVer = '1.47'; // Minimum speedalt2 version required on Bangle
|
|
|
|
curBangleVer = '-.--'
|
|
|
|
isStopped = true; // Data receive turned off
|
|
|
|
lastData = new Date().getTime() / 1000; // Time of last data received
|
|
|
|
|
2022-02-09 03:28:04 +00:00
|
|
|
//Colours
|
2022-02-09 02:25:50 +00:00
|
|
|
// Mode = 0 // 0=SPD, 1=ALT, 2=DST, 3=VMG, 4=POSN, 5=TIME
|
|
|
|
btnOff = '#175A63'
|
|
|
|
btnOn = '#4285F4'
|
|
|
|
col = new Array(['black'],['#64FF00'],['#FCFA00'],['#00E4FF']) // bg, main, units, wp - 0xFFFF,0x007F,0x0054,0x0054
|
|
|
|
|
2022-02-09 03:28:04 +00:00
|
|
|
// Settings
|
|
|
|
conf = JSON.parse( app.LoadText( "settings", "{}" ))
|
|
|
|
if ( typeof(conf.btAddr) != 'string' ) conf.btAddr = '' // Address of last connection
|
|
|
|
if ( typeof(conf.btName) != 'string' ) conf.btName = '' // Name of last connection
|
|
|
|
|
|
|
|
// Extend PuckJS
|
|
|
|
app.CreateBangleJS = function( options )
|
|
|
|
{
|
|
|
|
return new BangleJS( options );
|
|
|
|
}
|
|
|
|
|
|
|
|
class BangleJS extends PuckJS {
|
|
|
|
|
|
|
|
constructor(options) {
|
|
|
|
super(options)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2022-02-05 01:41:48 +00:00
|
|
|
|
2022-02-04 23:24:12 +00:00
|
|
|
//Called when application is started.
|
2022-02-05 07:46:28 +00:00
|
|
|
function OnStart() {
|
|
|
|
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
// Connect to Bangle
|
2022-02-07 19:29:01 +00:00
|
|
|
if( !app.IsBluetoothEnabled() ) app.SetBluetoothEnabled( true );
|
|
|
|
|
2022-02-09 03:28:04 +00:00
|
|
|
// puck = app.CreatePuckJS();
|
|
|
|
bngl = app.CreateBangleJS();
|
|
|
|
bngl.SetOnConnect(onConnect); // Callback.
|
|
|
|
bngl.SetOnReceive(readResponse); // Callback to capture console output from app.
|
2022-02-09 02:25:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
if ( conf.btAddr == '' ) {
|
|
|
|
console.log('Scanning')
|
2022-02-09 03:28:04 +00:00
|
|
|
bngl.Scan("Bangle");
|
2022-02-09 02:25:50 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
console.log('Reconnecting to : '+conf.btAddr)
|
2022-02-09 03:28:04 +00:00
|
|
|
bngl.address = conf.btAddr
|
|
|
|
bngl.name = conf.btName
|
|
|
|
bngl.Connect(bngl.address);
|
2022-02-09 02:25:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
app.SetDebugEnabled(false);
|
|
|
|
|
2022-02-05 11:55:51 +00:00
|
|
|
setInterval(checkConnection,5000) // Periodic check for data timeout and attempt a reconnect
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
// Controls
|
2022-02-07 01:34:36 +00:00
|
|
|
app.SetScreenMode("Full")
|
2022-02-07 00:17:30 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
//Create a layout with objects vertically centered.
|
|
|
|
layVert = app.CreateLayout("Linear", "VCenter,FillXY")
|
|
|
|
layVert.SetPadding(0.02, 0.02, 0.02, 0.02);
|
2022-02-07 00:17:30 +00:00
|
|
|
layVert.SetBackColor(col[0])
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
//Create a text label and add it to layout.
|
2022-02-07 00:17:30 +00:00
|
|
|
val = app.CreateText('', -1, -1, "Html,Multiline") // main value
|
2022-02-05 07:46:28 +00:00
|
|
|
val.SetTextSize(120)
|
2022-02-07 00:17:30 +00:00
|
|
|
val.SetTextColor(col[1]) // green
|
2022-02-05 07:46:28 +00:00
|
|
|
layVert.AddChild(val)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
val2 = app.CreateText('') // minor value or waypoint name
|
|
|
|
val2.SetTextSize(50)
|
2022-02-07 00:17:30 +00:00
|
|
|
val2.SetTextColor(col[3]) // cyan
|
2022-02-05 07:46:28 +00:00
|
|
|
layVert.AddChild(val2)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
// Units and status text
|
2022-02-05 07:46:28 +00:00
|
|
|
layHor = app.CreateLayout("Linear", "Horizontal")
|
|
|
|
layHor.SetMargins(-1, -1, -1, 10, 'px')
|
2022-02-04 23:24:12 +00:00
|
|
|
unit = app.CreateText('')
|
2022-02-05 07:46:28 +00:00
|
|
|
unit.SetSize(200, -1, "px")
|
|
|
|
unit.SetTextSize(32)
|
|
|
|
unit.SetTextColor('#FCFA00') // yellow
|
2022-02-04 23:24:12 +00:00
|
|
|
layHor.AddChild(unit)
|
2022-02-05 07:46:28 +00:00
|
|
|
|
|
|
|
// mode = app.CreateText( '' ,.3,-1,"Center" )
|
|
|
|
mode = app.CreateText('', -1, -1)
|
|
|
|
mode.SetSize(200, -1, "px")
|
|
|
|
mode.SetTextSize(32)
|
|
|
|
mode.SetTextColor('#FCFA00') // yellow
|
|
|
|
layHor.AddChild(mode)
|
|
|
|
|
|
|
|
// sats = app.CreateText( '' ,.3,-1,"Right")
|
|
|
|
sats = app.CreateText('', -1, -1, "FillXY,Bottom")
|
|
|
|
sats.SetSize(200, -1, "px")
|
|
|
|
sats.SetTextSize(20)
|
2022-02-07 00:17:30 +00:00
|
|
|
sats.SetTextColor(col[3]) // cyan
|
2022-02-05 07:46:28 +00:00
|
|
|
layHor.AddChild(sats)
|
|
|
|
|
|
|
|
layVert.AddChild(layHor)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
// Buttons
|
2022-02-05 07:46:28 +00:00
|
|
|
layBtn = app.CreateLayout("Linear", "Horizontal")
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-05 22:41:01 +00:00
|
|
|
btnAbout = app.CreateButton("About");
|
|
|
|
btnAbout.SetOnTouch(btn_OnAbout);
|
|
|
|
btnAbout.SetBackColor(btnOff)
|
|
|
|
layBtn.AddChild(btnAbout);
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
btnStart = app.CreateButton("Start");
|
|
|
|
btnStart.SetOnTouch(btn_OnStart);
|
2022-02-04 23:24:12 +00:00
|
|
|
btnStart.SetBackColor(btnOff)
|
2022-02-05 07:46:28 +00:00
|
|
|
layBtn.AddChild(btnStart);
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
btnStop = app.CreateButton("Stop");
|
|
|
|
btnStop.SetOnTouch(btn_OnStop);
|
2022-02-04 23:24:12 +00:00
|
|
|
btnStop.SetBackColor(btnOff)
|
2022-02-05 07:46:28 +00:00
|
|
|
layBtn.AddChild(btnStop);
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
btnScan = app.CreateButton("Scan");
|
|
|
|
btnScan.SetOnTouch(btn_OnScan);
|
2022-02-05 03:24:25 +00:00
|
|
|
btnScan.SetBackColor(btnOff)
|
2022-02-05 07:46:28 +00:00
|
|
|
layBtn.AddChild(btnScan);
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-05 03:24:25 +00:00
|
|
|
// Status 'LED'
|
2022-02-05 07:46:28 +00:00
|
|
|
led = app.AddCanvas(layBtn, 0.1, 0.1, "FillXY,Bottom")
|
2022-02-05 03:24:25 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
layVert.AddChild(layBtn)
|
2022-02-05 03:24:25 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
//Add layout to app.
|
|
|
|
app.AddLayout(layVert)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function readResponse(data) {
|
2022-02-05 07:46:28 +00:00
|
|
|
if (data.substring(0, 1) != '{') return; // ignore non JSON
|
2022-02-04 23:24:12 +00:00
|
|
|
btnStart.SetBackColor(btnOn)
|
|
|
|
|
2022-02-05 11:55:51 +00:00
|
|
|
lastData = new Date().getTime() / 1000; // Time of last data received
|
|
|
|
|
2022-02-04 23:24:12 +00:00
|
|
|
d = JSON.parse(data);
|
|
|
|
|
2022-02-05 22:41:01 +00:00
|
|
|
if ( ( d.id != 'speedalt2' ) || (parseFloat(d.v) < parseFloat(requiredBangleVer)) || (typeof(d.v) == 'undefined')) {
|
2022-02-04 23:24:12 +00:00
|
|
|
btn_OnStop()
|
2022-02-05 22:41:01 +00:00
|
|
|
app.Alert('The GPS Adv Sports II app on your Bangle must be at least version ' + requiredBangleVer, 'Bangle App Upgrade Required')
|
2022-02-04 23:24:12 +00:00
|
|
|
return
|
|
|
|
}
|
2022-02-05 22:41:01 +00:00
|
|
|
|
|
|
|
curBangleVer = d.v
|
|
|
|
|
|
|
|
if (parseFloat(v) < parseFloat(d.vd)) {
|
|
|
|
btn_OnStop()
|
|
|
|
app.Alert('This GPS Adv Sports II script must be at least version ' + d.vd, 'Droidscript script Upgrade Required')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-02-04 23:24:12 +00:00
|
|
|
|
2022-02-05 11:55:51 +00:00
|
|
|
isStopped = false; // Flag that we are running and receiving data
|
|
|
|
|
2022-02-05 03:24:25 +00:00
|
|
|
// Flash blue 'led' indicator when data packet received.
|
2022-02-05 11:55:51 +00:00
|
|
|
setLED(led,true,"#0051FF")
|
|
|
|
setTimeout(function() {setLED(led,false,-1)}, 500)
|
2022-02-05 03:24:25 +00:00
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
if (d.m == 0) { // Speed ( dont need pos or time here )
|
|
|
|
val.SetTextSize(120)
|
|
|
|
val2.SetTextSize(50)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
val.SetText(d.sp)
|
|
|
|
val2.SetText('')
|
|
|
|
unit.SetText(d.spd_unit)
|
|
|
|
mode.SetText('SPD')
|
|
|
|
sats.SetText(d.sats)
|
|
|
|
}
|
2022-02-05 07:46:28 +00:00
|
|
|
|
|
|
|
if (d.m == 1) { // Alt
|
|
|
|
val.SetTextSize(120)
|
|
|
|
val2.SetTextSize(50)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
val.SetText(d.al)
|
|
|
|
val2.SetText('')
|
|
|
|
unit.SetText(d.alt_unit)
|
|
|
|
mode.SetText('ALT')
|
|
|
|
sats.SetText(d.sats)
|
|
|
|
}
|
2022-02-05 07:46:28 +00:00
|
|
|
|
|
|
|
if (d.m == 2) { // Dist
|
|
|
|
val.SetTextSize(120)
|
|
|
|
val2.SetTextSize(50)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
val.SetText(d.di)
|
|
|
|
val2.SetText(d.wp)
|
|
|
|
unit.SetText(d.dist_unit)
|
|
|
|
mode.SetText('DST')
|
|
|
|
sats.SetText(d.sats)
|
|
|
|
}
|
2022-02-05 07:46:28 +00:00
|
|
|
|
|
|
|
if (d.m == 3) { // VMG
|
|
|
|
val.SetTextSize(120)
|
|
|
|
val2.SetTextSize(50)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
val.SetText(d.vmg)
|
|
|
|
val2.SetText(d.wp)
|
|
|
|
unit.SetText(d.spd_unit)
|
|
|
|
mode.SetText('VMG')
|
|
|
|
sats.SetText(d.sats)
|
|
|
|
}
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
if (d.m == 4) { // POS
|
|
|
|
val.SetTextSize(80)
|
2022-02-07 00:17:30 +00:00
|
|
|
val2.SetTextSize(10)
|
|
|
|
|
|
|
|
txt = d.lat +
|
|
|
|
' <font color='+col[2]+'><small><small>' +
|
|
|
|
d.ns +
|
|
|
|
"</small></small></font><br>" +
|
|
|
|
d.lon +
|
|
|
|
' <font color='+col[2]+'><small><small>' +
|
|
|
|
d.ew +
|
|
|
|
"</small></small></font>"
|
|
|
|
|
|
|
|
val.SetHtml(txt)
|
2022-02-04 23:24:12 +00:00
|
|
|
val2.SetText('')
|
|
|
|
unit.SetText('')
|
|
|
|
mode.SetText('')
|
|
|
|
sats.SetText(d.sats)
|
|
|
|
}
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
if (d.m == 5) { // Time
|
|
|
|
val.SetTextSize(90)
|
2022-02-09 02:25:50 +00:00
|
|
|
val2.SetTextSize(0)
|
2022-02-04 23:24:12 +00:00
|
|
|
|
|
|
|
dt = new Date();
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
val.SetText(String(dt.getHours()).padStart(2, '0') + "\n" + String(dt.getMinutes()).padStart(2, '0'))
|
2022-02-04 23:24:12 +00:00
|
|
|
val2.SetText('')
|
|
|
|
unit.SetText('')
|
|
|
|
mode.SetText('')
|
|
|
|
sats.SetText(d.sats)
|
|
|
|
}
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
}
|
|
|
|
|
2022-02-05 11:55:51 +00:00
|
|
|
function setLED(canvas,on,colour) {
|
|
|
|
if ( on ) {
|
|
|
|
canvas.SetPaintColor(colour)
|
|
|
|
canvas.DrawCircle(0.5, 0.5, 0.1)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
canvas.Clear()
|
|
|
|
}
|
|
|
|
canvas.Update()
|
2022-02-05 03:24:25 +00:00
|
|
|
}
|
|
|
|
|
2022-02-09 02:25:50 +00:00
|
|
|
function onConnect(name, address) {
|
|
|
|
// app.SetDebugEnabled(true)
|
|
|
|
|
|
|
|
if ( typeof(address) == 'string' ) conf.btAddr = address
|
|
|
|
if ( typeof(name) == 'string' ) conf.btName = name
|
|
|
|
app.SaveText( "settings", JSON.stringify( conf )) // persist connection for future so no need to scan each time used.
|
|
|
|
|
|
|
|
console.log( "Connected to : " + conf.btAddr );
|
2022-02-05 07:46:28 +00:00
|
|
|
btn_OnStart() // Once connect tell app to start sending updates
|
2022-02-09 02:25:50 +00:00
|
|
|
app.SetDebugEnabled(false)
|
2022-02-05 01:41:48 +00:00
|
|
|
}
|
|
|
|
|
2022-02-05 11:55:51 +00:00
|
|
|
// Periodic check for data timeout and attempt a reconnect
|
|
|
|
function checkConnection() {
|
|
|
|
if (isStopped) return
|
|
|
|
if ( parseFloat(new Date().getTime() / 1000) - lastData > 30 ) {
|
|
|
|
|
2022-02-09 02:25:50 +00:00
|
|
|
console.log( "Reconnecting to : "+conf.btAddr);
|
2022-02-05 11:55:51 +00:00
|
|
|
|
|
|
|
// Flash orange 'led' indicator for connection attempts.
|
|
|
|
setLED(led,true,"#FC8A00")
|
|
|
|
setTimeout(function() {setLED(led,false,-1)}, 500)
|
2022-02-09 03:28:04 +00:00
|
|
|
bngl.Connect(conf.btAddr)
|
2022-02-05 11:55:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-05 22:41:01 +00:00
|
|
|
function btn_OnAbout() {
|
2022-02-09 02:25:50 +00:00
|
|
|
app.ShowPopup(
|
|
|
|
"GPS Adv Sports II\nAndroid Mirror : "+v+
|
|
|
|
"\nBangle.js : "+curBangleVer+
|
|
|
|
"\nConnected : "+conf.btName,"Long")
|
2022-02-05 22:41:01 +00:00
|
|
|
}
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
function btn_OnStart() {
|
2022-02-04 23:24:12 +00:00
|
|
|
btnStart.SetBackColor(btnOn)
|
|
|
|
btnStop.SetBackColor(btnOff)
|
2022-02-09 03:28:04 +00:00
|
|
|
bngl.SendCode('btOn(1)\n') // Enable the data send
|
2022-02-05 11:55:51 +00:00
|
|
|
isStopped = false
|
2022-02-04 23:24:12 +00:00
|
|
|
}
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
function btn_OnStop() {
|
2022-02-04 23:24:12 +00:00
|
|
|
btnStart.SetBackColor(btnOff)
|
|
|
|
btnStop.SetBackColor(btnOn)
|
2022-02-09 03:28:04 +00:00
|
|
|
bngl.SendCode('btOn(0)\n') // Disable the data send
|
2022-02-05 11:55:51 +00:00
|
|
|
isStopped = true
|
2022-02-04 23:24:12 +00:00
|
|
|
val.SetText('')
|
|
|
|
val2.SetText('')
|
|
|
|
unit.SetText('')
|
|
|
|
mode.SetText('')
|
|
|
|
sats.SetText('')
|
|
|
|
}
|
|
|
|
|
2022-02-05 07:46:28 +00:00
|
|
|
function btn_OnScan() {
|
2022-02-05 03:24:25 +00:00
|
|
|
btnStart.SetBackColor(btnOff)
|
|
|
|
btnStop.SetBackColor(btnOff)
|
2022-02-09 03:28:04 +00:00
|
|
|
bngl.Scan("Bangle");
|
2022-02-05 03:24:25 +00:00
|
|
|
}
|