2023-09-07 21:36:18 +00:00
|
|
|
//---------------------------- Tyreid ----------------------------//
|
|
|
|
//
|
|
|
|
// Bluetooth war-driving app for the Bangle.js 2
|
|
|
|
//
|
|
|
|
// TH10111 2023
|
|
|
|
//
|
|
|
|
|
|
|
|
Bangle.loadWidgets();
|
|
|
|
Bangle.drawWidgets(); // <-- for development only (shouldn't need for a real app)
|
|
|
|
|
|
|
|
// Global variables
|
|
|
|
var gpsFix_flag = 0;
|
|
|
|
var bt_id_arr = [];
|
|
|
|
var num_bt_devices = 0;
|
|
|
|
var running_flag = 0; // 0 = stopped, 1 = running, 2 = paused
|
|
|
|
|
|
|
|
// Log file
|
|
|
|
var file = require("Storage").open("tyreid_log.csv","w");
|
|
|
|
|
|
|
|
// Logo
|
|
|
|
var logo = {
|
|
|
|
width : 176, height : 176, bpp : 2,
|
|
|
|
buffer : atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC///QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf///QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv/////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH///v//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///+f//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/+/4f//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//b/gf//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL/8v+Af//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//C/4Af//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4L/gAf//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//Av+AAb//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/0C/0AAb//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AP/QAAb//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/wA/9AAAb//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AD/0AAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv/gAP/QAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/8AA/9AAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//QAD/0AAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL/8AAP/QAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAA/9AAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAD/0AAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//AAAP/QAAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/0AAA/9AAAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/+AAAD/0AAAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/wAAAP/QAAAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAAA/9AAAAAAAL//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv/wAAAD/0A
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Functions
|
|
|
|
//
|
|
|
|
|
|
|
|
function gpsTick(fix) { // GPS fix callback
|
|
|
|
//console.log(fix); // print GPS Fix info to console
|
|
|
|
if (fix.fix > 0) {
|
|
|
|
gpsFix_flag = 1;
|
|
|
|
} else {
|
|
|
|
gpsFix_flag = 0;
|
|
|
|
}
|
|
|
|
WIDGETS["widTyreid"].draw(WIDGETS["widTyreid"]); // update widget with gps tick
|
|
|
|
Bangle.drawWidgets(); // Not sure why I need this here, but otherwise the widget draws over itself without clearing first!
|
|
|
|
}
|
|
|
|
|
|
|
|
function gpsON() { // Turn GPS on
|
|
|
|
Bangle.on('GPS',gpsTick);
|
|
|
|
Bangle.setGPSPower(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function gpsOFF() { // Turn GPS off
|
|
|
|
Bangle.setGPSPower(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
function btPacket(packet) { // BT packet callback
|
|
|
|
let latest_fix = Bangle.getGPSFix();
|
|
|
|
let mac = packet.id.substring(0,17);
|
|
|
|
let mac_info = packet.id.substring(18);
|
|
|
|
|
|
|
|
// console.log(" ");
|
|
|
|
// console.log(packet); // print packet info
|
|
|
|
//console.log(mac);
|
|
|
|
//console.log(5*latest_fix.hdop); // print latest GPS fix info
|
|
|
|
// console.log(" ");
|
|
|
|
|
|
|
|
// Compile the values to be stored
|
|
|
|
var new_data = [
|
|
|
|
latest_fix.time,
|
|
|
|
latest_fix.lat,
|
|
|
|
latest_fix.lon,
|
|
|
|
latest_fix.alt,
|
|
|
|
latest_fix.hdop*5,
|
|
|
|
packet.name,
|
|
|
|
mac,
|
|
|
|
mac_info,
|
|
|
|
packet.manufacturer,
|
|
|
|
packet.rssi,
|
|
|
|
packet.services,
|
|
|
|
packet.data,
|
|
|
|
packet.serviceData,
|
|
|
|
packet.manufacturerData
|
|
|
|
];
|
|
|
|
// Write data to the file (including a new line)
|
|
|
|
file.write(new_data.join(",")+"\n");
|
|
|
|
|
|
|
|
if (num_bt_devices < 99) {
|
|
|
|
if (!bt_id_arr.includes(mac)) { // if device id has not been recorded
|
|
|
|
bt_id_arr[num_bt_devices] = mac; // note the id
|
|
|
|
num_bt_devices++; // increment the number of devices found
|
|
|
|
// Add the new device to the devices menu, with information...
|
|
|
|
//console.log(" ");
|
|
|
|
//console.log(mac);
|
|
|
|
//console.log(packet.manufacturer);
|
|
|
|
//console.log(latest_fix.time);
|
|
|
|
//console.log(packet.rssi);
|
|
|
|
//console.log(" ");
|
|
|
|
// Add the new device to the devices menu, with information...
|
|
|
|
device_menu[mac] = () => {
|
|
|
|
E.showPrompt([mac,mac_info],{title:"MAC",buttons:{"Ok":true}}).then(function(v){
|
|
|
|
E.showPrompt(packet.manufacturer,{title:"Manufacturer",buttons:{"Ok":true}}).then(function(v){
|
|
|
|
E.showPrompt(latest_fix.time,{title:"First Seen",buttons:{"Ok":true}}).then(function(v){
|
|
|
|
E.showPrompt(packet.rssi,{title:"RSSI",buttons:{"Ok":true}}).then(function(v){
|
|
|
|
E.showMenu(device_menu);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function headings() { // Add headings to the file
|
|
|
|
// Compile the values to be stored
|
|
|
|
var new_data = [
|
|
|
|
"Time",
|
|
|
|
"Latitude",
|
|
|
|
"Longitude",
|
|
|
|
"Altitude",
|
|
|
|
"Accuracy",
|
|
|
|
"Name",
|
|
|
|
"MAC",
|
|
|
|
"MAC Info",
|
|
|
|
"Manufacturer",
|
|
|
|
"RSSI",
|
|
|
|
"Services",
|
|
|
|
"Data",
|
|
|
|
"Service Data",
|
|
|
|
"Manufacturer Data"
|
|
|
|
];
|
|
|
|
// Write data to the file (including a new line)
|
|
|
|
file.write(new_data.join(",")+"\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
function btON() { // Turn Bluetooth on
|
|
|
|
NRF.setScan(btPacket);
|
|
|
|
}
|
|
|
|
|
|
|
|
function btOFF() { // Turn Bluetooth off
|
|
|
|
NRF.setScan();
|
|
|
|
}
|
|
|
|
|
|
|
|
function start() { // Start the application
|
|
|
|
bt_id_arr = [];
|
|
|
|
headings();
|
|
|
|
num_bt_devices = 0;
|
|
|
|
btON();
|
|
|
|
running_flag = 1;
|
|
|
|
E.showMenu(running_menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
function exit() { // Exit the application
|
|
|
|
gpsOFF();
|
|
|
|
btOFF();
|
|
|
|
running_flag = 0;
|
|
|
|
load();
|
|
|
|
}
|
|
|
|
|
|
|
|
function pause() { // Pause the application
|
|
|
|
btOFF();
|
|
|
|
running_flag = 2;
|
|
|
|
//console.log(bt_id_arr);
|
|
|
|
E.showMenu(pause_menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
function resume() { // Continue after pause
|
|
|
|
btON();
|
|
|
|
running_flag = 1;
|
|
|
|
E.showMenu(running_menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
function marker() { // add a marker packet to the log
|
|
|
|
let latest_fix = Bangle.getGPSFix();
|
|
|
|
|
|
|
|
// console.log(" ");
|
|
|
|
// console.log("MARKER"); // print packet info
|
|
|
|
// console.log(" ");
|
|
|
|
|
|
|
|
// Compile the values to be stored
|
|
|
|
var new_data = [
|
|
|
|
latest_fix.time,
|
|
|
|
latest_fix.lat,
|
|
|
|
latest_fix.lon,
|
|
|
|
latest_fix.alt,
|
|
|
|
latest_fix.hdop,
|
|
|
|
"MARKER"
|
|
|
|
];
|
|
|
|
|
|
|
|
// Write data to the file (including a new line)
|
|
|
|
file.write(new_data.join(",")+"\n");
|
|
|
|
|
|
|
|
// Indicate that the marker has been added
|
|
|
|
E.showMessage("Marker Added.");
|
|
|
|
|
|
|
|
// Back to the menu
|
|
|
|
if (running_flag == 0) {
|
|
|
|
E.showMenu(init_menu);
|
|
|
|
} else if (running_flag == 1) {
|
|
|
|
E.showMenu(running_menu);
|
|
|
|
} else {
|
|
|
|
E.showMenu(pause_menu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setWatch(() => { // If the button is pressed, then add a marker
|
|
|
|
marker();
|
|
|
|
}, BTN1, {repeat:true});
|
|
|
|
|
|
|
|
WIDGETS["widTyreid"]={
|
|
|
|
area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right)
|
|
|
|
width: 24, // width of the widget
|
|
|
|
draw: function() {
|
|
|
|
let disp_dev_val = "-";
|
2023-09-10 19:32:17 +00:00
|
|
|
|
2023-09-07 21:36:18 +00:00
|
|
|
if (num_bt_devices < 99) {
|
|
|
|
disp_dev_val = num_bt_devices.toString();
|
|
|
|
} else {
|
|
|
|
disp_dev_val = "99+";
|
|
|
|
}
|
2023-09-10 19:32:17 +00:00
|
|
|
|
2023-09-07 21:36:18 +00:00
|
|
|
g.setFont("6x8",3);
|
2023-09-10 19:32:17 +00:00
|
|
|
if (gpsFix_flag == 1) {
|
|
|
|
g.setColor(0,1,0).drawString(disp_dev_val, this.x+24/2, this.y); // green
|
|
|
|
} else {
|
|
|
|
g.setColor(1,0,0).drawString(disp_dev_val, this.x+24/2, this.y); // red
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2023-09-07 21:36:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
let init_menu = {
|
|
|
|
"": { "title": "Tyreid" },
|
|
|
|
"Start": function() { start(); },
|
|
|
|
"Marker": function() { marker(); },
|
|
|
|
"Exit": function() { exit(); },
|
|
|
|
};
|
|
|
|
|
|
|
|
let running_menu = {
|
|
|
|
"": { "title": "[Running]" },
|
|
|
|
"Pause": function() { pause(); },
|
|
|
|
"Marker": function() { marker(); },
|
|
|
|
"Exit": function() { exit(); },
|
|
|
|
};
|
|
|
|
|
|
|
|
let pause_menu = {
|
|
|
|
"": { "title": "[Paused]" },
|
|
|
|
"Continue": function() { resume(); },
|
|
|
|
"Devices": function() { E.showMenu(device_menu); },
|
|
|
|
"Marker": function() { marker(); },
|
|
|
|
"Exit": function() { exit(); },
|
|
|
|
};
|
|
|
|
|
|
|
|
let device_menu = {
|
|
|
|
"": { "title": "Devices:" },
|
|
|
|
"Back": function() {
|
|
|
|
if (running_flag == 0) {
|
|
|
|
E.showMenu(init_menu);
|
|
|
|
} else if (running_flag == 1) {
|
|
|
|
E.showMenu(running_menu);
|
|
|
|
} else {
|
|
|
|
E.showMenu(pause_menu);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Main
|
|
|
|
gpsON(); // turn GPS on straight away to start trying for a fix
|
|
|
|
g.setColor(1,1,1).fillRect(0,0,176,176);
|
|
|
|
g.drawImage(logo,0,0); // splash screen
|
|
|
|
// 2sec wait before starting initial menu
|
|
|
|
setTimeout(function () {
|
|
|
|
E.showMenu(init_menu);
|
|
|
|
}, 2*1000);
|
|
|
|
|
|
|
|
|