var Clay = require('pebble-clay'); var clayConfig = require('./config'); var clay = new Clay(clayConfig); var messageKeys = require('message_keys'); var message; var locationInterval; var locationOptions = { 'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time) 'timeout': 2000, //2s timeout 'maximumAge': 1000 // 1s cache }; // Store location in Pebble app local storage // function storeLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; var timestamp = position.timestamp; localStorage.setItem("latitude", latitude); localStorage.setItem("longitude", longitude); localStorage.setItem("timestamp", timestamp); // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude); } // Get location from Pebble app local storage // function getLocation() { if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) { var la = localStorage.getItem("latitude"); var lo = localStorage.getItem("longitude"); var ti = localStorage.getItem("timestamp"); var co = { "latitude": la, "longitude": lo }; var pos = { "coords": co, "timestamp": ti }; // console.log("Stored location " + pos.co.la + ',' + pos.co.lo); return pos; } else { return null; } } // Calculate the distance from 2 geoloc in degrees. // IMPORTANT : this is a calculation from 2D projection, altitude is not involved // function distance_on_geoid(lat1, lon1, lat2, lon2) { // Convert degrees to radians lat1 = lat1 * Math.PI / 180.0; lon1 = lon1 * Math.PI / 180.0; lat2 = lat2 * Math.PI / 180.0; lon2 = lon2 * Math.PI / 180.0; // radius of earth in metres r = 6378100; // P rho1 = r * Math.cos(lat1); z1 = r * Math.sin(lat1); x1 = rho1 * Math.cos(lon1); y1 = rho1 * Math.sin(lon1); // Q rho2 = r * Math.cos(lat2); z2 = r * Math.sin(lat2); x2 = rho2 * Math.cos(lon2); y2 = rho2 * Math.sin(lon2); // Dot product dot = (x1 * x2 + y1 * y2 + z1 * z2); cos_theta = dot / (r * r); theta = Math.acos(cos_theta); // Distance in Metres return r * theta; } // Calculate speed from 2 geoloc point arrays (with lat,long,timestamp) // function speed_from_distance_and_time(p1, p2) { dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude); // timestamp is in milliseconds time_s = (p2.timestamp - p1.timestamp) / 1000.0; speed_mps = dist / time_s; speed_kph = (speed_mps * 3600.0) / 1000.0; return speed_kph; } // split float number into an array of int (null returned instead of 0 for decimal) // function splitFloatNumber(num) { const intStr = num.toString().split('.')[0]; const decimalStr = num.toString().split('.')[1]; return [Number(intStr), Number(decimalStr)]; } // Build GPX headers // function GPXHeadersBuilder(timestamp, name, type) { var headers = '' + name + '' + type + ''; var ret = localStorage.setItem("GPX", headers); return true; } // Build GPX footer // function GPXtrkptBuilder(lat, lon, ele, timestamp) { var GPX = localStorage.getItem("GPX"); var trkpt = '' + ele + ''; var ret = localStorage.setItem("GPX", GPX + trkpt); return true; } // Build GPX footer // function GPXfooterBuilder() { var GPX = localStorage.getItem("GPX"); var footer = ''; var ret = localStorage.setItem("GPX", GPX + footer); return true; } // Adding leading characters to string for nice displays // function padStart(string, max_length, padding) { if (string.length > max_length) { return string; } else { var new_str = string; for (index = string.length; index < max_length; index++) { new_str = "0" + new_str; } return new_str; } } // called in case of successful geoloc gathering and sends the coordinate to watch // function locationSuccess(new_pos) { var prev_pos = getLocation(); storeLocation(new_pos); if (prev_pos === null) { GPXHeadersBuilder(timestampISO = new Date(new_pos.timestamp).toISOString(), "test", "18"); return null; } else { var speed = speed_from_distance_and_time(prev_pos, new_pos); // Prepare display on watch // now it's only raw data //init strings var latitudeString = ""; var longitudeString = ""; var accuracyString = ""; var altitudeString = ""; //var altitudeAccuracyString = ""; //var timestampString = ""; var speedString = ""; //formating for precision and max size latitudeString = new_pos.coords.latitude.toString().substring(0, 12); longitudeString = new_pos.coords.longitude.toString().substring(0, 12); accuracyString = new_pos.coords.accuracy.toString().substring(0, 4); altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5); timestampISO = new Date(new_pos.timestamp).toISOString(); speedString = speed.toString().substring(0, 5); if (speedString == "NaN") { speedString = "---"; } // logging /*console.log('Your current position at ' + timestampString + ' is:'); console.log('Coordinates: ' + latitudeString+ ', ' + longitudeString+' ; with a ' + accuracyString + 'm accuracy'); console.log('Altitude: ' + altitudeString + 'm ; with a ' + altitudeAccuracyString + 'm accuracy'); console.log('Speed: ' + speedString + ' km/h.'); */ GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO); console.log('GPX: ' + localStorage.getItem("GPX")); // Build message message = "OK"; var dict = { //'latitude': padStart(latitudeString, 12, '0'), //'longitude': padStart(longitudeString, 12, '0'), 'accuracy': accuracyString, 'altitude': altitudeString, //'altitude_accuracy': padStart(altitudeAccuracyString, 3, '0'), //'timestamp': padStart(timestampString, 13, '0'), 'speed': speedString, 'status': message }; //console.log('Message to send: ' + JSON.stringify(dict)); // Send the message Pebble.sendAppMessage(dict, function () { console.log('Message sent successfully: ' + JSON.stringify(dict)); }, function (e) { console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e)); }); } } function locationError(err) { console.warn('location error (' + err.code + '): ' + err.message); /* // No app when no location Pebble.sendAppMessage({ 'WEATHER_CITY_KEY': 'Loc Unavailable', 'WEATHER_TEMPERATURE_KEY': 'N/A' });*/ } function get_coordinate() { console.log('---- get_coordinate'); navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions); } /* function switch_home(bool) { var response; console.log('---- authenticate'); if (sid != ""){ status = ""; console.log('---- get_status'); if (localStorage.getItem('username') && localStorage.getItem('password') && localStorage.getItem('server') ){ var username=localStorage.getItem('username'); var password=localStorage.getItem('password'); var server=localStorage.getItem('server'); var xhr = new XMLHttpRequest(); url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=GetInfo&_sid="+sid; xhr.open("GET", url,false); xhr.send(); if(xhr.status == 200) { response = JSON.parse(xhr.responseText); if (response.success == true){ status = response.data.on; console.log('------ status:'+status); var message; var dict; if ( status != bool){ console.log('---- switching home mode to '+ bool); url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=Switch&on="+bool+"&_sid="+sid; xhr.open("GET", url,false); xhr.send(); if(xhr.status == 200) { response = JSON.parse(xhr.responseText); if (response.success == true){ status=bool; switch (status) { case true: message = "You just set Home mode ON"; break; case false: message = "You just set Home mode OFF"; break; default: message = "something happened, try again !"; } // Build message dict = { 'status': message, }; // Send the message Pebble.sendAppMessage(dict, function(e) { console.log('sent'); }, function() { console.log('failed'); }); } }else { console.log('------Request returned error code ' + xhr.status.toString()); } }else{ console.log('---- nothing to do, status already '+status); switch (status) { case true: message = "Your Home Mode is already ON"; break; case false: message = "Your Home Mode is already OFF"; break; default: message = "something happened, try again !"; } // Build message dict = { 'status': message, }; // Send the message Pebble.sendAppMessage(dict, function(e) { console.log('sent'); }, function() { console.log('failed'); }); } } }else { console.log('------Request returned error code ' + xhr.status.toString()); } }else{ Pebble.showSimpleNotificationOnPebble("DSCam H-S", "You need to set your Synology account and server."); } } }*/ function init() { // local storage init localStorage.clear(); // clear any other var to do clearInterval(locationInterval); console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec'); locationInterval = setInterval(function () { navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions); }, 1000); } // Get JS readiness events Pebble.addEventListener('ready', function (e) { console.log('PebbleKit JS is ready'); // Update Watch on this Pebble.sendAppMessage({ 'JSReady': 1 }); init(); }); // Get AppMessage events Pebble.addEventListener('appmessage', function (e) { // Get the dictionary from the message var dict = e.payload; console.log(dict[0].toString()); switch (dict[0]) { case 'get': get_coordinate(); break;/* case 'home_on': switch_home(true); break; case 'home_off': switch_home(false); break;*/ default: console.log('Sorry. I don\'t understand your request :' + dict[0]); } });