Browse code

timeout system

Louis authored on13/06/2025 13:24:41
Showing1 changed files
... ...
@@ -9,6 +9,7 @@ var locate_me
9 9
 var firstlocationInterval = false;
10 10
 var locationInterval = false;
11 11
 var instantLocationInterval = false;
12
+var locationTimeout = false;
12 13
 
13 14
 // TODO to move to C for security
14 15
 var client_id = "94880";
... ...
@@ -21,8 +22,8 @@ var firstlocationOptions = {
21 22
 };
22 23
 var locationOptions = {
23 24
     'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
24
-    'timeout': 10000, // ms timeout to get a good signal
25
-    'maximumAge': 5000 // location can be x milliseconds old
25
+    'timeout': 30000, //30s timeout to get a good position
26
+    'maximumAge': 0 // no cache
26 27
 };
27 28
 
28 29
 Pebble.addEventListener('showConfiguration', function(e) {
... ...
@@ -379,7 +380,7 @@ function PostToWeb() {
379 380
 // Send location to web server for instant location (no live tracking)
380 381
 // TODO : secure it ?
381 382
 function instantLocationUpdate(pos) {
382
-    console.log('--- Instant location update');
383
+    // console.log('--- Instant location update');
383 384
     // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
384 385
 
385 386
     var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
... ...
@@ -412,7 +413,7 @@ function instantLocationUpdate(pos) {
412 413
 // called in case of successful geoloc gathering and sends the coordinate to watch
413 414
 //
414 415
 function locationSuccess(new_pos) {
415
-    console.log('--- locationSuccess');
416
+    // console.log('--- locationSuccess');
416 417
     // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
417 418
 
418 419
     var prev_pos = getLocation(false);
... ...
@@ -427,7 +428,6 @@ function locationSuccess(new_pos) {
427 428
         GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "Pebble track", "18");
428 429
 
429 430
     } else {
430
-        storeLocation(new_pos, false);
431 431
 
432 432
         // Prepare display on watch
433 433
         // now it's only raw data
... ...
@@ -439,49 +439,55 @@ function locationSuccess(new_pos) {
439 439
         var speedString = "";
440 440
         var distanceString = "";
441 441
 
442
-        // get speed from geoloc API isntead of calculate it
443
-        // speed is initially in m/s, get it at km/h
444
-        if (new_pos.coords.speed === null) {
445
-            var speed = 0;
446
-        } else {
447
-            var speed = new_pos.coords.speed * 3.6;
448
-            localStorage.setItem("speedsum", parseInt(localStorage.getItem("speedsum")) + speed);
449
-        }
442
+        
450 443
 
451 444
         // distance since beginning in m
445
+        console.log("--------- coordinates : " + new_pos.coords.latitude +", " + new_pos.coords.longitude);
452 446
         var dist = distance_on_geoid(prev_pos.coords.latitude, prev_pos.coords.longitude, new_pos.coords.latitude, new_pos.coords.longitude);
453
-        var totaldist = parseInt(localStorage.getItem("dist"));
454
-        if (!isNaN(dist)) {
447
+        console.log("--------- distance since last : " + dist);
448
+       var totaldist = parseInt(localStorage.getItem("dist"));
449
+        if (isNaN(dist) || dist == 0) {
450
+            // early exit as distance since previous position is too small to be parsed
451
+            console.log("--------- not recording this waypoint ");
452
+        }else{
453
+            // get speed from geoloc API isntead of calculate it
454
+            // speed is initially in m/s, get it at km/h
455
+            if (new_pos.coords.speed === null) {
456
+                var speed = 0;
457
+            } else {
458
+                var speed = new_pos.coords.speed * 3.6;
459
+                localStorage.setItem("speedsum", parseInt(localStorage.getItem("speedsum")) + speed);
460
+            }
455 461
             totaldist = totaldist + parseInt(dist);
456 462
             localStorage.setItem("dist", totaldist);
457
-        }
458
-        distanceString = splitFloatNumber(totaldist / 1000)[0].toString() + "." + splitFloatNumber(totaldist / 1000)[1].toString().substring(0, 3);
459
-        //console.log("total dist is now " + totaldist);
460
-
461
-        // avg speed (also when not moving) since beginning
462
-        var avgspeed = parseInt(localStorage.getItem("speedsum")) / parseInt(localStorage.getItem("totalcoordinates"));
463
-        var avgSpeedString = splitFloatNumber(avgspeed)[0].toString() + "." + splitFloatNumber(avgspeed)[1].toString().substring(0, 1);
464
-        console.log("speedsum=" + parseInt(localStorage.getItem("speedsum")) + " / totalcoordinates=" + parseInt(localStorage.getItem("totalcoordinates")));
465
-        console.log("--avgspeed=" + avgspeed + " / avgSpeedString=" + avgSpeedString)
466
-        if (avgSpeedString == "0.N") {
467
-            avgSpeedString = "0.0";
468
-        }
469
-        //console.log("avg speed is : " + avgSpeedString);
463
+            storeLocation(new_pos, false);
464
+        
465
+            distanceString = splitFloatNumber(totaldist / 1000)[0].toString() + "." + splitFloatNumber(totaldist / 1000)[1].toString().substring(0, 3);
466
+            //console.log("total dist is now " + totaldist);
467
+
468
+            // avg speed (also when not moving) since beginning
469
+            var avgspeed = parseInt(localStorage.getItem("speedsum")) / parseInt(localStorage.getItem("totalcoordinates"));
470
+            var avgSpeedString = splitFloatNumber(avgspeed)[0].toString() + "." + splitFloatNumber(avgspeed)[1].toString().substring(0, 1);
471
+            // console.log("speedsum=" + parseInt(localStorage.getItem("speedsum")) + " / totalcoordinates=" + parseInt(localStorage.getItem("totalcoordinates")));
472
+            if (avgSpeedString == "0.N") {
473
+                avgSpeedString = "-.-";
474
+            }
475
+            // console.log("--avgspeed=" + avgspeed + " / avgSpeedString=" + avgSpeedString)
470 476
 
471
-        // Duration
477
+            // Duration
472 478
 
473
-        var duration = new_pos.timestamp - first_pos.timestamp;
474
-        const date = new Date(duration);
475
-        durationString = padStart(date.getUTCHours().toString(), 2, "0") + ":" + padStart(date.getMinutes().toString(), 2, "0") + ":" + padStart(date.getSeconds().toString(), 2, "0");
476
-        console.log("durationString is : " + durationString);
479
+            var duration = new_pos.timestamp - first_pos.timestamp;
480
+            const date = new Date(duration);
481
+            durationString = padStart(date.getUTCHours().toString(), 2, "0") + ":" + padStart(date.getMinutes().toString(), 2, "0") + ":" + padStart(date.getSeconds().toString(), 2, "0");
482
+            // console.log("durationString is : " + durationString + "." + date.getUTCMilliseconds().toString());
477 483
 
478
-        //formating for precision and max size
479
-        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
480
-        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
481
-        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
482
-        //console.log("split num : " + new_pos.coords.altitude);
483
-        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
484
-        timestampISO = new Date(new_pos.timestamp).toISOString();
484
+            //formating for precision and max size
485
+            latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
486
+            longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
487
+            accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
488
+            //console.log("split num : " + new_pos.coords.altitude);
489
+            altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
490
+            timestampISO = new Date(new_pos.timestamp).toISOString();
485 491
 
486 492
         //console.log("split num : " + speed);
487 493
         if (isNaN(speed)) {
... ...
@@ -492,36 +498,48 @@ function locationSuccess(new_pos) {
492 498
                 speedString = "0.-";
493 499
             }
494 500
 
495
-            //console.log("split num : " + getMaxSpeed(speed));
496
-            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
501
+                //console.log("split num : " + getMaxSpeed(speed));
502
+                maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
503
+            }
504
+            // console.log("--speed=" + speed + " / speedString=" + speedString)
505
+
506
+            //add a new datapoint to GPX file
507
+            GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
508
+
509
+
510
+
511
+            // Build message
512
+            message = "L200";
513
+            var dict = {
514
+                'accuracy': accuracyString,
515
+                'distance': distanceString,
516
+                'avg_speed': avgSpeedString,
517
+                'duration': durationString,
518
+                'altitude': altitudeString,
519
+                'speed': speedString,
520
+                'max_speed': maxSpeedString,
521
+                'status': message
522
+            };
523
+
524
+            // Send the message
525
+            Pebble.sendAppMessage(dict, function() {
526
+                // console.log('Message sent successfully: ' + JSON.stringify(dict));
527
+            }, function(e) {
528
+                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
529
+            });
497 530
         }
498 531
 
499
-        //add a new datapoint to GPX file
500
-        GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
501
-
502
-
503
-
504
-        // Build message
505
-        message = "L200";
506
-        var dict = {
507
-            'accuracy': accuracyString,
508
-            'distance': distanceString,
509
-            'avg_speed': avgSpeedString,
510
-            'duration': durationString,
511
-            'altitude': altitudeString,
512
-            'speed': speedString,
513
-            'max_speed': maxSpeedString,
514
-            'status': message
515
-        };
516
-
517
-        // Send the message
518
-        Pebble.sendAppMessage(dict, function() {
519
-            console.log('Message sent successfully: ' + JSON.stringify(dict));
520
-        }, function(e) {
521
-            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
522
-        });
523 532
     }
524
-
533
+    
534
+    if ( locationTimeout !== false) {    
535
+        // console.log("tracking is ongoing, clearing timeout ref and setting a new one");
536
+        clearTimeout(locationTimeout); 
537
+        locationTimeout = setTimeout(function() {
538
+            navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
539
+        }, 1000);
540
+    }else{
541
+        // console.log("tracking is stopped");
542
+    }
525 543
 
526 544
 }
527 545
 
... ...
@@ -533,15 +551,15 @@ function locationError(err) {
533 551
 
534 552
 
535 553
 function start_get_coordinate() {
536
-    clearInterval(firstlocationInterval);
537
-    firstlocationInterval = false;
538
-    locationInterval = setInterval(function() {
554
+    clearTimeout(locationTimeout);
555
+    locationTimeout = false;
556
+    locationTimeout = setTimeout(function() {
539 557
         navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
540 558
     }, 1000);
541
-
559
+    
542 560
     if (locate_me) {
543 561
         instantLocationInterval = setInterval(function() {
544
-            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
562
+            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, firstlocationOptions);
545 563
         }, 60000);
546 564
     }
547 565
 
... ...
@@ -566,34 +584,34 @@ function init() {
566 584
     locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
567 585
 
568 586
 
569
-    console.log("Locate_me = " + locate_me);
570
-    console.log("Strava = " + se + " (" + typeof se + ")/ uploaded = " + su + " (" + typeof su + ")");
571
-    console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
587
+    // console.log("Locate_me = " + locate_me);
588
+    // console.log("Strava = " + se + " (" + typeof se + ")/ uploaded = " + su + " (" + typeof su + ")");
589
+    // console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
572 590
 
573 591
     if ((se && !su) || (ce && !cu)) {
574 592
 
575 593
         var GPX = localStorage.getItem("GPX");
576
-        console.log("last 6 char of GPX are " + GPX.substring(GPX.length - 6, GPX.length))
594
+        // console.log("last 6 char of GPX are " + GPX.substring(GPX.length - 6, GPX.length))
577 595
         if (GPX.substring(GPX.length - 6, GPX.length) !== "</gpx>") {
578 596
             console.log("WARNING - NO GPX FOOTER ")
579 597
                 /*var footer = '</trkseg></trk></gpx>';
580 598
                 localStorage.setItem("GPX", GPX + footer);*/
581 599
             GPXfooterBuilder();
582 600
             GPX = localStorage.getItem("GPX");
583
-            console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, GPX.length))
601
+            // console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, GPX.length))
584 602
         }
585 603
 
586 604
         if (se) {
587
-            console.log("GPX upload needed to Strava")
605
+            // console.log("GPX upload needed to Strava")
588 606
             SendToStrava();
589 607
         }
590 608
 
591 609
         if (ce) {
592
-            console.log("GPX upload needed to custom server")
610
+            // console.log("GPX upload needed to custom server")
593 611
             PostToWeb();
594 612
         }
595 613
     } else {
596
-        console.log("clearing var")
614
+        // console.log("clearing var")
597 615
         localStorage.setItem("maxSpeed", 0);
598 616
         localStorage.setItem("firstlatitude", "");
599 617
         localStorage.setItem("firstlongitude", "");
... ...
@@ -623,10 +641,10 @@ Pebble.addEventListener('appmessage', function(e) {
623 641
     //console.log(dict[0].toString());
624 642
     switch (dict[0]) {
625 643
         case 'startstop':
626
-            if (!locationInterval == false) {
644
+            if (!locationTimeout == false) {
627 645
                 console.log("Stopping the track");
628
-                clearInterval(locationInterval);
629
-                locationInterval = false;
646
+                clearInterval(locationTimeout);
647
+                locationTimeout = false;
630 648
                 clearInterval(instantLocationInterval);
631 649
                 instantLocationInterval = false;
632 650
                 /*firstlocationInterval = setInterval(function () {
Browse code

timeout fix

Louis Jonget authored on01/06/2025 20:34:15
Showing1 changed files
... ...
@@ -21,8 +21,8 @@ var firstlocationOptions = {
21 21
 };
22 22
 var locationOptions = {
23 23
     'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
24
-    'timeout': 5000, //5s timeout to get a good signal
25
-    'maximumAge': 0 // no cache
24
+    'timeout': 10000, // ms timeout to get a good signal
25
+    'maximumAge': 5000 // location can be x milliseconds old
26 26
 };
27 27
 
28 28
 Pebble.addEventListener('showConfiguration', function(e) {
... ...
@@ -485,11 +485,11 @@ function locationSuccess(new_pos) {
485 485
 
486 486
         //console.log("split num : " + speed);
487 487
         if (isNaN(speed)) {
488
-            speedString = "---";
488
+            speedString = "-.-";
489 489
         } else {
490 490
             speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
491 491
             if (speedString == "0.N") {
492
-                speedString = "0.0";
492
+                speedString = "0.-";
493 493
             }
494 494
 
495 495
             //console.log("split num : " + getMaxSpeed(speed));
Browse code

Merge branch 'master' of ssh://jonget.fr:5522/volume1/web/gitlist.1.0.2/repos/bike_companion

Louis Jonget authored on10/10/2023 10:42:39
Showing0 changed files
Browse code

enforcing activity type

Louis Jonget authored on10/10/2023 10:25:59
Showing1 changed files
... ...
@@ -283,7 +283,7 @@ function SendToStrava() {
283 283
   params = {
284 284
     url: "https://www.strava.com/api/v3/uploads",
285 285
     method: "POST",
286
-    data: { description: "desc", data_type: "gpx" },
286
+    data: { description: "desc", data_type: "gpx", sport_type: "Ride" , activity_types: "Ride"},
287 287
     files: { file: gpxfile },
288 288
     authorization: "Bearer " + bearer,
289 289
     callback: function (e) {
... ...
@@ -424,7 +424,7 @@ function locationSuccess(new_pos) {
424 424
         localStorage.setItem("custom_uploaded", false);
425 425
 
426 426
         // Start the GPX file
427
-        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
427
+        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "Pebble track", "18");
428 428
 
429 429
     } else {
430 430
         storeLocation(new_pos, false);
Browse code

new build from home

Louis Jonget authored on18/03/2023 14:55:56
Showing1 changed files
... ...
@@ -181,9 +181,9 @@ function splitFloatNumber(num) {
181 181
 // Build GPX headers
182 182
 //
183 183
 function GPXHeadersBuilder(timestamp, name, type) {
184
-  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
-  localStorage.setItem("GPX", headers);
186
-  return true;
184
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
+    localStorage.setItem("GPX", headers);
186
+    return true;
187 187
 }
188 188
 
189 189
 // Build GPX track point
... ...
@@ -198,11 +198,11 @@ function GPXtrkptBuilder(lat, lon, ele, timestamp) {
198 198
 // Build GPX footer
199 199
 //
200 200
 function GPXfooterBuilder() {
201
-  var GPX = localStorage.getItem("GPX");
202
-  var footer = '</trkseg></trk></gpx>';
203
-  var ret = localStorage.setItem("GPX", GPX + footer);
204
-  console.log("GPX closed : " + localStorage.getItem("GPX"));
205
-  return ret;
201
+    var GPX = localStorage.getItem("GPX");
202
+    var footer = '</trkseg></trk></gpx>';
203
+    var ret = localStorage.setItem("GPX", GPX + footer);
204
+    console.log("GPX closed : " + localStorage.getItem("GPX"));
205
+    return ret;
206 206
 }
207 207
 
208 208
 //------------------------------------------
... ...
@@ -279,58 +279,58 @@ function SendToStrava() {
279 279
     }
280 280
 
281 281
 
282
-  var bearer = JSON.parse(tokens).access_token;
283
-  params = {
284
-    url: "https://www.strava.com/api/v3/uploads",
285
-    method: "POST",
286
-    data: { description: "desc", data_type: "gpx" },
287
-    files: { file: gpxfile },
288
-    authorization: "Bearer " + bearer,
289
-    callback: function (e) {
290
-      var message = "";
291
-      if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
-        message = "S200";
293
-        localStorage.setItem("strava_uploaded", true);
294
-      } else if (400 == e.status) {
295
-        message = "S400";
296
-      } else if (401 == e.status) {
297
-        //token expired, retrying
298
-        message = "S401"
299
-        SendToStrava()
300
-      } else {
301
-        try {
302
-          response_json = JSON.parse(e.txt)
303
-          response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
304
-        } catch (err) {
305
-          console.log("Error log, " + err)
282
+    var bearer = JSON.parse(tokens).access_token;
283
+    params = {
284
+        url: "https://www.strava.com/api/v3/uploads",
285
+        method: "POST",
286
+        data: { description: "desc", data_type: "gpx" },
287
+        files: { file: gpxfile },
288
+        authorization: "Bearer " + bearer,
289
+        callback: function(e) {
290
+            var message = "";
291
+            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
+                message = "S200";
293
+                localStorage.setItem("strava_uploaded", true);
294
+            } else if (400 == e.status) {
295
+                message = "S400";
296
+            } else if (401 == e.status) {
297
+                //token expired, retrying
298
+                message = "S401"
299
+                SendToStrava()
300
+            } else {
301
+                try {
302
+                    response_json = JSON.parse(e.txt)
303
+                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
304
+                } catch (err) {
305
+                    console.log("Error log, " + err)
306
+                }
307
+                message = "S500";
308
+            }
309
+            //message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
310
+
311
+            // Build message
312
+            var dict = {
313
+                'status': message
314
+            };
315
+            // Send the message
316
+            Pebble.sendAppMessage(dict, function() {
317
+                console.log('Message sent successfully: ' + JSON.stringify(dict));
318
+            }, function(e) {
319
+                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
320
+            });
306 321
         }
307
-        message = "S500";
308
-      }
309
-      //message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
310
-      
311
-      // Build message
312
-      var dict = {
313
-        'status': message
314
-      };
315
-      // Send the message
316
-      Pebble.sendAppMessage(dict, function () {
317
-        console.log('Message sent successfully: ' + JSON.stringify(dict));
318
-      }, function (e) {
319
-        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
320
-      });
321 322
     }
322
-  }
323
-  var XHR = new XMLHttpRequest;
324
-  var n = this;
325
-  //console.log(params.url);
326
-  XHR.open(params.method, params.url, !0);
327
-  var body = "";
328
-  var boundary = Math.random().toString().substring(2);
329
-  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
330
-  XHR.setRequestHeader("Authorization", params.authorization);
331
-  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
332
-  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
333
-  body += "--" + boundary + "--\r\n"
323
+    var XHR = new XMLHttpRequest;
324
+    var n = this;
325
+    //console.log(params.url);
326
+    XHR.open(params.method, params.url, !0);
327
+    var body = "";
328
+    var boundary = Math.random().toString().substring(2);
329
+    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
330
+    XHR.setRequestHeader("Authorization", params.authorization);
331
+    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
332
+    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
333
+    body += "--" + boundary + "--\r\n"
334 334
 
335 335
     XHR.onreadystatechange = function() {
336 336
         try {
... ...
@@ -371,8 +371,8 @@ function PostToWeb() {
371 371
         }
372 372
     };
373 373
 
374
-  //send GPX in body
375
-  xhr.send(GPX);
374
+    //send GPX in body
375
+    xhr.send(GPX);
376 376
 
377 377
 }
378 378
 
... ...
@@ -501,18 +501,18 @@ function locationSuccess(new_pos) {
501 501
 
502 502
 
503 503
 
504
-    // Build message
505
-    message = "L200";
506
-    var dict = {
507
-      'accuracy': accuracyString,
508
-      'distance': distanceString,
509
-      'avg_speed': avgSpeedString,
510
-      'duration': durationString,
511
-      'altitude': altitudeString,
512
-      'speed': speedString,
513
-      'max_speed': maxSpeedString,
514
-      'status': message
515
-    };
504
+        // Build message
505
+        message = "L200";
506
+        var dict = {
507
+            'accuracy': accuracyString,
508
+            'distance': distanceString,
509
+            'avg_speed': avgSpeedString,
510
+            'duration': durationString,
511
+            'altitude': altitudeString,
512
+            'speed': speedString,
513
+            'max_speed': maxSpeedString,
514
+            'status': message
515
+        };
516 516
 
517 517
         // Send the message
518 518
         Pebble.sendAppMessage(dict, function() {
... ...
@@ -572,16 +572,16 @@ function init() {
572 572
 
573 573
     if ((se && !su) || (ce && !cu)) {
574 574
 
575
-    var GPX = localStorage.getItem("GPX");
576
-    console.log("last 6 char of GPX are " + GPX.substring(GPX.length - 6, GPX.length))
577
-    if (GPX.substring(GPX.length - 6, GPX.length) !== "</gpx>") {
578
-        console.log("WARNING - NO GPX FOOTER ")
579
-            /*var footer = '</trkseg></trk></gpx>';
580
-            localStorage.setItem("GPX", GPX + footer);*/
581
-        GPXfooterBuilder();
582
-        GPX = localStorage.getItem("GPX");
583
-        console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, GPX.length))
584
-    }
575
+        var GPX = localStorage.getItem("GPX");
576
+        console.log("last 6 char of GPX are " + GPX.substring(GPX.length - 6, GPX.length))
577
+        if (GPX.substring(GPX.length - 6, GPX.length) !== "</gpx>") {
578
+            console.log("WARNING - NO GPX FOOTER ")
579
+                /*var footer = '</trkseg></trk></gpx>';
580
+                localStorage.setItem("GPX", GPX + footer);*/
581
+            GPXfooterBuilder();
582
+            GPX = localStorage.getItem("GPX");
583
+            console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, GPX.length))
584
+        }
585 585
 
586 586
         if (se) {
587 587
             console.log("GPX upload needed to Strava")
... ...
@@ -617,37 +617,37 @@ Pebble.addEventListener('ready', function(e) {
617 617
 });
618 618
 
619 619
 // Get AppMessage events
620
-Pebble.addEventListener('appmessage', function (e) {
621
-  // Get the dictionary from the message
622
-  var dict = e.payload;
623
-  //console.log(dict[0].toString());
624
-  switch (dict[0]) {
625
-    case 'startstop':
626
-      if (!locationInterval == false) {
627
-        console.log("Stopping the track");
628
-        clearInterval(locationInterval);
629
-        locationInterval = false;
630
-        clearInterval(instantLocationInterval);
631
-        instantLocationInterval = false;
632
-        /*firstlocationInterval = setInterval(function () {
633
-          navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
634
-        }, 1000);*/
635
-      } else {
636
-        console.log("Starting the track");
637
-        start_get_coordinate();
638
-      }
639
-      break;
640
-    case 'send':
641
-      if (locate_me) {
642
-        var prev_pos = getLocation(false);
643
-        instantLocationUpdate(prev_pos);
644
-      }
645
-      
646
-      init();
647
-
648
-      break;
649
-    default:
650
-      console.log('Sorry. I don\'t understand your request :' + dict[0]);
651
-  }
620
+Pebble.addEventListener('appmessage', function(e) {
621
+    // Get the dictionary from the message
622
+    var dict = e.payload;
623
+    //console.log(dict[0].toString());
624
+    switch (dict[0]) {
625
+        case 'startstop':
626
+            if (!locationInterval == false) {
627
+                console.log("Stopping the track");
628
+                clearInterval(locationInterval);
629
+                locationInterval = false;
630
+                clearInterval(instantLocationInterval);
631
+                instantLocationInterval = false;
632
+                /*firstlocationInterval = setInterval(function () {
633
+                  navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
634
+                }, 1000);*/
635
+            } else {
636
+                console.log("Starting the track");
637
+                start_get_coordinate();
638
+            }
639
+            break;
640
+        case 'send':
641
+            if (locate_me) {
642
+                var prev_pos = getLocation(false);
643
+                instantLocationUpdate(prev_pos);
644
+            }
645
+
646
+            init();
647
+
648
+            break;
649
+        default:
650
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
651
+    }
652 652
 
653 653
 });
654 654
\ No newline at end of file
Browse code

retry on auth error

louis.jonget authored on16/03/2023 14:09:28
Showing1 changed files
... ...
@@ -181,9 +181,9 @@ function splitFloatNumber(num) {
181 181
 // Build GPX headers
182 182
 //
183 183
 function GPXHeadersBuilder(timestamp, name, type) {
184
-    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
-    localStorage.setItem("GPX", headers);
186
-    return true;
184
+  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
+  localStorage.setItem("GPX", headers);
186
+  return true;
187 187
 }
188 188
 
189 189
 // Build GPX track point
... ...
@@ -198,11 +198,11 @@ function GPXtrkptBuilder(lat, lon, ele, timestamp) {
198 198
 // Build GPX footer
199 199
 //
200 200
 function GPXfooterBuilder() {
201
-    var GPX = localStorage.getItem("GPX");
202
-    var footer = '</trkseg></trk></gpx>';
203
-    var ret = localStorage.setItem("GPX", GPX + footer);
204
-    //console.log("GPX closed : " + GPX + footer);
205
-    return ret;
201
+  var GPX = localStorage.getItem("GPX");
202
+  var footer = '</trkseg></trk></gpx>';
203
+  var ret = localStorage.setItem("GPX", GPX + footer);
204
+  console.log("GPX closed : " + localStorage.getItem("GPX"));
205
+  return ret;
206 206
 }
207 207
 
208 208
 //------------------------------------------
... ...
@@ -279,44 +279,58 @@ function SendToStrava() {
279 279
     }
280 280
 
281 281
 
282
-    var bearer = JSON.parse(tokens).access_token;
283
-    params = {
284
-        url: "https://www.strava.com/api/v3/uploads",
285
-        method: "POST",
286
-        data: { description: "desc", data_type: "gpx" },
287
-        files: { file: gpxfile },
288
-        authorization: "Bearer " + bearer,
289
-        callback: function(e) {
290
-            var message = "";
291
-            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
-                message = "Your activity has been created";
293
-                localStorage.setItem("strava_uploaded", true);
294
-            } else if (400 == e.status) {
295
-                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
296
-            } else if (401 == e.status) {
297
-                message = "Error - Unauthorized. Please check your credentials in the settings."
298
-            } else {
299
-                try {
300
-                    response_json = JSON.parse(e.txt)
301
-                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
302
-                } catch (e) {
303
-                    console.log("Error log, " + e)
304
-                }
305
-            }
306
-            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
282
+  var bearer = JSON.parse(tokens).access_token;
283
+  params = {
284
+    url: "https://www.strava.com/api/v3/uploads",
285
+    method: "POST",
286
+    data: { description: "desc", data_type: "gpx" },
287
+    files: { file: gpxfile },
288
+    authorization: "Bearer " + bearer,
289
+    callback: function (e) {
290
+      var message = "";
291
+      if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
+        message = "S200";
293
+        localStorage.setItem("strava_uploaded", true);
294
+      } else if (400 == e.status) {
295
+        message = "S400";
296
+      } else if (401 == e.status) {
297
+        //token expired, retrying
298
+        message = "S401"
299
+        SendToStrava()
300
+      } else {
301
+        try {
302
+          response_json = JSON.parse(e.txt)
303
+          response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
304
+        } catch (err) {
305
+          console.log("Error log, " + err)
307 306
         }
307
+        message = "S500";
308
+      }
309
+      //message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
310
+      
311
+      // Build message
312
+      var dict = {
313
+        'status': message
314
+      };
315
+      // Send the message
316
+      Pebble.sendAppMessage(dict, function () {
317
+        console.log('Message sent successfully: ' + JSON.stringify(dict));
318
+      }, function (e) {
319
+        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
320
+      });
308 321
     }
309
-    var XHR = new XMLHttpRequest;
310
-    var n = this;
311
-    //console.log(params.url);
312
-    XHR.open(params.method, params.url, !0);
313
-    var body = "";
314
-    var boundary = Math.random().toString().substring(2);
315
-    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
316
-    XHR.setRequestHeader("Authorization", params.authorization);
317
-    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
318
-    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
319
-    body += "--" + boundary + "--\r\n"
322
+  }
323
+  var XHR = new XMLHttpRequest;
324
+  var n = this;
325
+  //console.log(params.url);
326
+  XHR.open(params.method, params.url, !0);
327
+  var body = "";
328
+  var boundary = Math.random().toString().substring(2);
329
+  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
330
+  XHR.setRequestHeader("Authorization", params.authorization);
331
+  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
332
+  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
333
+  body += "--" + boundary + "--\r\n"
320 334
 
321 335
     XHR.onreadystatechange = function() {
322 336
         try {
... ...
@@ -357,8 +371,8 @@ function PostToWeb() {
357 371
         }
358 372
     };
359 373
 
360
-    //send GPX in body
361
-    xhr.send(GPX);
374
+  //send GPX in body
375
+  xhr.send(GPX);
362 376
 
363 377
 }
364 378
 
... ...
@@ -487,18 +501,18 @@ function locationSuccess(new_pos) {
487 501
 
488 502
 
489 503
 
490
-        // Build message
491
-        message = "OK";
492
-        var dict = {
493
-            'accuracy': accuracyString,
494
-            'distance': distanceString,
495
-            'avg_speed': avgSpeedString,
496
-            'duration': durationString,
497
-            'altitude': altitudeString,
498
-            'speed': speedString,
499
-            'max_speed': maxSpeedString,
500
-            'status': message
501
-        };
504
+    // Build message
505
+    message = "L200";
506
+    var dict = {
507
+      'accuracy': accuracyString,
508
+      'distance': distanceString,
509
+      'avg_speed': avgSpeedString,
510
+      'duration': durationString,
511
+      'altitude': altitudeString,
512
+      'speed': speedString,
513
+      'max_speed': maxSpeedString,
514
+      'status': message
515
+    };
502 516
 
503 517
         // Send the message
504 518
         Pebble.sendAppMessage(dict, function() {
... ...
@@ -558,16 +572,16 @@ function init() {
558 572
 
559 573
     if ((se && !su) || (ce && !cu)) {
560 574
 
561
-        var GPX = localStorage.getItem("GPX");
562
-        console.log("last 6 char of GPX are " + GPX.substring(GPX.length - 6, GPX.length))
563
-        if (GPX.substring(GPX.length - 6, GPX.length) !== "</gpx>") {
564
-            console.log("WARNING - NO GPX FOOTER ")
565
-                /*var footer = '</trkseg></trk></gpx>';
566
-                localStorage.setItem("GPX", GPX + footer);*/
567
-            GPXfooterBuilder();
568
-            GPX = localStorage.getItem("GPX");
569
-            console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, GPX.length))
570
-        }
575
+    var GPX = localStorage.getItem("GPX");
576
+    console.log("last 6 char of GPX are " + GPX.substring(GPX.length - 6, GPX.length))
577
+    if (GPX.substring(GPX.length - 6, GPX.length) !== "</gpx>") {
578
+        console.log("WARNING - NO GPX FOOTER ")
579
+            /*var footer = '</trkseg></trk></gpx>';
580
+            localStorage.setItem("GPX", GPX + footer);*/
581
+        GPXfooterBuilder();
582
+        GPX = localStorage.getItem("GPX");
583
+        console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, GPX.length))
584
+    }
571 585
 
572 586
         if (se) {
573 587
             console.log("GPX upload needed to Strava")
... ...
@@ -603,48 +617,37 @@ Pebble.addEventListener('ready', function(e) {
603 617
 });
604 618
 
605 619
 // Get AppMessage events
606
-Pebble.addEventListener('appmessage', function(e) {
607
-    // Get the dictionary from the message
608
-    var dict = e.payload;
609
-    //console.log(dict[0].toString());
610
-    switch (dict[0]) {
611
-        case 'startstop':
612
-            if (!locationInterval == false) {
613
-                console.log("Stopping the track");
614
-                clearInterval(locationInterval);
615
-                locationInterval = false;
616
-                clearInterval(instantLocationInterval);
617
-                instantLocationInterval = false;
618
-                firstlocationInterval = setInterval(function() {
619
-                    navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
620
-                }, 1000);
621
-            } else {
622
-                console.log("Starting the track");
623
-                start_get_coordinate();
624
-            }
625
-            break;
626
-        case 'send':
627
-            if (locate_me) {
628
-                var prev_pos = getLocation(false);
629
-                instantLocationUpdate(prev_pos);
630
-            }
631
-
632
-            init();
633
-
634
-            /*
635
-            // Send the message
636
-            var dict = {
637
-              'status': "EXIT"
638
-            };
639
-            Pebble.sendAppMessage(dict, function () {
640
-              console.log('Message sent successfully: ' + JSON.stringify(dict));
641
-            }, function (e) {
642
-              console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
643
-            });
644
-            */
645
-            break;
646
-        default:
647
-            console.log('Sorry. I don\'t understand your request :' + dict[0]);
648
-    }
620
+Pebble.addEventListener('appmessage', function (e) {
621
+  // Get the dictionary from the message
622
+  var dict = e.payload;
623
+  //console.log(dict[0].toString());
624
+  switch (dict[0]) {
625
+    case 'startstop':
626
+      if (!locationInterval == false) {
627
+        console.log("Stopping the track");
628
+        clearInterval(locationInterval);
629
+        locationInterval = false;
630
+        clearInterval(instantLocationInterval);
631
+        instantLocationInterval = false;
632
+        /*firstlocationInterval = setInterval(function () {
633
+          navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
634
+        }, 1000);*/
635
+      } else {
636
+        console.log("Starting the track");
637
+        start_get_coordinate();
638
+      }
639
+      break;
640
+    case 'send':
641
+      if (locate_me) {
642
+        var prev_pos = getLocation(false);
643
+        instantLocationUpdate(prev_pos);
644
+      }
645
+      
646
+      init();
647
+
648
+      break;
649
+    default:
650
+      console.log('Sorry. I don\'t understand your request :' + dict[0]);
651
+  }
649 652
 
650 653
 });
651 654
\ No newline at end of file
Browse code

Merge branch 'master' of ssh://192.168.170.33:5522/volume1/web/gitlist/repos/bike_companion

Louis authored on09/01/2023 21:33:55
Showing0 changed files
Browse code

removing barometer mention to let strava set altitude to map

Louis authored on09/01/2023 21:14:31
Showing1 changed files
... ...
@@ -10,7 +10,7 @@ var firstlocationInterval = false;
10 10
 var locationInterval = false;
11 11
 var instantLocationInterval = false;
12 12
 
13
-// TODO to remove for security
13
+// TODO to move to C for security
14 14
 var client_id = "94880";
15 15
 var client_secret = "08dc170f0fe38f39dd327bea82a28db4400e6f00";
16 16
 
... ...
@@ -181,7 +181,7 @@ function splitFloatNumber(num) {
181 181
 // Build GPX headers
182 182
 //
183 183
 function GPXHeadersBuilder(timestamp, name, type) {
184
-    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
184
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185 185
     localStorage.setItem("GPX", headers);
186 186
     return true;
187 187
 }
Browse code

gpx footer fixed

Louis authored on26/11/2022 19:56:52
Showing1 changed files
... ...
@@ -15,140 +15,140 @@ var client_id = "94880";
15 15
 var client_secret = "08dc170f0fe38f39dd327bea82a28db4400e6f00";
16 16
 
17 17
 var firstlocationOptions = {
18
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
19
-  'timeout': 60000, //60s timeout to get a first good signal
20
-  'maximumAge': 0 // no cache
18
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
19
+    'timeout': 60000, //60s timeout to get a first good signal
20
+    'maximumAge': 0 // no cache
21 21
 };
22 22
 var locationOptions = {
23
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
24
-  'timeout': 5000, //5s timeout to get a good signal
25
-  'maximumAge': 0 // no cache
23
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
24
+    'timeout': 5000, //5s timeout to get a good signal
25
+    'maximumAge': 0 // no cache
26 26
 };
27 27
 
28
-Pebble.addEventListener('showConfiguration', function (e) {
29
-  clay.config = clayConfig;
30
-  console.log("Clay config is showing...")
31
-  Pebble.openURL(clay.generateUrl());
28
+Pebble.addEventListener('showConfiguration', function(e) {
29
+    clay.config = clayConfig;
30
+    console.log("Clay config is showing...")
31
+    Pebble.openURL(clay.generateUrl());
32 32
 });
33 33
 
34
-Pebble.addEventListener('webviewclosed', function (t) {
35
-  if (!t || t.response) {
36
-    console.log("Clay config is submitted : " + t.response)
37
-    try {
38
-      if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
39
-        if (data.state == "bike_companion" && data.scope == "read,activity:write") {
40
-          getTokens(data.code);
41
-        } else {
42
-          console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
34
+Pebble.addEventListener('webviewclosed', function(t) {
35
+    if (!t || t.response) {
36
+        console.log("Clay config is submitted : " + t.response)
37
+        try {
38
+            if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
39
+                if (data.state == "bike_companion" && data.scope == "read,activity:write") {
40
+                    getTokens(data.code);
41
+                } else {
42
+                    console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
43
+                }
44
+            } else {
45
+                clay.getSettings(t.response);
46
+                console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
47
+            }
48
+        } catch (t) {
49
+            console.log("Oauth parsing error, continue on saving clay settings");
50
+            clay.getSettings(t.response);
51
+            var claysettings = JSON.parse(localStorage.getItem('clay-settings'))
52
+            claysettings.strava_enabled = false;
53
+            localStorage.setItem("clay-settings", JSON.stringify("claysettings"));
54
+            console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
43 55
         }
44
-      } else {
45
-        clay.getSettings(t.response);
46
-        console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
47
-      }
48
-    } catch (t) {
49
-      console.log("Oauth parsing error, continue on saving clay settings");
50
-      clay.getSettings(t.response);
51
-      var claysettings = JSON.parse(localStorage.getItem('clay-settings'))
52
-      claysettings.strava_enabled = false;
53
-      localStorage.setItem("clay-settings", JSON.stringify("claysettings"));
54
-      console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
55
-    }
56 56
 
57
-  }
57
+    }
58 58
 });
59 59
 
60 60
 // Calculate the distance from 2 geoloc in degrees.
61 61
 // IMPORTANT : this is a calculation from 2D projection, altitude is not involved
62 62
 //
63 63
 function distance_on_geoid(lat1, lon1, lat2, lon2) {
64
-  // Convert degrees to radians
65
-  lat1 = lat1 * Math.PI / 180.0;
66
-  lon1 = lon1 * Math.PI / 180.0;
67
-  lat2 = lat2 * Math.PI / 180.0;
68
-  lon2 = lon2 * Math.PI / 180.0;
69
-  // radius of earth in metres
70
-  r = 6378100;
71
-  // P
72
-  rho1 = r * Math.cos(lat1);
73
-  z1 = r * Math.sin(lat1);
74
-  x1 = rho1 * Math.cos(lon1);
75
-  y1 = rho1 * Math.sin(lon1);
76
-  // Q
77
-  rho2 = r * Math.cos(lat2);
78
-  z2 = r * Math.sin(lat2);
79
-  x2 = rho2 * Math.cos(lon2);
80
-  y2 = rho2 * Math.sin(lon2);
81
-  // Dot product
82
-  dot = (x1 * x2 + y1 * y2 + z1 * z2);
83
-  cos_theta = dot / (r * r);
84
-  theta = Math.acos(cos_theta);
85
-  // Distance in Metres
86
-  return r * theta;
64
+    // Convert degrees to radians
65
+    lat1 = lat1 * Math.PI / 180.0;
66
+    lon1 = lon1 * Math.PI / 180.0;
67
+    lat2 = lat2 * Math.PI / 180.0;
68
+    lon2 = lon2 * Math.PI / 180.0;
69
+    // radius of earth in metres
70
+    r = 6378100;
71
+    // P
72
+    rho1 = r * Math.cos(lat1);
73
+    z1 = r * Math.sin(lat1);
74
+    x1 = rho1 * Math.cos(lon1);
75
+    y1 = rho1 * Math.sin(lon1);
76
+    // Q
77
+    rho2 = r * Math.cos(lat2);
78
+    z2 = r * Math.sin(lat2);
79
+    x2 = rho2 * Math.cos(lon2);
80
+    y2 = rho2 * Math.sin(lon2);
81
+    // Dot product
82
+    dot = (x1 * x2 + y1 * y2 + z1 * z2);
83
+    cos_theta = dot / (r * r);
84
+    theta = Math.acos(cos_theta);
85
+    // Distance in Metres
86
+    return r * theta;
87 87
 }
88 88
 
89 89
 // Adding leading characters to string for nice displays
90 90
 //
91 91
 function padStart(string, max_length, padding) {
92
-  if (string.length > max_length) {
93
-    return string;
94
-  } else {
95
-    var new_str = string;
96
-    for (index = string.length; index < max_length; index++) {
97
-      new_str = padding + new_str;
92
+    if (string.length > max_length) {
93
+        return string;
94
+    } else {
95
+        var new_str = string;
96
+        for (index = string.length; index < max_length; index++) {
97
+            new_str = padding + new_str;
98
+        }
99
+        return new_str;
98 100
     }
99
-    return new_str;
100
-  }
101 101
 }
102 102
 
103 103
 
104 104
 // Store location in Pebble app local storage
105 105
 //
106 106
 function storeLocation(position, first) {
107
-  var latitude = position.coords.latitude;
108
-  var longitude = position.coords.longitude;
109
-  var timestamp = position.timestamp;
110
-  if (first == true) {
111
-    localStorage.setItem("firstlatitude", latitude);
112
-    localStorage.setItem("firstlongitude", longitude);
113
-    localStorage.setItem("firsttimestamp", Date.now());
114
-    //console.log("-- First timestamp: " + localStorage.getItem("firsttimestamp"));
115
-    localStorage.setItem("totalcoordinates", 0)
116
-  }
117
-
118
-  localStorage.setItem("lastlatitude", latitude);
119
-  localStorage.setItem("lastlongitude", longitude);
120
-  localStorage.setItem("lasttimestamp", timestamp);
121
-  localStorage.setItem("totalcoordinates", parseInt(localStorage.getItem("totalcoordinates")) + 1)
122
-  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
107
+    var latitude = position.coords.latitude;
108
+    var longitude = position.coords.longitude;
109
+    var timestamp = position.timestamp;
110
+    if (first == true) {
111
+        localStorage.setItem("firstlatitude", latitude);
112
+        localStorage.setItem("firstlongitude", longitude);
113
+        localStorage.setItem("firsttimestamp", Date.now());
114
+        //console.log("-- First timestamp: " + localStorage.getItem("firsttimestamp"));
115
+        localStorage.setItem("totalcoordinates", 0)
116
+    }
117
+
118
+    localStorage.setItem("lastlatitude", latitude);
119
+    localStorage.setItem("lastlongitude", longitude);
120
+    localStorage.setItem("lasttimestamp", timestamp);
121
+    localStorage.setItem("totalcoordinates", parseInt(localStorage.getItem("totalcoordinates")) + 1)
122
+        // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
123 123
 }
124 124
 
125 125
 // Get location from Pebble app local storage
126 126
 //
127 127
 function getLocation(first) {
128 128
 
129
-  if (first == false) {
130
-    if (localStorage.getItem("lastlatitude") || localStorage.getItem("lastlongitude") || localStorage.getItem("lasttimestamp")) {
131
-      var la = localStorage.getItem("lastlatitude");
132
-      var lo = localStorage.getItem("lastlongitude");
133
-      var ti = localStorage.getItem("lasttimestamp");
134
-      var co = { "latitude": la, "longitude": lo };
135
-      var pos = { "coords": co, "timestamp": ti };
136
-      return pos;
137
-    } else {
138
-      return null;
139
-    }
140
-  } else {
141
-    if (localStorage.getItem("firstlatitude") || localStorage.getItem("firstlongitude") || localStorage.getItem("firsttimestamp")) {
142
-      var la = localStorage.getItem("firstlatitude");
143
-      var lo = localStorage.getItem("firstlongitude");
144
-      var ti = localStorage.getItem("firsttimestamp");
145
-      var co = { "latitude": la, "longitude": lo };
146
-      var pos = { "coords": co, "timestamp": ti };
147
-      return pos;
129
+    if (first == false) {
130
+        if (localStorage.getItem("lastlatitude") || localStorage.getItem("lastlongitude") || localStorage.getItem("lasttimestamp")) {
131
+            var la = localStorage.getItem("lastlatitude");
132
+            var lo = localStorage.getItem("lastlongitude");
133
+            var ti = localStorage.getItem("lasttimestamp");
134
+            var co = { "latitude": la, "longitude": lo };
135
+            var pos = { "coords": co, "timestamp": ti };
136
+            return pos;
137
+        } else {
138
+            return null;
139
+        }
148 140
     } else {
149
-      return null;
141
+        if (localStorage.getItem("firstlatitude") || localStorage.getItem("firstlongitude") || localStorage.getItem("firsttimestamp")) {
142
+            var la = localStorage.getItem("firstlatitude");
143
+            var lo = localStorage.getItem("firstlongitude");
144
+            var ti = localStorage.getItem("firsttimestamp");
145
+            var co = { "latitude": la, "longitude": lo };
146
+            var pos = { "coords": co, "timestamp": ti };
147
+            return pos;
148
+        } else {
149
+            return null;
150
+        }
150 151
     }
151
-  }
152 152
 
153 153
 
154 154
 }
... ...
@@ -156,53 +156,53 @@ function getLocation(first) {
156 156
 // Get max speed of the run
157 157
 //
158 158
 function getMaxSpeed(lastSpeed) {
159
-  oldmax = localStorage.getItem("maxSpeed") || -1;
160
-  if (oldmax < lastSpeed) {
161
-    maxSpeed = lastSpeed
162
-  } else if (oldmax > lastSpeed) {
163
-    maxSpeed = oldmax
164
-  } else {
165
-    maxSpeed = oldmax
166
-  }
167
-  localStorage.setItem("maxSpeed", maxSpeed);
168
-  return maxSpeed
159
+    oldmax = localStorage.getItem("maxSpeed") || -1;
160
+    if (oldmax < lastSpeed) {
161
+        maxSpeed = lastSpeed
162
+    } else if (oldmax > lastSpeed) {
163
+        maxSpeed = oldmax
164
+    } else {
165
+        maxSpeed = oldmax
166
+    }
167
+    localStorage.setItem("maxSpeed", maxSpeed);
168
+    return maxSpeed
169 169
 }
170 170
 
171 171
 // split float number into an array of int (null returned instead of 0 for decimal)
172 172
 //
173 173
 function splitFloatNumber(num) {
174
-  const intStr = num.toString().split('.')[0];
175
-  var decimalStr = num.toString().split('.')[1];
176
-  if (decimalStr === undefined) { decimalStr = 0 } else { decimalStr = decimalStr }
177
-  return [Number(intStr), Number(decimalStr)];
174
+    const intStr = num.toString().split('.')[0];
175
+    var decimalStr = num.toString().split('.')[1];
176
+    if (decimalStr === undefined) { decimalStr = 0 } else { decimalStr = decimalStr }
177
+    return [Number(intStr), Number(decimalStr)];
178 178
 
179 179
 }
180 180
 
181 181
 // Build GPX headers
182 182
 //
183 183
 function GPXHeadersBuilder(timestamp, name, type) {
184
-  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
-  localStorage.setItem("GPX", headers);
186
-  return true;
184
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
+    localStorage.setItem("GPX", headers);
186
+    return true;
187 187
 }
188 188
 
189 189
 // Build GPX track point
190 190
 //
191 191
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
192
-  var GPX = localStorage.getItem("GPX");
193
-  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
194
-  localStorage.setItem("GPX", GPX + trkpt);
195
-  return true;
192
+    var GPX = localStorage.getItem("GPX");
193
+    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
194
+    localStorage.setItem("GPX", GPX + trkpt);
195
+    return true;
196 196
 }
197 197
 
198 198
 // Build GPX footer
199 199
 //
200 200
 function GPXfooterBuilder() {
201
-  var GPX = localStorage.getItem("GPX");
202
-  var footer = '</trkseg></trk></gpx>';
203
-  var ret = localStorage.setItem("GPX", GPX + footer);
204
-  //console.log("GPX closed : " + GPX + footer);
205
-  return ret;
201
+    var GPX = localStorage.getItem("GPX");
202
+    var footer = '</trkseg></trk></gpx>';
203
+    var ret = localStorage.setItem("GPX", GPX + footer);
204
+    //console.log("GPX closed : " + GPX + footer);
205
+    return ret;
206 206
 }
207 207
 
208 208
 //------------------------------------------
... ...
@@ -210,439 +210,441 @@ function GPXfooterBuilder() {
210 210
 //------------------------------------------
211 211
 
212 212
 function getTokens(code) {
213
-  // call to strava api to get tokens in exchange of temp code
214
-  // need to use strava.jonget.fr to proxy request and hide secret
215
-  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
216
-  var xhr = new XMLHttpRequest();
217
-  xhr.timeout = 10000; // time in milliseconds
218
-
219
-  xhr.open("POST", url, false);
220
-
221
-  xhr.send();
222
-
223
-  if (xhr.status === 200) {
224
-    console.log('------xhr request returned :', xhr.responseText);
225
-    response_json = JSON.parse(xhr.responseText);
226
-
227
-    var tokenjson = {
228
-      access_token: response_json.access_token,
229
-      refresh_token: response_json.refresh_token,
230
-      expiry: response_json.expires_at,
231
-      delay: response_json.expires_in
232
-    };
233
-    localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
234
-  }
213
+    // call to strava api to get tokens in exchange of temp code
214
+    // need to use strava.jonget.fr to proxy request and hide secret
215
+    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
216
+    var xhr = new XMLHttpRequest();
217
+    xhr.timeout = 10000; // time in milliseconds
218
+
219
+    xhr.open("POST", url, false);
220
+
221
+    xhr.send();
222
+
223
+    if (xhr.status === 200) {
224
+        console.log('------xhr request returned :', xhr.responseText);
225
+        response_json = JSON.parse(xhr.responseText);
226
+
227
+        var tokenjson = {
228
+            access_token: response_json.access_token,
229
+            refresh_token: response_json.refresh_token,
230
+            expiry: response_json.expires_at,
231
+            delay: response_json.expires_in
232
+        };
233
+        localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
234
+    }
235 235
 }
236 236
 
237 237
 function refreshTokens(refresh_token) {
238
-  // call to strava api to get tokens in exchange of refresh code
239
-  // need to use strava.jonget.fr to proxy request and hide secret
240
-  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
241
-  var xhr = new XMLHttpRequest();
242
-  xhr.timeout = 10000; // time in milliseconds
243
-
244
-  xhr.open("POST", url, false);
245
-
246
-  xhr.send();
247
-  //console.log('------Refresh token - xhr onloaded')
248
-  if (xhr.status === 200) {
249
-    console.log('------Refresh token - xhr request returned with ' + xhr.responseText);
250
-    response_json = JSON.parse(xhr.responseText);
251
-
252
-    var tokenjson = {
253
-      access_token: response_json.access_token,
254
-      refresh_token: response_json.refresh_token,
255
-      expiry: response_json.expires_at,
256
-      delay: response_json.expires_in
257
-    };
258
-    localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
238
+    // call to strava api to get tokens in exchange of refresh code
239
+    // need to use strava.jonget.fr to proxy request and hide secret
240
+    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
241
+    var xhr = new XMLHttpRequest();
242
+    xhr.timeout = 10000; // time in milliseconds
243
+
244
+    xhr.open("POST", url, false);
245
+
246
+    xhr.send();
247
+    //console.log('------Refresh token - xhr onloaded')
248
+    if (xhr.status === 200) {
249
+        console.log('------Refresh token - xhr request returned with ' + xhr.responseText);
250
+        response_json = JSON.parse(xhr.responseText);
251
+
252
+        var tokenjson = {
253
+            access_token: response_json.access_token,
254
+            refresh_token: response_json.refresh_token,
255
+            expiry: response_json.expires_at,
256
+            delay: response_json.expires_in
257
+        };
258
+        localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
259 259
 
260
-  }
260
+    }
261 261
 
262 262
 }
263 263
 
264 264
 // Send GPX to Strava profile
265 265
 function SendToStrava() {
266
-  console.log('--- GPX upload to strava');
267
-  var gpxfile = localStorage.getItem("GPX");
268
-
269
-  var tokens = localStorage.getItem("strava_tokens");
270
-
271
-  //checking token expiry
272
-  var date = (Date.now()) / 1000
273
-
274
-  if (JSON.parse(tokens).expiry < date) {
275
-    console.log("Strava oAuth token expired, refreshing it")
276
-    refreshTokens(JSON.parse(tokens).refresh_token);
277
-  } else {
278
-    console.log("token (" + JSON.parse(tokens).access_token + ") valid, continuing")
279
-  }
280
-
281
-
282
-  var bearer = JSON.parse(tokens).access_token;
283
-  params = {
284
-    url: "https://www.strava.com/api/v3/uploads",
285
-    method: "POST",
286
-    data: { description: "desc", data_type: "gpx" },
287
-    files: { file: gpxfile },
288
-    authorization: "Bearer " + bearer,
289
-    callback: function (e) {
290
-      var message = "";
291
-      if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
-        message = "Your activity has been created";
293
-        localStorage.setItem("strava_uploaded", true);
294
-      } else if (400 == e.status) {
295
-        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
296
-      } else if (401 == e.status) {
297
-        message = "Error - Unauthorized. Please check your credentials in the settings."
298
-      } else {
266
+    console.log('--- GPX upload to strava');
267
+    var gpxfile = localStorage.getItem("GPX");
268
+
269
+    var tokens = localStorage.getItem("strava_tokens");
270
+
271
+    //checking token expiry
272
+    var date = (Date.now()) / 1000
273
+
274
+    if (JSON.parse(tokens).expiry < date) {
275
+        console.log("Strava oAuth token expired, refreshing it")
276
+        refreshTokens(JSON.parse(tokens).refresh_token);
277
+    } else {
278
+        console.log("token (" + JSON.parse(tokens).access_token + ") valid, continuing")
279
+    }
280
+
281
+
282
+    var bearer = JSON.parse(tokens).access_token;
283
+    params = {
284
+        url: "https://www.strava.com/api/v3/uploads",
285
+        method: "POST",
286
+        data: { description: "desc", data_type: "gpx" },
287
+        files: { file: gpxfile },
288
+        authorization: "Bearer " + bearer,
289
+        callback: function(e) {
290
+            var message = "";
291
+            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
+                message = "Your activity has been created";
293
+                localStorage.setItem("strava_uploaded", true);
294
+            } else if (400 == e.status) {
295
+                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
296
+            } else if (401 == e.status) {
297
+                message = "Error - Unauthorized. Please check your credentials in the settings."
298
+            } else {
299
+                try {
300
+                    response_json = JSON.parse(e.txt)
301
+                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
302
+                } catch (e) {
303
+                    console.log("Error log, " + e)
304
+                }
305
+            }
306
+            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
307
+        }
308
+    }
309
+    var XHR = new XMLHttpRequest;
310
+    var n = this;
311
+    //console.log(params.url);
312
+    XHR.open(params.method, params.url, !0);
313
+    var body = "";
314
+    var boundary = Math.random().toString().substring(2);
315
+    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
316
+    XHR.setRequestHeader("Authorization", params.authorization);
317
+    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
318
+    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
319
+    body += "--" + boundary + "--\r\n"
320
+
321
+    XHR.onreadystatechange = function() {
299 322
         try {
300
-          response_json = JSON.parse(e.txt)
301
-          response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
323
+            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
302 324
         } catch (e) {
303
-          console.log("Error log, " + e)
325
+            console.error("Error2 loading, ", e)
304 326
         }
305
-      }
306
-      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
307 327
     }
308
-  }
309
-  var XHR = new XMLHttpRequest;
310
-  var n = this;
311
-  //console.log(params.url);
312
-  XHR.open(params.method, params.url, !0);
313
-  var body = "";
314
-  var boundary = Math.random().toString().substring(2);
315
-  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
316
-  XHR.setRequestHeader("Authorization", params.authorization);
317
-  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
318
-  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
319
-  body += "--" + boundary + "--\r\n"
320
-
321
-  XHR.onreadystatechange = function () {
322
-    try {
323
-      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
324
-    } catch (e) {
325
-      console.error("Error2 loading, ", e)
326
-    }
327
-  }
328
-  XHR.send(body)
328
+    XHR.send(body)
329 329
 }
330 330
 
331 331
 
332 332
 // Send GPX to web server (need configuration on serverside)
333 333
 // TODO : secure it ?
334 334
 function PostToWeb() {
335
-  console.log('--- GPX upload to custom web server');
336
-  var GPX = localStorage.getItem("GPX");
337
-  var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
338
-  var xhr = new XMLHttpRequest();
339
-  xhr.timeout = 10000; // time in milliseconds
340
-
341
-  xhr.open("POST", url, false);
342
-
343
-  //console.log('------ CSV / xhr opened')
344
-  xhr.onload = function () {
345
-    //console.log('------xhr onloaded')
346
-    if (xhr.readyState === 4) {
347
-      //console.log('------xhr request returned with ' + xhr.status);
348
-      //console.log(this.responseText);
349
-      localStorage.setItem("custom_uploaded", true);
350
-      if (xhr.status == 200) {
351
-        //console.log('--> HTTP 200');
352
-        return true;
353
-      } else {
354
-        //console.log('--> HTTP ' + xhr.status);
355
-        return false;
356
-      }
357
-    }
358
-  };
335
+    console.log('--- GPX upload to custom web server');
336
+    var GPX = localStorage.getItem("GPX");
337
+    var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
338
+    var xhr = new XMLHttpRequest();
339
+    xhr.timeout = 10000; // time in milliseconds
340
+
341
+    xhr.open("POST", url, false);
342
+
343
+    //console.log('------ CSV / xhr opened')
344
+    xhr.onload = function() {
345
+        //console.log('------xhr onloaded')
346
+        if (xhr.readyState === 4) {
347
+            //console.log('------xhr request returned with ' + xhr.status);
348
+            //console.log(this.responseText);
349
+            localStorage.setItem("custom_uploaded", true);
350
+            if (xhr.status == 200) {
351
+                //console.log('--> HTTP 200');
352
+                return true;
353
+            } else {
354
+                //console.log('--> HTTP ' + xhr.status);
355
+                return false;
356
+            }
357
+        }
358
+    };
359 359
 
360
-  //send CSV in body
361
-  xhr.send(GPX);
360
+    //send CSV in body
361
+    xhr.send(GPX);
362 362
 
363 363
 }
364 364
 
365 365
 // Send location to web server for instant location (no live tracking)
366 366
 // TODO : secure it ?
367 367
 function instantLocationUpdate(pos) {
368
-  console.log('--- Instant location update');
369
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
370
-
371
-  var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
372
-  var xhr = new XMLHttpRequest();
373
-  xhr.timeout = 10000; // time in milliseconds
374
-
375
-  xhr.open("POST", url);
376
-
377
-  //console.log('------ instant / xhr opened')
378
-  xhr.onload = function () {
379
-    //console.log('------xhr onloaded')
380
-    if (xhr.readyState === 4) {
381
-      //console.log('------xhr request returned with ' + xhr.status);
382
-      //console.log(this.responseText);
383
-      if (xhr.status == 200) {
384
-        //console.log('--> HTTP 200');
385
-        return true;
386
-      } else {
387
-        //console.log('--> HTTP ' + xhr.status);
388
-        return false;
389
-      }
390
-    }
391
-  };
368
+    console.log('--- Instant location update');
369
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
370
+
371
+    var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
372
+    var xhr = new XMLHttpRequest();
373
+    xhr.timeout = 10000; // time in milliseconds
374
+
375
+    xhr.open("POST", url);
376
+
377
+    //console.log('------ instant / xhr opened')
378
+    xhr.onload = function() {
379
+        //console.log('------xhr onloaded')
380
+        if (xhr.readyState === 4) {
381
+            //console.log('------xhr request returned with ' + xhr.status);
382
+            //console.log(this.responseText);
383
+            if (xhr.status == 200) {
384
+                //console.log('--> HTTP 200');
385
+                return true;
386
+            } else {
387
+                //console.log('--> HTTP ' + xhr.status);
388
+                return false;
389
+            }
390
+        }
391
+    };
392 392
 
393
-  //send without body
394
-  xhr.send();
393
+    //send without body
394
+    xhr.send();
395 395
 
396 396
 }
397 397
 
398 398
 // called in case of successful geoloc gathering and sends the coordinate to watch
399 399
 //
400 400
 function locationSuccess(new_pos) {
401
-  console.log('--- locationSuccess');
402
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
403
-
404
-  var prev_pos = getLocation(false);
405
-  var first_pos = getLocation(true);
406
-  if (prev_pos === null) {
407
-    console.log('--- start building gpx');
408
-    storeLocation(new_pos, true);
409
-    localStorage.setItem("strava_uploaded", false);
410
-    localStorage.setItem("custom_uploaded", false);
411
-
412
-    // Start the GPX file
413
-    GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
414
-
415
-  } else {
416
-    storeLocation(new_pos, false);
417
-
418
-    // Prepare display on watch
419
-    // now it's only raw data
420
-    // init strings
421
-    var latitudeString = "";
422
-    var longitudeString = "";
423
-    var accuracyString = "";
424
-    var altitudeString = "";
425
-    var speedString = "";
426
-    var distanceString = "";
427
-
428
-    // get speed from geoloc API isntead of calculate it
429
-    // speed is initially in m/s, get it at km/h
430
-    if (new_pos.coords.speed === null) {
431
-      var speed = 0;
432
-    } else {
433
-      var speed = new_pos.coords.speed * 3.6;
434
-      localStorage.setItem("speedsum", parseInt(localStorage.getItem("speedsum")) + speed);
435
-    }
401
+    console.log('--- locationSuccess');
402
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
436 403
 
437
-    // distance since beginning in m
438
-    var dist = distance_on_geoid(prev_pos.coords.latitude, prev_pos.coords.longitude, new_pos.coords.latitude, new_pos.coords.longitude);
439
-    var totaldist = parseInt(localStorage.getItem("dist"));
440
-    if (!isNaN(dist)) {
441
-      totaldist = totaldist + parseInt(dist);
442
-      localStorage.setItem("dist", totaldist);
443
-    }
444
-    distanceString = splitFloatNumber(totaldist / 1000)[0].toString() + "." + splitFloatNumber(totaldist / 1000)[1].toString().substring(0, 3);
445
-    //console.log("total dist is now " + totaldist);
446
-
447
-    // avg speed (also when not moving) since beginning
448
-    var avgspeed = parseInt(localStorage.getItem("speedsum")) / parseInt(localStorage.getItem("totalcoordinates"));
449
-    var avgSpeedString = splitFloatNumber(avgspeed)[0].toString() + "." + splitFloatNumber(avgspeed)[1].toString().substring(0, 1);
450
-    console.log("speedsum=" + parseInt(localStorage.getItem("speedsum")) + " / totalcoordinates=" + parseInt(localStorage.getItem("totalcoordinates")));
451
-    console.log("--avgspeed=" + avgspeed + " / avgSpeedString=" + avgSpeedString)
452
-    if (avgSpeedString == "0.N") {
453
-      avgSpeedString = "0.0";
454
-    }
455
-    //console.log("avg speed is : " + avgSpeedString);
456
-
457
-    // Duration
458
-
459
-    var duration = new_pos.timestamp - first_pos.timestamp;
460
-    const date = new Date(duration);
461
-    durationString = padStart(date.getUTCHours().toString(), 2, "0") + ":" + padStart(date.getMinutes().toString(), 2, "0") + ":" + padStart(date.getSeconds().toString(), 2, "0");
462
-    console.log("durationString is : " + durationString);
463
-
464
-    //formating for precision and max size
465
-    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
466
-    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
467
-    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
468
-    //console.log("split num : " + new_pos.coords.altitude);
469
-    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
470
-    timestampISO = new Date(new_pos.timestamp).toISOString();
471
-
472
-    //console.log("split num : " + speed);
473
-    if (isNaN(speed)) {
474
-      speedString = "---";
475
-    } else {
476
-      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
477
-      if (speedString == "0.N") {
478
-        speedString = "0.0";
479
-      }
480
-
481
-      //console.log("split num : " + getMaxSpeed(speed));
482
-      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
483
-    }
404
+    var prev_pos = getLocation(false);
405
+    var first_pos = getLocation(true);
406
+    if (prev_pos === null) {
407
+        console.log('--- start building gpx');
408
+        storeLocation(new_pos, true);
409
+        localStorage.setItem("strava_uploaded", false);
410
+        localStorage.setItem("custom_uploaded", false);
484 411
 
485
-    //add a new datapoint to GPX file
486
-    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
412
+        // Start the GPX file
413
+        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
487 414
 
415
+    } else {
416
+        storeLocation(new_pos, false);
417
+
418
+        // Prepare display on watch
419
+        // now it's only raw data
420
+        // init strings
421
+        var latitudeString = "";
422
+        var longitudeString = "";
423
+        var accuracyString = "";
424
+        var altitudeString = "";
425
+        var speedString = "";
426
+        var distanceString = "";
427
+
428
+        // get speed from geoloc API isntead of calculate it
429
+        // speed is initially in m/s, get it at km/h
430
+        if (new_pos.coords.speed === null) {
431
+            var speed = 0;
432
+        } else {
433
+            var speed = new_pos.coords.speed * 3.6;
434
+            localStorage.setItem("speedsum", parseInt(localStorage.getItem("speedsum")) + speed);
435
+        }
488 436
 
437
+        // distance since beginning in m
438
+        var dist = distance_on_geoid(prev_pos.coords.latitude, prev_pos.coords.longitude, new_pos.coords.latitude, new_pos.coords.longitude);
439
+        var totaldist = parseInt(localStorage.getItem("dist"));
440
+        if (!isNaN(dist)) {
441
+            totaldist = totaldist + parseInt(dist);
442
+            localStorage.setItem("dist", totaldist);
443
+        }
444
+        distanceString = splitFloatNumber(totaldist / 1000)[0].toString() + "." + splitFloatNumber(totaldist / 1000)[1].toString().substring(0, 3);
445
+        //console.log("total dist is now " + totaldist);
446
+
447
+        // avg speed (also when not moving) since beginning
448
+        var avgspeed = parseInt(localStorage.getItem("speedsum")) / parseInt(localStorage.getItem("totalcoordinates"));
449
+        var avgSpeedString = splitFloatNumber(avgspeed)[0].toString() + "." + splitFloatNumber(avgspeed)[1].toString().substring(0, 1);
450
+        console.log("speedsum=" + parseInt(localStorage.getItem("speedsum")) + " / totalcoordinates=" + parseInt(localStorage.getItem("totalcoordinates")));
451
+        console.log("--avgspeed=" + avgspeed + " / avgSpeedString=" + avgSpeedString)
452
+        if (avgSpeedString == "0.N") {
453
+            avgSpeedString = "0.0";
454
+        }
455
+        //console.log("avg speed is : " + avgSpeedString);
456
+
457
+        // Duration
458
+
459
+        var duration = new_pos.timestamp - first_pos.timestamp;
460
+        const date = new Date(duration);
461
+        durationString = padStart(date.getUTCHours().toString(), 2, "0") + ":" + padStart(date.getMinutes().toString(), 2, "0") + ":" + padStart(date.getSeconds().toString(), 2, "0");
462
+        console.log("durationString is : " + durationString);
463
+
464
+        //formating for precision and max size
465
+        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
466
+        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
467
+        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
468
+        //console.log("split num : " + new_pos.coords.altitude);
469
+        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
470
+        timestampISO = new Date(new_pos.timestamp).toISOString();
471
+
472
+        //console.log("split num : " + speed);
473
+        if (isNaN(speed)) {
474
+            speedString = "---";
475
+        } else {
476
+            speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
477
+            if (speedString == "0.N") {
478
+                speedString = "0.0";
479
+            }
489 480
 
490
-    // Build message
491
-    message = "OK";
492
-    var dict = {
493
-      'accuracy': accuracyString,
494
-      'distance': distanceString,
495
-      'avg_speed': avgSpeedString,
496
-      'duration': durationString,
497
-      'altitude': altitudeString,
498
-      'speed': speedString,
499
-      'max_speed': maxSpeedString,
500
-      'status': message
501
-    };
481
+            //console.log("split num : " + getMaxSpeed(speed));
482
+            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
483
+        }
502 484
 
503
-    // Send the message
504
-    Pebble.sendAppMessage(dict, function () {
505
-      console.log('Message sent successfully: ' + JSON.stringify(dict));
506
-    }, function (e) {
507
-      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
508
-    });
509
-  }
485
+        //add a new datapoint to GPX file
486
+        GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
487
+
488
+
489
+
490
+        // Build message
491
+        message = "OK";
492
+        var dict = {
493
+            'accuracy': accuracyString,
494
+            'distance': distanceString,
495
+            'avg_speed': avgSpeedString,
496
+            'duration': durationString,
497
+            'altitude': altitudeString,
498
+            'speed': speedString,
499
+            'max_speed': maxSpeedString,
500
+            'status': message
501
+        };
502
+
503
+        // Send the message
504
+        Pebble.sendAppMessage(dict, function() {
505
+            console.log('Message sent successfully: ' + JSON.stringify(dict));
506
+        }, function(e) {
507
+            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
508
+        });
509
+    }
510 510
 
511 511
 
512 512
 }
513 513
 
514 514
 function locationError(err) {
515 515
 
516
-  console.warn('location error (' + err.code + '): ' + err.message);
516
+    console.warn('location error (' + err.code + '): ' + err.message);
517 517
 
518 518
 }
519 519
 
520 520
 
521 521
 function start_get_coordinate() {
522
-  clearInterval(firstlocationInterval);
523
-  firstlocationInterval = false;
524
-  locationInterval = setInterval(function () {
525
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
526
-  }, 1000);
527
-
528
-  if (locate_me) {
529
-    instantLocationInterval = setInterval(function () {
530
-      navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
531
-    }, 60000);
532
-  }
522
+    clearInterval(firstlocationInterval);
523
+    firstlocationInterval = false;
524
+    locationInterval = setInterval(function() {
525
+        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
526
+    }, 1000);
527
+
528
+    if (locate_me) {
529
+        instantLocationInterval = setInterval(function() {
530
+            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
531
+        }, 60000);
532
+    }
533 533
 
534 534
 }
535 535
 
536 536
 function init() {
537 537
 
538
-  clearInterval(locationInterval);
539
-  locationInterval = false;
540
-  clearInterval(instantLocationInterval);
541
-  instantLocationInterval = false;
542
-  firstlocationInterval = setInterval(function () {
543
-    navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
544
-  }, 1000);
545
-
546
-  //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
547
-  var se = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
548
-  var su = ("true" === localStorage.getItem("strava_uploaded"));
549
-  var ce = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
550
-  var cu = ("true" === localStorage.getItem("custom_uploaded"));
551
-
552
-  locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
553
-
554
-
555
-  console.log("Locate_me = " + locate_me);
556
-  console.log("Strava = " + se + " (" + typeof se + ")/ uploaded = " + su + " (" + typeof su + ")");
557
-  console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
558
-
559
-  if ((se && !su) || (ce && !cu)) {
560
-
561
-    var GPX = localStorage.getItem("GPX");
562
-    if (!GPX.substring(GPX.length - 6, 6) == "</gpx>") {
563
-      console.log("WARNING - NO GPX FOOTER : " + GPX.substring(GPX.length - 6, 6))
564
-      /*var footer = '</trkseg></trk></gpx>';
565
-      localStorage.setItem("GPX", GPX + footer);*/
566
-      GPXfooterBuilder();
567
-      console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, 6))
568
-    }
538
+    clearInterval(locationInterval);
539
+    locationInterval = false;
540
+    clearInterval(instantLocationInterval);
541
+    instantLocationInterval = false;
542
+    firstlocationInterval = setInterval(function() {
543
+        navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
544
+    }, 1000);
545
+
546
+    //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
547
+    var se = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
548
+    var su = ("true" === localStorage.getItem("strava_uploaded"));
549
+    var ce = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
550
+    var cu = ("true" === localStorage.getItem("custom_uploaded"));
551
+
552
+    locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
553
+
554
+
555
+    console.log("Locate_me = " + locate_me);
556
+    console.log("Strava = " + se + " (" + typeof se + ")/ uploaded = " + su + " (" + typeof su + ")");
557
+    console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
558
+
559
+    if ((se && !su) || (ce && !cu)) {
560
+
561
+        var GPX = localStorage.getItem("GPX");
562
+        console.log("last 6 char of GPX are " + GPX.substring(GPX.length - 6, GPX.length))
563
+        if (GPX.substring(GPX.length - 6, GPX.length) !== "</gpx>") {
564
+            console.log("WARNING - NO GPX FOOTER ")
565
+                /*var footer = '</trkseg></trk></gpx>';
566
+                localStorage.setItem("GPX", GPX + footer);*/
567
+            GPXfooterBuilder();
568
+            GPX = localStorage.getItem("GPX");
569
+            console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, GPX.length))
570
+        }
569 571
 
570
-    if (se) {
571
-      console.log("GPX upload needed to Strava")
572
-      SendToStrava();
573
-    }
572
+        if (se) {
573
+            console.log("GPX upload needed to Strava")
574
+            SendToStrava();
575
+        }
574 576
 
575
-    if (ce) {
576
-      console.log("GPX upload needed to custom server")
577
-      PostToWeb();
577
+        if (ce) {
578
+            console.log("GPX upload needed to custom server")
579
+            PostToWeb();
580
+        }
581
+    } else {
582
+        console.log("clearing var")
583
+        localStorage.setItem("maxSpeed", 0);
584
+        localStorage.setItem("firstlatitude", "");
585
+        localStorage.setItem("firstlongitude", "");
586
+        localStorage.setItem("firsttimestamp", "");
587
+        localStorage.setItem("lastlatitude", "");
588
+        localStorage.setItem("lastlongitude", "");
589
+        localStorage.setItem("lasttimestamp", "");
590
+        localStorage.setItem("dist", 0)
591
+        localStorage.setItem("speedsum", 0)
578 592
     }
579
-  } else {
580
-    console.log("clearing var")
581
-    localStorage.setItem("maxSpeed", 0);
582
-    localStorage.setItem("firstlatitude", "");
583
-    localStorage.setItem("firstlongitude", "");
584
-    localStorage.setItem("firsttimestamp", "");
585
-    localStorage.setItem("lastlatitude", "");
586
-    localStorage.setItem("lastlongitude", "");
587
-    localStorage.setItem("lasttimestamp", "");
588
-    localStorage.setItem("dist", 0)
589
-    localStorage.setItem("speedsum", 0)
590
-  }
591 593
 
592 594
 }
593 595
 
594 596
 // Get JS readiness events
595
-Pebble.addEventListener('ready', function (e) {
596
-  console.log('PebbleKit JS is ready');
597
-  // Update Watch on this
598
-  Pebble.sendAppMessage({ 'JSReady': 1 });
597
+Pebble.addEventListener('ready', function(e) {
598
+    console.log('PebbleKit JS is ready');
599
+    // Update Watch on this
600
+    Pebble.sendAppMessage({ 'JSReady': 1 });
599 601
 
600
-  init();
602
+    init();
601 603
 });
602 604
 
603 605
 // Get AppMessage events
604
-Pebble.addEventListener('appmessage', function (e) {
605
-  // Get the dictionary from the message
606
-  var dict = e.payload;
607
-  //console.log(dict[0].toString());
608
-  switch (dict[0]) {
609
-    case 'startstop':
610
-      if (!locationInterval == false) {
611
-        console.log("Stopping the track");
612
-        clearInterval(locationInterval);
613
-        locationInterval = false;
614
-        clearInterval(instantLocationInterval);
615
-        instantLocationInterval = false;
616
-        firstlocationInterval = setInterval(function () {
617
-          navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
618
-        }, 1000);
619
-      } else {
620
-        console.log("Starting the track");
621
-        start_get_coordinate();
622
-      }
623
-      break;
624
-    case 'send':
625
-      if (locate_me) {
626
-        var prev_pos = getLocation(false);
627
-        instantLocationUpdate(prev_pos);
628
-      }
629
-
630
-      init();
631
-
632
-      /*
633
-      // Send the message
634
-      var dict = {
635
-        'status': "EXIT"
636
-      };
637
-      Pebble.sendAppMessage(dict, function () {
638
-        console.log('Message sent successfully: ' + JSON.stringify(dict));
639
-      }, function (e) {
640
-        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
641
-      });
642
-      */
643
-      break;
644
-    default:
645
-      console.log('Sorry. I don\'t understand your request :' + dict[0]);
646
-  }
606
+Pebble.addEventListener('appmessage', function(e) {
607
+    // Get the dictionary from the message
608
+    var dict = e.payload;
609
+    //console.log(dict[0].toString());
610
+    switch (dict[0]) {
611
+        case 'startstop':
612
+            if (!locationInterval == false) {
613
+                console.log("Stopping the track");
614
+                clearInterval(locationInterval);
615
+                locationInterval = false;
616
+                clearInterval(instantLocationInterval);
617
+                instantLocationInterval = false;
618
+                firstlocationInterval = setInterval(function() {
619
+                    navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
620
+                }, 1000);
621
+            } else {
622
+                console.log("Starting the track");
623
+                start_get_coordinate();
624
+            }
625
+            break;
626
+        case 'send':
627
+            if (locate_me) {
628
+                var prev_pos = getLocation(false);
629
+                instantLocationUpdate(prev_pos);
630
+            }
631
+
632
+            init();
633
+
634
+            /*
635
+            // Send the message
636
+            var dict = {
637
+              'status': "EXIT"
638
+            };
639
+            Pebble.sendAppMessage(dict, function () {
640
+              console.log('Message sent successfully: ' + JSON.stringify(dict));
641
+            }, function (e) {
642
+              console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
643
+            });
644
+            */
645
+            break;
646
+        default:
647
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
648
+    }
647 649
 
648 650
 });
649 651
\ No newline at end of file
Browse code

Merge branch 'strava-upload' of ssh://192.168.170.33:5522/volume1/web/gitlist/repos/bike_companion into strava-upload

louis.jonget authored on26/11/2022 09:25:28
Showing0 changed files
Browse code

GPX footer fix

louis.jonget authored on26/11/2022 09:18:50
Showing1 changed files
... ...
@@ -557,15 +557,18 @@ function init() {
557 557
   console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
558 558
 
559 559
   if ((se && !su) || (ce && !cu)) {
560
+
561
+    var GPX = localStorage.getItem("GPX");
562
+    if (!GPX.substring(GPX.length - 6, 6) == "</gpx>") {
563
+      console.log("WARNING - NO GPX FOOTER : " + GPX.substring(GPX.length - 6, 6))
564
+      /*var footer = '</trkseg></trk></gpx>';
565
+      localStorage.setItem("GPX", GPX + footer);*/
566
+      GPXfooterBuilder();
567
+      console.log("GPX FOOTER is now : " + GPX.substring(GPX.length - 6, 6))
568
+    }
569
+
560 570
     if (se) {
561 571
       console.log("GPX upload needed to Strava")
562
-
563
-      var GPX = localStorage.getItem("GPX");
564
-      if (!GPX.substring(GPX.length - 6, 6) == "</gpx>") {
565
-        var footer = '</trkseg></trk></gpx>';
566
-        localStorage.setItem("GPX", GPX + footer);
567
-        GPXfooterBuilder();
568
-      }
569 572
       SendToStrava();
570 573
     }
571 574
 
Browse code

more precision on distance and refresh token is a synchronous call

Louis authored on19/11/2022 18:55:54
Showing1 changed files
... ...
@@ -15,140 +15,140 @@ var client_id = "94880";
15 15
 var client_secret = "08dc170f0fe38f39dd327bea82a28db4400e6f00";
16 16
 
17 17
 var firstlocationOptions = {
18
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
19
-  'timeout': 60000, //60s timeout to get a first good signal
20
-  'maximumAge': 0 // no cache
18
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
19
+    'timeout': 60000, //60s timeout to get a first good signal
20
+    'maximumAge': 0 // no cache
21 21
 };
22 22
 var locationOptions = {
23
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
24
-  'timeout': 5000, //5s timeout to get a good signal
25
-  'maximumAge': 0 // no cache
23
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
24
+    'timeout': 5000, //5s timeout to get a good signal
25
+    'maximumAge': 0 // no cache
26 26
 };
27 27
 
28
-Pebble.addEventListener('showConfiguration', function (e) {
29
-  clay.config = clayConfig;
30
-  console.log("Clay config is showing...")
31
-  Pebble.openURL(clay.generateUrl());
28
+Pebble.addEventListener('showConfiguration', function(e) {
29
+    clay.config = clayConfig;
30
+    console.log("Clay config is showing...")
31
+    Pebble.openURL(clay.generateUrl());
32 32
 });
33 33
 
34
-Pebble.addEventListener('webviewclosed', function (t) {
35
-  if (!t || t.response) {
36
-    console.log("Clay config is submitted : " + t.response)
37
-    try {
38
-      if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
39
-        if (data.state == "bike_companion" && data.scope == "read,activity:write") {
40
-          getTokens(data.code);
41
-        } else {
42
-          console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
34
+Pebble.addEventListener('webviewclosed', function(t) {
35
+    if (!t || t.response) {
36
+        console.log("Clay config is submitted : " + t.response)
37
+        try {
38
+            if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
39
+                if (data.state == "bike_companion" && data.scope == "read,activity:write") {
40
+                    getTokens(data.code);
41
+                } else {
42
+                    console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
43
+                }
44
+            } else {
45
+                clay.getSettings(t.response);
46
+                console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
47
+            }
48
+        } catch (t) {
49
+            console.log("Oauth parsing error, continue on saving clay settings");
50
+            clay.getSettings(t.response);
51
+            var claysettings = JSON.parse(localStorage.getItem('clay-settings'))
52
+            claysettings.strava_enabled = false;
53
+            localStorage.setItem("clay-settings", JSON.stringify("claysettings"));
54
+            console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
43 55
         }
44
-      } else {
45
-        clay.getSettings(t.response);
46
-        console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
47
-      }
48
-    } catch (t) {
49
-      console.log("Oauth parsing error, continue on saving clay settings");
50
-      clay.getSettings(t.response);
51
-      var claysettings = JSON.parse(localStorage.getItem('clay-settings'))
52
-      claysettings.strava_enabled = false;
53
-      localStorage.setItem("clay-settings", JSON.stringify("claysettings"));
54
-      console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
55
-    }
56 56
 
57
-  }
57
+    }
58 58
 });
59 59
 
60 60
 // Calculate the distance from 2 geoloc in degrees.
61 61
 // IMPORTANT : this is a calculation from 2D projection, altitude is not involved
62 62
 //
63 63
 function distance_on_geoid(lat1, lon1, lat2, lon2) {
64
-  // Convert degrees to radians
65
-  lat1 = lat1 * Math.PI / 180.0;
66
-  lon1 = lon1 * Math.PI / 180.0;
67
-  lat2 = lat2 * Math.PI / 180.0;
68
-  lon2 = lon2 * Math.PI / 180.0;
69
-  // radius of earth in metres
70
-  r = 6378100;
71
-  // P
72
-  rho1 = r * Math.cos(lat1);
73
-  z1 = r * Math.sin(lat1);
74
-  x1 = rho1 * Math.cos(lon1);
75
-  y1 = rho1 * Math.sin(lon1);
76
-  // Q
77
-  rho2 = r * Math.cos(lat2);
78
-  z2 = r * Math.sin(lat2);
79
-  x2 = rho2 * Math.cos(lon2);
80
-  y2 = rho2 * Math.sin(lon2);
81
-  // Dot product
82
-  dot = (x1 * x2 + y1 * y2 + z1 * z2);
83
-  cos_theta = dot / (r * r);
84
-  theta = Math.acos(cos_theta);
85
-  // Distance in Metres
86
-  return r * theta;
64
+    // Convert degrees to radians
65
+    lat1 = lat1 * Math.PI / 180.0;
66
+    lon1 = lon1 * Math.PI / 180.0;
67
+    lat2 = lat2 * Math.PI / 180.0;
68
+    lon2 = lon2 * Math.PI / 180.0;
69
+    // radius of earth in metres
70
+    r = 6378100;
71
+    // P
72
+    rho1 = r * Math.cos(lat1);
73
+    z1 = r * Math.sin(lat1);
74
+    x1 = rho1 * Math.cos(lon1);
75
+    y1 = rho1 * Math.sin(lon1);
76
+    // Q
77
+    rho2 = r * Math.cos(lat2);
78
+    z2 = r * Math.sin(lat2);
79
+    x2 = rho2 * Math.cos(lon2);
80
+    y2 = rho2 * Math.sin(lon2);
81
+    // Dot product
82
+    dot = (x1 * x2 + y1 * y2 + z1 * z2);
83
+    cos_theta = dot / (r * r);
84
+    theta = Math.acos(cos_theta);
85
+    // Distance in Metres
86
+    return r * theta;
87 87
 }
88 88
 
89 89
 // Adding leading characters to string for nice displays
90 90
 //
91 91
 function padStart(string, max_length, padding) {
92
-  if (string.length > max_length) {
93
-    return string;
94
-  } else {
95
-    var new_str = string;
96
-    for (index = string.length; index < max_length; index++) {
97
-      new_str = padding + new_str;
92
+    if (string.length > max_length) {
93
+        return string;
94
+    } else {
95
+        var new_str = string;
96
+        for (index = string.length; index < max_length; index++) {
97
+            new_str = padding + new_str;
98
+        }
99
+        return new_str;
98 100
     }
99
-    return new_str;
100
-  }
101 101
 }
102 102
 
103 103
 
104 104
 // Store location in Pebble app local storage
105 105
 //
106 106
 function storeLocation(position, first) {
107
-  var latitude = position.coords.latitude;
108
-  var longitude = position.coords.longitude;
109
-  var timestamp = position.timestamp;
110
-  if (first == true) {
111
-    localStorage.setItem("firstlatitude", latitude);
112
-    localStorage.setItem("firstlongitude", longitude);
113
-    localStorage.setItem("firsttimestamp", Date.now());
114
-    //console.log("-- First timestamp: " + localStorage.getItem("firsttimestamp"));
115
-    localStorage.setItem("totalcoordinates", 0)
116
-  }
117
-
118
-  localStorage.setItem("lastlatitude", latitude);
119
-  localStorage.setItem("lastlongitude", longitude);
120
-  localStorage.setItem("lasttimestamp", timestamp);
121
-  localStorage.setItem("totalcoordinates", parseInt(localStorage.getItem("totalcoordinates")) + 1)
122
-  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
107
+    var latitude = position.coords.latitude;
108
+    var longitude = position.coords.longitude;
109
+    var timestamp = position.timestamp;
110
+    if (first == true) {
111
+        localStorage.setItem("firstlatitude", latitude);
112
+        localStorage.setItem("firstlongitude", longitude);
113
+        localStorage.setItem("firsttimestamp", Date.now());
114
+        //console.log("-- First timestamp: " + localStorage.getItem("firsttimestamp"));
115
+        localStorage.setItem("totalcoordinates", 0)
116
+    }
117
+
118
+    localStorage.setItem("lastlatitude", latitude);
119
+    localStorage.setItem("lastlongitude", longitude);
120
+    localStorage.setItem("lasttimestamp", timestamp);
121
+    localStorage.setItem("totalcoordinates", parseInt(localStorage.getItem("totalcoordinates")) + 1)
122
+        // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
123 123
 }
124 124
 
125 125
 // Get location from Pebble app local storage
126 126
 //
127 127
 function getLocation(first) {
128 128
 
129
-  if (first == false) {
130
-    if (localStorage.getItem("lastlatitude") || localStorage.getItem("lastlongitude") || localStorage.getItem("lasttimestamp")) {
131
-      var la = localStorage.getItem("lastlatitude");
132
-      var lo = localStorage.getItem("lastlongitude");
133
-      var ti = localStorage.getItem("lasttimestamp");
134
-      var co = { "latitude": la, "longitude": lo };
135
-      var pos = { "coords": co, "timestamp": ti };
136
-      return pos;
137
-    } else {
138
-      return null;
139
-    }
140
-  } else {
141
-    if (localStorage.getItem("firstlatitude") || localStorage.getItem("firstlongitude") || localStorage.getItem("firsttimestamp")) {
142
-      var la = localStorage.getItem("firstlatitude");
143
-      var lo = localStorage.getItem("firstlongitude");
144
-      var ti = localStorage.getItem("firsttimestamp");
145
-      var co = { "latitude": la, "longitude": lo };
146
-      var pos = { "coords": co, "timestamp": ti };
147
-      return pos;
129
+    if (first == false) {
130
+        if (localStorage.getItem("lastlatitude") || localStorage.getItem("lastlongitude") || localStorage.getItem("lasttimestamp")) {
131
+            var la = localStorage.getItem("lastlatitude");
132
+            var lo = localStorage.getItem("lastlongitude");
133
+            var ti = localStorage.getItem("lasttimestamp");
134
+            var co = { "latitude": la, "longitude": lo };
135
+            var pos = { "coords": co, "timestamp": ti };
136
+            return pos;
137
+        } else {
138
+            return null;
139
+        }
148 140
     } else {
149
-      return null;
141
+        if (localStorage.getItem("firstlatitude") || localStorage.getItem("firstlongitude") || localStorage.getItem("firsttimestamp")) {
142
+            var la = localStorage.getItem("firstlatitude");
143
+            var lo = localStorage.getItem("firstlongitude");
144
+            var ti = localStorage.getItem("firsttimestamp");
145
+            var co = { "latitude": la, "longitude": lo };
146
+            var pos = { "coords": co, "timestamp": ti };
147
+            return pos;
148
+        } else {
149
+            return null;
150
+        }
150 151
     }
151
-  }
152 152
 
153 153
 
154 154
 }
... ...
@@ -156,53 +156,53 @@ function getLocation(first) {
156 156
 // Get max speed of the run
157 157
 //
158 158
 function getMaxSpeed(lastSpeed) {
159
-  oldmax = localStorage.getItem("maxSpeed") || -1;
160
-  if (oldmax < lastSpeed) {
161
-    maxSpeed = lastSpeed
162
-  } else if (oldmax > lastSpeed) {
163
-    maxSpeed = oldmax
164
-  } else {
165
-    maxSpeed = oldmax
166
-  }
167
-  localStorage.setItem("maxSpeed", maxSpeed);
168
-  return maxSpeed
159
+    oldmax = localStorage.getItem("maxSpeed") || -1;
160
+    if (oldmax < lastSpeed) {
161
+        maxSpeed = lastSpeed
162
+    } else if (oldmax > lastSpeed) {
163
+        maxSpeed = oldmax
164
+    } else {
165
+        maxSpeed = oldmax
166
+    }
167
+    localStorage.setItem("maxSpeed", maxSpeed);
168
+    return maxSpeed
169 169
 }
170 170
 
171 171
 // split float number into an array of int (null returned instead of 0 for decimal)
172 172
 //
173 173
 function splitFloatNumber(num) {
174
-  const intStr = num.toString().split('.')[0];
175
-  var decimalStr = num.toString().split('.')[1];
176
-  if (decimalStr === undefined) { decimalStr = 0 } else { decimalStr = decimalStr }
177
-  return [Number(intStr), Number(decimalStr)];
174
+    const intStr = num.toString().split('.')[0];
175
+    var decimalStr = num.toString().split('.')[1];
176
+    if (decimalStr === undefined) { decimalStr = 0 } else { decimalStr = decimalStr }
177
+    return [Number(intStr), Number(decimalStr)];
178 178
 
179 179
 }
180 180
 
181 181
 // Build GPX headers
182 182
 //
183 183
 function GPXHeadersBuilder(timestamp, name, type) {
184
-  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
-  localStorage.setItem("GPX", headers);
186
-  return true;
184
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
+    localStorage.setItem("GPX", headers);
186
+    return true;
187 187
 }
188 188
 
189 189
 // Build GPX track point
190 190
 //
191 191
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
192
-  var GPX = localStorage.getItem("GPX");
193
-  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
194
-  localStorage.setItem("GPX", GPX + trkpt);
195
-  return true;
192
+    var GPX = localStorage.getItem("GPX");
193
+    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
194
+    localStorage.setItem("GPX", GPX + trkpt);
195
+    return true;
196 196
 }
197 197
 
198 198
 // Build GPX footer
199 199
 //
200 200
 function GPXfooterBuilder() {
201
-  var GPX = localStorage.getItem("GPX");
202
-  var footer = '</trkseg></trk></gpx>';
203
-  var ret = localStorage.setItem("GPX", GPX + footer);
204
-  //console.log("GPX closed : " + GPX + footer);
205
-  return ret;
201
+    var GPX = localStorage.getItem("GPX");
202
+    var footer = '</trkseg></trk></gpx>';
203
+    var ret = localStorage.setItem("GPX", GPX + footer);
204
+    //console.log("GPX closed : " + GPX + footer);
205
+    return ret;
206 206
 }
207 207
 
208 208
 //------------------------------------------
... ...
@@ -210,436 +210,436 @@ function GPXfooterBuilder() {
210 210
 //------------------------------------------
211 211
 
212 212
 function getTokens(code) {
213
-  // call to strava api to get tokens in exchange of temp code
214
-  // need to use strava.jonget.fr to proxy request and hide secret
215
-  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
216
-  var xhr = new XMLHttpRequest();
217
-  xhr.timeout = 10000; // time in milliseconds
218
-
219
-  xhr.open("POST", url, false);
220
-
221
-  xhr.send();
222
-
223
-  if (xhr.status === 200) {
224
-    console.log('------xhr request returned :', xhr.responseText);
225
-    response_json = JSON.parse(xhr.responseText);
226
-
227
-    var tokenjson = {
228
-      access_token: response_json.access_token,
229
-      refresh_token: response_json.refresh_token,
230
-      expiry: response_json.expires_at,
231
-      delay: response_json.expires_in
232
-    };
233
-    localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
234
-  }
213
+    // call to strava api to get tokens in exchange of temp code
214
+    // need to use strava.jonget.fr to proxy request and hide secret
215
+    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
216
+    var xhr = new XMLHttpRequest();
217
+    xhr.timeout = 10000; // time in milliseconds
218
+
219
+    xhr.open("POST", url, false);
220
+
221
+    xhr.send();
222
+
223
+    if (xhr.status === 200) {
224
+        console.log('------xhr request returned :', xhr.responseText);
225
+        response_json = JSON.parse(xhr.responseText);
226
+
227
+        var tokenjson = {
228
+            access_token: response_json.access_token,
229
+            refresh_token: response_json.refresh_token,
230
+            expiry: response_json.expires_at,
231
+            delay: response_json.expires_in
232
+        };
233
+        localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
234
+    }
235 235
 }
236 236
 
237 237
 function refreshTokens(refresh_token) {
238
-  // call to strava api to get tokens in exchange of refresh code
239
-  // need to use strava.jonget.fr to proxy request and hide secret
240
-  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
241
-  var xhr = new XMLHttpRequest();
242
-  xhr.timeout = 10000; // time in milliseconds
243
-
244
-  xhr.open("POST", url, false);
245
-
246
-  xhr.send();
247
-  //console.log('------Refresh token - xhr onloaded')
248
-  if (xhr.status === 200) {
249
-    console.log('------Refresh token - xhr request returned with ' + xhr.responseText);
250
-    response_json = JSON.parse(xhr.responseText);
251
-
252
-    var tokenjson = {
253
-      access_token: response_json.access_token,
254
-      refresh_token: response_json.refresh_token,
255
-      expiry: response_json.expires_at,
256
-      delay: response_json.expires_in
257
-    };
258
-    localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
238
+    // call to strava api to get tokens in exchange of refresh code
239
+    // need to use strava.jonget.fr to proxy request and hide secret
240
+    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
241
+    var xhr = new XMLHttpRequest();
242
+    xhr.timeout = 10000; // time in milliseconds
243
+
244
+    xhr.open("POST", url, false);
245
+
246
+    xhr.send();
247
+    //console.log('------Refresh token - xhr onloaded')
248
+    if (xhr.status === 200) {
249
+        console.log('------Refresh token - xhr request returned with ' + xhr.responseText);
250
+        response_json = JSON.parse(xhr.responseText);
251
+
252
+        var tokenjson = {
253
+            access_token: response_json.access_token,
254
+            refresh_token: response_json.refresh_token,
255
+            expiry: response_json.expires_at,
256
+            delay: response_json.expires_in
257
+        };
258
+        localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
259 259
 
260
-  }
260
+    }
261 261
 
262 262
 }
263 263
 
264 264
 // Send GPX to Strava profile
265 265
 function SendToStrava() {
266
-  console.log('--- GPX upload to strava');
267
-  var gpxfile = localStorage.getItem("GPX");
268
-
269
-  var tokens = localStorage.getItem("strava_tokens");
270
-
271
-  //checking token expiry
272
-  var date = (Date.now()) / 1000
273
-
274
-  if (JSON.parse(tokens).expiry < date) {
275
-    console.log("Strava oAuth token expired, refreshing it")
276
-    refreshTokens(JSON.parse(tokens).refresh_token);
277
-  } else {
278
-    console.log("token (" + JSON.parse(tokens).access_token + ") valid, continuing")
279
-  }
280
-
281
-
282
-  var bearer = JSON.parse(tokens).access_token;
283
-  params = {
284
-    url: "https://www.strava.com/api/v3/uploads",
285
-    method: "POST",
286
-    data: { description: "desc", data_type: "gpx" },
287
-    files: { file: gpxfile },
288
-    authorization: "Bearer " + bearer,
289
-    callback: function (e) {
290
-      var message = "";
291
-      if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
-        message = "Your activity has been created";
293
-        localStorage.setItem("strava_uploaded", true);
294
-      } else if (400 == e.status) {
295
-        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
296
-      } else if (401 == e.status) {
297
-        message = "Error - Unauthorized. Please check your credentials in the settings."
298
-      } else {
266
+    console.log('--- GPX upload to strava');
267
+    var gpxfile = localStorage.getItem("GPX");
268
+
269
+    var tokens = localStorage.getItem("strava_tokens");
270
+
271
+    //checking token expiry
272
+    var date = (Date.now()) / 1000
273
+
274
+    if (JSON.parse(tokens).expiry < date) {
275
+        console.log("Strava oAuth token expired, refreshing it")
276
+        refreshTokens(JSON.parse(tokens).refresh_token);
277
+    } else {
278
+        console.log("token (" + JSON.parse(tokens).access_token + ") valid, continuing")
279
+    }
280
+
281
+
282
+    var bearer = JSON.parse(tokens).access_token;
283
+    params = {
284
+        url: "https://www.strava.com/api/v3/uploads",
285
+        method: "POST",
286
+        data: { description: "desc", data_type: "gpx" },
287
+        files: { file: gpxfile },
288
+        authorization: "Bearer " + bearer,
289
+        callback: function(e) {
290
+            var message = "";
291
+            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
292
+                message = "Your activity has been created";
293
+                localStorage.setItem("strava_uploaded", true);
294
+            } else if (400 == e.status) {
295
+                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
296
+            } else if (401 == e.status) {
297
+                message = "Error - Unauthorized. Please check your credentials in the settings."
298
+            } else {
299
+                try {
300
+                    response_json = JSON.parse(e.txt)
301
+                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
302
+                } catch (e) {
303
+                    console.log("Error log, " + e)
304
+                }
305
+            }
306
+            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
307
+        }
308
+    }
309
+    var XHR = new XMLHttpRequest;
310
+    var n = this;
311
+    //console.log(params.url);
312
+    XHR.open(params.method, params.url, !0);
313
+    var body = "";
314
+    var boundary = Math.random().toString().substring(2);
315
+    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
316
+    XHR.setRequestHeader("Authorization", params.authorization);
317
+    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
318
+    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
319
+    body += "--" + boundary + "--\r\n"
320
+
321
+    XHR.onreadystatechange = function() {
299 322
         try {
300
-          response_json = JSON.parse(e.txt)
301
-          response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
323
+            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
302 324
         } catch (e) {
303
-          console.log("Error log, " + e)
325
+            console.error("Error2 loading, ", e)
304 326
         }
305
-      }
306
-      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
307 327
     }
308
-  }
309
-  var XHR = new XMLHttpRequest;
310
-  var n = this;
311
-  //console.log(params.url);
312
-  XHR.open(params.method, params.url, !0);
313
-  var body = "";
314
-  var boundary = Math.random().toString().substring(2);
315
-  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
316
-  XHR.setRequestHeader("Authorization", params.authorization);
317
-  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
318
-  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
319
-  body += "--" + boundary + "--\r\n"
320
-
321
-  XHR.onreadystatechange = function () {
322
-    try {
323
-      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
324
-    } catch (e) {
325
-      console.error("Error2 loading, ", e)
326
-    }
327
-  }
328
-  XHR.send(body)
328
+    XHR.send(body)
329 329
 }
330 330
 
331 331
 
332 332
 // Send GPX to web server (need configuration on serverside)
333 333
 // TODO : secure it ?
334 334
 function PostToWeb() {
335
-  console.log('--- GPX upload to custom web server');
336
-  var GPX = localStorage.getItem("GPX");
337
-  var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
338
-  var xhr = new XMLHttpRequest();
339
-  xhr.timeout = 10000; // time in milliseconds
340
-
341
-  xhr.open("POST", url, false);
342
-
343
-  //console.log('------ CSV / xhr opened')
344
-  xhr.onload = function () {
345
-    //console.log('------xhr onloaded')
346
-    if (xhr.readyState === 4) {
347
-      //console.log('------xhr request returned with ' + xhr.status);
348
-      //console.log(this.responseText);
349
-      localStorage.setItem("custom_uploaded", true);
350
-      if (xhr.status == 200) {
351
-        //console.log('--> HTTP 200');
352
-        return true;
353
-      } else {
354
-        //console.log('--> HTTP ' + xhr.status);
355
-        return false;
356
-      }
357
-    }
358
-  };
335
+    console.log('--- GPX upload to custom web server');
336
+    var GPX = localStorage.getItem("GPX");
337
+    var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
338
+    var xhr = new XMLHttpRequest();
339
+    xhr.timeout = 10000; // time in milliseconds
340
+
341
+    xhr.open("POST", url, false);
342
+
343
+    //console.log('------ CSV / xhr opened')
344
+    xhr.onload = function() {
345
+        //console.log('------xhr onloaded')
346
+        if (xhr.readyState === 4) {
347
+            //console.log('------xhr request returned with ' + xhr.status);
348
+            //console.log(this.responseText);
349
+            localStorage.setItem("custom_uploaded", true);
350
+            if (xhr.status == 200) {
351
+                //console.log('--> HTTP 200');
352
+                return true;
353
+            } else {
354
+                //console.log('--> HTTP ' + xhr.status);
355
+                return false;
356
+            }
357
+        }
358
+    };
359 359
 
360
-  //send CSV in body
361
-  xhr.send(GPX);
360
+    //send CSV in body
361
+    xhr.send(GPX);
362 362
 
363 363
 }
364 364
 
365 365
 // Send location to web server for instant location (no live tracking)
366 366
 // TODO : secure it ?
367 367
 function instantLocationUpdate(pos) {
368
-  console.log('--- Instant location update');
369
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
370
-
371
-  var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
372
-  var xhr = new XMLHttpRequest();
373
-  xhr.timeout = 10000; // time in milliseconds
374
-
375
-  xhr.open("POST", url);
376
-
377
-  //console.log('------ instant / xhr opened')
378
-  xhr.onload = function () {
379
-    //console.log('------xhr onloaded')
380
-    if (xhr.readyState === 4) {
381
-      //console.log('------xhr request returned with ' + xhr.status);
382
-      //console.log(this.responseText);
383
-      if (xhr.status == 200) {
384
-        //console.log('--> HTTP 200');
385
-        return true;
386
-      } else {
387
-        //console.log('--> HTTP ' + xhr.status);
388
-        return false;
389
-      }
390
-    }
391
-  };
368
+    console.log('--- Instant location update');
369
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
370
+
371
+    var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
372
+    var xhr = new XMLHttpRequest();
373
+    xhr.timeout = 10000; // time in milliseconds
374
+
375
+    xhr.open("POST", url);
376
+
377
+    //console.log('------ instant / xhr opened')
378
+    xhr.onload = function() {
379
+        //console.log('------xhr onloaded')
380
+        if (xhr.readyState === 4) {
381
+            //console.log('------xhr request returned with ' + xhr.status);
382
+            //console.log(this.responseText);
383
+            if (xhr.status == 200) {
384
+                //console.log('--> HTTP 200');
385
+                return true;
386
+            } else {
387
+                //console.log('--> HTTP ' + xhr.status);
388
+                return false;
389
+            }
390
+        }
391
+    };
392 392
 
393
-  //send without body
394
-  xhr.send();
393
+    //send without body
394
+    xhr.send();
395 395
 
396 396
 }
397 397
 
398 398
 // called in case of successful geoloc gathering and sends the coordinate to watch
399 399
 //
400 400
 function locationSuccess(new_pos) {
401
-  console.log('--- locationSuccess');
402
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
403
-
404
-  var prev_pos = getLocation(false);
405
-  var first_pos = getLocation(true);
406
-  if (prev_pos === null) {
407
-    console.log('--- start building gpx');
408
-    storeLocation(new_pos, true);
409
-    localStorage.setItem("strava_uploaded", false);
410
-    localStorage.setItem("custom_uploaded", false);
411
-
412
-    // Start the GPX file
413
-    GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
414
-
415
-  } else {
416
-    storeLocation(new_pos, false);
417
-
418
-    // Prepare display on watch
419
-    // now it's only raw data
420
-    // init strings
421
-    var latitudeString = "";
422
-    var longitudeString = "";
423
-    var accuracyString = "";
424
-    var altitudeString = "";
425
-    var speedString = "";
426
-    var distanceString = "";
427
-
428
-    // get speed from geoloc API isntead of calculate it
429
-    // speed is initially in m/s, get it at km/h
430
-    if (new_pos.coords.speed === null) {
431
-      var speed = 0;
432
-    } else {
433
-      var speed = new_pos.coords.speed * 3.6;
434
-      localStorage.setItem("speedsum", parseInt(localStorage.getItem("speedsum")) + speed);
435
-    }
436
-
437
-    // distance since beginning in m
438
-    var dist = distance_on_geoid(prev_pos.coords.latitude, prev_pos.coords.longitude, new_pos.coords.latitude, new_pos.coords.longitude);
439
-    var totaldist = parseInt(localStorage.getItem("dist"));
440
-    if (!isNaN(dist)) {
441
-      totaldist = totaldist + parseInt(dist);
442
-      localStorage.setItem("dist", totaldist);
443
-    }
444
-    distanceString = splitFloatNumber(totaldist / 1000)[0].toString();
445
-    //console.log("total dist is now " + totaldist);
446
-
447
-    // avg speed (also when not moving) since beginning
448
-    var avgspeed = parseInt(localStorage.getItem("speedsum")) / parseInt(localStorage.getItem("totalcoordinates"));
449
-    var avgSpeedString = splitFloatNumber(avgspeed)[0].toString() + "." + splitFloatNumber(avgspeed)[1].toString().substring(0, 1);
450
-    console.log("speedsum=" + parseInt(localStorage.getItem("speedsum")) + " / totalcoordinates=" + parseInt(localStorage.getItem("totalcoordinates")));
451
-    console.log("--avgspeed=" + avgspeed + " / avgSpeedString=" + avgSpeedString)
452
-    if (avgSpeedString == "0.N") {
453
-      avgSpeedString = "0.0";
454
-    }
455
-    //console.log("avg speed is : " + avgSpeedString);
456
-
457
-    // Duration
458
-
459
-    var duration = new_pos.timestamp - first_pos.timestamp;
460
-    const date = new Date(duration);
461
-    durationString = padStart(date.getUTCHours().toString(), 2, "0") + ":" + padStart(date.getMinutes().toString(), 2, "0") + ":" + padStart(date.getSeconds().toString(), 2, "0");
462
-    console.log("durationString is : " + durationString);
463
-
464
-    //formating for precision and max size
465
-    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
466
-    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
467
-    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
468
-    //console.log("split num : " + new_pos.coords.altitude);
469
-    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
470
-    timestampISO = new Date(new_pos.timestamp).toISOString();
471
-
472
-    //console.log("split num : " + speed);
473
-    if (isNaN(speed)) {
474
-      speedString = "---";
475
-    } else {
476
-      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
477
-      if (speedString == "0.N") {
478
-        speedString = "0.0";
479
-      }
401
+    console.log('--- locationSuccess');
402
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
480 403
 
481
-      //console.log("split num : " + getMaxSpeed(speed));
482
-      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
483
-    }
404
+    var prev_pos = getLocation(false);
405
+    var first_pos = getLocation(true);
406
+    if (prev_pos === null) {
407
+        console.log('--- start building gpx');
408
+        storeLocation(new_pos, true);
409
+        localStorage.setItem("strava_uploaded", false);
410
+        localStorage.setItem("custom_uploaded", false);
484 411
 
485
-    //add a new datapoint to GPX file
486
-    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
412
+        // Start the GPX file
413
+        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
487 414
 
415
+    } else {
416
+        storeLocation(new_pos, false);
417
+
418
+        // Prepare display on watch
419
+        // now it's only raw data
420
+        // init strings
421
+        var latitudeString = "";
422
+        var longitudeString = "";
423
+        var accuracyString = "";
424
+        var altitudeString = "";
425
+        var speedString = "";
426
+        var distanceString = "";
427
+
428
+        // get speed from geoloc API isntead of calculate it
429
+        // speed is initially in m/s, get it at km/h
430
+        if (new_pos.coords.speed === null) {
431
+            var speed = 0;
432
+        } else {
433
+            var speed = new_pos.coords.speed * 3.6;
434
+            localStorage.setItem("speedsum", parseInt(localStorage.getItem("speedsum")) + speed);
435
+        }
488 436
 
437
+        // distance since beginning in m
438
+        var dist = distance_on_geoid(prev_pos.coords.latitude, prev_pos.coords.longitude, new_pos.coords.latitude, new_pos.coords.longitude);
439
+        var totaldist = parseInt(localStorage.getItem("dist"));
440
+        if (!isNaN(dist)) {
441
+            totaldist = totaldist + parseInt(dist);
442
+            localStorage.setItem("dist", totaldist);
443
+        }
444
+        distanceString = splitFloatNumber(totaldist / 1000)[0].toString() + "." + splitFloatNumber(totaldist / 1000)[1].toString().substring(0, 3);
445
+        //console.log("total dist is now " + totaldist);
446
+
447
+        // avg speed (also when not moving) since beginning
448
+        var avgspeed = parseInt(localStorage.getItem("speedsum")) / parseInt(localStorage.getItem("totalcoordinates"));
449
+        var avgSpeedString = splitFloatNumber(avgspeed)[0].toString() + "." + splitFloatNumber(avgspeed)[1].toString().substring(0, 1);
450
+        console.log("speedsum=" + parseInt(localStorage.getItem("speedsum")) + " / totalcoordinates=" + parseInt(localStorage.getItem("totalcoordinates")));
451
+        console.log("--avgspeed=" + avgspeed + " / avgSpeedString=" + avgSpeedString)
452
+        if (avgSpeedString == "0.N") {
453
+            avgSpeedString = "0.0";
454
+        }
455
+        //console.log("avg speed is : " + avgSpeedString);
456
+
457
+        // Duration
458
+
459
+        var duration = new_pos.timestamp - first_pos.timestamp;
460
+        const date = new Date(duration);
461
+        durationString = padStart(date.getUTCHours().toString(), 2, "0") + ":" + padStart(date.getMinutes().toString(), 2, "0") + ":" + padStart(date.getSeconds().toString(), 2, "0");
462
+        console.log("durationString is : " + durationString);
463
+
464
+        //formating for precision and max size
465
+        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
466
+        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
467
+        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
468
+        //console.log("split num : " + new_pos.coords.altitude);
469
+        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
470
+        timestampISO = new Date(new_pos.timestamp).toISOString();
471
+
472
+        //console.log("split num : " + speed);
473
+        if (isNaN(speed)) {
474
+            speedString = "---";
475
+        } else {
476
+            speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
477
+            if (speedString == "0.N") {
478
+                speedString = "0.0";
479
+            }
489 480
 
490
-    // Build message
491
-    message = "OK";
492
-    var dict = {
493
-      'accuracy': accuracyString,
494
-      'distance': distanceString,
495
-      'avg_speed': avgSpeedString,
496
-      'duration': durationString,
497
-      'altitude': altitudeString,
498
-      'speed': speedString,
499
-      'max_speed': maxSpeedString,
500
-      'status': message
501
-    };
481
+            //console.log("split num : " + getMaxSpeed(speed));
482
+            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
483
+        }
502 484
 
503
-    // Send the message
504
-    Pebble.sendAppMessage(dict, function () {
505
-      console.log('Message sent successfully: ' + JSON.stringify(dict));
506
-    }, function (e) {
507
-      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
508
-    });
509
-  }
485
+        //add a new datapoint to GPX file
486
+        GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
487
+
488
+
489
+
490
+        // Build message
491
+        message = "OK";
492
+        var dict = {
493
+            'accuracy': accuracyString,
494
+            'distance': distanceString,
495
+            'avg_speed': avgSpeedString,
496
+            'duration': durationString,
497
+            'altitude': altitudeString,
498
+            'speed': speedString,
499
+            'max_speed': maxSpeedString,
500
+            'status': message
501
+        };
502
+
503
+        // Send the message
504
+        Pebble.sendAppMessage(dict, function() {
505
+            console.log('Message sent successfully: ' + JSON.stringify(dict));
506
+        }, function(e) {
507
+            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
508
+        });
509
+    }
510 510
 
511 511
 
512 512
 }
513 513
 
514 514
 function locationError(err) {
515 515
 
516
-  console.warn('location error (' + err.code + '): ' + err.message);
516
+    console.warn('location error (' + err.code + '): ' + err.message);
517 517
 
518 518
 }
519 519
 
520 520
 
521 521
 function start_get_coordinate() {
522
-  clearInterval(firstlocationInterval);
523
-  firstlocationInterval = false;
524
-  locationInterval = setInterval(function () {
525
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
526
-  }, 1000);
527
-
528
-  if (locate_me) {
529
-    instantLocationInterval = setInterval(function () {
530
-      navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
531
-    }, 60000);
532
-  }
522
+    clearInterval(firstlocationInterval);
523
+    firstlocationInterval = false;
524
+    locationInterval = setInterval(function() {
525
+        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
526
+    }, 1000);
527
+
528
+    if (locate_me) {
529
+        instantLocationInterval = setInterval(function() {
530
+            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
531
+        }, 60000);
532
+    }
533 533
 
534 534
 }
535 535
 
536 536
 function init() {
537 537
 
538
-  clearInterval(locationInterval);
539
-  locationInterval = false;
540
-  clearInterval(instantLocationInterval);
541
-  instantLocationInterval = false;
542
-  firstlocationInterval = setInterval(function () {
543
-    navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
544
-  }, 1000);
545
-
546
-  //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
547
-  var se = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
548
-  var su = ("true" === localStorage.getItem("strava_uploaded"));
549
-  var ce = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
550
-  var cu = ("true" === localStorage.getItem("custom_uploaded"));
551
-
552
-  locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
553
-
554
-
555
-  console.log("Locate_me = " + locate_me);
556
-  console.log("Strava = " + se + " (" + typeof se + ")/ uploaded = " + su + " (" + typeof su + ")");
557
-  console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
558
-
559
-  if ((se && !su) || (ce && !cu)) {
560
-    if (se) {
561
-      console.log("GPX upload needed to Strava")
562
-
563
-      var GPX = localStorage.getItem("GPX");
564
-      if (!GPX.substring(GPX.length - 6, 6) == "</gpx>") {
565
-        var footer = '</trkseg></trk></gpx>';
566
-        localStorage.setItem("GPX", GPX + footer);
567
-        GPXfooterBuilder();
568
-      }
569
-      SendToStrava();
570
-    }
538
+    clearInterval(locationInterval);
539
+    locationInterval = false;
540
+    clearInterval(instantLocationInterval);
541
+    instantLocationInterval = false;
542
+    firstlocationInterval = setInterval(function() {
543
+        navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
544
+    }, 1000);
545
+
546
+    //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
547
+    var se = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
548
+    var su = ("true" === localStorage.getItem("strava_uploaded"));
549
+    var ce = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
550
+    var cu = ("true" === localStorage.getItem("custom_uploaded"));
551
+
552
+    locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
553
+
554
+
555
+    console.log("Locate_me = " + locate_me);
556
+    console.log("Strava = " + se + " (" + typeof se + ")/ uploaded = " + su + " (" + typeof su + ")");
557
+    console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
558
+
559
+    if ((se && !su) || (ce && !cu)) {
560
+        if (se) {
561
+            console.log("GPX upload needed to Strava")
562
+
563
+            var GPX = localStorage.getItem("GPX");
564
+            if (!GPX.substring(GPX.length - 6, 6) == "</gpx>") {
565
+                var footer = '</trkseg></trk></gpx>';
566
+                localStorage.setItem("GPX", GPX + footer);
567
+                GPXfooterBuilder();
568
+            }
569
+            SendToStrava();
570
+        }
571 571
 
572
-    if (ce) {
573
-      console.log("GPX upload needed to custom server")
574
-      PostToWeb();
572
+        if (ce) {
573
+            console.log("GPX upload needed to custom server")
574
+            PostToWeb();
575
+        }
576
+    } else {
577
+        console.log("clearing var")
578
+        localStorage.setItem("maxSpeed", 0);
579
+        localStorage.setItem("firstlatitude", "");
580
+        localStorage.setItem("firstlongitude", "");
581
+        localStorage.setItem("firsttimestamp", "");
582
+        localStorage.setItem("lastlatitude", "");
583
+        localStorage.setItem("lastlongitude", "");
584
+        localStorage.setItem("lasttimestamp", "");
585
+        localStorage.setItem("dist", 0)
586
+        localStorage.setItem("speedsum", 0)
575 587
     }
576
-  } else {
577
-    console.log("clearing var")
578
-    localStorage.setItem("maxSpeed", 0);
579
-    localStorage.setItem("firstlatitude", "");
580
-    localStorage.setItem("firstlongitude", "");
581
-    localStorage.setItem("firsttimestamp", "");
582
-    localStorage.setItem("lastlatitude", "");
583
-    localStorage.setItem("lastlongitude", "");
584
-    localStorage.setItem("lasttimestamp", "");
585
-    localStorage.setItem("dist", 0)
586
-    localStorage.setItem("speedsum", 0)
587
-  }
588 588
 
589 589
 }
590 590
 
591 591
 // Get JS readiness events
592
-Pebble.addEventListener('ready', function (e) {
593
-  console.log('PebbleKit JS is ready');
594
-  // Update Watch on this
595
-  Pebble.sendAppMessage({ 'JSReady': 1 });
592
+Pebble.addEventListener('ready', function(e) {
593
+    console.log('PebbleKit JS is ready');
594
+    // Update Watch on this
595
+    Pebble.sendAppMessage({ 'JSReady': 1 });
596 596
 
597
-  init();
597
+    init();
598 598
 });
599 599
 
600 600
 // Get AppMessage events
601
-Pebble.addEventListener('appmessage', function (e) {
602
-  // Get the dictionary from the message
603
-  var dict = e.payload;
604
-  //console.log(dict[0].toString());
605
-  switch (dict[0]) {
606
-    case 'startstop':
607
-      if (!locationInterval == false) {
608
-        console.log("Stopping the track");
609
-        clearInterval(locationInterval);
610
-        locationInterval = false;
611
-        clearInterval(instantLocationInterval);
612
-        instantLocationInterval = false;
613
-        firstlocationInterval = setInterval(function () {
614
-          navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
615
-        }, 1000);
616
-      } else {
617
-        console.log("Starting the track");
618
-        start_get_coordinate();
619
-      }
620
-      break;
621
-    case 'send':
622
-      if (locate_me) {
623
-        var prev_pos = getLocation(false);
624
-        instantLocationUpdate(prev_pos);
625
-      }
626
-
627
-      init();
628
-
629
-      /*
630
-      // Send the message
631
-      var dict = {
632
-        'status': "EXIT"
633
-      };
634
-      Pebble.sendAppMessage(dict, function () {
635
-        console.log('Message sent successfully: ' + JSON.stringify(dict));
636
-      }, function (e) {
637
-        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
638
-      });
639
-      */
640
-      break;
641
-    default:
642
-      console.log('Sorry. I don\'t understand your request :' + dict[0]);
643
-  }
601
+Pebble.addEventListener('appmessage', function(e) {
602
+    // Get the dictionary from the message
603
+    var dict = e.payload;
604
+    //console.log(dict[0].toString());
605
+    switch (dict[0]) {
606
+        case 'startstop':
607
+            if (!locationInterval == false) {
608
+                console.log("Stopping the track");
609
+                clearInterval(locationInterval);
610
+                locationInterval = false;
611
+                clearInterval(instantLocationInterval);
612
+                instantLocationInterval = false;
613
+                firstlocationInterval = setInterval(function() {
614
+                    navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
615
+                }, 1000);
616
+            } else {
617
+                console.log("Starting the track");
618
+                start_get_coordinate();
619
+            }
620
+            break;
621
+        case 'send':
622
+            if (locate_me) {
623
+                var prev_pos = getLocation(false);
624
+                instantLocationUpdate(prev_pos);
625
+            }
626
+
627
+            init();
628
+
629
+            /*
630
+            // Send the message
631
+            var dict = {
632
+              'status': "EXIT"
633
+            };
634
+            Pebble.sendAppMessage(dict, function () {
635
+              console.log('Message sent successfully: ' + JSON.stringify(dict));
636
+            }, function (e) {
637
+              console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
638
+            });
639
+            */
640
+            break;
641
+        default:
642
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
643
+    }
644 644
 
645 645
 });
646 646
\ No newline at end of file
Browse code

fixed GPX format on restart

louis.jonget authored on10/11/2022 15:41:02
Showing1 changed files
... ...
@@ -218,25 +218,20 @@ function getTokens(code) {
218 218
 
219 219
   xhr.open("POST", url, false);
220 220
 
221
-  xhr.onload = function () {
222
-    //console.log('------xhr onloaded')
223
-    if (xhr.readyState === 4) {
224
-      console.log('------xhr request returned :', xhr.responseText);
225
-      response_json = JSON.parse(xhr.responseText);
226
-
227
-      var tokenjson = {
228
-        access_token: response_json.access_token,
229
-        refresh_token: response_json.refresh_token,
230
-        expiry: response_json.expires_at,
231
-        delay: response_json.expires_in
232
-      };
233
-      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
234
-
235
-    }
236
-  };
237
-
238 221
   xhr.send();
239 222
 
223
+  if (xhr.status === 200) {
224
+    console.log('------xhr request returned :', xhr.responseText);
225
+    response_json = JSON.parse(xhr.responseText);
226
+
227
+    var tokenjson = {
228
+      access_token: response_json.access_token,
229
+      refresh_token: response_json.refresh_token,
230
+      expiry: response_json.expires_at,
231
+      delay: response_json.expires_in
232
+    };
233
+    localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
234
+  }
240 235
 }
241 236
 
242 237
 function refreshTokens(refresh_token) {
... ...
@@ -248,24 +243,21 @@ function refreshTokens(refresh_token) {
248 243
 
249 244
   xhr.open("POST", url, false);
250 245
 
251
-  xhr.onload = function () {
252
-    //console.log('------Refresh token - xhr onloaded')
253
-    if (xhr.readyState === 4) {
254
-      console.log('------Refresh token - xhr request returned with ' + xhr.responseText);
255
-      response_json = JSON.parse(xhr.responseText);
256
-
257
-      var tokenjson = {
258
-        access_token: response_json.access_token,
259
-        refresh_token: response_json.refresh_token,
260
-        expiry: response_json.expires_at,
261
-        delay: response_json.expires_in
262
-      };
263
-      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
264
-
265
-    }
266
-  };
267
-
268 246
   xhr.send();
247
+  //console.log('------Refresh token - xhr onloaded')
248
+  if (xhr.status === 200) {
249
+    console.log('------Refresh token - xhr request returned with ' + xhr.responseText);
250
+    response_json = JSON.parse(xhr.responseText);
251
+
252
+    var tokenjson = {
253
+      access_token: response_json.access_token,
254
+      refresh_token: response_json.refresh_token,
255
+      expiry: response_json.expires_at,
256
+      delay: response_json.expires_in
257
+    };
258
+    localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
259
+
260
+  }
269 261
 
270 262
 }
271 263
 
... ...
@@ -567,6 +559,13 @@ function init() {
567 559
   if ((se && !su) || (ce && !cu)) {
568 560
     if (se) {
569 561
       console.log("GPX upload needed to Strava")
562
+
563
+      var GPX = localStorage.getItem("GPX");
564
+      if (!GPX.substring(GPX.length - 6, 6) == "</gpx>") {
565
+        var footer = '</trkseg></trk></gpx>';
566
+        localStorage.setItem("GPX", GPX + footer);
567
+        GPXfooterBuilder();
568
+      }
570 569
       SendToStrava();
571 570
     }
572 571
 
... ...
@@ -608,7 +607,6 @@ Pebble.addEventListener('appmessage', function (e) {
608 607
       if (!locationInterval == false) {
609 608
         console.log("Stopping the track");
610 609
         clearInterval(locationInterval);
611
-        GPXfooterBuilder();
612 610
         locationInterval = false;
613 611
         clearInterval(instantLocationInterval);
614 612
         instantLocationInterval = false;
Browse code

new UI with more data and cleaning + build

louis.jonget authored on10/11/2022 14:48:43
Showing1 changed files
... ...
@@ -4,138 +4,205 @@ var clay = new Clay(clayConfig, null, { autoHandleEvents: false });
4 4
 var messageKeys = require('message_keys');
5 5
 
6 6
 var message;
7
-var gpx_to_strava
8
-var gpx_to_web
9 7
 var locate_me
10 8
 
11
-var locationInterval;
12
-var instantLocationInterval;
9
+var firstlocationInterval = false;
10
+var locationInterval = false;
11
+var instantLocationInterval = false;
13 12
 
14 13
 // TODO to remove for security
15 14
 var client_id = "94880";
16 15
 var client_secret = "08dc170f0fe38f39dd327bea82a28db4400e6f00";
17 16
 
18 17
 var firstlocationOptions = {
19
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
20
-    'timeout': 60000, //60s timeout to get a first good signal
21
-    'maximumAge': 0 // no cache
18
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
19
+  'timeout': 60000, //60s timeout to get a first good signal
20
+  'maximumAge': 0 // no cache
22 21
 };
23 22
 var locationOptions = {
24
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
25
-    'timeout': 5000, //5s timeout to get a good signal
26
-    'maximumAge': 0 // no cache
23
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
24
+  'timeout': 5000, //5s timeout to get a good signal
25
+  'maximumAge': 0 // no cache
27 26
 };
28 27
 
29
-Pebble.addEventListener('showConfiguration', function(e) {
30
-    clay.config = clayConfig;
31
-    console.log("Clay config is showing...")
32
-    Pebble.openURL(clay.generateUrl());
28
+Pebble.addEventListener('showConfiguration', function (e) {
29
+  clay.config = clayConfig;
30
+  console.log("Clay config is showing...")
31
+  Pebble.openURL(clay.generateUrl());
33 32
 });
34 33
 
35
-Pebble.addEventListener('webviewclosed', function(t) {
36
-    if (!t || t.response) {
37
-        console.log("Clay config is submitted : " + t.response)
38
-        try {
39
-            if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
40
-                if (data.state == "bike_companion" && data.scope == "read,activity:write") {
41
-                    getTokens(data.code);
42
-                } else {
43
-                    console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
44
-                }
45
-            } else {
46
-                clay.getSettings(t.response);
47
-                console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
48
-            }
49
-        } catch (t) {
50
-            console.log("Oauth parsing error, continue on saving clay settings");
51
-            clay.getSettings(t.response);
52
-            var claysettings = JSON.parse(localStorage.getItem('clay-settings'))
53
-            claysettings.strava_enabled = false;
54
-            localStorage.setItem("clay-settings", JSON.stringify("claysettings"));
55
-            console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
34
+Pebble.addEventListener('webviewclosed', function (t) {
35
+  if (!t || t.response) {
36
+    console.log("Clay config is submitted : " + t.response)
37
+    try {
38
+      if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
39
+        if (data.state == "bike_companion" && data.scope == "read,activity:write") {
40
+          getTokens(data.code);
41
+        } else {
42
+          console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
56 43
         }
57
-
44
+      } else {
45
+        clay.getSettings(t.response);
46
+        console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
47
+      }
48
+    } catch (t) {
49
+      console.log("Oauth parsing error, continue on saving clay settings");
50
+      clay.getSettings(t.response);
51
+      var claysettings = JSON.parse(localStorage.getItem('clay-settings'))
52
+      claysettings.strava_enabled = false;
53
+      localStorage.setItem("clay-settings", JSON.stringify("claysettings"));
54
+      console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
58 55
     }
56
+
57
+  }
59 58
 });
60 59
 
60
+// Calculate the distance from 2 geoloc in degrees.
61
+// IMPORTANT : this is a calculation from 2D projection, altitude is not involved
62
+//
63
+function distance_on_geoid(lat1, lon1, lat2, lon2) {
64
+  // Convert degrees to radians
65
+  lat1 = lat1 * Math.PI / 180.0;
66
+  lon1 = lon1 * Math.PI / 180.0;
67
+  lat2 = lat2 * Math.PI / 180.0;
68
+  lon2 = lon2 * Math.PI / 180.0;
69
+  // radius of earth in metres
70
+  r = 6378100;
71
+  // P
72
+  rho1 = r * Math.cos(lat1);
73
+  z1 = r * Math.sin(lat1);
74
+  x1 = rho1 * Math.cos(lon1);
75
+  y1 = rho1 * Math.sin(lon1);
76
+  // Q
77
+  rho2 = r * Math.cos(lat2);
78
+  z2 = r * Math.sin(lat2);
79
+  x2 = rho2 * Math.cos(lon2);
80
+  y2 = rho2 * Math.sin(lon2);
81
+  // Dot product
82
+  dot = (x1 * x2 + y1 * y2 + z1 * z2);
83
+  cos_theta = dot / (r * r);
84
+  theta = Math.acos(cos_theta);
85
+  // Distance in Metres
86
+  return r * theta;
87
+}
88
+
89
+// Adding leading characters to string for nice displays
90
+//
91
+function padStart(string, max_length, padding) {
92
+  if (string.length > max_length) {
93
+    return string;
94
+  } else {
95
+    var new_str = string;
96
+    for (index = string.length; index < max_length; index++) {
97
+      new_str = padding + new_str;
98
+    }
99
+    return new_str;
100
+  }
101
+}
102
+
61 103
 
62 104
 // Store location in Pebble app local storage
63 105
 //
64
-function storeLocation(position) {
65
-    var latitude = position.coords.latitude;
66
-    var longitude = position.coords.longitude;
67
-    var timestamp = position.timestamp;
68
-    localStorage.setItem("latitude", latitude);
69
-    localStorage.setItem("longitude", longitude);
70
-    localStorage.setItem("timestamp", timestamp);
71
-    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
106
+function storeLocation(position, first) {
107
+  var latitude = position.coords.latitude;
108
+  var longitude = position.coords.longitude;
109
+  var timestamp = position.timestamp;
110
+  if (first == true) {
111
+    localStorage.setItem("firstlatitude", latitude);
112
+    localStorage.setItem("firstlongitude", longitude);
113
+    localStorage.setItem("firsttimestamp", Date.now());
114
+    //console.log("-- First timestamp: " + localStorage.getItem("firsttimestamp"));
115
+    localStorage.setItem("totalcoordinates", 0)
116
+  }
117
+
118
+  localStorage.setItem("lastlatitude", latitude);
119
+  localStorage.setItem("lastlongitude", longitude);
120
+  localStorage.setItem("lasttimestamp", timestamp);
121
+  localStorage.setItem("totalcoordinates", parseInt(localStorage.getItem("totalcoordinates")) + 1)
122
+  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
72 123
 }
73 124
 
74 125
 // Get location from Pebble app local storage
75 126
 //
76
-function getLocation() {
77
-    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
78
-        var la = localStorage.getItem("latitude");
79
-        var lo = localStorage.getItem("longitude");
80
-        var ti = localStorage.getItem("timestamp");
81
-        var co = { "latitude": la, "longitude": lo };
82
-        var pos = { "coords": co, "timestamp": ti };
83
-        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
84
-        return pos;
127
+function getLocation(first) {
128
+
129
+  if (first == false) {
130
+    if (localStorage.getItem("lastlatitude") || localStorage.getItem("lastlongitude") || localStorage.getItem("lasttimestamp")) {
131
+      var la = localStorage.getItem("lastlatitude");
132
+      var lo = localStorage.getItem("lastlongitude");
133
+      var ti = localStorage.getItem("lasttimestamp");
134
+      var co = { "latitude": la, "longitude": lo };
135
+      var pos = { "coords": co, "timestamp": ti };
136
+      return pos;
137
+    } else {
138
+      return null;
139
+    }
140
+  } else {
141
+    if (localStorage.getItem("firstlatitude") || localStorage.getItem("firstlongitude") || localStorage.getItem("firsttimestamp")) {
142
+      var la = localStorage.getItem("firstlatitude");
143
+      var lo = localStorage.getItem("firstlongitude");
144
+      var ti = localStorage.getItem("firsttimestamp");
145
+      var co = { "latitude": la, "longitude": lo };
146
+      var pos = { "coords": co, "timestamp": ti };
147
+      return pos;
85 148
     } else {
86
-        return null;
149
+      return null;
87 150
     }
151
+  }
152
+
153
+
88 154
 }
89 155
 
90 156
 // Get max speed of the run
91 157
 //
92 158
 function getMaxSpeed(lastSpeed) {
93
-    oldmax = localStorage.getItem("maxSpeed") || -1;
94
-    if (oldmax < lastSpeed) {
95
-        maxSpeed = lastSpeed
96
-    } else if (oldmax > lastSpeed) {
97
-        maxSpeed = oldmax
98
-    } else {
99
-        maxSpeed = oldmax
100
-    }
101
-    localStorage.setItem("maxSpeed", maxSpeed);
102
-    return maxSpeed
159
+  oldmax = localStorage.getItem("maxSpeed") || -1;
160
+  if (oldmax < lastSpeed) {
161
+    maxSpeed = lastSpeed
162
+  } else if (oldmax > lastSpeed) {
163
+    maxSpeed = oldmax
164
+  } else {
165
+    maxSpeed = oldmax
166
+  }
167
+  localStorage.setItem("maxSpeed", maxSpeed);
168
+  return maxSpeed
103 169
 }
104 170
 
105 171
 // split float number into an array of int (null returned instead of 0 for decimal)
106 172
 //
107 173
 function splitFloatNumber(num) {
108
-    const intStr = num.toString().split('.')[0];
109
-    const decimalStr = num.toString().split('.')[1];
110
-    return [Number(intStr), Number(decimalStr)];
174
+  const intStr = num.toString().split('.')[0];
175
+  var decimalStr = num.toString().split('.')[1];
176
+  if (decimalStr === undefined) { decimalStr = 0 } else { decimalStr = decimalStr }
177
+  return [Number(intStr), Number(decimalStr)];
111 178
 
112 179
 }
113 180
 
114 181
 // Build GPX headers
115 182
 //
116 183
 function GPXHeadersBuilder(timestamp, name, type) {
117
-    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
118
-    var ret = localStorage.setItem("GPX", headers);
119
-    return true;
184
+  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
185
+  localStorage.setItem("GPX", headers);
186
+  return true;
120 187
 }
121 188
 
122 189
 // Build GPX track point
123 190
 //
124 191
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
125
-    var GPX = localStorage.getItem("GPX");
126
-    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
127
-    localStorage.setItem("GPX", GPX + trkpt);
128
-    return true;
192
+  var GPX = localStorage.getItem("GPX");
193
+  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
194
+  localStorage.setItem("GPX", GPX + trkpt);
195
+  return true;
129 196
 }
130 197
 
131 198
 // Build GPX footer
132 199
 //
133 200
 function GPXfooterBuilder() {
134
-    var GPX = localStorage.getItem("GPX");
135
-    var footer = '</trkseg></trk></gpx>';
136
-    var ret = localStorage.setItem("GPX", GPX + footer);
137
-    //console.log("GPX closed : " + GPX + footer);
138
-    return ret;
201
+  var GPX = localStorage.getItem("GPX");
202
+  var footer = '</trkseg></trk></gpx>';
203
+  var ret = localStorage.setItem("GPX", GPX + footer);
204
+  //console.log("GPX closed : " + GPX + footer);
205
+  return ret;
139 206
 }
140 207
 
141 208
 //------------------------------------------
... ...
@@ -143,397 +210,438 @@ function GPXfooterBuilder() {
143 210
 //------------------------------------------
144 211
 
145 212
 function getTokens(code) {
146
-    // call to strava api to get tokens in exchange of temp code
147
-    // need to use strava.jonget.fr to proxy request and hide secret
148
-    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
149
-    var xhr = new XMLHttpRequest();
150
-    xhr.timeout = 10000; // time in milliseconds
151
-
152
-    xhr.open("POST", url, false);
153
-
154
-    xhr.onload = function() {
155
-        //console.log('------xhr onloaded')
156
-        if (xhr.readyState === 4) {
157
-            console.log('------xhr request returned :', xhr.responseText);
158
-            response_json = JSON.parse(xhr.responseText);
159
-
160
-            var tokenjson = {
161
-                access_token: response_json.access_token,
162
-                refresh_token: response_json.refresh_token,
163
-                expiry: response_json.expires_at
164
-            };
165
-            localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
213
+  // call to strava api to get tokens in exchange of temp code
214
+  // need to use strava.jonget.fr to proxy request and hide secret
215
+  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
216
+  var xhr = new XMLHttpRequest();
217
+  xhr.timeout = 10000; // time in milliseconds
218
+
219
+  xhr.open("POST", url, false);
220
+
221
+  xhr.onload = function () {
222
+    //console.log('------xhr onloaded')
223
+    if (xhr.readyState === 4) {
224
+      console.log('------xhr request returned :', xhr.responseText);
225
+      response_json = JSON.parse(xhr.responseText);
226
+
227
+      var tokenjson = {
228
+        access_token: response_json.access_token,
229
+        refresh_token: response_json.refresh_token,
230
+        expiry: response_json.expires_at,
231
+        delay: response_json.expires_in
232
+      };
233
+      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
166 234
 
167
-        }
168
-    };
235
+    }
236
+  };
169 237
 
170
-    xhr.send();
238
+  xhr.send();
171 239
 
172 240
 }
173 241
 
174 242
 function refreshTokens(refresh_token) {
175
-    // call to strava api to get tokens in exchange of refresh code
176
-    // need to use strava.jonget.fr to proxy request and hide secret
177
-    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
178
-    var xhr = new XMLHttpRequest();
179
-    xhr.timeout = 10000; // time in milliseconds
180
-
181
-    xhr.open("POST", url, false);
182
-
183
-    xhr.onload = function() {
184
-        //console.log('------xhr onloaded')
185
-        if (xhr.readyState === 4) {
186
-            //console.log('------xhr request returned with ' + xhr.status);
187
-            response_json = JSON.parse(xhr.responseText);
188
-
189
-            var tokenjson = {
190
-                access_token: response_json.access_token,
191
-                refresh_token: response_json.refresh_token,
192
-                expiry: response_json.expires_at
193
-            };
194
-            localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
243
+  // call to strava api to get tokens in exchange of refresh code
244
+  // need to use strava.jonget.fr to proxy request and hide secret
245
+  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
246
+  var xhr = new XMLHttpRequest();
247
+  xhr.timeout = 10000; // time in milliseconds
248
+
249
+  xhr.open("POST", url, false);
250
+
251
+  xhr.onload = function () {
252
+    //console.log('------Refresh token - xhr onloaded')
253
+    if (xhr.readyState === 4) {
254
+      console.log('------Refresh token - xhr request returned with ' + xhr.responseText);
255
+      response_json = JSON.parse(xhr.responseText);
256
+
257
+      var tokenjson = {
258
+        access_token: response_json.access_token,
259
+        refresh_token: response_json.refresh_token,
260
+        expiry: response_json.expires_at,
261
+        delay: response_json.expires_in
262
+      };
263
+      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
195 264
 
196
-        }
197
-    };
265
+    }
266
+  };
198 267
 
199
-    xhr.send();
268
+  xhr.send();
200 269
 
201 270
 }
202 271
 
203 272
 // Send GPX to Strava profile
204 273
 function SendToStrava() {
205
-    console.log('--- GPX upload to strava');
206
-    var gpxfile = localStorage.getItem("GPX");
207
-
208
-    var tokens = localStorage.getItem("strava_tokens");
209
-
210
-    var bearer = JSON.parse(tokens).access_token;
211
-    params = {
212
-        url: "https://www.strava.com/api/v3/uploads",
213
-        method: "POST",
214
-        data: { description: "desc", data_type: "gpx" },
215
-        files: { file: gpxfile },
216
-        authorization: "Bearer " + bearer,
217
-        callback: function(e) {
218
-            var message = "";
219
-            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
220
-                message = "Your activity has been created";
221
-                localStorage.setItem("strava_uploaded", true);
222
-            } else if (400 == e.status) {
223
-                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
224
-            } else if (401 == e.status) {
225
-                message = "Error - Unauthorized. Please check your credentials in the settings."
226
-            } else {
227
-                try {
228
-                    response_json = JSON.parse(e.txt)
229
-                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
230
-                } catch (e) {
231
-                    console.log("Error log, " + e)
232
-                }
233
-            }
234
-            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
235
-        }
236
-    }
237
-    var XHR = new XMLHttpRequest;
238
-    var n = this;
239
-    console.log(params.url);
240
-    XHR.open(params.method, params.url, !0);
241
-    var body = "";
242
-    var boundary = Math.random().toString().substring(2);
243
-    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
244
-    XHR.setRequestHeader("Authorization", params.authorization);
245
-    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
246
-    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
247
-    body += "--" + boundary + "--\r\n"
248
-
249
-    XHR.onreadystatechange = function() {
274
+  console.log('--- GPX upload to strava');
275
+  var gpxfile = localStorage.getItem("GPX");
276
+
277
+  var tokens = localStorage.getItem("strava_tokens");
278
+
279
+  //checking token expiry
280
+  var date = (Date.now()) / 1000
281
+
282
+  if (JSON.parse(tokens).expiry < date) {
283
+    console.log("Strava oAuth token expired, refreshing it")
284
+    refreshTokens(JSON.parse(tokens).refresh_token);
285
+  } else {
286
+    console.log("token (" + JSON.parse(tokens).access_token + ") valid, continuing")
287
+  }
288
+
289
+
290
+  var bearer = JSON.parse(tokens).access_token;
291
+  params = {
292
+    url: "https://www.strava.com/api/v3/uploads",
293
+    method: "POST",
294
+    data: { description: "desc", data_type: "gpx" },
295
+    files: { file: gpxfile },
296
+    authorization: "Bearer " + bearer,
297
+    callback: function (e) {
298
+      var message = "";
299
+      if (console.log(e.status + " - " + e.txt), 201 == e.status) {
300
+        message = "Your activity has been created";
301
+        localStorage.setItem("strava_uploaded", true);
302
+      } else if (400 == e.status) {
303
+        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
304
+      } else if (401 == e.status) {
305
+        message = "Error - Unauthorized. Please check your credentials in the settings."
306
+      } else {
250 307
         try {
251
-            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
308
+          response_json = JSON.parse(e.txt)
309
+          response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
252 310
         } catch (e) {
253
-            console.error("Error2 loading, ", e)
311
+          console.log("Error log, " + e)
254 312
         }
313
+      }
314
+      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
315
+    }
316
+  }
317
+  var XHR = new XMLHttpRequest;
318
+  var n = this;
319
+  //console.log(params.url);
320
+  XHR.open(params.method, params.url, !0);
321
+  var body = "";
322
+  var boundary = Math.random().toString().substring(2);
323
+  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
324
+  XHR.setRequestHeader("Authorization", params.authorization);
325
+  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
326
+  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
327
+  body += "--" + boundary + "--\r\n"
328
+
329
+  XHR.onreadystatechange = function () {
330
+    try {
331
+      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
332
+    } catch (e) {
333
+      console.error("Error2 loading, ", e)
255 334
     }
256
-    XHR.send(body)
335
+  }
336
+  XHR.send(body)
257 337
 }
258 338
 
259 339
 
260 340
 // Send GPX to web server (need configuration on serverside)
261 341
 // TODO : secure it ?
262 342
 function PostToWeb() {
263
-    console.log('--- GPX upload to custom web server');
264
-    var GPX = localStorage.getItem("GPX");
265
-    var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
266
-    var xhr = new XMLHttpRequest();
267
-    xhr.timeout = 10000; // time in milliseconds
268
-
269
-    xhr.open("POST", url, false);
270
-
271
-    //console.log('------ CSV / xhr opened')
272
-    xhr.onload = function() {
273
-        //console.log('------xhr onloaded')
274
-        if (xhr.readyState === 4) {
275
-            //console.log('------xhr request returned with ' + xhr.status);
276
-            //console.log(this.responseText);
277
-            localStorage.setItem("custom_uploaded", true);
278
-            if (xhr.status == 200) {
279
-                //console.log('--> HTTP 200');
280
-                return true;
281
-            } else {
282
-                //console.log('--> HTTP ' + xhr.status);
283
-                return false;
284
-            }
285
-        }
286
-    };
343
+  console.log('--- GPX upload to custom web server');
344
+  var GPX = localStorage.getItem("GPX");
345
+  var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
346
+  var xhr = new XMLHttpRequest();
347
+  xhr.timeout = 10000; // time in milliseconds
348
+
349
+  xhr.open("POST", url, false);
350
+
351
+  //console.log('------ CSV / xhr opened')
352
+  xhr.onload = function () {
353
+    //console.log('------xhr onloaded')
354
+    if (xhr.readyState === 4) {
355
+      //console.log('------xhr request returned with ' + xhr.status);
356
+      //console.log(this.responseText);
357
+      localStorage.setItem("custom_uploaded", true);
358
+      if (xhr.status == 200) {
359
+        //console.log('--> HTTP 200');
360
+        return true;
361
+      } else {
362
+        //console.log('--> HTTP ' + xhr.status);
363
+        return false;
364
+      }
365
+    }
366
+  };
287 367
 
288
-    //send CSV in body
289
-    xhr.send(GPX);
368
+  //send CSV in body
369
+  xhr.send(GPX);
290 370
 
291 371
 }
292 372
 
293 373
 // Send location to web server for instant location (no live tracking)
294 374
 // TODO : secure it ?
295 375
 function instantLocationUpdate(pos) {
296
-    console.log('--- Instant location update');
297
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
298
-
299
-    var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
300
-    var xhr = new XMLHttpRequest();
301
-    xhr.timeout = 10000; // time in milliseconds
302
-
303
-    xhr.open("POST", url);
304
-
305
-    //console.log('------ instant / xhr opened')
306
-    xhr.onload = function() {
307
-        //console.log('------xhr onloaded')
308
-        if (xhr.readyState === 4) {
309
-            //console.log('------xhr request returned with ' + xhr.status);
310
-            //console.log(this.responseText);
311
-            if (xhr.status == 200) {
312
-                //console.log('--> HTTP 200');
313
-                return true;
314
-            } else {
315
-                //console.log('--> HTTP ' + xhr.status);
316
-                return false;
317
-            }
318
-        }
319
-    };
376
+  console.log('--- Instant location update');
377
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
378
+
379
+  var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
380
+  var xhr = new XMLHttpRequest();
381
+  xhr.timeout = 10000; // time in milliseconds
382
+
383
+  xhr.open("POST", url);
384
+
385
+  //console.log('------ instant / xhr opened')
386
+  xhr.onload = function () {
387
+    //console.log('------xhr onloaded')
388
+    if (xhr.readyState === 4) {
389
+      //console.log('------xhr request returned with ' + xhr.status);
390
+      //console.log(this.responseText);
391
+      if (xhr.status == 200) {
392
+        //console.log('--> HTTP 200');
393
+        return true;
394
+      } else {
395
+        //console.log('--> HTTP ' + xhr.status);
396
+        return false;
397
+      }
398
+    }
399
+  };
320 400
 
321
-    //send without body
322
-    xhr.send();
401
+  //send without body
402
+  xhr.send();
323 403
 
324 404
 }
325 405
 
326 406
 // called in case of successful geoloc gathering and sends the coordinate to watch
327 407
 //
328 408
 function locationSuccess(new_pos) {
329
-    console.log('--- locationSuccess');
330
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
331
-
332
-    var prev_pos = getLocation();
333
-    storeLocation(new_pos);
334
-    if (prev_pos === null) {
335
-        console.log('--- start building gpx');
336
-
337
-
338
-        // Start the GPX file
339
-        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
409
+  console.log('--- locationSuccess');
410
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
411
+
412
+  var prev_pos = getLocation(false);
413
+  var first_pos = getLocation(true);
414
+  if (prev_pos === null) {
415
+    console.log('--- start building gpx');
416
+    storeLocation(new_pos, true);
417
+    localStorage.setItem("strava_uploaded", false);
418
+    localStorage.setItem("custom_uploaded", false);
419
+
420
+    // Start the GPX file
421
+    GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
422
+
423
+  } else {
424
+    storeLocation(new_pos, false);
425
+
426
+    // Prepare display on watch
427
+    // now it's only raw data
428
+    // init strings
429
+    var latitudeString = "";
430
+    var longitudeString = "";
431
+    var accuracyString = "";
432
+    var altitudeString = "";
433
+    var speedString = "";
434
+    var distanceString = "";
435
+
436
+    // get speed from geoloc API isntead of calculate it
437
+    // speed is initially in m/s, get it at km/h
438
+    if (new_pos.coords.speed === null) {
439
+      var speed = 0;
440
+    } else {
441
+      var speed = new_pos.coords.speed * 3.6;
442
+      localStorage.setItem("speedsum", parseInt(localStorage.getItem("speedsum")) + speed);
443
+    }
340 444
 
445
+    // distance since beginning in m
446
+    var dist = distance_on_geoid(prev_pos.coords.latitude, prev_pos.coords.longitude, new_pos.coords.latitude, new_pos.coords.longitude);
447
+    var totaldist = parseInt(localStorage.getItem("dist"));
448
+    if (!isNaN(dist)) {
449
+      totaldist = totaldist + parseInt(dist);
450
+      localStorage.setItem("dist", totaldist);
451
+    }
452
+    distanceString = splitFloatNumber(totaldist / 1000)[0].toString();
453
+    //console.log("total dist is now " + totaldist);
454
+
455
+    // avg speed (also when not moving) since beginning
456
+    var avgspeed = parseInt(localStorage.getItem("speedsum")) / parseInt(localStorage.getItem("totalcoordinates"));
457
+    var avgSpeedString = splitFloatNumber(avgspeed)[0].toString() + "." + splitFloatNumber(avgspeed)[1].toString().substring(0, 1);
458
+    console.log("speedsum=" + parseInt(localStorage.getItem("speedsum")) + " / totalcoordinates=" + parseInt(localStorage.getItem("totalcoordinates")));
459
+    console.log("--avgspeed=" + avgspeed + " / avgSpeedString=" + avgSpeedString)
460
+    if (avgSpeedString == "0.N") {
461
+      avgSpeedString = "0.0";
462
+    }
463
+    //console.log("avg speed is : " + avgSpeedString);
464
+
465
+    // Duration
466
+
467
+    var duration = new_pos.timestamp - first_pos.timestamp;
468
+    const date = new Date(duration);
469
+    durationString = padStart(date.getUTCHours().toString(), 2, "0") + ":" + padStart(date.getMinutes().toString(), 2, "0") + ":" + padStart(date.getSeconds().toString(), 2, "0");
470
+    console.log("durationString is : " + durationString);
471
+
472
+    //formating for precision and max size
473
+    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
474
+    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
475
+    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
476
+    //console.log("split num : " + new_pos.coords.altitude);
477
+    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
478
+    timestampISO = new Date(new_pos.timestamp).toISOString();
479
+
480
+    //console.log("split num : " + speed);
481
+    if (isNaN(speed)) {
482
+      speedString = "---";
341 483
     } else {
342
-        //clear watch of new position to avoid overlap
343
-        //navigator.geolocation.clearWatch(geoloc_id);
344
-        //console.log('--- watch geoloc cleared');
345
-        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
346
-
347
-        //get speed from geoloc API isntead of calculate it
348
-        // speed is initially in m/s, get it at km/h
349
-        if (new_pos.coords.speed === null) {
350
-            var speed = 0;
351
-        } else {
352
-            var speed = new_pos.coords.speed * 3.6;
353
-        }
484
+      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
485
+      if (speedString == "0.N") {
486
+        speedString = "0.0";
487
+      }
354 488
 
355
-        // Prepare display on watch
356
-        // now it's only raw data
357
-        // init strings
358
-        var latitudeString = "";
359
-        var longitudeString = "";
360
-        var accuracyString = "";
361
-        var altitudeString = "";
362
-        var speedString = "";
363
-
364
-        //formating for precision and max size
365
-        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
366
-        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
367
-        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
368
-        //console.log("split num : " + new_pos.coords.altitude);
369
-        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
370
-        timestampISO = new Date(new_pos.timestamp).toISOString();
371
-        //console.log("split num : " + speed);
372
-        if (isNaN(speed)) {
373
-            speedString = "---";
374
-        } else {
375
-            speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
376
-            if (speedString == "0.N") {
377
-                speedString = "0.0";
378
-            }
489
+      //console.log("split num : " + getMaxSpeed(speed));
490
+      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
491
+    }
379 492
 
380
-            //console.log("split num : " + getMaxSpeed(speed));
381
-            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
382
-        }
493
+    //add a new datapoint to GPX file
494
+    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
383 495
 
384
-        //add a new datapoint to GPX file
385
-        GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
386 496
 
387 497
 
498
+    // Build message
499
+    message = "OK";
500
+    var dict = {
501
+      'accuracy': accuracyString,
502
+      'distance': distanceString,
503
+      'avg_speed': avgSpeedString,
504
+      'duration': durationString,
505
+      'altitude': altitudeString,
506
+      'speed': speedString,
507
+      'max_speed': maxSpeedString,
508
+      'status': message
509
+    };
388 510
 
389
-        // Build message
390
-        message = "OK";
391
-        var dict = {
392
-            'accuracy': accuracyString,
393
-            'altitude': altitudeString,
394
-            'speed': speedString,
395
-            'max_speed': maxSpeedString,
396
-            'status': message
397
-        };
511
+    // Send the message
512
+    Pebble.sendAppMessage(dict, function () {
513
+      console.log('Message sent successfully: ' + JSON.stringify(dict));
514
+    }, function (e) {
515
+      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
516
+    });
517
+  }
398 518
 
399
-        // Send the message
400
-        Pebble.sendAppMessage(dict, function() {
401
-            console.log('Message sent successfully: ' + JSON.stringify(dict));
402
-        }, function(e) {
403
-            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
404
-        });
405
-    }
406 519
 
407 520
 }
408 521
 
409 522
 function locationError(err) {
410 523
 
411
-    console.warn('location error (' + err.code + '): ' + err.message);
524
+  console.warn('location error (' + err.code + '): ' + err.message);
412 525
 
413 526
 }
414 527
 
415 528
 
416
-function get_coordinate() {
417
-    console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
418
-
419
-    locationInterval = setInterval(function() {
420
-        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
421
-    }, 1000);
529
+function start_get_coordinate() {
530
+  clearInterval(firstlocationInterval);
531
+  firstlocationInterval = false;
532
+  locationInterval = setInterval(function () {
533
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
534
+  }, 1000);
422 535
 
423
-    if (locate_me) {
424
-        instantLocationInterval = setInterval(function() {
425
-            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
426
-        }, 60000);
427
-    }
536
+  if (locate_me) {
537
+    instantLocationInterval = setInterval(function () {
538
+      navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
539
+    }, 60000);
540
+  }
428 541
 
429 542
 }
430 543
 
431 544
 function init() {
432
-    // local storage init
433
-    try {
434
-        //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
435
-        gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
436
-        gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
437
-        locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
438
-
439
-        console.log("Locate_me = " + locate_me);
440
-        console.log("Strava = " + gpx_to_strava);
441
-        console.log("Custom web = " + gpx_to_web);
442
-
443
-        var ce = gpx_to_web;
444
-        var cu = localStorage.getItem("custom_uploaded");
445
-        var se = gpx_to_strava;
446
-        var su = localStorage.getItem("strava_uploaded");
447
-
448
-        //checking token freshness (expiry >4h)
449
-        var delay = (Date.now() + 14400000) / 1000
450
-        if (se) {
451
-            if (JSON.parse(localStorage.getItem("strava_tokens")).expiry < delay) {
452
-                console.log("Strava oAuth token expiring or expired, refreshing it")
453
-                refreshTokens(JSON.parse(localStorage.getItem("strava_tokens")).refresh_token);
454
-            } else {
455
-                console.log("token (" + JSON.parse(localStorage.getItem("strava_tokens")).access_token + ")valid for 4h min, continuing")
456
-            }
457
-        }
458
-    } catch (e) {}
459 545
 
460
-    if ((se && !su) || (ce && !cu)) {
461
-        //posting any missed XHR from previous ride session
462
-        if (ce) {
463
-            PostToWeb();
464
-        }
465
-        if (se) {
466
-            SendToStrava();
467
-        }
468
-    } else {
469
-        localStorage.setItem("GPX", "");
470
-        localStorage.setItem("maxSpeed", "");
471
-        localStorage.setItem("latitude", "");
472
-        localStorage.setItem("longitude", "");
473
-        localStorage.setItem("timestamp", "");
474
-        localStorage.setItem("custom_uploaded", false);
475
-        localStorage.setItem("strava_uploaded", false);
476
-    }
477
-    // clear any other var to do
478
-    clearInterval(locationInterval);
479
-    clearInterval(instantLocationInterval);
546
+  clearInterval(locationInterval);
547
+  locationInterval = false;
548
+  clearInterval(instantLocationInterval);
549
+  instantLocationInterval = false;
550
+  firstlocationInterval = setInterval(function () {
480 551
     navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
552
+  }, 1000);
553
+
554
+  //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
555
+  var se = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
556
+  var su = ("true" === localStorage.getItem("strava_uploaded"));
557
+  var ce = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
558
+  var cu = ("true" === localStorage.getItem("custom_uploaded"));
559
+
560
+  locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
561
+
562
+
563
+  console.log("Locate_me = " + locate_me);
564
+  console.log("Strava = " + se + " (" + typeof se + ")/ uploaded = " + su + " (" + typeof su + ")");
565
+  console.log("Custom web = " + ce + " (" + typeof ce + ")/ uploaded = " + cu + " (" + typeof cu + ")");
566
+
567
+  if ((se && !su) || (ce && !cu)) {
568
+    if (se) {
569
+      console.log("GPX upload needed to Strava")
570
+      SendToStrava();
571
+    }
572
+
573
+    if (ce) {
574
+      console.log("GPX upload needed to custom server")
575
+      PostToWeb();
576
+    }
577
+  } else {
578
+    console.log("clearing var")
579
+    localStorage.setItem("maxSpeed", 0);
580
+    localStorage.setItem("firstlatitude", "");
581
+    localStorage.setItem("firstlongitude", "");
582
+    localStorage.setItem("firsttimestamp", "");
583
+    localStorage.setItem("lastlatitude", "");
584
+    localStorage.setItem("lastlongitude", "");
585
+    localStorage.setItem("lasttimestamp", "");
586
+    localStorage.setItem("dist", 0)
587
+    localStorage.setItem("speedsum", 0)
588
+  }
481 589
 
482 590
 }
483 591
 
484 592
 // Get JS readiness events
485
-Pebble.addEventListener('ready', function(e) {
486
-    console.log('PebbleKit JS is ready');
487
-    // Update Watch on this
488
-    Pebble.sendAppMessage({ 'JSReady': 1 });
593
+Pebble.addEventListener('ready', function (e) {
594
+  console.log('PebbleKit JS is ready');
595
+  // Update Watch on this
596
+  Pebble.sendAppMessage({ 'JSReady': 1 });
489 597
 
490
-    init();
598
+  init();
491 599
 });
492 600
 
493 601
 // Get AppMessage events
494
-Pebble.addEventListener('appmessage', function(e) {
495
-    // Get the dictionary from the message
496
-    var dict = e.payload;
497
-    //console.log(dict[0].toString());
498
-    switch (dict[0]) {
499
-        case 'get':
500
-            get_coordinate();
501
-            break;
502
-        case 'exit':
503
-            clearInterval(instantLocationInterval);
504
-            clearInterval(locationInterval);
505
-            gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
506
-            gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
507
-            locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
508
-
509
-            //End GPX file
510
-            GPXfooterBuilder();
511
-            if (gpx_to_strava) {
512
-                //send to strava through API
513
-                SendToStrava();
514
-            }
515
-            if (gpx_to_web) {
516
-                // send CSV to web server through API
517
-                PostToWeb();
518
-            }
519
-            if (locate_me) {
520
-                var prev_pos = getLocation();
521
-                instantLocationUpdate(prev_pos);
522
-            }
523
-
524
-            // Send the message
525
-            var dict = {
526
-                'status': "EXIT"
527
-            };
528
-            Pebble.sendAppMessage(dict, function() {
529
-                console.log('Message sent successfully: ' + JSON.stringify(dict));
530
-            }, function(e) {
531
-                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
532
-            });
533
-
534
-            break;
535
-        default:
536
-            console.log('Sorry. I don\'t understand your request :' + dict[0]);
537
-    }
602
+Pebble.addEventListener('appmessage', function (e) {
603
+  // Get the dictionary from the message
604
+  var dict = e.payload;
605
+  //console.log(dict[0].toString());
606
+  switch (dict[0]) {
607
+    case 'startstop':
608
+      if (!locationInterval == false) {
609
+        console.log("Stopping the track");
610
+        clearInterval(locationInterval);
611
+        GPXfooterBuilder();
612
+        locationInterval = false;
613
+        clearInterval(instantLocationInterval);
614
+        instantLocationInterval = false;
615
+        firstlocationInterval = setInterval(function () {
616
+          navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
617
+        }, 1000);
618
+      } else {
619
+        console.log("Starting the track");
620
+        start_get_coordinate();
621
+      }
622
+      break;
623
+    case 'send':
624
+      if (locate_me) {
625
+        var prev_pos = getLocation(false);
626
+        instantLocationUpdate(prev_pos);
627
+      }
628
+
629
+      init();
630
+
631
+      /*
632
+      // Send the message
633
+      var dict = {
634
+        'status': "EXIT"
635
+      };
636
+      Pebble.sendAppMessage(dict, function () {
637
+        console.log('Message sent successfully: ' + JSON.stringify(dict));
638
+      }, function (e) {
639
+        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
640
+      });
641
+      */
642
+      break;
643
+    default:
644
+      console.log('Sorry. I don\'t understand your request :' + dict[0]);
645
+  }
538 646
 
539 647
 });
540 648
\ No newline at end of file
Browse code

xhr typo on refresh token

Louis authored on24/10/2022 18:40:47
Showing1 changed files
... ...
@@ -184,7 +184,7 @@ function refreshTokens(refresh_token) {
184 184
         //console.log('------xhr onloaded')
185 185
         if (xhr.readyState === 4) {
186 186
             //console.log('------xhr request returned with ' + xhr.status);
187
-            response_json = JSON.parse(xhr.txt);
187
+            response_json = JSON.parse(xhr.responseText);
188 188
 
189 189
             var tokenjson = {
190 190
                 access_token: response_json.access_token,
Browse code

code and UX cleaning

Louis authored on24/10/2022 18:11:43
Showing1 changed files
... ...
@@ -16,156 +16,126 @@ var client_id = "94880";
16 16
 var client_secret = "08dc170f0fe38f39dd327bea82a28db4400e6f00";
17 17
 
18 18
 var firstlocationOptions = {
19
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
20
-  'timeout': 60000, //60s timeout to get a first good signal
21
-  'maximumAge': 0 // no cache
19
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
20
+    'timeout': 60000, //60s timeout to get a first good signal
21
+    'maximumAge': 0 // no cache
22 22
 };
23 23
 var locationOptions = {
24
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
25
-  'timeout': 5000, //5s timeout to get a good signal
26
-  'maximumAge': 0 // no cache
24
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
25
+    'timeout': 5000, //5s timeout to get a good signal
26
+    'maximumAge': 0 // no cache
27 27
 };
28 28
 
29
-Pebble.addEventListener('showConfiguration', function (e) {
30
-  clay.config = clayConfig;
31
-  console.log("Clay config is showing...")
32
-  Pebble.openURL(clay.generateUrl());
29
+Pebble.addEventListener('showConfiguration', function(e) {
30
+    clay.config = clayConfig;
31
+    console.log("Clay config is showing...")
32
+    Pebble.openURL(clay.generateUrl());
33 33
 });
34 34
 
35
-Pebble.addEventListener('webviewclosed', function (t) {
36
-  if (!t || t.response) {
37
-    console.log("Clay config is submitted : " + t.response)
38
-    try {
39
-      if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
40
-        // data looks like this :
41
-        // {"code":"db896b06f89804997a8088320fba755e6299c0d6","scope":"read,activity:write","state":"bike_companion"}
42
-        // so need to parse it correctly
43
-        //var grantcode = JSON.parse(data.strava.value)
44
-        if (data.state == "bike_companion" && data.scope == "read,activity:write") {
45
-          getTokens(data.code);
46
-        } else {
47
-          console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
35
+Pebble.addEventListener('webviewclosed', function(t) {
36
+    if (!t || t.response) {
37
+        console.log("Clay config is submitted : " + t.response)
38
+        try {
39
+            if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
40
+                if (data.state == "bike_companion" && data.scope == "read,activity:write") {
41
+                    getTokens(data.code);
42
+                } else {
43
+                    console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
44
+                }
45
+            } else {
46
+                clay.getSettings(t.response);
47
+                console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
48
+            }
49
+        } catch (t) {
50
+            console.log("Oauth parsing error, continue on saving clay settings");
51
+            clay.getSettings(t.response);
52
+            var claysettings = JSON.parse(localStorage.getItem('clay-settings'))
53
+            claysettings.strava_enabled = false;
54
+            localStorage.setItem("clay-settings", JSON.stringify("claysettings"));
55
+            console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
48 56
         }
49
-      } else {
50
-        clay.getSettings(t.response);
51
-        console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
52
-      }
53
-    } catch (t) {
54
-      console.log("Oauth parsing error, continue on saving clay settings");
55
-      clay.getSettings(t.response);
56
-      console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
57
-      //set strava to false
58
-    }
59 57
 
60
-    // dict is not used as intended to send settings to watch
61
-
62
-    /* assess if needed to send setting to watch as already in phone (done with "getsettings")
63
-    m.live_mmt_enable = dict[p.live_mmt_enable]
64
-    m.live_mmt_login = dict[p.live_mmt_login]
65
-    m.live_mmt_password = dict[p.live_mmt_password]
66
-    m.live_jayps_enable = dict[p.live_jayps_enable]
67
-    m.live_jayps_login = dict[p.live_jayps_login]
68
-    m.live_jayps_password = dict[p.live_jayps_password]
69
-    m.strava_automatic_upload = dict[p.strava_automatic_upload]
70
-
71
-    i = dict[p.debug]
72
-    console.log("debug:" + i)
73
-    g.setDebug(i)
74
-    h.setDebug(i)
75
-    b.setDebug(i)
76
-    y.setDebug(i)
77
-    m.setDebug(i)
78
-
79
-    m.save()
80
-    // Assess if needed to send settings values to watch side
81
-    /*
82
-    Pebble.sendAppMessage(dict, function(e) {
83
-        console.log('Sent config data to Pebble');
84
-    }, function(e) {
85
-        console.log('Failed to send config data!');
86
-        console.log(JSON.stringify(e));
87
-    });*/
88
-  }
58
+    }
89 59
 });
90 60
 
91 61
 
92 62
 // Store location in Pebble app local storage
93 63
 //
94 64
 function storeLocation(position) {
95
-  var latitude = position.coords.latitude;
96
-  var longitude = position.coords.longitude;
97
-  var timestamp = position.timestamp;
98
-  localStorage.setItem("latitude", latitude);
99
-  localStorage.setItem("longitude", longitude);
100
-  localStorage.setItem("timestamp", timestamp);
101
-  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
65
+    var latitude = position.coords.latitude;
66
+    var longitude = position.coords.longitude;
67
+    var timestamp = position.timestamp;
68
+    localStorage.setItem("latitude", latitude);
69
+    localStorage.setItem("longitude", longitude);
70
+    localStorage.setItem("timestamp", timestamp);
71
+    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
102 72
 }
103 73
 
104 74
 // Get location from Pebble app local storage
105 75
 //
106 76
 function getLocation() {
107
-  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
108
-    var la = localStorage.getItem("latitude");
109
-    var lo = localStorage.getItem("longitude");
110
-    var ti = localStorage.getItem("timestamp");
111
-    var co = { "latitude": la, "longitude": lo };
112
-    var pos = { "coords": co, "timestamp": ti };
113
-    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
114
-    return pos;
115
-  } else {
116
-    return null;
117
-  }
77
+    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
78
+        var la = localStorage.getItem("latitude");
79
+        var lo = localStorage.getItem("longitude");
80
+        var ti = localStorage.getItem("timestamp");
81
+        var co = { "latitude": la, "longitude": lo };
82
+        var pos = { "coords": co, "timestamp": ti };
83
+        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
84
+        return pos;
85
+    } else {
86
+        return null;
87
+    }
118 88
 }
119 89
 
120 90
 // Get max speed of the run
121 91
 //
122 92
 function getMaxSpeed(lastSpeed) {
123
-  oldmax = localStorage.getItem("maxSpeed") || -1;
124
-  if (oldmax < lastSpeed) {
125
-    maxSpeed = lastSpeed
126
-  } else if (oldmax > lastSpeed) {
127
-    maxSpeed = oldmax
128
-  } else {
129
-    maxSpeed = oldmax
130
-  }
131
-  localStorage.setItem("maxSpeed", maxSpeed);
132
-  return maxSpeed
93
+    oldmax = localStorage.getItem("maxSpeed") || -1;
94
+    if (oldmax < lastSpeed) {
95
+        maxSpeed = lastSpeed
96
+    } else if (oldmax > lastSpeed) {
97
+        maxSpeed = oldmax
98
+    } else {
99
+        maxSpeed = oldmax
100
+    }
101
+    localStorage.setItem("maxSpeed", maxSpeed);
102
+    return maxSpeed
133 103
 }
134 104
 
135 105
 // split float number into an array of int (null returned instead of 0 for decimal)
136 106
 //
137 107
 function splitFloatNumber(num) {
138
-  const intStr = num.toString().split('.')[0];
139
-  const decimalStr = num.toString().split('.')[1];
140
-  return [Number(intStr), Number(decimalStr)];
108
+    const intStr = num.toString().split('.')[0];
109
+    const decimalStr = num.toString().split('.')[1];
110
+    return [Number(intStr), Number(decimalStr)];
141 111
 
142 112
 }
143 113
 
144 114
 // Build GPX headers
145 115
 //
146 116
 function GPXHeadersBuilder(timestamp, name, type) {
147
-  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
148
-  var ret = localStorage.setItem("GPX", headers);
149
-  return true;
117
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
118
+    var ret = localStorage.setItem("GPX", headers);
119
+    return true;
150 120
 }
151 121
 
152 122
 // Build GPX track point
153 123
 //
154 124
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
155
-  var GPX = localStorage.getItem("GPX");
156
-  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
157
-  localStorage.setItem("GPX", GPX + trkpt);
158
-  return true;
125
+    var GPX = localStorage.getItem("GPX");
126
+    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
127
+    localStorage.setItem("GPX", GPX + trkpt);
128
+    return true;
159 129
 }
160 130
 
161 131
 // Build GPX footer
162 132
 //
163 133
 function GPXfooterBuilder() {
164
-  var GPX = localStorage.getItem("GPX");
165
-  var footer = '</trkseg></trk></gpx>';
166
-  var ret = localStorage.setItem("GPX", GPX + footer);
167
-  //console.log("GPX closed : " + GPX + footer);
168
-  return ret;
134
+    var GPX = localStorage.getItem("GPX");
135
+    var footer = '</trkseg></trk></gpx>';
136
+    var ret = localStorage.setItem("GPX", GPX + footer);
137
+    //console.log("GPX closed : " + GPX + footer);
138
+    return ret;
169 139
 }
170 140
 
171 141
 //------------------------------------------
... ...
@@ -173,402 +143,397 @@ function GPXfooterBuilder() {
173 143
 //------------------------------------------
174 144
 
175 145
 function getTokens(code) {
176
-  // call to strava api to get tokens in exchange of temp code
177
-  // need to use strava.jonget.fr to proxy request and hide secret
178
-  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
179
-  var xhr = new XMLHttpRequest();
180
-  xhr.timeout = 10000; // time in milliseconds
181
-
182
-  xhr.open("POST", url, false);
183
-
184
-  xhr.onload = function () {
185
-    //console.log('------xhr onloaded')
186
-    if (xhr.readyState === 4) {
187
-      console.log('------xhr request returned :', xhr.responseText);
188
-      response_json = JSON.parse(xhr.responseText);
189
-
190
-      var tokenjson = {
191
-        access_token: response_json.access_token,
192
-        refresh_token: response_json.refresh_token,
193
-        expiry: response_json.expires_at
194
-      };
195
-      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
146
+    // call to strava api to get tokens in exchange of temp code
147
+    // need to use strava.jonget.fr to proxy request and hide secret
148
+    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
149
+    var xhr = new XMLHttpRequest();
150
+    xhr.timeout = 10000; // time in milliseconds
151
+
152
+    xhr.open("POST", url, false);
153
+
154
+    xhr.onload = function() {
155
+        //console.log('------xhr onloaded')
156
+        if (xhr.readyState === 4) {
157
+            console.log('------xhr request returned :', xhr.responseText);
158
+            response_json = JSON.parse(xhr.responseText);
159
+
160
+            var tokenjson = {
161
+                access_token: response_json.access_token,
162
+                refresh_token: response_json.refresh_token,
163
+                expiry: response_json.expires_at
164
+            };
165
+            localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
196 166
 
197
-    }
198
-  };
167
+        }
168
+    };
199 169
 
200
-  xhr.send();
170
+    xhr.send();
201 171
 
202 172
 }
203 173
 
204 174
 function refreshTokens(refresh_token) {
205
-  // call to strava api to get tokens in exchange of refresh code
206
-  // need to use strava.jonget.fr to proxy request and hide secret
207
-  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
208
-  var xhr = new XMLHttpRequest();
209
-  xhr.timeout = 10000; // time in milliseconds
210
-
211
-  xhr.open("POST", url, false);
212
-
213
-  xhr.onload = function () {
214
-    //console.log('------xhr onloaded')
215
-    if (xhr.readyState === 4) {
216
-      //console.log('------xhr request returned with ' + xhr.status);
217
-      response_json = JSON.parse(xhr.txt);
218
-
219
-      var tokenjson = {
220
-        access_token: response_json.access_token,
221
-        refresh_token: response_json.refresh_token,
222
-        expiry: response_json.expires_at
223
-      };
224
-      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
175
+    // call to strava api to get tokens in exchange of refresh code
176
+    // need to use strava.jonget.fr to proxy request and hide secret
177
+    var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
178
+    var xhr = new XMLHttpRequest();
179
+    xhr.timeout = 10000; // time in milliseconds
180
+
181
+    xhr.open("POST", url, false);
182
+
183
+    xhr.onload = function() {
184
+        //console.log('------xhr onloaded')
185
+        if (xhr.readyState === 4) {
186
+            //console.log('------xhr request returned with ' + xhr.status);
187
+            response_json = JSON.parse(xhr.txt);
188
+
189
+            var tokenjson = {
190
+                access_token: response_json.access_token,
191
+                refresh_token: response_json.refresh_token,
192
+                expiry: response_json.expires_at
193
+            };
194
+            localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
225 195
 
226
-    }
227
-  };
196
+        }
197
+    };
228 198
 
229
-  xhr.send();
199
+    xhr.send();
230 200
 
231 201
 }
232 202
 
233 203
 // Send GPX to Strava profile
234 204
 function SendToStrava() {
235
-  console.log('--- GPX upload to strava');
236
-  var gpxfile = localStorage.getItem("GPX");
237
-
238
-  var tokens = localStorage.getItem("strava_tokens");
239
-
240
-  var bearer = JSON.parse(tokens).access_token;
241
-  params = {
242
-    url: "https://www.strava.com/api/v3/uploads",
243
-    method: "POST",
244
-    data: { description: "desc", data_type: "gpx" },
245
-    files: { file: gpxfile },
246
-    authorization: "Bearer " + bearer,
247
-    callback: function (e) {
248
-      var message = "";
249
-      // what is 'r'
250
-      // what is 'e'
251
-      // what is 'o'
252
-      // what is 'z'
253
-      if (console.log(e.status + " - " + e.txt), 201 == e.status) {
254
-        message = "Your activity has been created";
255
-        localStorage.setItem("strava_uploaded", true);
256
-      } else if (400 == e.status) {
257
-        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
258
-      } else if (401 == e.status) {
259
-        message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
260
-      } else {
205
+    console.log('--- GPX upload to strava');
206
+    var gpxfile = localStorage.getItem("GPX");
207
+
208
+    var tokens = localStorage.getItem("strava_tokens");
209
+
210
+    var bearer = JSON.parse(tokens).access_token;
211
+    params = {
212
+        url: "https://www.strava.com/api/v3/uploads",
213
+        method: "POST",
214
+        data: { description: "desc", data_type: "gpx" },
215
+        files: { file: gpxfile },
216
+        authorization: "Bearer " + bearer,
217
+        callback: function(e) {
218
+            var message = "";
219
+            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
220
+                message = "Your activity has been created";
221
+                localStorage.setItem("strava_uploaded", true);
222
+            } else if (400 == e.status) {
223
+                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
224
+            } else if (401 == e.status) {
225
+                message = "Error - Unauthorized. Please check your credentials in the settings."
226
+            } else {
227
+                try {
228
+                    response_json = JSON.parse(e.txt)
229
+                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error) : response_json.status && (console.log("status:" + response_json.status))
230
+                } catch (e) {
231
+                    console.log("Error log, " + e)
232
+                }
233
+            }
234
+            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
235
+        }
236
+    }
237
+    var XHR = new XMLHttpRequest;
238
+    var n = this;
239
+    console.log(params.url);
240
+    XHR.open(params.method, params.url, !0);
241
+    var body = "";
242
+    var boundary = Math.random().toString().substring(2);
243
+    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
244
+    XHR.setRequestHeader("Authorization", params.authorization);
245
+    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
246
+    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
247
+    body += "--" + boundary + "--\r\n"
248
+
249
+    XHR.onreadystatechange = function() {
261 250
         try {
262
-          response_json = JSON.parse(e.txt)
263
-          response_json.error ? (console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (console.log("status:" + response_json.status), z = response_json.status)
251
+            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
264 252
         } catch (e) {
265
-          console.log("Error log, " + e)
253
+            console.error("Error2 loading, ", e)
266 254
         }
267
-      }
268
-      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
269 255
     }
270
-  }
271
-  var XHR = new XMLHttpRequest;
272
-  var n = this;
273
-  console.log(params.url);
274
-  XHR.open(params.method, params.url, !0);
275
-  var body = "";
276
-  var boundary = Math.random().toString().substring(2);
277
-  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
278
-  XHR.setRequestHeader("Authorization", params.authorization);
279
-  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
280
-  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
281
-  body += "--" + boundary + "--\r\n"
282
-
283
-  XHR.onreadystatechange = function () {
284
-    // what is 'n'
285
-    try {
286
-      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
287
-    } catch (e) {
288
-      console.error("Error2 loading, ", e)
289
-    }
290
-  }
291
-  XHR.send(body)
256
+    XHR.send(body)
292 257
 }
293 258
 
294 259
 
295 260
 // Send GPX to web server (need configuration on serverside)
296 261
 // TODO : secure it ?
297 262
 function PostToWeb() {
298
-  console.log('--- GPX upload to custom web server');
299
-  var GPX = localStorage.getItem("GPX");
300
-  var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
301
-  var xhr = new XMLHttpRequest();
302
-  xhr.timeout = 10000; // time in milliseconds
303
-
304
-  xhr.open("POST", url, false);
305
-
306
-  //console.log('------ CSV / xhr opened')
307
-  xhr.onload = function () {
308
-    //console.log('------xhr onloaded')
309
-    if (xhr.readyState === 4) {
310
-      //console.log('------xhr request returned with ' + xhr.status);
311
-      //console.log(this.responseText);
312
-      localStorage.setItem("custom_uploaded", true);
313
-      if (xhr.status == 200) {
314
-        //console.log('--> HTTP 200');
315
-        return true;
316
-      } else {
317
-        //console.log('--> HTTP ' + xhr.status);
318
-        return false;
319
-      }
320
-    }
321
-  };
263
+    console.log('--- GPX upload to custom web server');
264
+    var GPX = localStorage.getItem("GPX");
265
+    var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
266
+    var xhr = new XMLHttpRequest();
267
+    xhr.timeout = 10000; // time in milliseconds
268
+
269
+    xhr.open("POST", url, false);
270
+
271
+    //console.log('------ CSV / xhr opened')
272
+    xhr.onload = function() {
273
+        //console.log('------xhr onloaded')
274
+        if (xhr.readyState === 4) {
275
+            //console.log('------xhr request returned with ' + xhr.status);
276
+            //console.log(this.responseText);
277
+            localStorage.setItem("custom_uploaded", true);
278
+            if (xhr.status == 200) {
279
+                //console.log('--> HTTP 200');
280
+                return true;
281
+            } else {
282
+                //console.log('--> HTTP ' + xhr.status);
283
+                return false;
284
+            }
285
+        }
286
+    };
322 287
 
323
-  //send CSV in body
324
-  xhr.send(GPX);
288
+    //send CSV in body
289
+    xhr.send(GPX);
325 290
 
326 291
 }
327 292
 
328 293
 // Send location to web server for instant location (no live tracking)
329 294
 // TODO : secure it ?
330 295
 function instantLocationUpdate(pos) {
331
-  console.log('--- Instant location update');
332
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
333
-
334
-  var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
335
-  var xhr = new XMLHttpRequest();
336
-  xhr.timeout = 10000; // time in milliseconds
337
-
338
-  xhr.open("POST", url);
339
-
340
-  //console.log('------ instant / xhr opened')
341
-  xhr.onload = function () {
342
-    //console.log('------xhr onloaded')
343
-    if (xhr.readyState === 4) {
344
-      //console.log('------xhr request returned with ' + xhr.status);
345
-      //console.log(this.responseText);
346
-      if (xhr.status == 200) {
347
-        //console.log('--> HTTP 200');
348
-        return true;
349
-      } else {
350
-        //console.log('--> HTTP ' + xhr.status);
351
-        return false;
352
-      }
353
-    }
354
-  };
296
+    console.log('--- Instant location update');
297
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
298
+
299
+    var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
300
+    var xhr = new XMLHttpRequest();
301
+    xhr.timeout = 10000; // time in milliseconds
302
+
303
+    xhr.open("POST", url);
304
+
305
+    //console.log('------ instant / xhr opened')
306
+    xhr.onload = function() {
307
+        //console.log('------xhr onloaded')
308
+        if (xhr.readyState === 4) {
309
+            //console.log('------xhr request returned with ' + xhr.status);
310
+            //console.log(this.responseText);
311
+            if (xhr.status == 200) {
312
+                //console.log('--> HTTP 200');
313
+                return true;
314
+            } else {
315
+                //console.log('--> HTTP ' + xhr.status);
316
+                return false;
317
+            }
318
+        }
319
+    };
355 320
 
356
-  //send without body
357
-  xhr.send();
321
+    //send without body
322
+    xhr.send();
358 323
 
359 324
 }
360 325
 
361 326
 // called in case of successful geoloc gathering and sends the coordinate to watch
362 327
 //
363 328
 function locationSuccess(new_pos) {
364
-  console.log('--- locationSuccess');
365
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
329
+    console.log('--- locationSuccess');
330
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
366 331
 
367
-  var prev_pos = getLocation();
368
-  storeLocation(new_pos);
369
-  if (prev_pos === null) {
370
-    console.log('--- start building gpx');
332
+    var prev_pos = getLocation();
333
+    storeLocation(new_pos);
334
+    if (prev_pos === null) {
335
+        console.log('--- start building gpx');
371 336
 
372 337
 
373
-    // Start the GPX file
374
-    GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
338
+        // Start the GPX file
339
+        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
375 340
 
376
-  } else {
377
-    //clear watch of new position to avoid overlap
378
-    //navigator.geolocation.clearWatch(geoloc_id);
379
-    //console.log('--- watch geoloc cleared');
380
-    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
381
-
382
-    //get speed from geoloc API isntead of calculate it
383
-    // speed is initially in m/s, get it at km/h
384
-    if (new_pos.coords.speed === null) {
385
-      var speed = 0;
386 341
     } else {
387
-      var speed = new_pos.coords.speed * 3.6;
388
-    }
342
+        //clear watch of new position to avoid overlap
343
+        //navigator.geolocation.clearWatch(geoloc_id);
344
+        //console.log('--- watch geoloc cleared');
345
+        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
346
+
347
+        //get speed from geoloc API isntead of calculate it
348
+        // speed is initially in m/s, get it at km/h
349
+        if (new_pos.coords.speed === null) {
350
+            var speed = 0;
351
+        } else {
352
+            var speed = new_pos.coords.speed * 3.6;
353
+        }
389 354
 
390
-    // Prepare display on watch
391
-    // now it's only raw data
392
-    // init strings
393
-    var latitudeString = "";
394
-    var longitudeString = "";
395
-    var accuracyString = "";
396
-    var altitudeString = "";
397
-    var speedString = "";
398
-
399
-    //formating for precision and max size
400
-    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
401
-    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
402
-    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
403
-    //console.log("split num : " + new_pos.coords.altitude);
404
-    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
405
-    timestampISO = new Date(new_pos.timestamp).toISOString();
406
-    //console.log("split num : " + speed);
407
-    if (isNaN(speed)) {
408
-      speedString = "---";
409
-    } else {
410
-      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
411
-      if (speedString == "0.N") {
412
-        speedString = "0.0";
413
-      }
355
+        // Prepare display on watch
356
+        // now it's only raw data
357
+        // init strings
358
+        var latitudeString = "";
359
+        var longitudeString = "";
360
+        var accuracyString = "";
361
+        var altitudeString = "";
362
+        var speedString = "";
363
+
364
+        //formating for precision and max size
365
+        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
366
+        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
367
+        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
368
+        //console.log("split num : " + new_pos.coords.altitude);
369
+        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
370
+        timestampISO = new Date(new_pos.timestamp).toISOString();
371
+        //console.log("split num : " + speed);
372
+        if (isNaN(speed)) {
373
+            speedString = "---";
374
+        } else {
375
+            speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
376
+            if (speedString == "0.N") {
377
+                speedString = "0.0";
378
+            }
414 379
 
415
-      //console.log("split num : " + getMaxSpeed(speed));
416
-      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
417
-    }
380
+            //console.log("split num : " + getMaxSpeed(speed));
381
+            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
382
+        }
418 383
 
419
-    //add a new datapoint to GPX file
420
-    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
384
+        //add a new datapoint to GPX file
385
+        GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
421 386
 
422 387
 
423 388
 
424
-    // Build message
425
-    message = "OK";
426
-    var dict = {
427
-      'accuracy': accuracyString,
428
-      'altitude': altitudeString,
429
-      'speed': speedString,
430
-      'max_speed': maxSpeedString,
431
-      'status': message
432
-    };
389
+        // Build message
390
+        message = "OK";
391
+        var dict = {
392
+            'accuracy': accuracyString,
393
+            'altitude': altitudeString,
394
+            'speed': speedString,
395
+            'max_speed': maxSpeedString,
396
+            'status': message
397
+        };
433 398
 
434
-    // Send the message
435
-    Pebble.sendAppMessage(dict, function () {
436
-      console.log('Message sent successfully: ' + JSON.stringify(dict));
437
-    }, function (e) {
438
-      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
439
-    });
440
-  }
399
+        // Send the message
400
+        Pebble.sendAppMessage(dict, function() {
401
+            console.log('Message sent successfully: ' + JSON.stringify(dict));
402
+        }, function(e) {
403
+            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
404
+        });
405
+    }
441 406
 
442 407
 }
443 408
 
444 409
 function locationError(err) {
445 410
 
446
-  console.warn('location error (' + err.code + '): ' + err.message);
411
+    console.warn('location error (' + err.code + '): ' + err.message);
447 412
 
448 413
 }
449 414
 
450 415
 
451 416
 function get_coordinate() {
452
-  console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
417
+    console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
453 418
 
454
-  locationInterval = setInterval(function () {
455
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
456
-  }, 1000);
419
+    locationInterval = setInterval(function() {
420
+        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
421
+    }, 1000);
457 422
 
458
-  if (locate_me) {
459
-    instantLocationInterval = setInterval(function () {
460
-      navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
461
-    }, 60000);
462
-  }
423
+    if (locate_me) {
424
+        instantLocationInterval = setInterval(function() {
425
+            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
426
+        }, 60000);
427
+    }
463 428
 
464 429
 }
465 430
 
466 431
 function init() {
467
-  // local storage init
468
-  try {
469
-    //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
470
-    gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
471
-    gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
472
-    locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
473
-
474
-    console.log("Locate_me = " + locate_me);
475
-    console.log("Strava = " + gpx_to_strava);
476
-    console.log("Custom web = " + gpx_to_web);
477
-
478
-    var ce = gpx_to_web;
479
-    var cu = localStorage.getItem("custom_uploaded");
480
-    var se = gpx_to_strava;
481
-    var su = localStorage.getItem("strava_uploaded");
482
-
483
-    //checking token freshness (expiry >4h)
484
-    var delay = (Date.now() + 14400000) / 1000
485
-    if (se) {
486
-      if (JSON.parse(localStorage.getItem("strava_tokens")).expiry < delay) {
487
-        console.log("Strava oAuth token expiring or expired, refreshing it")
488
-        refreshTokens(JSON.parse(localStorage.getItem("strava_tokens")).refresh_token);
489
-      } else {
490
-        console.log("token (" + JSON.parse(localStorage.getItem("strava_tokens")).access_token + ")valid for 4h min, continuing")
491
-      }
492
-    }
493
-  } catch (e) { }
432
+    // local storage init
433
+    try {
434
+        //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
435
+        gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
436
+        gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
437
+        locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
438
+
439
+        console.log("Locate_me = " + locate_me);
440
+        console.log("Strava = " + gpx_to_strava);
441
+        console.log("Custom web = " + gpx_to_web);
442
+
443
+        var ce = gpx_to_web;
444
+        var cu = localStorage.getItem("custom_uploaded");
445
+        var se = gpx_to_strava;
446
+        var su = localStorage.getItem("strava_uploaded");
447
+
448
+        //checking token freshness (expiry >4h)
449
+        var delay = (Date.now() + 14400000) / 1000
450
+        if (se) {
451
+            if (JSON.parse(localStorage.getItem("strava_tokens")).expiry < delay) {
452
+                console.log("Strava oAuth token expiring or expired, refreshing it")
453
+                refreshTokens(JSON.parse(localStorage.getItem("strava_tokens")).refresh_token);
454
+            } else {
455
+                console.log("token (" + JSON.parse(localStorage.getItem("strava_tokens")).access_token + ")valid for 4h min, continuing")
456
+            }
457
+        }
458
+    } catch (e) {}
494 459
 
495
-  if ((se && !su) || (ce && !cu)) {
496
-    //posting any missed XHR from previous ride session
497
-    if (ce) {
498
-      PostToWeb();
499
-    }
500
-    if (se) {
501
-      SendToStrava();
460
+    if ((se && !su) || (ce && !cu)) {
461
+        //posting any missed XHR from previous ride session
462
+        if (ce) {
463
+            PostToWeb();
464
+        }
465
+        if (se) {
466
+            SendToStrava();
467
+        }
468
+    } else {
469
+        localStorage.setItem("GPX", "");
470
+        localStorage.setItem("maxSpeed", "");
471
+        localStorage.setItem("latitude", "");
472
+        localStorage.setItem("longitude", "");
473
+        localStorage.setItem("timestamp", "");
474
+        localStorage.setItem("custom_uploaded", false);
475
+        localStorage.setItem("strava_uploaded", false);
502 476
     }
503
-  } else {
504
-    localStorage.setItem("GPX", "");
505
-    localStorage.setItem("maxSpeed", "");
506
-    localStorage.setItem("latitude", "");
507
-    localStorage.setItem("longitude", "");
508
-    localStorage.setItem("timestamp", "");
509
-    localStorage.setItem("custom_uploaded", false);
510
-    localStorage.setItem("strava_uploaded", false);
511
-  }
512
-  // clear any other var to do
513
-  clearInterval(locationInterval);
514
-  clearInterval(instantLocationInterval);
515
-  navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
477
+    // clear any other var to do
478
+    clearInterval(locationInterval);
479
+    clearInterval(instantLocationInterval);
480
+    navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
516 481
 
517 482
 }
518 483
 
519 484
 // Get JS readiness events
520
-Pebble.addEventListener('ready', function (e) {
521
-  console.log('PebbleKit JS is ready');
522
-  // Update Watch on this
523
-  Pebble.sendAppMessage({ 'JSReady': 1 });
485
+Pebble.addEventListener('ready', function(e) {
486
+    console.log('PebbleKit JS is ready');
487
+    // Update Watch on this
488
+    Pebble.sendAppMessage({ 'JSReady': 1 });
524 489
 
525
-  init();
490
+    init();
526 491
 });
527 492
 
528 493
 // Get AppMessage events
529
-Pebble.addEventListener('appmessage', function (e) {
530
-  // Get the dictionary from the message
531
-  var dict = e.payload;
532
-  //console.log(dict[0].toString());
533
-  switch (dict[0]) {
534
-    case 'get':
535
-      get_coordinate();
536
-      break;
537
-    case 'exit':
538
-      clearInterval(instantLocationInterval);
539
-      clearInterval(locationInterval);
540
-      gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
541
-      gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
542
-      locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
543
-
544
-      //End GPX file
545
-      GPXfooterBuilder();
546
-      if (gpx_to_strava) {
547
-        //send to strava through API
548
-        SendToStrava();
549
-      }
550
-      if (gpx_to_web) {
551
-        // send CSV to web server through API
552
-        PostToWeb();
553
-      }
554
-      if (locate_me) {
555
-        var prev_pos = getLocation();
556
-        instantLocationUpdate(prev_pos);
557
-      }
558
-
559
-      // Send the message
560
-      var dict = {
561
-        'status': "EXIT"
562
-      };
563
-      Pebble.sendAppMessage(dict, function () {
564
-        console.log('Message sent successfully: ' + JSON.stringify(dict));
565
-      }, function (e) {
566
-        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
567
-      });
568
-
569
-      break;
570
-    default:
571
-      console.log('Sorry. I don\'t understand your request :' + dict[0]);
572
-  }
494
+Pebble.addEventListener('appmessage', function(e) {
495
+    // Get the dictionary from the message
496
+    var dict = e.payload;
497
+    //console.log(dict[0].toString());
498
+    switch (dict[0]) {
499
+        case 'get':
500
+            get_coordinate();
501
+            break;
502
+        case 'exit':
503
+            clearInterval(instantLocationInterval);
504
+            clearInterval(locationInterval);
505
+            gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
506
+            gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
507
+            locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
508
+
509
+            //End GPX file
510
+            GPXfooterBuilder();
511
+            if (gpx_to_strava) {
512
+                //send to strava through API
513
+                SendToStrava();
514
+            }
515
+            if (gpx_to_web) {
516
+                // send CSV to web server through API
517
+                PostToWeb();
518
+            }
519
+            if (locate_me) {
520
+                var prev_pos = getLocation();
521
+                instantLocationUpdate(prev_pos);
522
+            }
523
+
524
+            // Send the message
525
+            var dict = {
526
+                'status': "EXIT"
527
+            };
528
+            Pebble.sendAppMessage(dict, function() {
529
+                console.log('Message sent successfully: ' + JSON.stringify(dict));
530
+            }, function(e) {
531
+                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
532
+            });
533
+
534
+            break;
535
+        default:
536
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
537
+    }
573 538
 
574 539
 });
575 540
\ No newline at end of file
Browse code

strava upload with oauth (unsecured for now) and clay settings are working

louis.jonget authored on21/10/2022 16:01:55
Showing1 changed files
... ...
@@ -3,63 +3,6 @@ var clayConfig = require('./config');
3 3
 var clay = new Clay(clayConfig, null, { autoHandleEvents: false });
4 4
 var messageKeys = require('message_keys');
5 5
 
6
-Pebble.addEventListener('showConfiguration', function(e) {
7
-
8
-    // This is an example of how you might load a different config based on platform.
9
-    var platform = clay.meta.activeWatchInfo.platform || 'aplite';
10
-    if (platform === 'aplite') {
11
-        clay.config = clayConfigAplite;
12
-    }
13
-
14
-    Pebble.openURL(clay.generateUrl());
15
-});
16
-
17
-Pebble.addEventListener('webviewclosed', function(t) {
18
-    if (!t || t.response) {
19
-        try {
20
-            if (data = JSON.parse(t.response), data.strava) {
21
-                //data.strava will be like this :
22
-                // {"code":"db896b06f89804997a8088320fba755e6299c0d6","scope":"read,activity:write","state":"bike_companion"}
23
-                // so need to parse it correctly
24
-                //console.log("strava temp code to exchange to access token : " + data.code)
25
-                // placeholder to get token from code from php
26
-                return token
27
-            }
28
-        } catch (t) {
29
-            i && console.error("Parsing error:", t)
30
-        }
31
-        var dict = clay.getSettings(t.response);
32
-
33
-        /* assess if needed to send setting to watch as already in phone (done with "getsettings")
34
-        m.live_mmt_enable = dict[p.live_mmt_enable]
35
-        m.live_mmt_login = dict[p.live_mmt_login]
36
-        m.live_mmt_password = dict[p.live_mmt_password]
37
-        m.live_jayps_enable = dict[p.live_jayps_enable]
38
-        m.live_jayps_login = dict[p.live_jayps_login]
39
-        m.live_jayps_password = dict[p.live_jayps_password]
40
-        m.strava_automatic_upload = dict[p.strava_automatic_upload]
41
-    
42
-        i = dict[p.debug]
43
-        console.log("debug:" + i)
44
-        g.setDebug(i)
45
-        h.setDebug(i)
46
-        b.setDebug(i)
47
-        y.setDebug(i)
48
-        m.setDebug(i)
49
-    
50
-        m.save()
51
-        // Assess if needed to send settings values to watch side
52
-        /*
53
-        Pebble.sendAppMessage(dict, function(e) {
54
-            console.log('Sent config data to Pebble');
55
-        }, function(e) {
56
-            console.log('Failed to send config data!');
57
-            console.log(JSON.stringify(e));
58
-        });*/
59
-    }
60
-});
61
-
62
-
63 6
 var message;
64 7
 var gpx_to_strava
65 8
 var gpx_to_web
... ...
@@ -68,410 +11,564 @@ var locate_me
68 11
 var locationInterval;
69 12
 var instantLocationInterval;
70 13
 
14
+// TODO to remove for security
15
+var client_id = "94880";
16
+var client_secret = "08dc170f0fe38f39dd327bea82a28db4400e6f00";
17
+
71 18
 var firstlocationOptions = {
72
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
73
-    'timeout': 60000, //60s timeout to get a first good signal
74
-    'maximumAge': 0 // no cache
19
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
20
+  'timeout': 60000, //60s timeout to get a first good signal
21
+  'maximumAge': 0 // no cache
75 22
 };
76 23
 var locationOptions = {
77
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
78
-    'timeout': 5000, //5s timeout to get a good signal
79
-    'maximumAge': 0 // no cache
24
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
25
+  'timeout': 5000, //5s timeout to get a good signal
26
+  'maximumAge': 0 // no cache
80 27
 };
81
-var geoloc_id;
28
+
29
+Pebble.addEventListener('showConfiguration', function (e) {
30
+  clay.config = clayConfig;
31
+  console.log("Clay config is showing...")
32
+  Pebble.openURL(clay.generateUrl());
33
+});
34
+
35
+Pebble.addEventListener('webviewclosed', function (t) {
36
+  if (!t || t.response) {
37
+    console.log("Clay config is submitted : " + t.response)
38
+    try {
39
+      if (data = JSON.parse(t.response), data.code && data.scope == "read,activity:write") {
40
+        // data looks like this :
41
+        // {"code":"db896b06f89804997a8088320fba755e6299c0d6","scope":"read,activity:write","state":"bike_companion"}
42
+        // so need to parse it correctly
43
+        //var grantcode = JSON.parse(data.strava.value)
44
+        if (data.state == "bike_companion" && data.scope == "read,activity:write") {
45
+          getTokens(data.code);
46
+        } else {
47
+          console.log("Error on response returned : scope is " + grantcode.scope + " and state is " + grantcode.state);
48
+        }
49
+      } else {
50
+        clay.getSettings(t.response);
51
+        console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
52
+      }
53
+    } catch (t) {
54
+      console.log("Oauth parsing error, continue on saving clay settings");
55
+      clay.getSettings(t.response);
56
+      console.log("Clay settings in Localstorage looks like " + localStorage.getItem("clay-settings"));
57
+      //set strava to false
58
+    }
59
+
60
+    // dict is not used as intended to send settings to watch
61
+
62
+    /* assess if needed to send setting to watch as already in phone (done with "getsettings")
63
+    m.live_mmt_enable = dict[p.live_mmt_enable]
64
+    m.live_mmt_login = dict[p.live_mmt_login]
65
+    m.live_mmt_password = dict[p.live_mmt_password]
66
+    m.live_jayps_enable = dict[p.live_jayps_enable]
67
+    m.live_jayps_login = dict[p.live_jayps_login]
68
+    m.live_jayps_password = dict[p.live_jayps_password]
69
+    m.strava_automatic_upload = dict[p.strava_automatic_upload]
70
+
71
+    i = dict[p.debug]
72
+    console.log("debug:" + i)
73
+    g.setDebug(i)
74
+    h.setDebug(i)
75
+    b.setDebug(i)
76
+    y.setDebug(i)
77
+    m.setDebug(i)
78
+
79
+    m.save()
80
+    // Assess if needed to send settings values to watch side
81
+    /*
82
+    Pebble.sendAppMessage(dict, function(e) {
83
+        console.log('Sent config data to Pebble');
84
+    }, function(e) {
85
+        console.log('Failed to send config data!');
86
+        console.log(JSON.stringify(e));
87
+    });*/
88
+  }
89
+});
90
+
82 91
 
83 92
 // Store location in Pebble app local storage
84 93
 //
85 94
 function storeLocation(position) {
86
-    var latitude = position.coords.latitude;
87
-    var longitude = position.coords.longitude;
88
-    var timestamp = position.timestamp;
89
-    localStorage.setItem("latitude", latitude);
90
-    localStorage.setItem("longitude", longitude);
91
-    localStorage.setItem("timestamp", timestamp);
92
-    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
95
+  var latitude = position.coords.latitude;
96
+  var longitude = position.coords.longitude;
97
+  var timestamp = position.timestamp;
98
+  localStorage.setItem("latitude", latitude);
99
+  localStorage.setItem("longitude", longitude);
100
+  localStorage.setItem("timestamp", timestamp);
101
+  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
93 102
 }
94 103
 
95 104
 // Get location from Pebble app local storage
96 105
 //
97 106
 function getLocation() {
98
-    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
99
-        var la = localStorage.getItem("latitude");
100
-        var lo = localStorage.getItem("longitude");
101
-        var ti = localStorage.getItem("timestamp");
102
-        var co = { "latitude": la, "longitude": lo };
103
-        var pos = { "coords": co, "timestamp": ti };
104
-        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
105
-        return pos;
106
-    } else {
107
-        return null;
108
-    }
107
+  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
108
+    var la = localStorage.getItem("latitude");
109
+    var lo = localStorage.getItem("longitude");
110
+    var ti = localStorage.getItem("timestamp");
111
+    var co = { "latitude": la, "longitude": lo };
112
+    var pos = { "coords": co, "timestamp": ti };
113
+    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
114
+    return pos;
115
+  } else {
116
+    return null;
117
+  }
109 118
 }
110 119
 
111 120
 // Get max speed of the run
112 121
 //
113 122
 function getMaxSpeed(lastSpeed) {
114
-    oldmax = localStorage.getItem("maxSpeed") || -1;
115
-    if (oldmax < lastSpeed) {
116
-        maxSpeed = lastSpeed
117
-    } else if (oldmax > lastSpeed) {
118
-        maxSpeed = oldmax
119
-    } else {
120
-        maxSpeed = oldmax
121
-    }
122
-    localStorage.setItem("maxSpeed", maxSpeed);
123
-    return maxSpeed
123
+  oldmax = localStorage.getItem("maxSpeed") || -1;
124
+  if (oldmax < lastSpeed) {
125
+    maxSpeed = lastSpeed
126
+  } else if (oldmax > lastSpeed) {
127
+    maxSpeed = oldmax
128
+  } else {
129
+    maxSpeed = oldmax
130
+  }
131
+  localStorage.setItem("maxSpeed", maxSpeed);
132
+  return maxSpeed
124 133
 }
125 134
 
126 135
 // split float number into an array of int (null returned instead of 0 for decimal)
127 136
 //
128 137
 function splitFloatNumber(num) {
129
-    const intStr = num.toString().split('.')[0];
130
-    const decimalStr = num.toString().split('.')[1];
131
-    return [Number(intStr), Number(decimalStr)];
138
+  const intStr = num.toString().split('.')[0];
139
+  const decimalStr = num.toString().split('.')[1];
140
+  return [Number(intStr), Number(decimalStr)];
132 141
 
133 142
 }
134 143
 
135 144
 // Build GPX headers
136 145
 //
137 146
 function GPXHeadersBuilder(timestamp, name, type) {
138
-    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
139
-    var ret = localStorage.setItem("GPX", headers);
140
-    return true;
147
+  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
148
+  var ret = localStorage.setItem("GPX", headers);
149
+  return true;
141 150
 }
142 151
 
143
-// Build GPX footer
152
+// Build GPX track point
144 153
 //
145 154
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
146
-    var GPX = localStorage.getItem("GPX");
147
-    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
148
-    localStorage.setItem("GPX", GPX + trkpt);
149
-    return true;
155
+  var GPX = localStorage.getItem("GPX");
156
+  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
157
+  localStorage.setItem("GPX", GPX + trkpt);
158
+  return true;
150 159
 }
151 160
 
152 161
 // Build GPX footer
153 162
 //
154 163
 function GPXfooterBuilder() {
155
-    var GPX = localStorage.getItem("GPX");
156
-    var footer = '</trkseg></trk></gpx>';
157
-    var ret = localStorage.setItem("GPX", GPX + footer);
158
-    //console.log("GPX closed : " + GPX + footer);
159
-    return ret;
164
+  var GPX = localStorage.getItem("GPX");
165
+  var footer = '</trkseg></trk></gpx>';
166
+  var ret = localStorage.setItem("GPX", GPX + footer);
167
+  //console.log("GPX closed : " + GPX + footer);
168
+  return ret;
160 169
 }
161 170
 
171
+//------------------------------------------
172
+// OAUTH functions
173
+//------------------------------------------
174
+
175
+function getTokens(code) {
176
+  // call to strava api to get tokens in exchange of temp code
177
+  // need to use strava.jonget.fr to proxy request and hide secret
178
+  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + code + "&grant_type=authorization_code";
179
+  var xhr = new XMLHttpRequest();
180
+  xhr.timeout = 10000; // time in milliseconds
181
+
182
+  xhr.open("POST", url, false);
183
+
184
+  xhr.onload = function () {
185
+    //console.log('------xhr onloaded')
186
+    if (xhr.readyState === 4) {
187
+      console.log('------xhr request returned :', xhr.responseText);
188
+      response_json = JSON.parse(xhr.responseText);
189
+
190
+      var tokenjson = {
191
+        access_token: response_json.access_token,
192
+        refresh_token: response_json.refresh_token,
193
+        expiry: response_json.expires_at
194
+      };
195
+      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
196
+
197
+    }
198
+  };
199
+
200
+  xhr.send();
201
+
202
+}
203
+
204
+function refreshTokens(refresh_token) {
205
+  // call to strava api to get tokens in exchange of refresh code
206
+  // need to use strava.jonget.fr to proxy request and hide secret
207
+  var url = "https://www.strava.com/oauth/token?client_id=" + client_id + "&client_secret=" + client_secret + "&refresh_token=" + refresh_token + "&grant_type=refresh_token";
208
+  var xhr = new XMLHttpRequest();
209
+  xhr.timeout = 10000; // time in milliseconds
210
+
211
+  xhr.open("POST", url, false);
212
+
213
+  xhr.onload = function () {
214
+    //console.log('------xhr onloaded')
215
+    if (xhr.readyState === 4) {
216
+      //console.log('------xhr request returned with ' + xhr.status);
217
+      response_json = JSON.parse(xhr.txt);
218
+
219
+      var tokenjson = {
220
+        access_token: response_json.access_token,
221
+        refresh_token: response_json.refresh_token,
222
+        expiry: response_json.expires_at
223
+      };
224
+      localStorage.setItem("strava_tokens", JSON.stringify(tokenjson));
225
+
226
+    }
227
+  };
228
+
229
+  xhr.send();
230
+
231
+}
162 232
 
163 233
 // Send GPX to Strava profile
164
-// TODO : get authentication creds from settings
165 234
 function SendToStrava() {
166
-    console.log('--- GPX upload to strava');
167
-    var gpxfile = localStorage.getItem("GPX");
168
-    // need to automate oAUTH
169
-    var bearer = "09f93068353f11f09d22059f1e8e42ef526949a5"
170
-    params = {
171
-        url: "https://www.strava.com/api/v3/uploads",
172
-        method: "POST",
173
-        data: { description: "desc", data_type: "gpx" },
174
-        files: { file: gpxfile },
175
-        authorization: "Bearer " + bearer,
176
-        callback: function(e) {
177
-            var message = "";
178
-            // what is 'r'
179
-            // what is 'e'
180
-            // what is 'o'
181
-            // what is 'z'
182
-            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
183
-                message = "Your activity has been created";
184
-            } else if (400 == e.status) {
185
-                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
186
-            } else if (401 == e.status) {
187
-                message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
188
-            } else {
189
-                try {
190
-                    response_json = JSON.parse(e.txt)
191
-                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (console.log("status:" + response_json.status), z = response_json.status)
192
-                } catch (e) {
193
-                    console.log("Error log, " + e)
194
-                }
195
-            }
196
-            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
197
-        }
198
-    }
199
-    var XHR = new XMLHttpRequest;
200
-    var n = this;
201
-    console.log(params.url);
202
-    XHR.open(params.method, params.url, !0);
203
-    var body = "";
204
-    var boundary = Math.random().toString().substring(2);
205
-    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
206
-    XHR.setRequestHeader("Authorization", params.authorization);
207
-    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
208
-    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
209
-    body += "--" + boundary + "--\r\n"
210
-
211
-    XHR.onreadystatechange = function() {
212
-        // what is 'n'
235
+  console.log('--- GPX upload to strava');
236
+  var gpxfile = localStorage.getItem("GPX");
237
+
238
+  var tokens = localStorage.getItem("strava_tokens");
239
+
240
+  var bearer = JSON.parse(tokens).access_token;
241
+  params = {
242
+    url: "https://www.strava.com/api/v3/uploads",
243
+    method: "POST",
244
+    data: { description: "desc", data_type: "gpx" },
245
+    files: { file: gpxfile },
246
+    authorization: "Bearer " + bearer,
247
+    callback: function (e) {
248
+      var message = "";
249
+      // what is 'r'
250
+      // what is 'e'
251
+      // what is 'o'
252
+      // what is 'z'
253
+      if (console.log(e.status + " - " + e.txt), 201 == e.status) {
254
+        message = "Your activity has been created";
255
+        localStorage.setItem("strava_uploaded", true);
256
+      } else if (400 == e.status) {
257
+        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
258
+      } else if (401 == e.status) {
259
+        message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
260
+      } else {
213 261
         try {
214
-            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
262
+          response_json = JSON.parse(e.txt)
263
+          response_json.error ? (console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (console.log("status:" + response_json.status), z = response_json.status)
215 264
         } catch (e) {
216
-            console.error("Error2 loading, ", e)
265
+          console.log("Error log, " + e)
217 266
         }
267
+      }
268
+      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
269
+    }
270
+  }
271
+  var XHR = new XMLHttpRequest;
272
+  var n = this;
273
+  console.log(params.url);
274
+  XHR.open(params.method, params.url, !0);
275
+  var body = "";
276
+  var boundary = Math.random().toString().substring(2);
277
+  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
278
+  XHR.setRequestHeader("Authorization", params.authorization);
279
+  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
280
+  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
281
+  body += "--" + boundary + "--\r\n"
282
+
283
+  XHR.onreadystatechange = function () {
284
+    // what is 'n'
285
+    try {
286
+      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
287
+    } catch (e) {
288
+      console.error("Error2 loading, ", e)
218 289
     }
219
-    XHR.send(body)
290
+  }
291
+  XHR.send(body)
220 292
 }
221 293
 
222 294
 
223 295
 // Send GPX to web server (need configuration on serverside)
224 296
 // TODO : secure it ?
225 297
 function PostToWeb() {
226
-    console.log('--- GPX upload to custom web server');
227
-    var GPX = localStorage.getItem("GPX");
228
-    var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
229
-    var xhr = new XMLHttpRequest();
230
-    xhr.timeout = 10000; // time in milliseconds
231
-
232
-    xhr.open("POST", url, false);
233
-
234
-    //console.log('------ CSV / xhr opened')
235
-    xhr.onload = function() {
236
-        //console.log('------xhr onload')
237
-        if (xhr.readyState === 4) {
238
-            //console.log('------xhr request returned with ' + xhr.status);
239
-            //console.log(this.responseText);
240
-            if (xhr.status == 200) {
241
-                //console.log('--> HTTP 200');
242
-                return true;
243
-            } else {
244
-                //console.log('--> HTTP ' + xhr.status);
245
-                return false;
246
-            }
247
-        }
248
-    };
298
+  console.log('--- GPX upload to custom web server');
299
+  var GPX = localStorage.getItem("GPX");
300
+  var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
301
+  var xhr = new XMLHttpRequest();
302
+  xhr.timeout = 10000; // time in milliseconds
303
+
304
+  xhr.open("POST", url, false);
305
+
306
+  //console.log('------ CSV / xhr opened')
307
+  xhr.onload = function () {
308
+    //console.log('------xhr onloaded')
309
+    if (xhr.readyState === 4) {
310
+      //console.log('------xhr request returned with ' + xhr.status);
311
+      //console.log(this.responseText);
312
+      localStorage.setItem("custom_uploaded", true);
313
+      if (xhr.status == 200) {
314
+        //console.log('--> HTTP 200');
315
+        return true;
316
+      } else {
317
+        //console.log('--> HTTP ' + xhr.status);
318
+        return false;
319
+      }
320
+    }
321
+  };
249 322
 
250
-    //send CSV in body
251
-    xhr.send(GPX);
323
+  //send CSV in body
324
+  xhr.send(GPX);
252 325
 
253 326
 }
254 327
 
255 328
 // Send location to web server for instant location (no live tracking)
256 329
 // TODO : secure it ?
257 330
 function instantLocationUpdate(pos) {
258
-    console.log('--- Instant location update');
259
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
260
-
261
-    var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
262
-    var xhr = new XMLHttpRequest();
263
-    xhr.timeout = 10000; // time in milliseconds
264
-
265
-    xhr.open("POST", url);
266
-
267
-    //console.log('------ instant / xhr opened')
268
-    xhr.onload = function() {
269
-        //console.log('------xhr onload')
270
-        if (xhr.readyState === 4) {
271
-            //console.log('------xhr request returned with ' + xhr.status);
272
-            //console.log(this.responseText);
273
-            if (xhr.status == 200) {
274
-                //console.log('--> HTTP 200');
275
-                return true;
276
-            } else {
277
-                //console.log('--> HTTP ' + xhr.status);
278
-                return false;
279
-            }
280
-        }
281
-    };
331
+  console.log('--- Instant location update');
332
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
333
+
334
+  var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
335
+  var xhr = new XMLHttpRequest();
336
+  xhr.timeout = 10000; // time in milliseconds
337
+
338
+  xhr.open("POST", url);
339
+
340
+  //console.log('------ instant / xhr opened')
341
+  xhr.onload = function () {
342
+    //console.log('------xhr onloaded')
343
+    if (xhr.readyState === 4) {
344
+      //console.log('------xhr request returned with ' + xhr.status);
345
+      //console.log(this.responseText);
346
+      if (xhr.status == 200) {
347
+        //console.log('--> HTTP 200');
348
+        return true;
349
+      } else {
350
+        //console.log('--> HTTP ' + xhr.status);
351
+        return false;
352
+      }
353
+    }
354
+  };
282 355
 
283
-    //send without body
284
-    xhr.send();
356
+  //send without body
357
+  xhr.send();
285 358
 
286 359
 }
287 360
 
288 361
 // called in case of successful geoloc gathering and sends the coordinate to watch
289 362
 //
290 363
 function locationSuccess(new_pos) {
291
-    console.log('--- locationSuccess');
292
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
364
+  console.log('--- locationSuccess');
365
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
293 366
 
294
-    var prev_pos = getLocation();
295
-    storeLocation(new_pos);
296
-    if (prev_pos === null) {
297
-        console.log('--- start building gpx');
367
+  var prev_pos = getLocation();
368
+  storeLocation(new_pos);
369
+  if (prev_pos === null) {
370
+    console.log('--- start building gpx');
298 371
 
299
-        if (gpx_to_strava || gpx_to_web) {
300
-            // Start the GPX file
301
-            GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
302
-        }
303
-    } else {
304
-        //clear watch of new position to avoid overlap
305
-        //navigator.geolocation.clearWatch(geoloc_id);
306
-        //console.log('--- watch geoloc cleared');
307
-        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
308
-
309
-        //get speed from geoloc API isntead of calculate it
310
-        // speed is initially in m/s, get it at km/h
311
-        if (new_pos.coords.speed === null) {
312
-            var speed = 0;
313
-        } else {
314
-            var speed = new_pos.coords.speed * 3.6;
315
-        }
316 372
 
317
-        // Prepare display on watch
318
-        // now it's only raw data
319
-        // init strings
320
-        var latitudeString = "";
321
-        var longitudeString = "";
322
-        var accuracyString = "";
323
-        var altitudeString = "";
324
-        var speedString = "";
325
-
326
-        //formating for precision and max size
327
-        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
328
-        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
329
-        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
330
-        //console.log("split num : " + new_pos.coords.altitude);
331
-        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
332
-        timestampISO = new Date(new_pos.timestamp).toISOString();
333
-        //console.log("split num : " + speed);
334
-        if (isNaN(speed)) {
335
-            speedString = "---";
336
-        } else {
337
-            speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
338
-            if (speedString == "0.N") {
339
-                speedString = "0.0";
340
-            }
373
+    // Start the GPX file
374
+    GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
341 375
 
342
-            //console.log("split num : " + getMaxSpeed(speed));
343
-            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
344
-        }
376
+  } else {
377
+    //clear watch of new position to avoid overlap
378
+    //navigator.geolocation.clearWatch(geoloc_id);
379
+    //console.log('--- watch geoloc cleared');
380
+    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
345 381
 
346
-        if (gpx_to_strava || gpx_to_web) {
347
-            //add a new datapoint to GPX file
348
-            GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
382
+    //get speed from geoloc API isntead of calculate it
383
+    // speed is initially in m/s, get it at km/h
384
+    if (new_pos.coords.speed === null) {
385
+      var speed = 0;
386
+    } else {
387
+      var speed = new_pos.coords.speed * 3.6;
388
+    }
349 389
 
350
-        }
390
+    // Prepare display on watch
391
+    // now it's only raw data
392
+    // init strings
393
+    var latitudeString = "";
394
+    var longitudeString = "";
395
+    var accuracyString = "";
396
+    var altitudeString = "";
397
+    var speedString = "";
398
+
399
+    //formating for precision and max size
400
+    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
401
+    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
402
+    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
403
+    //console.log("split num : " + new_pos.coords.altitude);
404
+    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
405
+    timestampISO = new Date(new_pos.timestamp).toISOString();
406
+    //console.log("split num : " + speed);
407
+    if (isNaN(speed)) {
408
+      speedString = "---";
409
+    } else {
410
+      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
411
+      if (speedString == "0.N") {
412
+        speedString = "0.0";
413
+      }
351 414
 
352
-        // Build message
353
-        message = "OK";
354
-        var dict = {
355
-            'accuracy': accuracyString,
356
-            'altitude': altitudeString,
357
-            'speed': speedString,
358
-            'max_speed': maxSpeedString,
359
-            'status': message
360
-        };
361
-
362
-        // Send the message
363
-        Pebble.sendAppMessage(dict, function() {
364
-            console.log('Message sent successfully: ' + JSON.stringify(dict));
365
-        }, function(e) {
366
-            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
367
-        });
415
+      //console.log("split num : " + getMaxSpeed(speed));
416
+      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
368 417
     }
369 418
 
419
+    //add a new datapoint to GPX file
420
+    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
421
+
422
+
423
+
424
+    // Build message
425
+    message = "OK";
426
+    var dict = {
427
+      'accuracy': accuracyString,
428
+      'altitude': altitudeString,
429
+      'speed': speedString,
430
+      'max_speed': maxSpeedString,
431
+      'status': message
432
+    };
433
+
434
+    // Send the message
435
+    Pebble.sendAppMessage(dict, function () {
436
+      console.log('Message sent successfully: ' + JSON.stringify(dict));
437
+    }, function (e) {
438
+      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
439
+    });
440
+  }
441
+
370 442
 }
371 443
 
372 444
 function locationError(err) {
373 445
 
374
-    console.warn('location error (' + err.code + '): ' + err.message);
446
+  console.warn('location error (' + err.code + '): ' + err.message);
375 447
 
376 448
 }
377 449
 
378 450
 
379 451
 function get_coordinate() {
380
-    console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
452
+  console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
381 453
 
382
-    locationInterval = setInterval(function() {
383
-        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
384
-    }, 1000);
454
+  locationInterval = setInterval(function () {
455
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
456
+  }, 1000);
385 457
 
386
-    if (locate_me) {
387
-        instantLocationInterval = setInterval(function() {
388
-            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
389
-        }, 60000);
390
-    }
458
+  if (locate_me) {
459
+    instantLocationInterval = setInterval(function () {
460
+      navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
461
+    }, 60000);
462
+  }
391 463
 
392 464
 }
393 465
 
394 466
 function init() {
395
-    // local storage init
396
-    gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_upload;
397
-    gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enable;
398
-    locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enable;
467
+  // local storage init
468
+  try {
469
+    //console.log("Clay settings = " + localStorage.getItem('clay-settings'));
470
+    gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
471
+    gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
472
+    locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
473
+
474
+    console.log("Locate_me = " + locate_me);
475
+    console.log("Strava = " + gpx_to_strava);
476
+    console.log("Custom web = " + gpx_to_web);
399 477
 
400 478
     var ce = gpx_to_web;
401
-    var cu = localStorage.getItem("custom_enabled");
479
+    var cu = localStorage.getItem("custom_uploaded");
402 480
     var se = gpx_to_strava;
403
-    var su = localStorage.getItem("strava_enabled");
481
+    var su = localStorage.getItem("strava_uploaded");
482
+
483
+    //checking token freshness (expiry >4h)
484
+    var delay = (Date.now() + 14400000) / 1000
485
+    if (se) {
486
+      if (JSON.parse(localStorage.getItem("strava_tokens")).expiry < delay) {
487
+        console.log("Strava oAuth token expiring or expired, refreshing it")
488
+        refreshTokens(JSON.parse(localStorage.getItem("strava_tokens")).refresh_token);
489
+      } else {
490
+        console.log("token (" + JSON.parse(localStorage.getItem("strava_tokens")).access_token + ")valid for 4h min, continuing")
491
+      }
492
+    }
493
+  } catch (e) { }
404 494
 
405
-    if ((se && !su) || (ce && !cu)) {
406
-        //posting any missed XHR from previous ride session
407
-        if (ce) {
408
-            PostToWeb();
409
-        }
410
-        if (se) {
411
-            SendToStrava();
412
-        }
413
-    } else {
414
-        localStorage.setItem("GPX", "");
415
-        localStorage.setItem("maxSpeed", "");
416
-        localStorage.setItem("latitude", "");
417
-        localStorage.setItem("longitude", "");
418
-        localStorage.setItem("timestamp", "");
419
-        localStorage.setItem("custom_uploaded", false);
420
-        localStorage.setItem("strava_uploaded", false);
495
+  if ((se && !su) || (ce && !cu)) {
496
+    //posting any missed XHR from previous ride session
497
+    if (ce) {
498
+      PostToWeb();
421 499
     }
422
-    // clear any other var to do
423
-    clearInterval(locationInterval);
424
-    clearInterval(instantLocationInterval);
425
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
500
+    if (se) {
501
+      SendToStrava();
502
+    }
503
+  } else {
504
+    localStorage.setItem("GPX", "");
505
+    localStorage.setItem("maxSpeed", "");
506
+    localStorage.setItem("latitude", "");
507
+    localStorage.setItem("longitude", "");
508
+    localStorage.setItem("timestamp", "");
509
+    localStorage.setItem("custom_uploaded", false);
510
+    localStorage.setItem("strava_uploaded", false);
511
+  }
512
+  // clear any other var to do
513
+  clearInterval(locationInterval);
514
+  clearInterval(instantLocationInterval);
515
+  navigator.geolocation.getCurrentPosition(null, locationError, firstlocationOptions);
426 516
 
427 517
 }
428 518
 
429 519
 // Get JS readiness events
430
-Pebble.addEventListener('ready', function(e) {
431
-    console.log('PebbleKit JS is ready');
432
-    // Update Watch on this
433
-    Pebble.sendAppMessage({ 'JSReady': 1 });
520
+Pebble.addEventListener('ready', function (e) {
521
+  console.log('PebbleKit JS is ready');
522
+  // Update Watch on this
523
+  Pebble.sendAppMessage({ 'JSReady': 1 });
434 524
 
435
-    init();
525
+  init();
436 526
 });
437 527
 
438 528
 // Get AppMessage events
439
-Pebble.addEventListener('appmessage', function(e) {
440
-    // Get the dictionary from the message
441
-    var dict = e.payload;
442
-    //console.log(dict[0].toString());
443
-    switch (dict[0]) {
444
-        case 'get':
445
-            get_coordinate();
446
-            break;
447
-        case 'exit':
448
-            clearInterval(instantLocationInterval);
449
-            clearInterval(locationInterval);
450
-            if (gpx_to_strava || gpx_to_web) {
451
-                //End GPX file
452
-                GPXfooterBuilder();
453
-                if (gpx_to_strava) {
454
-                    //send to strava through API
455
-                    SendToStrava();
456
-                }
457
-                if (gpx_to_web) {
458
-                    // send CSV to web server through API
459
-                    PostToWeb();
460
-                }
461
-            }
462
-            // Send the message
463
-            var dict = {
464
-                'status': "EXIT"
465
-            };
466
-            Pebble.sendAppMessage(dict, function() {
467
-                console.log('Message sent successfully: ' + JSON.stringify(dict));
468
-            }, function(e) {
469
-                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
470
-            });
471
-
472
-            break;
473
-        default:
474
-            console.log('Sorry. I don\'t understand your request :' + dict[0]);
475
-    }
529
+Pebble.addEventListener('appmessage', function (e) {
530
+  // Get the dictionary from the message
531
+  var dict = e.payload;
532
+  //console.log(dict[0].toString());
533
+  switch (dict[0]) {
534
+    case 'get':
535
+      get_coordinate();
536
+      break;
537
+    case 'exit':
538
+      clearInterval(instantLocationInterval);
539
+      clearInterval(locationInterval);
540
+      gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_enabled;
541
+      gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enabled;
542
+      locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enabled;
543
+
544
+      //End GPX file
545
+      GPXfooterBuilder();
546
+      if (gpx_to_strava) {
547
+        //send to strava through API
548
+        SendToStrava();
549
+      }
550
+      if (gpx_to_web) {
551
+        // send CSV to web server through API
552
+        PostToWeb();
553
+      }
554
+      if (locate_me) {
555
+        var prev_pos = getLocation();
556
+        instantLocationUpdate(prev_pos);
557
+      }
558
+
559
+      // Send the message
560
+      var dict = {
561
+        'status': "EXIT"
562
+      };
563
+      Pebble.sendAppMessage(dict, function () {
564
+        console.log('Message sent successfully: ' + JSON.stringify(dict));
565
+      }, function (e) {
566
+        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
567
+      });
568
+
569
+      break;
570
+    default:
571
+      console.log('Sorry. I don\'t understand your request :' + dict[0]);
572
+  }
476 573
 
477 574
 });
478 575
\ No newline at end of file
Browse code

fixed typo

Louis authored on20/10/2022 00:01:37
Showing1 changed files
... ...
@@ -14,7 +14,7 @@ Pebble.addEventListener('showConfiguration', function(e) {
14 14
     Pebble.openURL(clay.generateUrl());
15 15
 });
16 16
 
17
-Pebble.addEventListener('webviewclosed', function(e) {
17
+Pebble.addEventListener('webviewclosed', function(t) {
18 18
     if (!t || t.response) {
19 19
         try {
20 20
             if (data = JSON.parse(t.response), data.strava) {
Browse code

POST to strava Ok, oauth to do on webviewclose

Louis authored on20/10/2022 00:00:26
Showing1 changed files
... ...
@@ -1,511 +1,477 @@
1 1
 var Clay = require('pebble-clay');
2 2
 var clayConfig = require('./config');
3
-var clay = new Clay(clayConfig);
3
+var clay = new Clay(clayConfig, null, { autoHandleEvents: false });
4
+var messageKeys = require('message_keys');
4 5
 
6
+Pebble.addEventListener('showConfiguration', function(e) {
7
+
8
+    // This is an example of how you might load a different config based on platform.
9
+    var platform = clay.meta.activeWatchInfo.platform || 'aplite';
10
+    if (platform === 'aplite') {
11
+        clay.config = clayConfigAplite;
12
+    }
13
+
14
+    Pebble.openURL(clay.generateUrl());
15
+});
16
+
17
+Pebble.addEventListener('webviewclosed', function(e) {
18
+    if (!t || t.response) {
19
+        try {
20
+            if (data = JSON.parse(t.response), data.strava) {
21
+                //data.strava will be like this :
22
+                // {"code":"db896b06f89804997a8088320fba755e6299c0d6","scope":"read,activity:write","state":"bike_companion"}
23
+                // so need to parse it correctly
24
+                //console.log("strava temp code to exchange to access token : " + data.code)
25
+                // placeholder to get token from code from php
26
+                return token
27
+            }
28
+        } catch (t) {
29
+            i && console.error("Parsing error:", t)
30
+        }
31
+        var dict = clay.getSettings(t.response);
32
+
33
+        /* assess if needed to send setting to watch as already in phone (done with "getsettings")
34
+        m.live_mmt_enable = dict[p.live_mmt_enable]
35
+        m.live_mmt_login = dict[p.live_mmt_login]
36
+        m.live_mmt_password = dict[p.live_mmt_password]
37
+        m.live_jayps_enable = dict[p.live_jayps_enable]
38
+        m.live_jayps_login = dict[p.live_jayps_login]
39
+        m.live_jayps_password = dict[p.live_jayps_password]
40
+        m.strava_automatic_upload = dict[p.strava_automatic_upload]
41
+    
42
+        i = dict[p.debug]
43
+        console.log("debug:" + i)
44
+        g.setDebug(i)
45
+        h.setDebug(i)
46
+        b.setDebug(i)
47
+        y.setDebug(i)
48
+        m.setDebug(i)
49
+    
50
+        m.save()
51
+        // Assess if needed to send settings values to watch side
52
+        /*
53
+        Pebble.sendAppMessage(dict, function(e) {
54
+            console.log('Sent config data to Pebble');
55
+        }, function(e) {
56
+            console.log('Failed to send config data!');
57
+            console.log(JSON.stringify(e));
58
+        });*/
59
+    }
60
+});
5 61
 
6
-var messageKeys = require('message_keys');
7 62
 
8 63
 var message;
9
-var gpx_to_strava = false;
10
-var gpx_to_web = true;
64
+var gpx_to_strava
65
+var gpx_to_web
66
+var locate_me
11 67
 
12 68
 var locationInterval;
69
+var instantLocationInterval;
13 70
 
14 71
 var firstlocationOptions = {
15
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
16
-  'timeout': 60000, //60s timeout to get a good signal
17
-  'maximumAge': 5 // no cache
72
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
73
+    'timeout': 60000, //60s timeout to get a first good signal
74
+    'maximumAge': 0 // no cache
18 75
 };
19 76
 var locationOptions = {
20
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
21
-  'timeout': 5000, //5s timeout to get a good signal
22
-  'maximumAge': 5 // no cache
77
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
78
+    'timeout': 5000, //5s timeout to get a good signal
79
+    'maximumAge': 0 // no cache
23 80
 };
24 81
 var geoloc_id;
25 82
 
26 83
 // Store location in Pebble app local storage
27 84
 //
28 85
 function storeLocation(position) {
29
-  var latitude = position.coords.latitude;
30
-  var longitude = position.coords.longitude;
31
-  var timestamp = position.timestamp;
32
-  localStorage.setItem("latitude", latitude);
33
-  localStorage.setItem("longitude", longitude);
34
-  localStorage.setItem("timestamp", timestamp);
35
-  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
86
+    var latitude = position.coords.latitude;
87
+    var longitude = position.coords.longitude;
88
+    var timestamp = position.timestamp;
89
+    localStorage.setItem("latitude", latitude);
90
+    localStorage.setItem("longitude", longitude);
91
+    localStorage.setItem("timestamp", timestamp);
92
+    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
36 93
 }
37 94
 
38 95
 // Get location from Pebble app local storage
39 96
 //
40 97
 function getLocation() {
41
-  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
42
-    var la = localStorage.getItem("latitude");
43
-    var lo = localStorage.getItem("longitude");
44
-    var ti = localStorage.getItem("timestamp");
45
-    var co = { "latitude": la, "longitude": lo };
46
-    var pos = { "coords": co, "timestamp": ti };
47
-    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
48
-    return pos;
49
-  } else {
50
-    return null;
51
-  }
52
-}
53
-
54
-// Calculate the distance from 2 geoloc in degrees.
55
-// IMPORTANT : this is a calculation from 2D projection, altitude is not involved
56
-//
57
-function distance_on_geoid(lat1, lon1, lat2, lon2) {
58
-  // Convert degrees to radians
59
-  lat1 = lat1 * Math.PI / 180.0;
60
-  lon1 = lon1 * Math.PI / 180.0;
61
-  lat2 = lat2 * Math.PI / 180.0;
62
-  lon2 = lon2 * Math.PI / 180.0;
63
-  // radius of earth in metres
64
-  r = 6378100;
65
-  // P
66
-  rho1 = r * Math.cos(lat1);
67
-  z1 = r * Math.sin(lat1);
68
-  x1 = rho1 * Math.cos(lon1);
69
-  y1 = rho1 * Math.sin(lon1);
70
-  // Q
71
-  rho2 = r * Math.cos(lat2);
72
-  z2 = r * Math.sin(lat2);
73
-  x2 = rho2 * Math.cos(lon2);
74
-  y2 = rho2 * Math.sin(lon2);
75
-  // Dot product
76
-  dot = (x1 * x2 + y1 * y2 + z1 * z2);
77
-  cos_theta = dot / (r * r);
78
-  theta = Math.acos(cos_theta);
79
-  // Distance in Metres
80
-  return r * theta;
81
-}
82
-
83
-// Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
84
-//
85
-function speed_from_distance_and_time(p1, p2) {
86
-  dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
87
-  // timestamp is in milliseconds
88
-  time_s = (p2.timestamp - p1.timestamp) / 1000.0;
89
-  speed_mps = dist / time_s;
90
-  speed_kph = (speed_mps * 3600.0) / 1000.0;
91
-  return speed_kph;
98
+    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
99
+        var la = localStorage.getItem("latitude");
100
+        var lo = localStorage.getItem("longitude");
101
+        var ti = localStorage.getItem("timestamp");
102
+        var co = { "latitude": la, "longitude": lo };
103
+        var pos = { "coords": co, "timestamp": ti };
104
+        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
105
+        return pos;
106
+    } else {
107
+        return null;
108
+    }
92 109
 }
93 110
 
94 111
 // Get max speed of the run
95 112
 //
96 113
 function getMaxSpeed(lastSpeed) {
97
-  oldmax = localStorage.getItem("maxSpeed") || -1;
98
-  if (oldmax < lastSpeed) {
99
-    maxSpeed = lastSpeed
100
-  } else if (oldmax > lastSpeed) {
101
-    maxSpeed = oldmax
102
-  } else {
103
-    maxSpeed = oldmax
104
-  }
105
-  localStorage.setItem("maxSpeed", maxSpeed);
106
-  return maxSpeed
114
+    oldmax = localStorage.getItem("maxSpeed") || -1;
115
+    if (oldmax < lastSpeed) {
116
+        maxSpeed = lastSpeed
117
+    } else if (oldmax > lastSpeed) {
118
+        maxSpeed = oldmax
119
+    } else {
120
+        maxSpeed = oldmax
121
+    }
122
+    localStorage.setItem("maxSpeed", maxSpeed);
123
+    return maxSpeed
107 124
 }
108 125
 
109 126
 // split float number into an array of int (null returned instead of 0 for decimal)
110 127
 //
111 128
 function splitFloatNumber(num) {
112
-  const intStr = num.toString().split('.')[0];
113
-  const decimalStr = num.toString().split('.')[1];
114
-  return [Number(intStr), Number(decimalStr)];
129
+    const intStr = num.toString().split('.')[0];
130
+    const decimalStr = num.toString().split('.')[1];
131
+    return [Number(intStr), Number(decimalStr)];
115 132
 
116 133
 }
117 134
 
118 135
 // Build GPX headers
119 136
 //
120 137
 function GPXHeadersBuilder(timestamp, name, type) {
121
-  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
122
-  var ret = localStorage.setItem("GPX", headers);
123
-  return true;
138
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
139
+    var ret = localStorage.setItem("GPX", headers);
140
+    return true;
124 141
 }
125 142
 
126 143
 // Build GPX footer
127 144
 //
128 145
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
129
-  var GPX = localStorage.getItem("GPX");
130
-  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
131
-  localStorage.setItem("GPX", GPX + trkpt);
132
-  return true;
146
+    var GPX = localStorage.getItem("GPX");
147
+    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
148
+    localStorage.setItem("GPX", GPX + trkpt);
149
+    return true;
133 150
 }
134 151
 
135 152
 // Build GPX footer
136 153
 //
137 154
 function GPXfooterBuilder() {
138
-  var GPX = localStorage.getItem("GPX");
139
-  var footer = '</trkseg></trk></gpx>';
140
-  var ret = localStorage.setItem("GPX", GPX + footer);
141
-  //console.log("GPX closed : " + GPX + footer);
142
-  return ret;
155
+    var GPX = localStorage.getItem("GPX");
156
+    var footer = '</trkseg></trk></gpx>';
157
+    var ret = localStorage.setItem("GPX", GPX + footer);
158
+    //console.log("GPX closed : " + GPX + footer);
159
+    return ret;
143 160
 }
144 161
 
145 162
 
146 163
 // Send GPX to Strava profile
147 164
 // TODO : get authentication creds from settings
148 165
 function SendToStrava() {
149
-  console.log('--- GPX upload to strava');
150
-  var gpxfile = localStorage.getItem("GPX");
151
-  // need to automate oAUTH
152
-  var bearer = "8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58"
153
-  params = {
154
-    url: "https://www.strava.com/api/v3/uploads",
155
-    method: "POST",
156
-    data: { description: "desc", data_type: "gpx" },
157
-    files: { file: gpxfile },
158
-    authorization: "Bearer " + bearer,
159
-    callback: function () {
160
-      var message = "";
161
-      // what is 'r'
162
-      // what is 'e'
163
-      // what is 'o'
164
-      // what is 'z'
165
-      if (r && console.log(e.status + " - " + e.txt), 201 == e.status) {
166
-        message = "Your activity has been created";
167
-      } else if (400 == e.status) {
168
-        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
169
-      } else if (401 == e.status) {
170
-        message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
171
-      } else {
166
+    console.log('--- GPX upload to strava');
167
+    var gpxfile = localStorage.getItem("GPX");
168
+    // need to automate oAUTH
169
+    var bearer = "09f93068353f11f09d22059f1e8e42ef526949a5"
170
+    params = {
171
+        url: "https://www.strava.com/api/v3/uploads",
172
+        method: "POST",
173
+        data: { description: "desc", data_type: "gpx" },
174
+        files: { file: gpxfile },
175
+        authorization: "Bearer " + bearer,
176
+        callback: function(e) {
177
+            var message = "";
178
+            // what is 'r'
179
+            // what is 'e'
180
+            // what is 'o'
181
+            // what is 'z'
182
+            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
183
+                message = "Your activity has been created";
184
+            } else if (400 == e.status) {
185
+                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
186
+            } else if (401 == e.status) {
187
+                message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
188
+            } else {
189
+                try {
190
+                    response_json = JSON.parse(e.txt)
191
+                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (console.log("status:" + response_json.status), z = response_json.status)
192
+                } catch (e) {
193
+                    console.log("Error log, " + e)
194
+                }
195
+            }
196
+            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
197
+        }
198
+    }
199
+    var XHR = new XMLHttpRequest;
200
+    var n = this;
201
+    console.log(params.url);
202
+    XHR.open(params.method, params.url, !0);
203
+    var body = "";
204
+    var boundary = Math.random().toString().substring(2);
205
+    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
206
+    XHR.setRequestHeader("Authorization", params.authorization);
207
+    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
208
+    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
209
+    body += "--" + boundary + "--\r\n"
210
+
211
+    XHR.onreadystatechange = function() {
212
+        // what is 'n'
172 213
         try {
173
-          response_json = JSON.parse(e.txt)
174
-          response_json.error ? (r && console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (r && console.log("status:" + response_json.status), z = response_json.status)
214
+            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
175 215
         } catch (e) {
176
-          console.log("Error log, " + e)
216
+            console.error("Error2 loading, ", e)
177 217
         }
178
-      }
179
-      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
180
-    }
181
-  }
182
-  var XHR = new XMLHttpRequest;
183
-  console.log(params.url);
184
-  XHR.open(params.method, params.url, !0);
185
-  var body = "";
186
-  var boundary = Math.random().toString().substring(2);
187
-  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
188
-  XHR.setRequestHeader("Authorization", params.authorization);
189
-  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
190
-  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
191
-  body += "--" + boundary + "--\r\n"
192
-
193
-  XHR.onreadystatechange = function () {
194
-    // what is 'n'
195
-    try {
196
-      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback())
197
-    } catch (e) {
198
-      console.error("Error2 loading, ", e)
199 218
     }
200
-  }
201
-  XHR.send(body)
202
-
203
-
204
-
205
-  // fetch or Blob or Formdata are not implemented in pebblekitJS
206
-  /*fetch('data:application/gpx+xml;base64,'.btoa(GPX))
207
-      .then(function(value) { return value.blob() })
208
-      .then(
209
-          function(value) {
210
-  var data = new FormData();
211
-  data.append("name", "test");
212
-  data.append("description", "description");
213
-  data.append("data_type", "gpx");
214
-  data.append("file", value, "blob.gpx");
215
-
216
-  var xhr = new XMLHttpRequest();
217
-  var url = "https://www.strava.com/api/v3/uploads";
218
-  xhr.withCredentials = true;
219
-  xhr.timeout = 10000; // time in milliseconds
220
-
221
-  xhr.open("POST", url, false);
222
-  xhr.setRequestHeader("Authorization", "Bearer 8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58");
223
-
224
-  console.log('------GPX / xhr opened with authorization')
225
-  console.log('------array for blob: ' + [GPX])
226
-  xhr.onload = function() {
227
-      console.log('------xhr onload')
228
-      if (xhr.readyState === 4) {
229
-          console.log('------xhr request returned with ' + xhr.status);
230
-          console.log(this.responseText);
231
-          if (xhr.status == 200) {
232
-              //console.log('--> HTTP 200');
233
-              return true;
234
-          } else {
235
-              //console.log('--> HTTP ' + xhr.status);
236
-              return false;
237
-          }
238
-      }
239
-  };
240
-
241
-  xhr.send(data);
242
-  },
243
-          function(error) {
244
-              console.log('error')
245
-          }
246
-      )*/
247
-  /* -------------------- */
248
-
249
-
219
+    XHR.send(body)
250 220
 }
251 221
 
252 222
 
253
-// Build CSV
254
-function CSV(pos) {
255
-  var CSV = localStorage.getItem("CSV");
256
-  var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
257
-
258
-  localStorage.setItem("CSV", CSV + datapoint);
259
-
260
-}
261
-// Send CSV to web server (need configuration on serverside)
223
+// Send GPX to web server (need configuration on serverside)
262 224
 // TODO : secure it ?
263 225
 function PostToWeb() {
264
-  console.log('--- GPX upload to custom web server');
265
-  var GPX = localStorage.getItem("GPX");
266
-
267
-  var url = "https://jonget.fr/strava/upload.php?name=pebblegpx&type=application/gpx+xml";
268
-  var xhr = new XMLHttpRequest();
269
-  xhr.timeout = 10000; // time in milliseconds
270
-
271
-  xhr.open("POST", url, false);
272
-
273
-  //console.log('------ CSV / xhr opened')
274
-  xhr.onload = function () {
275
-    //console.log('------xhr onload')
276
-    if (xhr.readyState === 4) {
277
-      //console.log('------xhr request returned with ' + xhr.status);
278
-      //console.log(this.responseText);
279
-      if (xhr.status == 200) {
280
-        //console.log('--> HTTP 200');
281
-        return true;
282
-      } else {
283
-        //console.log('--> HTTP ' + xhr.status);
284
-        return false;
285
-      }
286
-    }
287
-  };
226
+    console.log('--- GPX upload to custom web server');
227
+    var GPX = localStorage.getItem("GPX");
228
+    var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
229
+    var xhr = new XMLHttpRequest();
230
+    xhr.timeout = 10000; // time in milliseconds
231
+
232
+    xhr.open("POST", url, false);
233
+
234
+    //console.log('------ CSV / xhr opened')
235
+    xhr.onload = function() {
236
+        //console.log('------xhr onload')
237
+        if (xhr.readyState === 4) {
238
+            //console.log('------xhr request returned with ' + xhr.status);
239
+            //console.log(this.responseText);
240
+            if (xhr.status == 200) {
241
+                //console.log('--> HTTP 200');
242
+                return true;
243
+            } else {
244
+                //console.log('--> HTTP ' + xhr.status);
245
+                return false;
246
+            }
247
+        }
248
+    };
288 249
 
289
-  //send CSV in body
290
-  xhr.send(GPX);
250
+    //send CSV in body
251
+    xhr.send(GPX);
291 252
 
292 253
 }
293 254
 
294
-// Send location to web server for instant location (no tracking)
255
+// Send location to web server for instant location (no live tracking)
295 256
 // TODO : secure it ?
296 257
 function instantLocationUpdate(pos) {
297
-  console.log('--- Instant location update');
298
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
299
-
300
-  var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
301
-  var xhr = new XMLHttpRequest();
302
-  xhr.timeout = 10000; // time in milliseconds
303
-
304
-  xhr.open("POST", url);
305
-
306
-  //console.log('------ instant / xhr opened')
307
-  xhr.onload = function () {
308
-    //console.log('------xhr onload')
309
-    if (xhr.readyState === 4) {
310
-      //console.log('------xhr request returned with ' + xhr.status);
311
-      //console.log(this.responseText);
312
-      if (xhr.status == 200) {
313
-        //console.log('--> HTTP 200');
314
-        return true;
315
-      } else {
316
-        //console.log('--> HTTP ' + xhr.status);
317
-        return false;
318
-      }
319
-    }
320
-  };
321
-
322
-  //send without body
323
-  xhr.send();
324
-
325
-}
258
+    console.log('--- Instant location update');
259
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
260
+
261
+    var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
262
+    var xhr = new XMLHttpRequest();
263
+    xhr.timeout = 10000; // time in milliseconds
264
+
265
+    xhr.open("POST", url);
266
+
267
+    //console.log('------ instant / xhr opened')
268
+    xhr.onload = function() {
269
+        //console.log('------xhr onload')
270
+        if (xhr.readyState === 4) {
271
+            //console.log('------xhr request returned with ' + xhr.status);
272
+            //console.log(this.responseText);
273
+            if (xhr.status == 200) {
274
+                //console.log('--> HTTP 200');
275
+                return true;
276
+            } else {
277
+                //console.log('--> HTTP ' + xhr.status);
278
+                return false;
279
+            }
280
+        }
281
+    };
326 282
 
283
+    //send without body
284
+    xhr.send();
327 285
 
328
-// Adding leading characters to string for nice displays
329
-//
330
-function padStart(string, max_length, padding) {
331
-  if (string.length > max_length) {
332
-    return string;
333
-  } else {
334
-    var new_str = string;
335
-    for (index = string.length; index < max_length; index++) {
336
-      new_str = "0" + new_str;
337
-    }
338
-    return new_str;
339
-  }
340 286
 }
341 287
 
342 288
 // called in case of successful geoloc gathering and sends the coordinate to watch
343 289
 //
344 290
 function locationSuccess(new_pos) {
345
-  console.log('--- locationSuccess');
346
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
291
+    console.log('--- locationSuccess');
292
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
347 293
 
348
-  var prev_pos = getLocation();
349
-  storeLocation(new_pos);
350
-  if (prev_pos === null) {
351
-    console.log('--- start building gpx');
294
+    var prev_pos = getLocation();
295
+    storeLocation(new_pos);
296
+    if (prev_pos === null) {
297
+        console.log('--- start building gpx');
352 298
 
353
-    if (gpx_to_strava || gpx_to_web) {
354
-      // Start the GPX file
355
-      GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
356
-    }
357
-  } else {
358
-    //clear watch of new position to avoid overlap
359
-    //navigator.geolocation.clearWatch(geoloc_id);
360
-    //console.log('--- watch geoloc cleared');
361
-    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
362
-
363
-    //get speed from geoloc API isntead of calculate it
364
-    // speed is initially in m/s, get it at km/h
365
-    if (new_pos.coords.speed === null) {
366
-      var speed = 0;
299
+        if (gpx_to_strava || gpx_to_web) {
300
+            // Start the GPX file
301
+            GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
302
+        }
367 303
     } else {
368
-      var speed = new_pos.coords.speed * 3.6;
369
-    }
304
+        //clear watch of new position to avoid overlap
305
+        //navigator.geolocation.clearWatch(geoloc_id);
306
+        //console.log('--- watch geoloc cleared');
307
+        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
308
+
309
+        //get speed from geoloc API isntead of calculate it
310
+        // speed is initially in m/s, get it at km/h
311
+        if (new_pos.coords.speed === null) {
312
+            var speed = 0;
313
+        } else {
314
+            var speed = new_pos.coords.speed * 3.6;
315
+        }
370 316
 
371
-    // Prepare display on watch
372
-    // now it's only raw data
373
-    // init strings
374
-    var latitudeString = "";
375
-    var longitudeString = "";
376
-    var accuracyString = "";
377
-    var altitudeString = "";
378
-    var speedString = "";
379
-
380
-    //formating for precision and max size
381
-    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
382
-    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
383
-    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
384
-    //console.log("split num : " + new_pos.coords.altitude);
385
-    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
386
-    timestampISO = new Date(new_pos.timestamp).toISOString();
387
-    //console.log("split num : " + speed);
388
-    speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
389
-
390
-    //console.log("split num : " + getMaxSpeed(speed));
391
-    maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
392
-
393
-    if (speedString == "NaN") {
394
-      speedString = "---";
395
-    }
317
+        // Prepare display on watch
318
+        // now it's only raw data
319
+        // init strings
320
+        var latitudeString = "";
321
+        var longitudeString = "";
322
+        var accuracyString = "";
323
+        var altitudeString = "";
324
+        var speedString = "";
325
+
326
+        //formating for precision and max size
327
+        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
328
+        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
329
+        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
330
+        //console.log("split num : " + new_pos.coords.altitude);
331
+        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
332
+        timestampISO = new Date(new_pos.timestamp).toISOString();
333
+        //console.log("split num : " + speed);
334
+        if (isNaN(speed)) {
335
+            speedString = "---";
336
+        } else {
337
+            speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
338
+            if (speedString == "0.N") {
339
+                speedString = "0.0";
340
+            }
341
+
342
+            //console.log("split num : " + getMaxSpeed(speed));
343
+            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
344
+        }
396 345
 
397
-    if (gpx_to_strava || gpx_to_web) {
398
-      //add a new datapoint to GPX file
399
-      GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
346
+        if (gpx_to_strava || gpx_to_web) {
347
+            //add a new datapoint to GPX file
348
+            GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
400 349
 
401
-    }
402
-
403
-    // Build message
404
-    message = "OK";
405
-    var dict = {
406
-      'accuracy': accuracyString,
407
-      'altitude': altitudeString,
408
-      'speed': speedString,
409
-      'max_speed': maxSpeedString,
410
-      'status': message
411
-    };
350
+        }
412 351
 
413
-    // Send the message
414
-    Pebble.sendAppMessage(dict, function () {
415
-      console.log('Message sent successfully: ' + JSON.stringify(dict));
416
-    }, function (e) {
417
-      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
418
-    });
419
-  }
352
+        // Build message
353
+        message = "OK";
354
+        var dict = {
355
+            'accuracy': accuracyString,
356
+            'altitude': altitudeString,
357
+            'speed': speedString,
358
+            'max_speed': maxSpeedString,
359
+            'status': message
360
+        };
361
+
362
+        // Send the message
363
+        Pebble.sendAppMessage(dict, function() {
364
+            console.log('Message sent successfully: ' + JSON.stringify(dict));
365
+        }, function(e) {
366
+            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
367
+        });
368
+    }
420 369
 
421 370
 }
422 371
 
423 372
 function locationError(err) {
424 373
 
425
-  console.warn('location error (' + err.code + '): ' + err.message);
426
-  /*
427
-  if (gpx_to_web) {
428
-
429
-      var CSV = localStorage.getItem("CSV");
430
-      var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
431
-
432
-      localStorage.setItem("CSV", CSV + datapoint);
433
-  }*/
374
+    console.warn('location error (' + err.code + '): ' + err.message);
434 375
 
435 376
 }
436 377
 
437 378
 
438 379
 function get_coordinate() {
439
-  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
380
+    console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
440 381
 
441
-  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
382
+    locationInterval = setInterval(function() {
383
+        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
384
+    }, 1000);
442 385
 
443
-  locationInterval = setInterval(function () {
444
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
445
-  }, 1000);
446
-
447
-  instantLocationInterval = setInterval(function () {
448
-    navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
449
-  }, 60000);
386
+    if (locate_me) {
387
+        instantLocationInterval = setInterval(function() {
388
+            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
389
+        }, 60000);
390
+    }
450 391
 
451 392
 }
452 393
 
453 394
 function init() {
454
-  // local storage init,
455
-  // todo : clear only temporary values, not clay config (and do it on exit ?)
456
-  localStorage.clear();
457
-  localStorage.setItem("CSV", "");
458
-  // clear any other var to do
459
-  clearInterval(locationInterval);
395
+    // local storage init
396
+    gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_upload;
397
+    gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enable;
398
+    locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enable;
399
+
400
+    var ce = gpx_to_web;
401
+    var cu = localStorage.getItem("custom_enabled");
402
+    var se = gpx_to_strava;
403
+    var su = localStorage.getItem("strava_enabled");
404
+
405
+    if ((se && !su) || (ce && !cu)) {
406
+        //posting any missed XHR from previous ride session
407
+        if (ce) {
408
+            PostToWeb();
409
+        }
410
+        if (se) {
411
+            SendToStrava();
412
+        }
413
+    } else {
414
+        localStorage.setItem("GPX", "");
415
+        localStorage.setItem("maxSpeed", "");
416
+        localStorage.setItem("latitude", "");
417
+        localStorage.setItem("longitude", "");
418
+        localStorage.setItem("timestamp", "");
419
+        localStorage.setItem("custom_uploaded", false);
420
+        localStorage.setItem("strava_uploaded", false);
421
+    }
422
+    // clear any other var to do
423
+    clearInterval(locationInterval);
424
+    clearInterval(instantLocationInterval);
425
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
460 426
 
461 427
 }
462 428
 
463 429
 // Get JS readiness events
464
-Pebble.addEventListener('ready', function (e) {
465
-  console.log('PebbleKit JS is ready');
466
-  // Update Watch on this
467
-  Pebble.sendAppMessage({ 'JSReady': 1 });
430
+Pebble.addEventListener('ready', function(e) {
431
+    console.log('PebbleKit JS is ready');
432
+    // Update Watch on this
433
+    Pebble.sendAppMessage({ 'JSReady': 1 });
468 434
 
469
-  init();
435
+    init();
470 436
 });
471 437
 
472 438
 // Get AppMessage events
473
-Pebble.addEventListener('appmessage', function (e) {
474
-  // Get the dictionary from the message
475
-  var dict = e.payload;
476
-  //console.log(dict[0].toString());
477
-  switch (dict[0]) {
478
-    case 'get':
479
-      get_coordinate();
480
-      break;
481
-    case 'exit':
482
-      clearInterval(instantLocationInterval);
483
-      clearInterval(locationInterval);
484
-      if (gpx_to_strava || gpx_to_web) {
485
-        //End GPX file
486
-        GPXfooterBuilder();
487
-        if (gpx_to_strava) {
488
-          //send to strava through API
489
-          SendToStrava();
490
-        }
491
-        if (gpx_to_web) {
492
-          // send CSV to web server through API
493
-          PostToWeb();
494
-        }
495
-      }
496
-      // Send the message
497
-      var dict = {
498
-        'status': "KO"
499
-      };
500
-      Pebble.sendAppMessage(dict, function () {
501
-        console.log('Message sent successfully: ' + JSON.stringify(dict));
502
-      }, function (e) {
503
-        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
504
-      });
505
-
506
-      break;
507
-    default:
508
-      console.log('Sorry. I don\'t understand your request :' + dict[0]);
509
-  }
439
+Pebble.addEventListener('appmessage', function(e) {
440
+    // Get the dictionary from the message
441
+    var dict = e.payload;
442
+    //console.log(dict[0].toString());
443
+    switch (dict[0]) {
444
+        case 'get':
445
+            get_coordinate();
446
+            break;
447
+        case 'exit':
448
+            clearInterval(instantLocationInterval);
449
+            clearInterval(locationInterval);
450
+            if (gpx_to_strava || gpx_to_web) {
451
+                //End GPX file
452
+                GPXfooterBuilder();
453
+                if (gpx_to_strava) {
454
+                    //send to strava through API
455
+                    SendToStrava();
456
+                }
457
+                if (gpx_to_web) {
458
+                    // send CSV to web server through API
459
+                    PostToWeb();
460
+                }
461
+            }
462
+            // Send the message
463
+            var dict = {
464
+                'status': "EXIT"
465
+            };
466
+            Pebble.sendAppMessage(dict, function() {
467
+                console.log('Message sent successfully: ' + JSON.stringify(dict));
468
+            }, function(e) {
469
+                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
470
+            });
471
+
472
+            break;
473
+        default:
474
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
475
+    }
510 476
 
511 477
 });
512 478
\ No newline at end of file
Browse code

clarifying variables in XHR for strava

louis.jonget authored on19/10/2022 18:02:20
Showing1 changed files
... ...
@@ -12,212 +12,239 @@ var gpx_to_web = true;
12 12
 var locationInterval;
13 13
 
14 14
 var firstlocationOptions = {
15
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
16
-    'timeout': 60000, //60s timeout to get a good signal
17
-    'maximumAge': 5 // no cache
15
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
16
+  'timeout': 60000, //60s timeout to get a good signal
17
+  'maximumAge': 5 // no cache
18 18
 };
19 19
 var locationOptions = {
20
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
21
-    'timeout': 5000, //5s timeout to get a good signal
22
-    'maximumAge': 5 // no cache
20
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
21
+  'timeout': 5000, //5s timeout to get a good signal
22
+  'maximumAge': 5 // no cache
23 23
 };
24 24
 var geoloc_id;
25 25
 
26 26
 // Store location in Pebble app local storage
27 27
 //
28 28
 function storeLocation(position) {
29
-    var latitude = position.coords.latitude;
30
-    var longitude = position.coords.longitude;
31
-    var timestamp = position.timestamp;
32
-    localStorage.setItem("latitude", latitude);
33
-    localStorage.setItem("longitude", longitude);
34
-    localStorage.setItem("timestamp", timestamp);
35
-    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
29
+  var latitude = position.coords.latitude;
30
+  var longitude = position.coords.longitude;
31
+  var timestamp = position.timestamp;
32
+  localStorage.setItem("latitude", latitude);
33
+  localStorage.setItem("longitude", longitude);
34
+  localStorage.setItem("timestamp", timestamp);
35
+  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
36 36
 }
37 37
 
38 38
 // Get location from Pebble app local storage
39 39
 //
40 40
 function getLocation() {
41
-    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
42
-        var la = localStorage.getItem("latitude");
43
-        var lo = localStorage.getItem("longitude");
44
-        var ti = localStorage.getItem("timestamp");
45
-        var co = { "latitude": la, "longitude": lo };
46
-        var pos = { "coords": co, "timestamp": ti };
47
-        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
48
-        return pos;
49
-    } else {
50
-        return null;
51
-    }
41
+  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
42
+    var la = localStorage.getItem("latitude");
43
+    var lo = localStorage.getItem("longitude");
44
+    var ti = localStorage.getItem("timestamp");
45
+    var co = { "latitude": la, "longitude": lo };
46
+    var pos = { "coords": co, "timestamp": ti };
47
+    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
48
+    return pos;
49
+  } else {
50
+    return null;
51
+  }
52 52
 }
53 53
 
54 54
 // Calculate the distance from 2 geoloc in degrees.
55 55
 // IMPORTANT : this is a calculation from 2D projection, altitude is not involved
56 56
 //
57 57
 function distance_on_geoid(lat1, lon1, lat2, lon2) {
58
-    // Convert degrees to radians
59
-    lat1 = lat1 * Math.PI / 180.0;
60
-    lon1 = lon1 * Math.PI / 180.0;
61
-    lat2 = lat2 * Math.PI / 180.0;
62
-    lon2 = lon2 * Math.PI / 180.0;
63
-    // radius of earth in metres
64
-    r = 6378100;
65
-    // P
66
-    rho1 = r * Math.cos(lat1);
67
-    z1 = r * Math.sin(lat1);
68
-    x1 = rho1 * Math.cos(lon1);
69
-    y1 = rho1 * Math.sin(lon1);
70
-    // Q
71
-    rho2 = r * Math.cos(lat2);
72
-    z2 = r * Math.sin(lat2);
73
-    x2 = rho2 * Math.cos(lon2);
74
-    y2 = rho2 * Math.sin(lon2);
75
-    // Dot product
76
-    dot = (x1 * x2 + y1 * y2 + z1 * z2);
77
-    cos_theta = dot / (r * r);
78
-    theta = Math.acos(cos_theta);
79
-    // Distance in Metres
80
-    return r * theta;
58
+  // Convert degrees to radians
59
+  lat1 = lat1 * Math.PI / 180.0;
60
+  lon1 = lon1 * Math.PI / 180.0;
61
+  lat2 = lat2 * Math.PI / 180.0;
62
+  lon2 = lon2 * Math.PI / 180.0;
63
+  // radius of earth in metres
64
+  r = 6378100;
65
+  // P
66
+  rho1 = r * Math.cos(lat1);
67
+  z1 = r * Math.sin(lat1);
68
+  x1 = rho1 * Math.cos(lon1);
69
+  y1 = rho1 * Math.sin(lon1);
70
+  // Q
71
+  rho2 = r * Math.cos(lat2);
72
+  z2 = r * Math.sin(lat2);
73
+  x2 = rho2 * Math.cos(lon2);
74
+  y2 = rho2 * Math.sin(lon2);
75
+  // Dot product
76
+  dot = (x1 * x2 + y1 * y2 + z1 * z2);
77
+  cos_theta = dot / (r * r);
78
+  theta = Math.acos(cos_theta);
79
+  // Distance in Metres
80
+  return r * theta;
81 81
 }
82 82
 
83 83
 // Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
84 84
 //
85 85
 function speed_from_distance_and_time(p1, p2) {
86
-    dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
87
-    // timestamp is in milliseconds
88
-    time_s = (p2.timestamp - p1.timestamp) / 1000.0;
89
-    speed_mps = dist / time_s;
90
-    speed_kph = (speed_mps * 3600.0) / 1000.0;
91
-    return speed_kph;
86
+  dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
87
+  // timestamp is in milliseconds
88
+  time_s = (p2.timestamp - p1.timestamp) / 1000.0;
89
+  speed_mps = dist / time_s;
90
+  speed_kph = (speed_mps * 3600.0) / 1000.0;
91
+  return speed_kph;
92 92
 }
93 93
 
94 94
 // Get max speed of the run
95 95
 //
96 96
 function getMaxSpeed(lastSpeed) {
97
-    oldmax = localStorage.getItem("maxSpeed") || -1;
98
-    if (oldmax < lastSpeed) {
99
-        maxSpeed = lastSpeed
100
-    } else if (oldmax > lastSpeed) {
101
-        maxSpeed = oldmax
102
-    } else {
103
-        maxSpeed = oldmax
104
-    }
105
-    localStorage.setItem("maxSpeed", maxSpeed);
106
-    return maxSpeed
97
+  oldmax = localStorage.getItem("maxSpeed") || -1;
98
+  if (oldmax < lastSpeed) {
99
+    maxSpeed = lastSpeed
100
+  } else if (oldmax > lastSpeed) {
101
+    maxSpeed = oldmax
102
+  } else {
103
+    maxSpeed = oldmax
104
+  }
105
+  localStorage.setItem("maxSpeed", maxSpeed);
106
+  return maxSpeed
107 107
 }
108 108
 
109 109
 // split float number into an array of int (null returned instead of 0 for decimal)
110 110
 //
111 111
 function splitFloatNumber(num) {
112
-    const intStr = num.toString().split('.')[0];
113
-    const decimalStr = num.toString().split('.')[1];
114
-    return [Number(intStr), Number(decimalStr)];
112
+  const intStr = num.toString().split('.')[0];
113
+  const decimalStr = num.toString().split('.')[1];
114
+  return [Number(intStr), Number(decimalStr)];
115 115
 
116 116
 }
117 117
 
118 118
 // Build GPX headers
119 119
 //
120 120
 function GPXHeadersBuilder(timestamp, name, type) {
121
-    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
122
-    var ret = localStorage.setItem("GPX", headers);
123
-    return true;
121
+  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
122
+  var ret = localStorage.setItem("GPX", headers);
123
+  return true;
124 124
 }
125 125
 
126 126
 // Build GPX footer
127 127
 //
128 128
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
129
-    var GPX = localStorage.getItem("GPX");
130
-    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
131
-    localStorage.setItem("GPX", GPX + trkpt);
132
-    return true;
129
+  var GPX = localStorage.getItem("GPX");
130
+  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
131
+  localStorage.setItem("GPX", GPX + trkpt);
132
+  return true;
133 133
 }
134 134
 
135 135
 // Build GPX footer
136 136
 //
137 137
 function GPXfooterBuilder() {
138
-    var GPX = localStorage.getItem("GPX");
139
-    var footer = '</trkseg></trk></gpx>';
140
-    var ret = localStorage.setItem("GPX", GPX + footer);
141
-    //console.log("GPX closed : " + GPX + footer);
142
-    return ret;
138
+  var GPX = localStorage.getItem("GPX");
139
+  var footer = '</trkseg></trk></gpx>';
140
+  var ret = localStorage.setItem("GPX", GPX + footer);
141
+  //console.log("GPX closed : " + GPX + footer);
142
+  return ret;
143 143
 }
144 144
 
145 145
 
146 146
 // Send GPX to Strava profile
147 147
 // TODO : get authentication creds from settings
148 148
 function SendToStrava() {
149
-    console.log('--- GPX upload to strava');
150
-    var GPX = localStorage.getItem("GPX");
151
-    // need to automate oAUTH
152
-    var bearer = "8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58"
153
-    params = {
154
-        url: s,
155
-        method: "POST",
156
-        data: { description: "desc", data_type: "gpx" },
157
-        files: { file: gpxfile },
158
-        authorization: "Bearer " + bearer,
159
-        callback: function() {
160
-            var message = "";
161
-            if (r && console.log(e.status + " - " + e.txt), 201 == e.status) {
162
-                message = "Your activity has been created";
163
-            } else if (400 == e.status) {
164
-                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
165
-            } else if (401 == e.status) {
166
-                message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
167
-            } else {
168
-                try {
169
-                    response_json = JSON.parse(e.txt), response_json.error ? (r && console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (r && console.log("status:" + response_json.status), z = response_json.status)
170
-                } catch (z) {
171
-                    console.log("Error log, " + z)
172
-                }
173
-            }
174
-            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
149
+  console.log('--- GPX upload to strava');
150
+  var gpxfile = localStorage.getItem("GPX");
151
+  // need to automate oAUTH
152
+  var bearer = "8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58"
153
+  params = {
154
+    url: "https://www.strava.com/api/v3/uploads",
155
+    method: "POST",
156
+    data: { description: "desc", data_type: "gpx" },
157
+    files: { file: gpxfile },
158
+    authorization: "Bearer " + bearer,
159
+    callback: function () {
160
+      var message = "";
161
+      // what is 'r'
162
+      // what is 'e'
163
+      // what is 'o'
164
+      // what is 'z'
165
+      if (r && console.log(e.status + " - " + e.txt), 201 == e.status) {
166
+        message = "Your activity has been created";
167
+      } else if (400 == e.status) {
168
+        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
169
+      } else if (401 == e.status) {
170
+        message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
171
+      } else {
172
+        try {
173
+          response_json = JSON.parse(e.txt)
174
+          response_json.error ? (r && console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (r && console.log("status:" + response_json.status), z = response_json.status)
175
+        } catch (e) {
176
+          console.log("Error log, " + e)
175 177
         }
178
+      }
179
+      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
176 180
     }
177
-
178
-    // fetch or Blob or Formdata are not implemented in pebblekitJS
179
-    /*fetch('data:application/gpx+xml;base64,'.btoa(GPX))
180
-        .then(function(value) { return value.blob() })
181
-        .then(
182
-            function(value) {
183
-    var data = new FormData();
184
-    data.append("name", "test");
185
-    data.append("description", "description");
186
-    data.append("data_type", "gpx");
187
-    data.append("file", value, "blob.gpx");
188
-
189
-    var xhr = new XMLHttpRequest();
190
-    var url = "https://www.strava.com/api/v3/uploads";
191
-    xhr.withCredentials = true;
192
-    xhr.timeout = 10000; // time in milliseconds
193
-
194
-    xhr.open("POST", url, false);
195
-    xhr.setRequestHeader("Authorization", "Bearer 8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58");
196
-
197
-    console.log('------GPX / xhr opened with authorization')
198
-    console.log('------array for blob: ' + [GPX])
199
-    xhr.onload = function() {
200
-        console.log('------xhr onload')
201
-        if (xhr.readyState === 4) {
202
-            console.log('------xhr request returned with ' + xhr.status);
203
-            console.log(this.responseText);
204
-            if (xhr.status == 200) {
205
-                //console.log('--> HTTP 200');
206
-                return true;
207
-            } else {
208
-                //console.log('--> HTTP ' + xhr.status);
209
-                return false;
210
-            }
211
-        }
212
-    };
213
-
214
-    xhr.send(data);
215
-    },
216
-            function(error) {
217
-                console.log('error')
218
-            }
219
-        )*/
220
-    /* -------------------- */
181
+  }
182
+  var XHR = new XMLHttpRequest;
183
+  console.log(params.url);
184
+  XHR.open(params.method, params.url, !0);
185
+  var body = "";
186
+  var boundary = Math.random().toString().substring(2);
187
+  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
188
+  XHR.setRequestHeader("Authorization", params.authorization);
189
+  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
190
+  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
191
+  body += "--" + boundary + "--\r\n"
192
+
193
+  XHR.onreadystatechange = function () {
194
+    // what is 'n'
195
+    try {
196
+      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback())
197
+    } catch (e) {
198
+      console.error("Error2 loading, ", e)
199
+    }
200
+  }
201
+  XHR.send(body)
202
+
203
+
204
+
205
+  // fetch or Blob or Formdata are not implemented in pebblekitJS
206
+  /*fetch('data:application/gpx+xml;base64,'.btoa(GPX))
207
+      .then(function(value) { return value.blob() })
208
+      .then(
209
+          function(value) {
210
+  var data = new FormData();
211
+  data.append("name", "test");
212
+  data.append("description", "description");
213
+  data.append("data_type", "gpx");
214
+  data.append("file", value, "blob.gpx");
215
+
216
+  var xhr = new XMLHttpRequest();
217
+  var url = "https://www.strava.com/api/v3/uploads";
218
+  xhr.withCredentials = true;
219
+  xhr.timeout = 10000; // time in milliseconds
220
+
221
+  xhr.open("POST", url, false);
222
+  xhr.setRequestHeader("Authorization", "Bearer 8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58");
223
+
224
+  console.log('------GPX / xhr opened with authorization')
225
+  console.log('------array for blob: ' + [GPX])
226
+  xhr.onload = function() {
227
+      console.log('------xhr onload')
228
+      if (xhr.readyState === 4) {
229
+          console.log('------xhr request returned with ' + xhr.status);
230
+          console.log(this.responseText);
231
+          if (xhr.status == 200) {
232
+              //console.log('--> HTTP 200');
233
+              return true;
234
+          } else {
235
+              //console.log('--> HTTP ' + xhr.status);
236
+              return false;
237
+          }
238
+      }
239
+  };
240
+
241
+  xhr.send(data);
242
+  },
243
+          function(error) {
244
+              console.log('error')
245
+          }
246
+      )*/
247
+  /* -------------------- */
221 248
 
222 249
 
223 250
 }
... ...
@@ -225,75 +252,75 @@ function SendToStrava() {
225 252
 
226 253
 // Build CSV
227 254
 function CSV(pos) {
228
-    var CSV = localStorage.getItem("CSV");
229
-    var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
255
+  var CSV = localStorage.getItem("CSV");
256
+  var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
230 257
 
231
-    localStorage.setItem("CSV", CSV + datapoint);
258
+  localStorage.setItem("CSV", CSV + datapoint);
232 259
 
233 260
 }
234 261
 // Send CSV to web server (need configuration on serverside)
235 262
 // TODO : secure it ?
236 263
 function PostToWeb() {
237
-    console.log('--- GPX upload to custom web server');
238
-    var GPX = localStorage.getItem("GPX");
239
-
240
-    var url = "https://jonget.fr/strava/upload.php?name=pebblegpx&type=application/gpx+xml";
241
-    var xhr = new XMLHttpRequest();
242
-    xhr.timeout = 10000; // time in milliseconds
243
-
244
-    xhr.open("POST", url, false);
245
-
246
-    //console.log('------ CSV / xhr opened')
247
-    xhr.onload = function() {
248
-        //console.log('------xhr onload')
249
-        if (xhr.readyState === 4) {
250
-            //console.log('------xhr request returned with ' + xhr.status);
251
-            //console.log(this.responseText);
252
-            if (xhr.status == 200) {
253
-                //console.log('--> HTTP 200');
254
-                return true;
255
-            } else {
256
-                //console.log('--> HTTP ' + xhr.status);
257
-                return false;
258
-            }
259
-        }
260
-    };
264
+  console.log('--- GPX upload to custom web server');
265
+  var GPX = localStorage.getItem("GPX");
266
+
267
+  var url = "https://jonget.fr/strava/upload.php?name=pebblegpx&type=application/gpx+xml";
268
+  var xhr = new XMLHttpRequest();
269
+  xhr.timeout = 10000; // time in milliseconds
270
+
271
+  xhr.open("POST", url, false);
272
+
273
+  //console.log('------ CSV / xhr opened')
274
+  xhr.onload = function () {
275
+    //console.log('------xhr onload')
276
+    if (xhr.readyState === 4) {
277
+      //console.log('------xhr request returned with ' + xhr.status);
278
+      //console.log(this.responseText);
279
+      if (xhr.status == 200) {
280
+        //console.log('--> HTTP 200');
281
+        return true;
282
+      } else {
283
+        //console.log('--> HTTP ' + xhr.status);
284
+        return false;
285
+      }
286
+    }
287
+  };
261 288
 
262
-    //send CSV in body
263
-    xhr.send(GPX);
289
+  //send CSV in body
290
+  xhr.send(GPX);
264 291
 
265 292
 }
266 293
 
267 294
 // Send location to web server for instant location (no tracking)
268 295
 // TODO : secure it ?
269 296
 function instantLocationUpdate(pos) {
270
-    console.log('--- Instant location update');
271
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
272
-
273
-    var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
274
-    var xhr = new XMLHttpRequest();
275
-    xhr.timeout = 10000; // time in milliseconds
276
-
277
-    xhr.open("POST", url);
278
-
279
-    //console.log('------ instant / xhr opened')
280
-    xhr.onload = function() {
281
-        //console.log('------xhr onload')
282
-        if (xhr.readyState === 4) {
283
-            //console.log('------xhr request returned with ' + xhr.status);
284
-            //console.log(this.responseText);
285
-            if (xhr.status == 200) {
286
-                //console.log('--> HTTP 200');
287
-                return true;
288
-            } else {
289
-                //console.log('--> HTTP ' + xhr.status);
290
-                return false;
291
-            }
292
-        }
293
-    };
297
+  console.log('--- Instant location update');
298
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
299
+
300
+  var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
301
+  var xhr = new XMLHttpRequest();
302
+  xhr.timeout = 10000; // time in milliseconds
303
+
304
+  xhr.open("POST", url);
305
+
306
+  //console.log('------ instant / xhr opened')
307
+  xhr.onload = function () {
308
+    //console.log('------xhr onload')
309
+    if (xhr.readyState === 4) {
310
+      //console.log('------xhr request returned with ' + xhr.status);
311
+      //console.log(this.responseText);
312
+      if (xhr.status == 200) {
313
+        //console.log('--> HTTP 200');
314
+        return true;
315
+      } else {
316
+        //console.log('--> HTTP ' + xhr.status);
317
+        return false;
318
+      }
319
+    }
320
+  };
294 321
 
295
-    //send without body
296
-    xhr.send();
322
+  //send without body
323
+  xhr.send();
297 324
 
298 325
 }
299 326
 
... ...
@@ -301,184 +328,184 @@ function instantLocationUpdate(pos) {
301 328
 // Adding leading characters to string for nice displays
302 329
 //
303 330
 function padStart(string, max_length, padding) {
304
-    if (string.length > max_length) {
305
-        return string;
306
-    } else {
307
-        var new_str = string;
308
-        for (index = string.length; index < max_length; index++) {
309
-            new_str = "0" + new_str;
310
-        }
311
-        return new_str;
331
+  if (string.length > max_length) {
332
+    return string;
333
+  } else {
334
+    var new_str = string;
335
+    for (index = string.length; index < max_length; index++) {
336
+      new_str = "0" + new_str;
312 337
     }
338
+    return new_str;
339
+  }
313 340
 }
314 341
 
315 342
 // called in case of successful geoloc gathering and sends the coordinate to watch
316 343
 //
317 344
 function locationSuccess(new_pos) {
318
-    console.log('--- locationSuccess');
319
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
345
+  console.log('--- locationSuccess');
346
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
320 347
 
321
-    var prev_pos = getLocation();
322
-    storeLocation(new_pos);
323
-    if (prev_pos === null) {
324
-        console.log('--- start building gpx');
348
+  var prev_pos = getLocation();
349
+  storeLocation(new_pos);
350
+  if (prev_pos === null) {
351
+    console.log('--- start building gpx');
325 352
 
326
-        if (gpx_to_strava || gpx_to_web) {
327
-            // Start the GPX file
328
-            GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
329
-        }
353
+    if (gpx_to_strava || gpx_to_web) {
354
+      // Start the GPX file
355
+      GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
356
+    }
357
+  } else {
358
+    //clear watch of new position to avoid overlap
359
+    //navigator.geolocation.clearWatch(geoloc_id);
360
+    //console.log('--- watch geoloc cleared');
361
+    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
362
+
363
+    //get speed from geoloc API isntead of calculate it
364
+    // speed is initially in m/s, get it at km/h
365
+    if (new_pos.coords.speed === null) {
366
+      var speed = 0;
330 367
     } else {
331
-        //clear watch of new position to avoid overlap
332
-        //navigator.geolocation.clearWatch(geoloc_id);
333
-        //console.log('--- watch geoloc cleared');
334
-        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
335
-
336
-        //get speed from geoloc API isntead of calculate it
337
-        // speed is initially in m/s, get it at km/h
338
-        if (new_pos.coords.speed === null) {
339
-            var speed = 0;
340
-        } else {
341
-            var speed = new_pos.coords.speed * 3.6;
342
-        }
368
+      var speed = new_pos.coords.speed * 3.6;
369
+    }
343 370
 
344
-        // Prepare display on watch
345
-        // now it's only raw data
346
-        // init strings
347
-        var latitudeString = "";
348
-        var longitudeString = "";
349
-        var accuracyString = "";
350
-        var altitudeString = "";
351
-        var speedString = "";
352
-
353
-        //formating for precision and max size
354
-        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
355
-        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
356
-        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
357
-        //console.log("split num : " + new_pos.coords.altitude);
358
-        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
359
-        timestampISO = new Date(new_pos.timestamp).toISOString();
360
-        //console.log("split num : " + speed);
361
-        speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
362
-
363
-        //console.log("split num : " + getMaxSpeed(speed));
364
-        maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
365
-
366
-        if (speedString == "NaN") {
367
-            speedString = "---";
368
-        }
371
+    // Prepare display on watch
372
+    // now it's only raw data
373
+    // init strings
374
+    var latitudeString = "";
375
+    var longitudeString = "";
376
+    var accuracyString = "";
377
+    var altitudeString = "";
378
+    var speedString = "";
379
+
380
+    //formating for precision and max size
381
+    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
382
+    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
383
+    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
384
+    //console.log("split num : " + new_pos.coords.altitude);
385
+    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
386
+    timestampISO = new Date(new_pos.timestamp).toISOString();
387
+    //console.log("split num : " + speed);
388
+    speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
389
+
390
+    //console.log("split num : " + getMaxSpeed(speed));
391
+    maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
392
+
393
+    if (speedString == "NaN") {
394
+      speedString = "---";
395
+    }
369 396
 
370
-        if (gpx_to_strava || gpx_to_web) {
371
-            //add a new datapoint to GPX file
372
-            GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
397
+    if (gpx_to_strava || gpx_to_web) {
398
+      //add a new datapoint to GPX file
399
+      GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
373 400
 
374
-        }
375
-
376
-        // Build message
377
-        message = "OK";
378
-        var dict = {
379
-            'accuracy': accuracyString,
380
-            'altitude': altitudeString,
381
-            'speed': speedString,
382
-            'max_speed': maxSpeedString,
383
-            'status': message
384
-        };
385
-
386
-        // Send the message
387
-        Pebble.sendAppMessage(dict, function() {
388
-            console.log('Message sent successfully: ' + JSON.stringify(dict));
389
-        }, function(e) {
390
-            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
391
-        });
392 401
     }
393 402
 
403
+    // Build message
404
+    message = "OK";
405
+    var dict = {
406
+      'accuracy': accuracyString,
407
+      'altitude': altitudeString,
408
+      'speed': speedString,
409
+      'max_speed': maxSpeedString,
410
+      'status': message
411
+    };
412
+
413
+    // Send the message
414
+    Pebble.sendAppMessage(dict, function () {
415
+      console.log('Message sent successfully: ' + JSON.stringify(dict));
416
+    }, function (e) {
417
+      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
418
+    });
419
+  }
420
+
394 421
 }
395 422
 
396 423
 function locationError(err) {
397 424
 
398
-    console.warn('location error (' + err.code + '): ' + err.message);
399
-    /*
400
-    if (gpx_to_web) {
425
+  console.warn('location error (' + err.code + '): ' + err.message);
426
+  /*
427
+  if (gpx_to_web) {
401 428
 
402
-        var CSV = localStorage.getItem("CSV");
403
-        var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
429
+      var CSV = localStorage.getItem("CSV");
430
+      var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
404 431
 
405
-        localStorage.setItem("CSV", CSV + datapoint);
406
-    }*/
432
+      localStorage.setItem("CSV", CSV + datapoint);
433
+  }*/
407 434
 
408 435
 }
409 436
 
410 437
 
411 438
 function get_coordinate() {
412
-    console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
439
+  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
413 440
 
414
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
441
+  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
415 442
 
416
-    locationInterval = setInterval(function() {
417
-        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
418
-    }, 1000);
443
+  locationInterval = setInterval(function () {
444
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
445
+  }, 1000);
419 446
 
420
-    instantLocationInterval = setInterval(function() {
421
-        navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
422
-    }, 60000);
447
+  instantLocationInterval = setInterval(function () {
448
+    navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
449
+  }, 60000);
423 450
 
424 451
 }
425 452
 
426 453
 function init() {
427
-    // local storage init,
428
-    // todo : clear only temporary values, not clay config (and do it on exit ?)
429
-    localStorage.clear();
430
-    localStorage.setItem("CSV", "");
431
-    // clear any other var to do
432
-    clearInterval(locationInterval);
454
+  // local storage init,
455
+  // todo : clear only temporary values, not clay config (and do it on exit ?)
456
+  localStorage.clear();
457
+  localStorage.setItem("CSV", "");
458
+  // clear any other var to do
459
+  clearInterval(locationInterval);
433 460
 
434 461
 }
435 462
 
436 463
 // Get JS readiness events
437
-Pebble.addEventListener('ready', function(e) {
438
-    console.log('PebbleKit JS is ready');
439
-    // Update Watch on this
440
-    Pebble.sendAppMessage({ 'JSReady': 1 });
464
+Pebble.addEventListener('ready', function (e) {
465
+  console.log('PebbleKit JS is ready');
466
+  // Update Watch on this
467
+  Pebble.sendAppMessage({ 'JSReady': 1 });
441 468
 
442
-    init();
469
+  init();
443 470
 });
444 471
 
445 472
 // Get AppMessage events
446
-Pebble.addEventListener('appmessage', function(e) {
447
-    // Get the dictionary from the message
448
-    var dict = e.payload;
449
-    //console.log(dict[0].toString());
450
-    switch (dict[0]) {
451
-        case 'get':
452
-            get_coordinate();
453
-            break;
454
-        case 'exit':
455
-            clearInterval(instantLocationInterval);
456
-            clearInterval(locationInterval);
457
-            if (gpx_to_strava || gpx_to_web) {
458
-                //End GPX file
459
-                GPXfooterBuilder();
460
-                if (gpx_to_strava) {
461
-                    //send to strava through API
462
-                    SendToStrava();
463
-                }
464
-                if (gpx_to_web) {
465
-                    // send CSV to web server through API
466
-                    PostToWeb();
467
-                }
468
-            }
469
-            // Send the message
470
-            var dict = {
471
-                'status': "KO"
472
-            };
473
-            Pebble.sendAppMessage(dict, function() {
474
-                console.log('Message sent successfully: ' + JSON.stringify(dict));
475
-            }, function(e) {
476
-                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
477
-            });
478
-
479
-            break;
480
-        default:
481
-            console.log('Sorry. I don\'t understand your request :' + dict[0]);
482
-    }
473
+Pebble.addEventListener('appmessage', function (e) {
474
+  // Get the dictionary from the message
475
+  var dict = e.payload;
476
+  //console.log(dict[0].toString());
477
+  switch (dict[0]) {
478
+    case 'get':
479
+      get_coordinate();
480
+      break;
481
+    case 'exit':
482
+      clearInterval(instantLocationInterval);
483
+      clearInterval(locationInterval);
484
+      if (gpx_to_strava || gpx_to_web) {
485
+        //End GPX file
486
+        GPXfooterBuilder();
487
+        if (gpx_to_strava) {
488
+          //send to strava through API
489
+          SendToStrava();
490
+        }
491
+        if (gpx_to_web) {
492
+          // send CSV to web server through API
493
+          PostToWeb();
494
+        }
495
+      }
496
+      // Send the message
497
+      var dict = {
498
+        'status': "KO"
499
+      };
500
+      Pebble.sendAppMessage(dict, function () {
501
+        console.log('Message sent successfully: ' + JSON.stringify(dict));
502
+      }, function (e) {
503
+        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
504
+      });
505
+
506
+      break;
507
+    default:
508
+      console.log('Sorry. I don\'t understand your request :' + dict[0]);
509
+  }
483 510
 
484 511
 });
485 512
\ No newline at end of file
Browse code

removed click on back handler

Louis authored on18/10/2022 22:30:07
Showing1 changed files
... ...
@@ -6,8 +6,8 @@ var clay = new Clay(clayConfig);
6 6
 var messageKeys = require('message_keys');
7 7
 
8 8
 var message;
9
-var gpx_to_strava = true;
10
-var gpx_to_web = false;
9
+var gpx_to_strava = false;
10
+var gpx_to_web = true;
11 11
 
12 12
 var locationInterval;
13 13
 
... ...
@@ -452,6 +452,8 @@ Pebble.addEventListener('appmessage', function(e) {
452 452
             get_coordinate();
453 453
             break;
454 454
         case 'exit':
455
+            clearInterval(instantLocationInterval);
456
+            clearInterval(locationInterval);
455 457
             if (gpx_to_strava || gpx_to_web) {
456 458
                 //End GPX file
457 459
                 GPXfooterBuilder();
Browse code

baseline for strava upload

Louis authored on18/10/2022 22:22:24
Showing1 changed files
... ...
@@ -2,11 +2,12 @@ var Clay = require('pebble-clay');
2 2
 var clayConfig = require('./config');
3 3
 var clay = new Clay(clayConfig);
4 4
 
5
+
5 6
 var messageKeys = require('message_keys');
6 7
 
7 8
 var message;
8
-var gpx_to_strava = false;
9
-var gpx_to_web = true;
9
+var gpx_to_strava = true;
10
+var gpx_to_web = false;
10 11
 
11 12
 var locationInterval;
12 13
 
... ...
@@ -50,7 +51,6 @@ function getLocation() {
50 51
     }
51 52
 }
52 53
 
53
-
54 54
 // Calculate the distance from 2 geoloc in degrees.
55 55
 // IMPORTANT : this is a calculation from 2D projection, altitude is not involved
56 56
 //
... ...
@@ -142,34 +142,60 @@ function GPXfooterBuilder() {
142 142
     return ret;
143 143
 }
144 144
 
145
+
145 146
 // Send GPX to Strava profile
146 147
 // TODO : get authentication creds from settings
147 148
 function SendToStrava() {
148 149
     console.log('--- GPX upload to strava');
149 150
     var GPX = localStorage.getItem("GPX");
151
+    // need to automate oAUTH
152
+    var bearer = "8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58"
153
+    params = {
154
+        url: s,
155
+        method: "POST",
156
+        data: { description: "desc", data_type: "gpx" },
157
+        files: { file: gpxfile },
158
+        authorization: "Bearer " + bearer,
159
+        callback: function() {
160
+            var message = "";
161
+            if (r && console.log(e.status + " - " + e.txt), 201 == e.status) {
162
+                message = "Your activity has been created";
163
+            } else if (400 == e.status) {
164
+                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
165
+            } else if (401 == e.status) {
166
+                message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
167
+            } else {
168
+                try {
169
+                    response_json = JSON.parse(e.txt), response_json.error ? (r && console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (r && console.log("status:" + response_json.status), z = response_json.status)
170
+                } catch (z) {
171
+                    console.log("Error log, " + z)
172
+                }
173
+            }
174
+            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
175
+        }
176
+    }
150 177
 
151
-
152
-    /* -------------------- */
153
-    var array = [GPX]; // an array consisting of a single string
154
-    var blob = new Blob(array, { type: "application/gpx+xml" }); // the blob
155
-
156
-    // creating multipart/form-data to be sent
178
+    // fetch or Blob or Formdata are not implemented in pebblekitJS
179
+    /*fetch('data:application/gpx+xml;base64,'.btoa(GPX))
180
+        .then(function(value) { return value.blob() })
181
+        .then(
182
+            function(value) {
157 183
     var data = new FormData();
158
-    data.append("file", blob, "blob.gpx");
159 184
     data.append("name", "test");
160
-    data.append("description", "testdesc");
185
+    data.append("description", "description");
161 186
     data.append("data_type", "gpx");
187
+    data.append("file", value, "blob.gpx");
162 188
 
163
-    var url = "https://www.strava.com/api/v3/uploads";
164 189
     var xhr = new XMLHttpRequest();
190
+    var url = "https://www.strava.com/api/v3/uploads";
165 191
     xhr.withCredentials = true;
166 192
     xhr.timeout = 10000; // time in milliseconds
167 193
 
168 194
     xhr.open("POST", url, false);
169
-    xhr.setRequestHeader("Authorization", "Bearer d8927033b3996efe1e5a4e62425bc2aff8f635b0");
195
+    xhr.setRequestHeader("Authorization", "Bearer 8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58");
170 196
 
171 197
     console.log('------GPX / xhr opened with authorization')
172
-    console.log('------array for blob: ' + array)
198
+    console.log('------array for blob: ' + [GPX])
173 199
     xhr.onload = function() {
174 200
         console.log('------xhr onload')
175 201
         if (xhr.readyState === 4) {
... ...
@@ -185,10 +211,15 @@ function SendToStrava() {
185 211
         }
186 212
     };
187 213
 
188
-    // send with data in body
189 214
     xhr.send(data);
215
+    },
216
+            function(error) {
217
+                console.log('error')
218
+            }
219
+        )*/
190 220
     /* -------------------- */
191 221
 
222
+
192 223
 }
193 224
 
194 225
 
... ...
@@ -433,6 +464,15 @@ Pebble.addEventListener('appmessage', function(e) {
433 464
                     PostToWeb();
434 465
                 }
435 466
             }
467
+            // Send the message
468
+            var dict = {
469
+                'status': "KO"
470
+            };
471
+            Pebble.sendAppMessage(dict, function() {
472
+                console.log('Message sent successfully: ' + JSON.stringify(dict));
473
+            }, function(e) {
474
+                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
475
+            });
436 476
 
437 477
             break;
438 478
         default:
Browse code

adding var init under condition

louis.jonget authored on14/10/2022 15:46:53
Showing1 changed files
... ...
@@ -5,49 +5,46 @@ var clay = new Clay(clayConfig);
5 5
 var messageKeys = require('message_keys');
6 6
 
7 7
 var message;
8
-var gpx_to_strava = false;
9
-var gpx_to_web = true;
10 8
 
11 9
 var locationInterval;
12 10
 
13 11
 var firstlocationOptions = {
14
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
15
-    'timeout': 60000, //60s timeout to get a good signal
16
-    'maximumAge': 5 // no cache
12
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
13
+  'timeout': 60000, //60s timeout to get a good signal
14
+  'maximumAge': 5 // no cache
17 15
 };
18 16
 var locationOptions = {
19
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
20
-    'timeout': 5000, //5s timeout to get a good signal
21
-    'maximumAge': 5 // no cache
17
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
18
+  'timeout': 5000, //5s timeout to get a good signal
19
+  'maximumAge': 5 // no cache
22 20
 };
23
-var geoloc_id;
24 21
 
25 22
 // Store location in Pebble app local storage
26 23
 //
27 24
 function storeLocation(position) {
28
-    var latitude = position.coords.latitude;
29
-    var longitude = position.coords.longitude;
30
-    var timestamp = position.timestamp;
31
-    localStorage.setItem("latitude", latitude);
32
-    localStorage.setItem("longitude", longitude);
33
-    localStorage.setItem("timestamp", timestamp);
34
-    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
25
+  var latitude = position.coords.latitude;
26
+  var longitude = position.coords.longitude;
27
+  var timestamp = position.timestamp;
28
+  localStorage.setItem("latitude", latitude);
29
+  localStorage.setItem("longitude", longitude);
30
+  localStorage.setItem("timestamp", timestamp);
31
+  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
35 32
 }
36 33
 
37 34
 // Get location from Pebble app local storage
38 35
 //
39 36
 function getLocation() {
40
-    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
41
-        var la = localStorage.getItem("latitude");
42
-        var lo = localStorage.getItem("longitude");
43
-        var ti = localStorage.getItem("timestamp");
44
-        var co = { "latitude": la, "longitude": lo };
45
-        var pos = { "coords": co, "timestamp": ti };
46
-        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
47
-        return pos;
48
-    } else {
49
-        return null;
50
-    }
37
+  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
38
+    var la = localStorage.getItem("latitude");
39
+    var lo = localStorage.getItem("longitude");
40
+    var ti = localStorage.getItem("timestamp");
41
+    var co = { "latitude": la, "longitude": lo };
42
+    var pos = { "coords": co, "timestamp": ti };
43
+    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
44
+    return pos;
45
+  } else {
46
+    return null;
47
+  }
51 48
 }
52 49
 
53 50
 
... ...
@@ -55,390 +52,375 @@ function getLocation() {
55 52
 // IMPORTANT : this is a calculation from 2D projection, altitude is not involved
56 53
 //
57 54
 function distance_on_geoid(lat1, lon1, lat2, lon2) {
58
-    // Convert degrees to radians
59
-    lat1 = lat1 * Math.PI / 180.0;
60
-    lon1 = lon1 * Math.PI / 180.0;
61
-    lat2 = lat2 * Math.PI / 180.0;
62
-    lon2 = lon2 * Math.PI / 180.0;
63
-    // radius of earth in metres
64
-    r = 6378100;
65
-    // P
66
-    rho1 = r * Math.cos(lat1);
67
-    z1 = r * Math.sin(lat1);
68
-    x1 = rho1 * Math.cos(lon1);
69
-    y1 = rho1 * Math.sin(lon1);
70
-    // Q
71
-    rho2 = r * Math.cos(lat2);
72
-    z2 = r * Math.sin(lat2);
73
-    x2 = rho2 * Math.cos(lon2);
74
-    y2 = rho2 * Math.sin(lon2);
75
-    // Dot product
76
-    dot = (x1 * x2 + y1 * y2 + z1 * z2);
77
-    cos_theta = dot / (r * r);
78
-    theta = Math.acos(cos_theta);
79
-    // Distance in Metres
80
-    return r * theta;
55
+  // Convert degrees to radians
56
+  lat1 = lat1 * Math.PI / 180.0;
57
+  lon1 = lon1 * Math.PI / 180.0;
58
+  lat2 = lat2 * Math.PI / 180.0;
59
+  lon2 = lon2 * Math.PI / 180.0;
60
+  // radius of earth in metres
61
+  r = 6378100;
62
+  // P
63
+  rho1 = r * Math.cos(lat1);
64
+  z1 = r * Math.sin(lat1);
65
+  x1 = rho1 * Math.cos(lon1);
66
+  y1 = rho1 * Math.sin(lon1);
67
+  // Q
68
+  rho2 = r * Math.cos(lat2);
69
+  z2 = r * Math.sin(lat2);
70
+  x2 = rho2 * Math.cos(lon2);
71
+  y2 = rho2 * Math.sin(lon2);
72
+  // Dot product
73
+  dot = (x1 * x2 + y1 * y2 + z1 * z2);
74
+  cos_theta = dot / (r * r);
75
+  theta = Math.acos(cos_theta);
76
+  // Distance in Metres
77
+  return r * theta;
81 78
 }
82 79
 
83
-// Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
84
-//
85
-function speed_from_distance_and_time(p1, p2) {
86
-    dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
87
-    // timestamp is in milliseconds
88
-    time_s = (p2.timestamp - p1.timestamp) / 1000.0;
89
-    speed_mps = dist / time_s;
90
-    speed_kph = (speed_mps * 3600.0) / 1000.0;
91
-    return speed_kph;
92
-}
93 80
 
94 81
 // Get max speed of the run
95 82
 //
96 83
 function getMaxSpeed(lastSpeed) {
97
-    oldmax = localStorage.getItem("maxSpeed") || -1;
98
-    if (oldmax < lastSpeed) {
99
-        maxSpeed = lastSpeed
100
-    } else if (oldmax > lastSpeed) {
101
-        maxSpeed = oldmax
102
-    } else {
103
-        maxSpeed = oldmax
104
-    }
105
-    localStorage.setItem("maxSpeed", maxSpeed);
106
-    return maxSpeed
84
+  oldmax = localStorage.getItem("maxSpeed") || -1;
85
+  if (oldmax < lastSpeed) {
86
+    maxSpeed = lastSpeed
87
+  } else if (oldmax > lastSpeed) {
88
+    maxSpeed = oldmax
89
+  } else {
90
+    maxSpeed = oldmax
91
+  }
92
+  localStorage.setItem("maxSpeed", maxSpeed);
93
+  return maxSpeed
107 94
 }
108 95
 
109 96
 // split float number into an array of int (null returned instead of 0 for decimal)
110 97
 //
111 98
 function splitFloatNumber(num) {
112
-    const intStr = num.toString().split('.')[0];
113
-    const decimalStr = num.toString().split('.')[1];
114
-    return [Number(intStr), Number(decimalStr)];
99
+  const intStr = num.toString().split('.')[0];
100
+  const decimalStr = num.toString().split('.')[1];
101
+  return [Number(intStr), Number(decimalStr)];
115 102
 
116 103
 }
117 104
 
118 105
 // Build GPX headers
119 106
 //
120 107
 function GPXHeadersBuilder(timestamp, name, type) {
121
-    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
122
-    var ret = localStorage.setItem("GPX", headers);
123
-    return true;
108
+  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
109
+  var ret = localStorage.setItem("GPX", headers);
110
+  return true;
124 111
 }
125 112
 
126 113
 // Build GPX footer
127 114
 //
128 115
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
129
-    var GPX = localStorage.getItem("GPX");
130
-    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
131
-    localStorage.setItem("GPX", GPX + trkpt);
132
-    return true;
116
+  var GPX = localStorage.getItem("GPX");
117
+  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
118
+  localStorage.setItem("GPX", GPX + trkpt);
119
+  return true;
133 120
 }
134 121
 
135 122
 // Build GPX footer
136 123
 //
137 124
 function GPXfooterBuilder() {
138
-    var GPX = localStorage.getItem("GPX");
139
-    var footer = '</trkseg></trk></gpx>';
140
-    var ret = localStorage.setItem("GPX", GPX + footer);
141
-    //console.log("GPX closed : " + GPX + footer);
142
-    return ret;
125
+  var GPX = localStorage.getItem("GPX");
126
+  var footer = '</trkseg></trk></gpx>';
127
+  var ret = localStorage.setItem("GPX", GPX + footer);
128
+  //console.log("GPX closed : " + GPX + footer);
129
+  return ret;
143 130
 }
144 131
 
145 132
 // Send GPX to Strava profile
146 133
 // TODO : get authentication creds from settings
147 134
 function SendToStrava() {
148
-    console.log('--- GPX upload to strava');
149
-    var GPX = localStorage.getItem("GPX");
150
-
151
-
152
-    /* -------------------- */
153
-    var array = [GPX]; // an array consisting of a single string
154
-    var blob = new Blob(array, { type: "application/gpx+xml" }); // the blob
155
-
156
-    // creating multipart/form-data to be sent
157
-    var data = new FormData();
158
-    data.append("file", blob, "blob.gpx");
159
-    data.append("name", "test");
160
-    data.append("description", "testdesc");
161
-    data.append("data_type", "gpx");
162
-
163
-    var url = "https://www.strava.com/api/v3/uploads";
164
-    var xhr = new XMLHttpRequest();
165
-    xhr.withCredentials = true;
166
-    xhr.timeout = 10000; // time in milliseconds
167
-
168
-    xhr.open("POST", url, false);
169
-    xhr.setRequestHeader("Authorization", "Bearer d8927033b3996efe1e5a4e62425bc2aff8f635b0");
170
-
171
-    console.log('------GPX / xhr opened with authorization')
172
-    console.log('------array for blob: ' + array)
173
-    xhr.onload = function() {
174
-        console.log('------xhr onload')
175
-        if (xhr.readyState === 4) {
176
-            console.log('------xhr request returned with ' + xhr.status);
177
-            console.log(this.responseText);
178
-            if (xhr.status == 200) {
179
-                //console.log('--> HTTP 200');
180
-                return true;
181
-            } else {
182
-                //console.log('--> HTTP ' + xhr.status);
183
-                return false;
184
-            }
185
-        }
186
-    };
135
+  console.log('--- GPX upload to strava');
136
+  var GPX = localStorage.getItem("GPX");
137
+
138
+
139
+  /* -------------------- */
140
+  var array = [GPX]; // an array consisting of a single string
141
+  var blob = new Blob(array, { type: "application/gpx+xml" }); // the blob
142
+
143
+  // creating multipart/form-data to be sent
144
+  var data = new FormData();
145
+  data.append("file", blob, "blob.gpx");
146
+  data.append("name", "test");
147
+  data.append("description", "testdesc");
148
+  data.append("data_type", "gpx");
149
+
150
+  var url = "https://www.strava.com/api/v3/uploads";
151
+  var xhr = new XMLHttpRequest();
152
+  xhr.withCredentials = true;
153
+  xhr.timeout = 10000; // time in milliseconds
154
+
155
+  xhr.open("POST", url, false);
156
+  xhr.setRequestHeader("Authorization", "Bearer d8927033b3996efe1e5a4e62425bc2aff8f635b0");
157
+
158
+  console.log('------GPX / xhr opened with authorization')
159
+  console.log('------array for blob: ' + array)
160
+  xhr.onload = function () {
161
+    console.log('------xhr onload')
162
+    if (xhr.readyState === 4) {
163
+      console.log('------xhr request returned with ' + xhr.status);
164
+      console.log(this.responseText);
165
+      if (xhr.status == 200) {
166
+        localStorage.setItem("strava_uploaded", true);
167
+        //console.log('--> HTTP 200');
168
+        return true;
169
+      } else {
170
+        //console.log('--> HTTP ' + xhr.status);
171
+        return false;
172
+      }
173
+    }
174
+  };
187 175
 
188
-    // send with data in body
189
-    xhr.send(data);
190
-    /* -------------------- */
176
+  // send with data in body
177
+  xhr.send(data);
178
+  /* -------------------- */
191 179
 
192 180
 }
193 181
 
194 182
 
195
-// Build CSV
196
-function CSV(pos) {
197
-    var CSV = localStorage.getItem("CSV");
198
-    var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
199
-
200
-    localStorage.setItem("CSV", CSV + datapoint);
201
-
202
-}
203
-// Send CSV to web server (need configuration on serverside)
183
+// Send GPX to web server (need configuration on serverside)
204 184
 // TODO : secure it ?
205 185
 function PostToWeb() {
206
-    console.log('--- GPX upload to custom web server');
207
-    var GPX = localStorage.getItem("GPX");
208
-
209
-    var url = "https://jonget.fr/strava/upload.php?name=pebblegpx&type=application/gpx+xml";
210
-    var xhr = new XMLHttpRequest();
211
-    xhr.timeout = 10000; // time in milliseconds
212
-
213
-    xhr.open("POST", url, false);
214
-
215
-    //console.log('------ CSV / xhr opened')
216
-    xhr.onload = function() {
217
-        //console.log('------xhr onload')
218
-        if (xhr.readyState === 4) {
219
-            //console.log('------xhr request returned with ' + xhr.status);
220
-            //console.log(this.responseText);
221
-            if (xhr.status == 200) {
222
-                //console.log('--> HTTP 200');
223
-                return true;
224
-            } else {
225
-                //console.log('--> HTTP ' + xhr.status);
226
-                return false;
227
-            }
228
-        }
229
-    };
186
+  console.log('--- GPX upload to custom web server');
187
+  var GPX = localStorage.getItem("GPX");
188
+
189
+  var url = "https://jonget.fr/strava/upload.php?name=pebblegpx&type=application/gpx+xml";
190
+  var xhr = new XMLHttpRequest();
191
+  xhr.timeout = 10000; // time in milliseconds
192
+
193
+  xhr.open("POST", url, false);
194
+
195
+  //console.log('------ GPX / xhr opened')
196
+  xhr.onload = function () {
197
+    //console.log('------xhr onload')
198
+    if (xhr.readyState === 4) {
199
+      //console.log('------xhr request returned with ' + xhr.status);
200
+      //console.log(this.responseText);
201
+      if (xhr.status == 200) {
202
+        localStorage.setItem("custom_uploaded", true);
203
+        //console.log('--> HTTP 200');
204
+        return true;
205
+      } else {
206
+        //console.log('--> HTTP ' + xhr.status);
207
+        return false;
208
+      }
209
+    }
210
+  };
230 211
 
231
-    //send CSV in body
232
-    xhr.send(GPX);
212
+  //send GPX in body
213
+  xhr.send(GPX);
233 214
 
234 215
 }
235 216
 
236 217
 // Send location to web server for instant location (no tracking)
237 218
 // TODO : secure it ?
238 219
 function instantLocationUpdate(pos) {
239
-    console.log('--- Instant location update');
240
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
241
-
242
-    var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
243
-    var xhr = new XMLHttpRequest();
244
-    xhr.timeout = 10000; // time in milliseconds
245
-
246
-    xhr.open("POST", url);
247
-
248
-    //console.log('------ instant / xhr opened')
249
-    xhr.onload = function() {
250
-        //console.log('------xhr onload')
251
-        if (xhr.readyState === 4) {
252
-            //console.log('------xhr request returned with ' + xhr.status);
253
-            //console.log(this.responseText);
254
-            if (xhr.status == 200) {
255
-                //console.log('--> HTTP 200');
256
-                return true;
257
-            } else {
258
-                //console.log('--> HTTP ' + xhr.status);
259
-                return false;
260
-            }
261
-        }
262
-    };
220
+  console.log('--- Instant location update');
221
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
222
+
223
+  var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
224
+  var xhr = new XMLHttpRequest();
225
+  xhr.timeout = 10000; // time in milliseconds
226
+
227
+  xhr.open("POST", url, false);
228
+
229
+  //console.log('------ instant / xhr opened')
230
+  xhr.onload = function () {
231
+    //console.log('------xhr onload')
232
+    if (xhr.readyState === 4) {
233
+      //console.log('------xhr request returned with ' + xhr.status);
234
+      //console.log(this.responseText);
235
+      if (xhr.status == 200) {
236
+        //console.log('--> HTTP 200');
237
+        return true;
238
+      } else {
239
+        //console.log('--> HTTP ' + xhr.status);
240
+        return false;
241
+      }
242
+    }
243
+  };
263 244
 
264
-    //send without body
265
-    xhr.send();
245
+  //send without body
246
+  xhr.send();
266 247
 
267 248
 }
268 249
 
269 250
 
270
-// Adding leading characters to string for nice displays
271
-//
272
-function padStart(string, max_length, padding) {
273
-    if (string.length > max_length) {
274
-        return string;
275
-    } else {
276
-        var new_str = string;
277
-        for (index = string.length; index < max_length; index++) {
278
-            new_str = "0" + new_str;
279
-        }
280
-        return new_str;
281
-    }
282
-}
283
-
284 251
 // called in case of successful geoloc gathering and sends the coordinate to watch
285 252
 //
286 253
 function locationSuccess(new_pos) {
287
-    console.log('--- locationSuccess');
288
-    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
254
+  console.log('--- locationSuccess');
255
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
289 256
 
290
-    var prev_pos = getLocation();
291
-    storeLocation(new_pos);
292
-    if (prev_pos === null) {
293
-      console.log('--- start building gpx');
257
+  var prev_pos = getLocation();
258
+  storeLocation(new_pos);
259
+  if (prev_pos === null) {
260
+    console.log('--- start building gpx');
294 261
 
295
-      if (gpx_to_strava || gpx_to_web) {
296
-        // Start the GPX file
297
-        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
298
-      }
262
+    if (localStorage.getItem("strava_enabled") || localStorage.getItem("custom_enabled")) {
263
+      // Start the GPX file
264
+      GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
265
+    }
266
+  } else {
267
+    //clear watch of new position to avoid overlap
268
+    //navigator.geolocation.clearWatch(geoloc_id);
269
+    //console.log('--- watch geoloc cleared');
270
+    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
271
+
272
+    //get speed from geoloc API isntead of calculate it
273
+    // speed is initially in m/s, get it at km/h
274
+    if (new_pos.coords.speed === null) {
275
+      var speed = 0;
299 276
     } else {
300
-      //clear watch of new position to avoid overlap
301
-      //navigator.geolocation.clearWatch(geoloc_id);
302
-      //console.log('--- watch geoloc cleared');
303
-      //var speed = speed_from_distance_and_time(prev_pos, new_pos);
304
-
305
-      //get speed from geoloc API isntead of calculate it
306
-      // speed is initially in m/s, get it at km/h
307
-      if (new_pos.coords.speed === null) {
308
-        var speed = 0;
309
-      } else {
310
-        var speed = new_pos.coords.speed * 3.6;
311
-      }
312
-
313
-      // Prepare display on watch
314
-      // now it's only raw data
315
-      // init strings
316
-      var latitudeString = "";
317
-      var longitudeString = "";
318
-      var accuracyString = "";
319
-      var altitudeString = "";
320
-      var speedString = "";
321
-
322
-      //formating for precision and max size
323
-      latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
324
-      longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
325
-      accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
326
-      //console.log("split num : " + new_pos.coords.altitude);
327
-      altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
328
-      timestampISO = new Date(new_pos.timestamp).toISOString();
329
-      //console.log("split num : " + speed);
330
-      if (isNaN(speed)) {
331
-        speedString = "---";
332
-      } else {
333
-        speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
334
-        if (speedString == "0.N") {
335
-          speedString = "0.0";
336
-        }
277
+      var speed = new_pos.coords.speed * 3.6;
278
+    }
337 279
 
338
-        //console.log("split num : " + getMaxSpeed(speed));
339
-        maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
280
+    // Prepare display on watch
281
+    // now it's only raw data
282
+    // init strings
283
+    var latitudeString = "";
284
+    var longitudeString = "";
285
+    var accuracyString = "";
286
+    var altitudeString = "";
287
+    var speedString = "";
288
+
289
+    //formating for precision and max size
290
+    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
291
+    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
292
+    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
293
+    //console.log("split num : " + new_pos.coords.altitude);
294
+    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
295
+    timestampISO = new Date(new_pos.timestamp).toISOString();
296
+    //console.log("split num : " + speed);
297
+    if (isNaN(speed)) {
298
+      speedString = "---";
299
+    } else {
300
+      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
301
+      if (speedString == "0.N") {
302
+        speedString = "0.0";
340 303
       }
341
-      if (gpx_to_strava || gpx_to_web) {
342
-        //add a new datapoint to GPX file
343
-        GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
344 304
 
345
-      }
305
+      //console.log("split num : " + getMaxSpeed(speed));
306
+      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
307
+    }
308
+    if (localStorage.getItem("strava_enabled") || localStorage.getItem("custom_enabled")) {
309
+      //add a new datapoint to GPX file
310
+      GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
346 311
 
347
-      // Build message
348
-      message = "OK";
349
-      var dict = {
350
-        'accuracy': accuracyString,
351
-        'altitude': altitudeString,
352
-        'speed': speedString,
353
-        'max_speed': maxSpeedString,
354
-        'status': message
355
-      };
356
-
357
-      // Send the message
358
-      Pebble.sendAppMessage(dict, function () {
359
-        console.log('Message sent successfully: ' + JSON.stringify(dict));
360
-      }, function (e) {
361
-        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
362
-      });
363 312
     }
364 313
 
365
-}
314
+    // Build message
315
+    message = "OK";
316
+    var dict = {
317
+      'accuracy': accuracyString,
318
+      'altitude': altitudeString,
319
+      'speed': speedString,
320
+      'max_speed': maxSpeedString,
321
+      'status': message
322
+    };
366 323
 
367
-function locationError(err) {
324
+    // Send the message
325
+    Pebble.sendAppMessage(dict, function () {
326
+      console.log('Message sent successfully: ' + JSON.stringify(dict));
327
+    }, function (e) {
328
+      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
329
+    });
330
+  }
368 331
 
369
-    console.warn('location error (' + err.code + '): ' + err.message);
370
-    /*
371
-    if (gpx_to_web) {
332
+}
372 333
 
373
-        var CSV = localStorage.getItem("CSV");
374
-        var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
334
+function locationError(err) {
375 335
 
376
-        localStorage.setItem("CSV", CSV + datapoint);
377
-    }*/
336
+  console.warn('location error (' + err.code + '): ' + err.message);
378 337
 
379 338
 }
380 339
 
381 340
 
382 341
 function get_coordinate() {
383
-    console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
342
+  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
384 343
 
385
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
344
+  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
386 345
 
387
-    locationInterval = setInterval(function() {
388
-        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
389
-    }, 1000);
346
+  locationInterval = setInterval(function () {
347
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
348
+  }, 1000);
390 349
 
391
-    instantLocationInterval = setInterval(function() {
392
-        navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
393
-    }, 60000);
350
+  instantLocationInterval = setInterval(function () {
351
+    navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
352
+  }, 60000);
394 353
 
395 354
 }
396 355
 
397 356
 function init() {
398
-    // local storage init,
399
-    // todo : clear only temporary values, not clay config (and do it on exit ?)
400
-    localStorage.clear();
401
-    localStorage.setItem("CSV", "");
402
-    // clear any other var to do
403
-    clearInterval(locationInterval);
357
+  // local storage init,
358
+
359
+  //to be replaced by Clay settings :
360
+  localStorage.setItem("custom_enabled", true);
361
+  localStorage.setItem("strava_enabled", false);
362
+
363
+  var ce = localStorage.getItem("custom_uploaded");
364
+  var cu = localStorage.getItem("custom_enabled");
365
+  var se = localStorage.getItem("strava_uploaded");
366
+  var su = localStorage.getItem("strava_enabled");
367
+
368
+  if ((se && !su) || (ce && !cu)) {
369
+    if (ce) {
370
+      PostToWeb();
371
+    }
372
+    if (se) {
373
+      SendToStrava();
374
+    }
375
+  } else {
376
+    localStorage.setItem("GPX", "");
377
+    localStorage.setItem("maxSpeed", "");
378
+    localStorage.setItem("latitude", "");
379
+    localStorage.setItem("longitude", "");
380
+    localStorage.setItem("timestamp", "");
381
+    localStorage.setItem("custom_uploaded", false);
382
+    localStorage.setItem("strava_uploaded", false);
383
+  }
384
+  // clear any other var to do
385
+  clearInterval(locationInterval);
404 386
 
405 387
 }
406 388
 
407 389
 // Get JS readiness events
408
-Pebble.addEventListener('ready', function(e) {
409
-    console.log('PebbleKit JS is ready');
410
-    // Update Watch on this
411
-    Pebble.sendAppMessage({ 'JSReady': 1 });
390
+Pebble.addEventListener('ready', function (e) {
391
+  console.log('PebbleKit JS is ready');
392
+  // Update Watch on this
393
+  Pebble.sendAppMessage({ 'JSReady': 1 });
412 394
 
413
-    init();
395
+  init();
414 396
 });
415 397
 
416 398
 // Get AppMessage events
417
-Pebble.addEventListener('appmessage', function(e) {
418
-    // Get the dictionary from the message
419
-    var dict = e.payload;
420
-    //console.log(dict[0].toString());
421
-    switch (dict[0]) {
422
-        case 'get':
423
-            get_coordinate();
424
-            break;
425
-        case 'exit':
426
-            if (gpx_to_strava || gpx_to_web) {
427
-                //End GPX file
428
-                GPXfooterBuilder();
429
-                if (gpx_to_strava) {
430
-                    //send to strava through API
431
-                    SendToStrava();
432
-                }
433
-                if (gpx_to_web) {
434
-                    // send CSV to web server through API
435
-                    PostToWeb();
436
-                }
437
-            }
438
-
439
-            break;
440
-        default:
441
-            console.log('Sorry. I don\'t understand your request :' + dict[0]);
442
-    }
399
+Pebble.addEventListener('appmessage', function (e) {
400
+  // Get the dictionary from the message
401
+  var dict = e.payload;
402
+  //console.log(dict[0].toString());
403
+  switch (dict[0]) {
404
+    case 'get':
405
+      get_coordinate();
406
+      break;
407
+    case 'exit':
408
+      if (localStorage.getItem("strava_enabled") || localStorage.getItem("custom_enabled")) {
409
+        //End GPX file
410
+        GPXfooterBuilder();
411
+        if (localStorage.getItem("strava_enabled")) {
412
+          //send to strava through API
413
+          SendToStrava();
414
+        }
415
+        if (localStorage.getItem("custom_enabled")) {
416
+          // send GPX to web server through API
417
+          PostToWeb();
418
+        }
419
+      }
420
+
421
+      break;
422
+    default:
423
+      console.log('Sorry. I don\'t understand your request :' + dict[0]);
424
+  }
443 425
 
444 426
 });
445 427
\ No newline at end of file
Browse code

font and text layer tuning

louis.jonget authored on13/10/2022 15:01:07
Showing1 changed files
... ...
@@ -327,15 +327,17 @@ function locationSuccess(new_pos) {
327 327
       altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
328 328
       timestampISO = new Date(new_pos.timestamp).toISOString();
329 329
       //console.log("split num : " + speed);
330
-      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
331
-
332
-      //console.log("split num : " + getMaxSpeed(speed));
333
-      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
334
-
335
-      if (speedString == "NaN") {
330
+      if (isNaN(speed)) {
336 331
         speedString = "---";
337
-      }
332
+      } else {
333
+        speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
334
+        if (speedString == "0.N") {
335
+          speedString = "0.0";
336
+        }
338 337
 
338
+        //console.log("split num : " + getMaxSpeed(speed));
339
+        maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
340
+      }
339 341
       if (gpx_to_strava || gpx_to_web) {
340 342
         //add a new datapoint to GPX file
341 343
         GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
Browse code

font change and speed with 1 decimal

louis.jonget authored on13/10/2022 14:32:28
Showing1 changed files
... ...
@@ -290,74 +290,74 @@ function locationSuccess(new_pos) {
290 290
     var prev_pos = getLocation();
291 291
     storeLocation(new_pos);
292 292
     if (prev_pos === null) {
293
-        console.log('--- start building gpx');
293
+      console.log('--- start building gpx');
294 294
 
295
-        if (gpx_to_strava || gpx_to_web) {
296
-            // Start the GPX file
297
-            GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
298
-        }
295
+      if (gpx_to_strava || gpx_to_web) {
296
+        // Start the GPX file
297
+        GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
298
+      }
299 299
     } else {
300
-        //clear watch of new position to avoid overlap
301
-        //navigator.geolocation.clearWatch(geoloc_id);
302
-        //console.log('--- watch geoloc cleared');
303
-        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
304
-
305
-        //get speed from geoloc API isntead of calculate it
306
-        // speed is initially in m/s, get it at km/h
307
-        if (new_pos.coords.speed === null) {
308
-            var speed = 0;
309
-        } else {
310
-            var speed = new_pos.coords.speed * 3.6;
311
-        }
312
-
313
-        // Prepare display on watch
314
-        // now it's only raw data
315
-        // init strings
316
-        var latitudeString = "";
317
-        var longitudeString = "";
318
-        var accuracyString = "";
319
-        var altitudeString = "";
320
-        var speedString = "";
321
-
322
-        //formating for precision and max size
323
-        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
324
-        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
325
-        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
326
-        //console.log("split num : " + new_pos.coords.altitude);
327
-        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
328
-        timestampISO = new Date(new_pos.timestamp).toISOString();
329
-        //console.log("split num : " + speed);
330
-        speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
331
-
332
-        //console.log("split num : " + getMaxSpeed(speed));
333
-        maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
334
-
335
-        if (speedString == "NaN") {
336
-            speedString = "---";
337
-        }
338
-
339
-        if (gpx_to_strava || gpx_to_web) {
340
-            //add a new datapoint to GPX file
341
-            GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
342
-
343
-        }
344
-
345
-        // Build message
346
-        message = "OK";
347
-        var dict = {
348
-            'accuracy': accuracyString,
349
-            'altitude': altitudeString,
350
-            'speed': speedString,
351
-            'max_speed': maxSpeedString,
352
-            'status': message
353
-        };
354
-
355
-        // Send the message
356
-        Pebble.sendAppMessage(dict, function() {
357
-            console.log('Message sent successfully: ' + JSON.stringify(dict));
358
-        }, function(e) {
359
-            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
360
-        });
300
+      //clear watch of new position to avoid overlap
301
+      //navigator.geolocation.clearWatch(geoloc_id);
302
+      //console.log('--- watch geoloc cleared');
303
+      //var speed = speed_from_distance_and_time(prev_pos, new_pos);
304
+
305
+      //get speed from geoloc API isntead of calculate it
306
+      // speed is initially in m/s, get it at km/h
307
+      if (new_pos.coords.speed === null) {
308
+        var speed = 0;
309
+      } else {
310
+        var speed = new_pos.coords.speed * 3.6;
311
+      }
312
+
313
+      // Prepare display on watch
314
+      // now it's only raw data
315
+      // init strings
316
+      var latitudeString = "";
317
+      var longitudeString = "";
318
+      var accuracyString = "";
319
+      var altitudeString = "";
320
+      var speedString = "";
321
+
322
+      //formating for precision and max size
323
+      latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
324
+      longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
325
+      accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
326
+      //console.log("split num : " + new_pos.coords.altitude);
327
+      altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
328
+      timestampISO = new Date(new_pos.timestamp).toISOString();
329
+      //console.log("split num : " + speed);
330
+      speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
331
+
332
+      //console.log("split num : " + getMaxSpeed(speed));
333
+      maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
334
+
335
+      if (speedString == "NaN") {
336
+        speedString = "---";
337
+      }
338
+
339
+      if (gpx_to_strava || gpx_to_web) {
340
+        //add a new datapoint to GPX file
341
+        GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
342
+
343
+      }
344
+
345
+      // Build message
346
+      message = "OK";
347
+      var dict = {
348
+        'accuracy': accuracyString,
349
+        'altitude': altitudeString,
350
+        'speed': speedString,
351
+        'max_speed': maxSpeedString,
352
+        'status': message
353
+      };
354
+
355
+      // Send the message
356
+      Pebble.sendAppMessage(dict, function () {
357
+        console.log('Message sent successfully: ' + JSON.stringify(dict));
358
+      }, function (e) {
359
+        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
360
+      });
361 361
     }
362 362
 
363 363
 }
Browse code

switch post to web with gpx instead of CSV

Louis authored on12/10/2022 08:00:32
Showing1 changed files
... ...
@@ -6,48 +6,48 @@ var messageKeys = require('message_keys');
6 6
 
7 7
 var message;
8 8
 var gpx_to_strava = false;
9
-var csv_to_web = true;
9
+var gpx_to_web = true;
10 10
 
11 11
 var locationInterval;
12 12
 
13 13
 var firstlocationOptions = {
14
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
15
-  'timeout': 60000, //60s timeout to get a good signal
16
-  'maximumAge': 5 // no cache
14
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
15
+    'timeout': 60000, //60s timeout to get a good signal
16
+    'maximumAge': 5 // no cache
17 17
 };
18 18
 var locationOptions = {
19
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
20
-  'timeout': 5000, //5s timeout to get a good signal
21
-  'maximumAge': 5 // no cache
19
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
20
+    'timeout': 5000, //5s timeout to get a good signal
21
+    'maximumAge': 5 // no cache
22 22
 };
23 23
 var geoloc_id;
24 24
 
25 25
 // Store location in Pebble app local storage
26 26
 //
27 27
 function storeLocation(position) {
28
-  var latitude = position.coords.latitude;
29
-  var longitude = position.coords.longitude;
30
-  var timestamp = position.timestamp;
31
-  localStorage.setItem("latitude", latitude);
32
-  localStorage.setItem("longitude", longitude);
33
-  localStorage.setItem("timestamp", timestamp);
34
-  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
28
+    var latitude = position.coords.latitude;
29
+    var longitude = position.coords.longitude;
30
+    var timestamp = position.timestamp;
31
+    localStorage.setItem("latitude", latitude);
32
+    localStorage.setItem("longitude", longitude);
33
+    localStorage.setItem("timestamp", timestamp);
34
+    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
35 35
 }
36 36
 
37 37
 // Get location from Pebble app local storage
38 38
 //
39 39
 function getLocation() {
40
-  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
41
-    var la = localStorage.getItem("latitude");
42
-    var lo = localStorage.getItem("longitude");
43
-    var ti = localStorage.getItem("timestamp");
44
-    var co = { "latitude": la, "longitude": lo };
45
-    var pos = { "coords": co, "timestamp": ti };
46
-    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
47
-    return pos;
48
-  } else {
49
-    return null;
50
-  }
40
+    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
41
+        var la = localStorage.getItem("latitude");
42
+        var lo = localStorage.getItem("longitude");
43
+        var ti = localStorage.getItem("timestamp");
44
+        var co = { "latitude": la, "longitude": lo };
45
+        var pos = { "coords": co, "timestamp": ti };
46
+        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
47
+        return pos;
48
+    } else {
49
+        return null;
50
+    }
51 51
 }
52 52
 
53 53
 
... ...
@@ -55,214 +55,214 @@ function getLocation() {
55 55
 // IMPORTANT : this is a calculation from 2D projection, altitude is not involved
56 56
 //
57 57
 function distance_on_geoid(lat1, lon1, lat2, lon2) {
58
-  // Convert degrees to radians
59
-  lat1 = lat1 * Math.PI / 180.0;
60
-  lon1 = lon1 * Math.PI / 180.0;
61
-  lat2 = lat2 * Math.PI / 180.0;
62
-  lon2 = lon2 * Math.PI / 180.0;
63
-  // radius of earth in metres
64
-  r = 6378100;
65
-  // P
66
-  rho1 = r * Math.cos(lat1);
67
-  z1 = r * Math.sin(lat1);
68
-  x1 = rho1 * Math.cos(lon1);
69
-  y1 = rho1 * Math.sin(lon1);
70
-  // Q
71
-  rho2 = r * Math.cos(lat2);
72
-  z2 = r * Math.sin(lat2);
73
-  x2 = rho2 * Math.cos(lon2);
74
-  y2 = rho2 * Math.sin(lon2);
75
-  // Dot product
76
-  dot = (x1 * x2 + y1 * y2 + z1 * z2);
77
-  cos_theta = dot / (r * r);
78
-  theta = Math.acos(cos_theta);
79
-  // Distance in Metres
80
-  return r * theta;
58
+    // Convert degrees to radians
59
+    lat1 = lat1 * Math.PI / 180.0;
60
+    lon1 = lon1 * Math.PI / 180.0;
61
+    lat2 = lat2 * Math.PI / 180.0;
62
+    lon2 = lon2 * Math.PI / 180.0;
63
+    // radius of earth in metres
64
+    r = 6378100;
65
+    // P
66
+    rho1 = r * Math.cos(lat1);
67
+    z1 = r * Math.sin(lat1);
68
+    x1 = rho1 * Math.cos(lon1);
69
+    y1 = rho1 * Math.sin(lon1);
70
+    // Q
71
+    rho2 = r * Math.cos(lat2);
72
+    z2 = r * Math.sin(lat2);
73
+    x2 = rho2 * Math.cos(lon2);
74
+    y2 = rho2 * Math.sin(lon2);
75
+    // Dot product
76
+    dot = (x1 * x2 + y1 * y2 + z1 * z2);
77
+    cos_theta = dot / (r * r);
78
+    theta = Math.acos(cos_theta);
79
+    // Distance in Metres
80
+    return r * theta;
81 81
 }
82 82
 
83 83
 // Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
84 84
 //
85 85
 function speed_from_distance_and_time(p1, p2) {
86
-  dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
87
-  // timestamp is in milliseconds
88
-  time_s = (p2.timestamp - p1.timestamp) / 1000.0;
89
-  speed_mps = dist / time_s;
90
-  speed_kph = (speed_mps * 3600.0) / 1000.0;
91
-  return speed_kph;
86
+    dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
87
+    // timestamp is in milliseconds
88
+    time_s = (p2.timestamp - p1.timestamp) / 1000.0;
89
+    speed_mps = dist / time_s;
90
+    speed_kph = (speed_mps * 3600.0) / 1000.0;
91
+    return speed_kph;
92 92
 }
93 93
 
94 94
 // Get max speed of the run
95 95
 //
96 96
 function getMaxSpeed(lastSpeed) {
97
-  oldmax = localStorage.getItem("maxSpeed") || -1;
98
-  if (oldmax < lastSpeed) {
99
-    maxSpeed = lastSpeed
100
-  } else if (oldmax > lastSpeed) {
101
-    maxSpeed = oldmax
102
-  } else {
103
-    maxSpeed = oldmax
104
-  }
105
-  localStorage.setItem("maxSpeed", maxSpeed);
106
-  return maxSpeed
97
+    oldmax = localStorage.getItem("maxSpeed") || -1;
98
+    if (oldmax < lastSpeed) {
99
+        maxSpeed = lastSpeed
100
+    } else if (oldmax > lastSpeed) {
101
+        maxSpeed = oldmax
102
+    } else {
103
+        maxSpeed = oldmax
104
+    }
105
+    localStorage.setItem("maxSpeed", maxSpeed);
106
+    return maxSpeed
107 107
 }
108 108
 
109 109
 // split float number into an array of int (null returned instead of 0 for decimal)
110 110
 //
111 111
 function splitFloatNumber(num) {
112
-  const intStr = num.toString().split('.')[0];
113
-  const decimalStr = num.toString().split('.')[1];
114
-  return [Number(intStr), Number(decimalStr)];
112
+    const intStr = num.toString().split('.')[0];
113
+    const decimalStr = num.toString().split('.')[1];
114
+    return [Number(intStr), Number(decimalStr)];
115 115
 
116 116
 }
117 117
 
118 118
 // Build GPX headers
119 119
 //
120 120
 function GPXHeadersBuilder(timestamp, name, type) {
121
-  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
122
-  var ret = localStorage.setItem("GPX", headers);
123
-  return true;
121
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
122
+    var ret = localStorage.setItem("GPX", headers);
123
+    return true;
124 124
 }
125 125
 
126 126
 // Build GPX footer
127 127
 //
128 128
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
129
-  var GPX = localStorage.getItem("GPX");
130
-  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
131
-  localStorage.setItem("GPX", GPX + trkpt);
132
-  return true;
129
+    var GPX = localStorage.getItem("GPX");
130
+    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
131
+    localStorage.setItem("GPX", GPX + trkpt);
132
+    return true;
133 133
 }
134 134
 
135 135
 // Build GPX footer
136 136
 //
137 137
 function GPXfooterBuilder() {
138
-  var GPX = localStorage.getItem("GPX");
139
-  var footer = '</trkseg></trk></gpx>';
140
-  var ret = localStorage.setItem("GPX", GPX + footer);
141
-  //console.log("GPX closed : " + GPX + footer);
142
-  return ret;
138
+    var GPX = localStorage.getItem("GPX");
139
+    var footer = '</trkseg></trk></gpx>';
140
+    var ret = localStorage.setItem("GPX", GPX + footer);
141
+    //console.log("GPX closed : " + GPX + footer);
142
+    return ret;
143 143
 }
144 144
 
145 145
 // Send GPX to Strava profile
146 146
 // TODO : get authentication creds from settings
147 147
 function SendToStrava() {
148
-  console.log('--- GPX upload to strava');
149
-  var GPX = localStorage.getItem("GPX");
150
-
151
-
152
-  /* -------------------- */
153
-  var array = [GPX]; // an array consisting of a single string
154
-  var blob = new Blob(array, { type: "application/gpx+xml" }); // the blob
155
-
156
-  // creating multipart/form-data to be sent
157
-  var data = new FormData();
158
-  data.append("file", blob, "blob.gpx");
159
-  data.append("name", "test");
160
-  data.append("description", "testdesc");
161
-  data.append("data_type", "gpx");
162
-
163
-  var url = "https://www.strava.com/api/v3/uploads";
164
-  var xhr = new XMLHttpRequest();
165
-  xhr.withCredentials = true;
166
-  xhr.timeout = 10000; // time in milliseconds
167
-
168
-  xhr.open("POST", url, false);
169
-  xhr.setRequestHeader("Authorization", "Bearer d8927033b3996efe1e5a4e62425bc2aff8f635b0");
170
-
171
-  console.log('------GPX / xhr opened with authorization')
172
-  console.log('------array for blob: ' + array)
173
-  xhr.onload = function () {
174
-    console.log('------xhr onload')
175
-    if (xhr.readyState === 4) {
176
-      console.log('------xhr request returned with ' + xhr.status);
177
-      console.log(this.responseText);
178
-      if (xhr.status == 200) {
179
-        //console.log('--> HTTP 200');
180
-        return true;
181
-      } else {
182
-        //console.log('--> HTTP ' + xhr.status);
183
-        return false;
184
-      }
185
-    }
186
-  };
148
+    console.log('--- GPX upload to strava');
149
+    var GPX = localStorage.getItem("GPX");
150
+
151
+
152
+    /* -------------------- */
153
+    var array = [GPX]; // an array consisting of a single string
154
+    var blob = new Blob(array, { type: "application/gpx+xml" }); // the blob
155
+
156
+    // creating multipart/form-data to be sent
157
+    var data = new FormData();
158
+    data.append("file", blob, "blob.gpx");
159
+    data.append("name", "test");
160
+    data.append("description", "testdesc");
161
+    data.append("data_type", "gpx");
162
+
163
+    var url = "https://www.strava.com/api/v3/uploads";
164
+    var xhr = new XMLHttpRequest();
165
+    xhr.withCredentials = true;
166
+    xhr.timeout = 10000; // time in milliseconds
167
+
168
+    xhr.open("POST", url, false);
169
+    xhr.setRequestHeader("Authorization", "Bearer d8927033b3996efe1e5a4e62425bc2aff8f635b0");
170
+
171
+    console.log('------GPX / xhr opened with authorization')
172
+    console.log('------array for blob: ' + array)
173
+    xhr.onload = function() {
174
+        console.log('------xhr onload')
175
+        if (xhr.readyState === 4) {
176
+            console.log('------xhr request returned with ' + xhr.status);
177
+            console.log(this.responseText);
178
+            if (xhr.status == 200) {
179
+                //console.log('--> HTTP 200');
180
+                return true;
181
+            } else {
182
+                //console.log('--> HTTP ' + xhr.status);
183
+                return false;
184
+            }
185
+        }
186
+    };
187 187
 
188
-  // send with data in body
189
-  xhr.send(data);
190
-  /* -------------------- */
188
+    // send with data in body
189
+    xhr.send(data);
190
+    /* -------------------- */
191 191
 
192 192
 }
193 193
 
194 194
 
195 195
 // Build CSV
196 196
 function CSV(pos) {
197
-  var CSV = localStorage.getItem("CSV");
198
-  var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
197
+    var CSV = localStorage.getItem("CSV");
198
+    var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
199 199
 
200
-  localStorage.setItem("CSV", CSV + datapoint);
200
+    localStorage.setItem("CSV", CSV + datapoint);
201 201
 
202 202
 }
203 203
 // Send CSV to web server (need configuration on serverside)
204 204
 // TODO : secure it ?
205 205
 function PostToWeb() {
206
-  console.log('--- CSV upload to web');
207
-  var CSV = localStorage.getItem("CSV");
208
-
209
-  var url = "https://jonget.fr/strava/upload.php?name=pebblecsv&type=application/gpx+xml";
210
-  var xhr = new XMLHttpRequest();
211
-  xhr.timeout = 10000; // time in milliseconds
212
-
213
-  xhr.open("POST", url, false);
214
-
215
-  //console.log('------ CSV / xhr opened')
216
-  xhr.onload = function () {
217
-    //console.log('------xhr onload')
218
-    if (xhr.readyState === 4) {
219
-      //console.log('------xhr request returned with ' + xhr.status);
220
-      //console.log(this.responseText);
221
-      if (xhr.status == 200) {
222
-        //console.log('--> HTTP 200');
223
-        return true;
224
-      } else {
225
-        //console.log('--> HTTP ' + xhr.status);
226
-        return false;
227
-      }
228
-    }
229
-  };
206
+    console.log('--- GPX upload to custom web server');
207
+    var GPX = localStorage.getItem("GPX");
208
+
209
+    var url = "https://jonget.fr/strava/upload.php?name=pebblegpx&type=application/gpx+xml";
210
+    var xhr = new XMLHttpRequest();
211
+    xhr.timeout = 10000; // time in milliseconds
212
+
213
+    xhr.open("POST", url, false);
214
+
215
+    //console.log('------ CSV / xhr opened')
216
+    xhr.onload = function() {
217
+        //console.log('------xhr onload')
218
+        if (xhr.readyState === 4) {
219
+            //console.log('------xhr request returned with ' + xhr.status);
220
+            //console.log(this.responseText);
221
+            if (xhr.status == 200) {
222
+                //console.log('--> HTTP 200');
223
+                return true;
224
+            } else {
225
+                //console.log('--> HTTP ' + xhr.status);
226
+                return false;
227
+            }
228
+        }
229
+    };
230 230
 
231
-  //send CSV in body
232
-  xhr.send(CSV);
231
+    //send CSV in body
232
+    xhr.send(GPX);
233 233
 
234 234
 }
235 235
 
236 236
 // Send location to web server for instant location (no tracking)
237 237
 // TODO : secure it ?
238 238
 function instantLocationUpdate(pos) {
239
-  console.log('--- Instant location update');
240
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
241
-
242
-  var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
243
-  var xhr = new XMLHttpRequest();
244
-  xhr.timeout = 10000; // time in milliseconds
245
-
246
-  xhr.open("POST", url);
247
-
248
-  //console.log('------ instant / xhr opened')
249
-  xhr.onload = function () {
250
-    //console.log('------xhr onload')
251
-    if (xhr.readyState === 4) {
252
-      //console.log('------xhr request returned with ' + xhr.status);
253
-      //console.log(this.responseText);
254
-      if (xhr.status == 200) {
255
-        //console.log('--> HTTP 200');
256
-        return true;
257
-      } else {
258
-        //console.log('--> HTTP ' + xhr.status);
259
-        return false;
260
-      }
261
-    }
262
-  };
239
+    console.log('--- Instant location update');
240
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
241
+
242
+    var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
243
+    var xhr = new XMLHttpRequest();
244
+    xhr.timeout = 10000; // time in milliseconds
245
+
246
+    xhr.open("POST", url);
247
+
248
+    //console.log('------ instant / xhr opened')
249
+    xhr.onload = function() {
250
+        //console.log('------xhr onload')
251
+        if (xhr.readyState === 4) {
252
+            //console.log('------xhr request returned with ' + xhr.status);
253
+            //console.log(this.responseText);
254
+            if (xhr.status == 200) {
255
+                //console.log('--> HTTP 200');
256
+                return true;
257
+            } else {
258
+                //console.log('--> HTTP ' + xhr.status);
259
+                return false;
260
+            }
261
+        }
262
+    };
263 263
 
264
-  //send without body
265
-  xhr.send();
264
+    //send without body
265
+    xhr.send();
266 266
 
267 267
 }
268 268
 
... ...
@@ -270,179 +270,173 @@ function instantLocationUpdate(pos) {
270 270
 // Adding leading characters to string for nice displays
271 271
 //
272 272
 function padStart(string, max_length, padding) {
273
-  if (string.length > max_length) {
274
-    return string;
275
-  } else {
276
-    var new_str = string;
277
-    for (index = string.length; index < max_length; index++) {
278
-      new_str = "0" + new_str;
273
+    if (string.length > max_length) {
274
+        return string;
275
+    } else {
276
+        var new_str = string;
277
+        for (index = string.length; index < max_length; index++) {
278
+            new_str = "0" + new_str;
279
+        }
280
+        return new_str;
279 281
     }
280
-    return new_str;
281
-  }
282 282
 }
283 283
 
284 284
 // called in case of successful geoloc gathering and sends the coordinate to watch
285 285
 //
286 286
 function locationSuccess(new_pos) {
287
-  console.log('--- locationSuccess');
288
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
289
-
290
-  var prev_pos = getLocation();
291
-  storeLocation(new_pos);
292
-  if (prev_pos === null) {
293
-    console.log('--- start building gpx');
294
-
295
-    if (gpx_to_strava) {
296
-      // Start the GPX file
297
-      GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
298
-    }
299
-    if (csv_to_web) {
300
-      // Start the csv file
301
-      CSV(new_pos);
302
-    }
303
-  } else {
304
-    //clear watch of new position to avoid overlap
305
-    //navigator.geolocation.clearWatch(geoloc_id);
306
-    //console.log('--- watch geoloc cleared');
307
-    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
308
-
309
-    //get speed from geoloc API isntead of calculate it
310
-    // speed is initially in m/s, get it at km/h
311
-    if (new_pos.coords.speed === null) {
312
-      var speed = 0;
287
+    console.log('--- locationSuccess');
288
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
289
+
290
+    var prev_pos = getLocation();
291
+    storeLocation(new_pos);
292
+    if (prev_pos === null) {
293
+        console.log('--- start building gpx');
294
+
295
+        if (gpx_to_strava || gpx_to_web) {
296
+            // Start the GPX file
297
+            GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
298
+        }
313 299
     } else {
314
-      var speed = new_pos.coords.speed * 3.6;
315
-    }
316
-
317
-    // Prepare display on watch
318
-    // now it's only raw data
319
-    // init strings
320
-    var latitudeString = "";
321
-    var longitudeString = "";
322
-    var accuracyString = "";
323
-    var altitudeString = "";
324
-    var speedString = "";
325
-
326
-    //formating for precision and max size
327
-    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
328
-    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
329
-    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
330
-    //console.log("split num : " + new_pos.coords.altitude);
331
-    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
332
-    timestampISO = new Date(new_pos.timestamp).toISOString();
333
-    //console.log("split num : " + speed);
334
-    speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
335
-
336
-    //console.log("split num : " + getMaxSpeed(speed));
337
-    maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
338
-
339
-    if (speedString == "NaN") {
340
-      speedString = "---";
300
+        //clear watch of new position to avoid overlap
301
+        //navigator.geolocation.clearWatch(geoloc_id);
302
+        //console.log('--- watch geoloc cleared');
303
+        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
304
+
305
+        //get speed from geoloc API isntead of calculate it
306
+        // speed is initially in m/s, get it at km/h
307
+        if (new_pos.coords.speed === null) {
308
+            var speed = 0;
309
+        } else {
310
+            var speed = new_pos.coords.speed * 3.6;
311
+        }
312
+
313
+        // Prepare display on watch
314
+        // now it's only raw data
315
+        // init strings
316
+        var latitudeString = "";
317
+        var longitudeString = "";
318
+        var accuracyString = "";
319
+        var altitudeString = "";
320
+        var speedString = "";
321
+
322
+        //formating for precision and max size
323
+        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
324
+        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
325
+        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
326
+        //console.log("split num : " + new_pos.coords.altitude);
327
+        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
328
+        timestampISO = new Date(new_pos.timestamp).toISOString();
329
+        //console.log("split num : " + speed);
330
+        speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
331
+
332
+        //console.log("split num : " + getMaxSpeed(speed));
333
+        maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
334
+
335
+        if (speedString == "NaN") {
336
+            speedString = "---";
337
+        }
338
+
339
+        if (gpx_to_strava || gpx_to_web) {
340
+            //add a new datapoint to GPX file
341
+            GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
342
+
343
+        }
344
+
345
+        // Build message
346
+        message = "OK";
347
+        var dict = {
348
+            'accuracy': accuracyString,
349
+            'altitude': altitudeString,
350
+            'speed': speedString,
351
+            'max_speed': maxSpeedString,
352
+            'status': message
353
+        };
354
+
355
+        // Send the message
356
+        Pebble.sendAppMessage(dict, function() {
357
+            console.log('Message sent successfully: ' + JSON.stringify(dict));
358
+        }, function(e) {
359
+            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
360
+        });
341 361
     }
342 362
 
343
-    if (gpx_to_strava) {
344
-      //add a new datapoint to GPX file
345
-      GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
346
-      //console.log('GPX: ' + localStorage.getItem("GPX"));
347
-    }
348
-    if (csv_to_web) {
349
-      // Start the csv file
350
-      CSV(new_pos);
351
-      //console.log('CSV: ' + localStorage.getItem("CSV"));
352
-    }
353
-
354
-
355
-    // Build message
356
-    message = "OK";
357
-    var dict = {
358
-      'accuracy': accuracyString,
359
-      'altitude': altitudeString,
360
-      'speed': speedString,
361
-      'max_speed': maxSpeedString,
362
-      'status': message
363
-    };
364
-
365
-    // Send the message
366
-    Pebble.sendAppMessage(dict, function () {
367
-      console.log('Message sent successfully: ' + JSON.stringify(dict));
368
-    }, function (e) {
369
-      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
370
-    });
371
-  }
372
-
373 363
 }
374 364
 
375 365
 function locationError(err) {
376 366
 
377
-  console.warn('location error (' + err.code + '): ' + err.message);
378
-  if (csv_to_web) {
367
+    console.warn('location error (' + err.code + '): ' + err.message);
368
+    /*
369
+    if (gpx_to_web) {
379 370
 
380
-    var CSV = localStorage.getItem("CSV");
381
-    var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
371
+        var CSV = localStorage.getItem("CSV");
372
+        var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
382 373
 
383
-    localStorage.setItem("CSV", CSV + datapoint);
384
-  }
374
+        localStorage.setItem("CSV", CSV + datapoint);
375
+    }*/
385 376
 
386 377
 }
387 378
 
388 379
 
389 380
 function get_coordinate() {
390
-  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
381
+    console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
391 382
 
392
-  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
383
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
393 384
 
394
-  locationInterval = setInterval(function () {
395
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
396
-  }, 1000);
385
+    locationInterval = setInterval(function() {
386
+        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
387
+    }, 1000);
397 388
 
398
-  instantLocationInterval = setInterval(function () {
399
-    navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
400
-  }, 60000);
389
+    instantLocationInterval = setInterval(function() {
390
+        navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
391
+    }, 60000);
401 392
 
402 393
 }
403 394
 
404 395
 function init() {
405
-  // local storage init,
406
-  // todo : clear only temporary values, not clay config (and do it on exit ?)
407
-  localStorage.clear();
408
-  localStorage.setItem("CSV", "");
409
-  // clear any other var to do
410
-  clearInterval(locationInterval);
396
+    // local storage init,
397
+    // todo : clear only temporary values, not clay config (and do it on exit ?)
398
+    localStorage.clear();
399
+    localStorage.setItem("CSV", "");
400
+    // clear any other var to do
401
+    clearInterval(locationInterval);
411 402
 
412 403
 }
413 404
 
414 405
 // Get JS readiness events
415
-Pebble.addEventListener('ready', function (e) {
416
-  console.log('PebbleKit JS is ready');
417
-  // Update Watch on this
418
-  Pebble.sendAppMessage({ 'JSReady': 1 });
406
+Pebble.addEventListener('ready', function(e) {
407
+    console.log('PebbleKit JS is ready');
408
+    // Update Watch on this
409
+    Pebble.sendAppMessage({ 'JSReady': 1 });
419 410
 
420
-  init();
411
+    init();
421 412
 });
422 413
 
423 414
 // Get AppMessage events
424
-Pebble.addEventListener('appmessage', function (e) {
425
-  // Get the dictionary from the message
426
-  var dict = e.payload;
427
-  //console.log(dict[0].toString());
428
-  switch (dict[0]) {
429
-    case 'get':
430
-      get_coordinate();
431
-      break;
432
-    case 'exit':
433
-      if (gpx_to_strava) {
434
-        //End GPX file
435
-        GPXfooterBuilder();
436
-        //send to strava through API
437
-        SendToStrava();
438
-      }
439
-      if (csv_to_web) {
440
-        // send CSV to web server through API
441
-        PostToWeb();
442
-      }
443
-      break;
444
-    default:
445
-      console.log('Sorry. I don\'t understand your request :' + dict[0]);
446
-  }
415
+Pebble.addEventListener('appmessage', function(e) {
416
+    // Get the dictionary from the message
417
+    var dict = e.payload;
418
+    //console.log(dict[0].toString());
419
+    switch (dict[0]) {
420
+        case 'get':
421
+            get_coordinate();
422
+            break;
423
+        case 'exit':
424
+            if (gpx_to_strava || gpx_to_web) {
425
+                //End GPX file
426
+                GPXfooterBuilder();
427
+                if (gpx_to_strava) {
428
+                    //send to strava through API
429
+                    SendToStrava();
430
+                }
431
+                if (gpx_to_web) {
432
+                    // send CSV to web server through API
433
+                    PostToWeb();
434
+                }
435
+            }
436
+
437
+            break;
438
+        default:
439
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
440
+    }
447 441
 
448
-});
442
+});
449 443
\ No newline at end of file
Browse code

adding Strava API workflow && clearing UI

louis.jonget authored on11/10/2022 14:46:45
Showing1 changed files
... ...
@@ -8,7 +8,6 @@ var message;
8 8
 var gpx_to_strava = false;
9 9
 var csv_to_web = true;
10 10
 
11
-var firstlocationInterval;
12 11
 var locationInterval;
13 12
 
14 13
 var firstlocationOptions = {
... ...
@@ -129,7 +128,7 @@ function GPXHeadersBuilder(timestamp, name, type) {
129 128
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
130 129
   var GPX = localStorage.getItem("GPX");
131 130
   var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
132
-  var ret = localStorage.setItem("GPX", GPX + trkpt);
131
+  localStorage.setItem("GPX", GPX + trkpt);
133 132
   return true;
134 133
 }
135 134
 
... ...
@@ -139,13 +138,14 @@ function GPXfooterBuilder() {
139 138
   var GPX = localStorage.getItem("GPX");
140 139
   var footer = '</trkseg></trk></gpx>';
141 140
   var ret = localStorage.setItem("GPX", GPX + footer);
142
-  console.log("GPX closed : " + GPX + footer);
141
+  //console.log("GPX closed : " + GPX + footer);
143 142
   return ret;
144 143
 }
145 144
 
146 145
 // Send GPX to Strava profile
147 146
 // TODO : get authentication creds from settings
148 147
 function SendToStrava() {
148
+  console.log('--- GPX upload to strava');
149 149
   var GPX = localStorage.getItem("GPX");
150 150
 
151 151
 
... ...
@@ -203,20 +203,21 @@ function CSV(pos) {
203 203
 // Send CSV to web server (need configuration on serverside)
204 204
 // TODO : secure it ?
205 205
 function PostToWeb() {
206
+  console.log('--- CSV upload to web');
206 207
   var CSV = localStorage.getItem("CSV");
207 208
 
208
-  var url = "https://jonget.fr/strava/upload.php?name=pebblecsv&type=gpx/xml";
209
+  var url = "https://jonget.fr/strava/upload.php?name=pebblecsv&type=application/gpx+xml";
209 210
   var xhr = new XMLHttpRequest();
210 211
   xhr.timeout = 10000; // time in milliseconds
211 212
 
212 213
   xhr.open("POST", url, false);
213 214
 
214
-  console.log('------ CSV / xhr opened')
215
+  //console.log('------ CSV / xhr opened')
215 216
   xhr.onload = function () {
216
-    console.log('------xhr onload')
217
+    //console.log('------xhr onload')
217 218
     if (xhr.readyState === 4) {
218
-      console.log('------xhr request returned with ' + xhr.status);
219
-      console.log(this.responseText);
219
+      //console.log('------xhr request returned with ' + xhr.status);
220
+      //console.log(this.responseText);
220 221
       if (xhr.status == 200) {
221 222
         //console.log('--> HTTP 200');
222 223
         return true;
... ...
@@ -235,7 +236,6 @@ function PostToWeb() {
235 236
 // Send location to web server for instant location (no tracking)
236 237
 // TODO : secure it ?
237 238
 function instantLocationUpdate(pos) {
238
-
239 239
   console.log('--- Instant location update');
240 240
   // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
241 241
 
... ...
@@ -245,12 +245,12 @@ function instantLocationUpdate(pos) {
245 245
 
246 246
   xhr.open("POST", url);
247 247
 
248
-  console.log('------ instant / xhr opened')
248
+  //console.log('------ instant / xhr opened')
249 249
   xhr.onload = function () {
250
-    console.log('------xhr onload')
250
+    //console.log('------xhr onload')
251 251
     if (xhr.readyState === 4) {
252
-      console.log('------xhr request returned with ' + xhr.status);
253
-      console.log(this.responseText);
252
+      //console.log('------xhr request returned with ' + xhr.status);
253
+      //console.log(this.responseText);
254 254
       if (xhr.status == 200) {
255 255
         //console.log('--> HTTP 200');
256 256
         return true;
... ...
@@ -343,12 +343,12 @@ function locationSuccess(new_pos) {
343 343
     if (gpx_to_strava) {
344 344
       //add a new datapoint to GPX file
345 345
       GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
346
-      console.log('GPX: ' + localStorage.getItem("GPX"));
346
+      //console.log('GPX: ' + localStorage.getItem("GPX"));
347 347
     }
348 348
     if (csv_to_web) {
349 349
       // Start the csv file
350 350
       CSV(new_pos);
351
-      console.log('CSV: ' + localStorage.getItem("CSV"));
351
+      //console.log('CSV: ' + localStorage.getItem("CSV"));
352 352
     }
353 353
 
354 354
 
... ...
@@ -370,13 +370,9 @@ function locationSuccess(new_pos) {
370 370
     });
371 371
   }
372 372
 
373
-  // restart the watch
374
-  //geoloc_id = navigator.geolocation.watchPosition(locationSuccess, locationError, locationOptions);
375 373
 }
376 374
 
377 375
 function locationError(err) {
378
-  //clear watch of new position to avoid overlap
379
-  //navigator.geolocation.clearWatch(geoloc_id);
380 376
 
381 377
   console.warn('location error (' + err.code + '): ' + err.message);
382 378
   if (csv_to_web) {
... ...
@@ -387,8 +383,6 @@ function locationError(err) {
387 383
     localStorage.setItem("CSV", CSV + datapoint);
388 384
   }
389 385
 
390
-  // restart the watch
391
-  //geoloc_id = navigator.geolocation.watchPosition(locationSuccess, locationError, locationOptions);
392 386
 }
393 387
 
394 388
 
... ...
@@ -399,7 +393,7 @@ function get_coordinate() {
399 393
 
400 394
   locationInterval = setInterval(function () {
401 395
     navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
402
-  }, 5000);
396
+  }, 1000);
403 397
 
404 398
   instantLocationInterval = setInterval(function () {
405 399
     navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
... ...
@@ -430,7 +424,7 @@ Pebble.addEventListener('ready', function (e) {
430 424
 Pebble.addEventListener('appmessage', function (e) {
431 425
   // Get the dictionary from the message
432 426
   var dict = e.payload;
433
-  console.log(dict[0].toString());
427
+  //console.log(dict[0].toString());
434 428
   switch (dict[0]) {
435 429
     case 'get':
436 430
       get_coordinate();
... ...
@@ -443,7 +437,6 @@ Pebble.addEventListener('appmessage', function (e) {
443 437
         SendToStrava();
444 438
       }
445 439
       if (csv_to_web) {
446
-        //CSV(new_pos);
447 440
         // send CSV to web server through API
448 441
         PostToWeb();
449 442
       }
Browse code

added instant location for "find_me" webpage

louis.jonget authored on10/10/2022 15:49:15
Showing1 changed files
... ...
@@ -151,7 +151,6 @@ function SendToStrava() {
151 151
 
152 152
   /* -------------------- */
153 153
   var array = [GPX]; // an array consisting of a single string
154
-  console.log('------array for blob: ' + array)
155 154
   var blob = new Blob(array, { type: "application/gpx+xml" }); // the blob
156 155
 
157 156
   // creating multipart/form-data to be sent
... ...
@@ -169,7 +168,8 @@ function SendToStrava() {
169 168
   xhr.open("POST", url, false);
170 169
   xhr.setRequestHeader("Authorization", "Bearer d8927033b3996efe1e5a4e62425bc2aff8f635b0");
171 170
 
172
-  console.log('------xhr opened with authorization')
171
+  console.log('------GPX / xhr opened with authorization')
172
+  console.log('------array for blob: ' + array)
173 173
   xhr.onload = function () {
174 174
     console.log('------xhr onload')
175 175
     if (xhr.readyState === 4) {
... ...
@@ -185,6 +185,7 @@ function SendToStrava() {
185 185
     }
186 186
   };
187 187
 
188
+  // send with data in body
188 189
   xhr.send(data);
189 190
   /* -------------------- */
190 191
 
... ...
@@ -194,7 +195,7 @@ function SendToStrava() {
194 195
 // Build CSV
195 196
 function CSV(pos) {
196 197
   var CSV = localStorage.getItem("CSV");
197
-  var datapoint = pos.timestamp + "," + pos.coords.lat + "," + pos.coords.long + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed;
198
+  var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
198 199
 
199 200
   localStorage.setItem("CSV", CSV + datapoint);
200 201
 
... ...
@@ -204,13 +205,13 @@ function CSV(pos) {
204 205
 function PostToWeb() {
205 206
   var CSV = localStorage.getItem("CSV");
206 207
 
207
-  var url = "https://192.168.170.33/strava/upload.php";
208
+  var url = "https://jonget.fr/strava/upload.php?name=pebblecsv&type=gpx/xml";
208 209
   var xhr = new XMLHttpRequest();
209 210
   xhr.timeout = 10000; // time in milliseconds
210 211
 
211 212
   xhr.open("POST", url, false);
212 213
 
213
-  console.log('------xhr opened')
214
+  console.log('------ CSV / xhr opened')
214 215
   xhr.onload = function () {
215 216
     console.log('------xhr onload')
216 217
     if (xhr.readyState === 4) {
... ...
@@ -231,6 +232,40 @@ function PostToWeb() {
231 232
 
232 233
 }
233 234
 
235
+// Send location to web server for instant location (no tracking)
236
+// TODO : secure it ?
237
+function instantLocationUpdate(pos) {
238
+
239
+  console.log('--- Instant location update');
240
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
241
+
242
+  var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
243
+  var xhr = new XMLHttpRequest();
244
+  xhr.timeout = 10000; // time in milliseconds
245
+
246
+  xhr.open("POST", url);
247
+
248
+  console.log('------ instant / xhr opened')
249
+  xhr.onload = function () {
250
+    console.log('------xhr onload')
251
+    if (xhr.readyState === 4) {
252
+      console.log('------xhr request returned with ' + xhr.status);
253
+      console.log(this.responseText);
254
+      if (xhr.status == 200) {
255
+        //console.log('--> HTTP 200');
256
+        return true;
257
+      } else {
258
+        //console.log('--> HTTP ' + xhr.status);
259
+        return false;
260
+      }
261
+    }
262
+  };
263
+
264
+  //send without body
265
+  xhr.send();
266
+
267
+}
268
+
234 269
 
235 270
 // Adding leading characters to string for nice displays
236 271
 //
... ...
@@ -250,7 +285,7 @@ function padStart(string, max_length, padding) {
250 285
 //
251 286
 function locationSuccess(new_pos) {
252 287
   console.log('--- locationSuccess');
253
-  console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
288
+  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
254 289
 
255 290
   var prev_pos = getLocation();
256 291
   storeLocation(new_pos);
... ...
@@ -269,7 +304,15 @@ function locationSuccess(new_pos) {
269 304
     //clear watch of new position to avoid overlap
270 305
     //navigator.geolocation.clearWatch(geoloc_id);
271 306
     //console.log('--- watch geoloc cleared');
272
-    var speed = speed_from_distance_and_time(prev_pos, new_pos);
307
+    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
308
+
309
+    //get speed from geoloc API isntead of calculate it
310
+    // speed is initially in m/s, get it at km/h
311
+    if (new_pos.coords.speed === null) {
312
+      var speed = 0;
313
+    } else {
314
+      var speed = new_pos.coords.speed * 3.6;
315
+    }
273 316
 
274 317
     // Prepare display on watch
275 318
     // now it's only raw data
... ...
@@ -300,13 +343,14 @@ function locationSuccess(new_pos) {
300 343
     if (gpx_to_strava) {
301 344
       //add a new datapoint to GPX file
302 345
       GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
346
+      console.log('GPX: ' + localStorage.getItem("GPX"));
303 347
     }
304 348
     if (csv_to_web) {
305 349
       // Start the csv file
306 350
       CSV(new_pos);
351
+      console.log('CSV: ' + localStorage.getItem("CSV"));
307 352
     }
308 353
 
309
-    console.log('GPX: ' + localStorage.getItem("GPX"));
310 354
 
311 355
     // Build message
312 356
     message = "OK";
... ...
@@ -357,12 +401,17 @@ function get_coordinate() {
357 401
     navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
358 402
   }, 5000);
359 403
 
404
+  instantLocationInterval = setInterval(function () {
405
+    navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
406
+  }, 60000);
407
+
360 408
 }
361 409
 
362 410
 function init() {
363 411
   // local storage init,
364 412
   // todo : clear only temporary values, not clay config (and do it on exit ?)
365 413
   localStorage.clear();
414
+  localStorage.setItem("CSV", "");
366 415
   // clear any other var to do
367 416
   clearInterval(locationInterval);
368 417
 
Browse code

csv to web function and specific timeout for first get location

louis.jonget authored on10/10/2022 10:33:01
Showing1 changed files
... ...
@@ -5,12 +5,21 @@ var clay = new Clay(clayConfig);
5 5
 var messageKeys = require('message_keys');
6 6
 
7 7
 var message;
8
+var gpx_to_strava = false;
9
+var csv_to_web = true;
8 10
 
9
-//var locationInterval;
11
+var firstlocationInterval;
12
+var locationInterval;
13
+
14
+var firstlocationOptions = {
15
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
16
+  'timeout': 60000, //60s timeout to get a good signal
17
+  'maximumAge': 5 // no cache
18
+};
10 19
 var locationOptions = {
11 20
   'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
12
-  'timeout': 5000, //2s timeout
13
-  'maximumAge': 0 // no cache
21
+  'timeout': 5000, //5s timeout to get a good signal
22
+  'maximumAge': 5 // no cache
14 23
 };
15 24
 var geoloc_id;
16 25
 
... ...
@@ -83,12 +92,28 @@ function speed_from_distance_and_time(p1, p2) {
83 92
   return speed_kph;
84 93
 }
85 94
 
95
+// Get max speed of the run
96
+//
97
+function getMaxSpeed(lastSpeed) {
98
+  oldmax = localStorage.getItem("maxSpeed") || -1;
99
+  if (oldmax < lastSpeed) {
100
+    maxSpeed = lastSpeed
101
+  } else if (oldmax > lastSpeed) {
102
+    maxSpeed = oldmax
103
+  } else {
104
+    maxSpeed = oldmax
105
+  }
106
+  localStorage.setItem("maxSpeed", maxSpeed);
107
+  return maxSpeed
108
+}
109
+
86 110
 // split float number into an array of int (null returned instead of 0 for decimal)
87 111
 //
88 112
 function splitFloatNumber(num) {
89 113
   const intStr = num.toString().split('.')[0];
90 114
   const decimalStr = num.toString().split('.')[1];
91 115
   return [Number(intStr), Number(decimalStr)];
116
+
92 117
 }
93 118
 
94 119
 // Build GPX headers
... ...
@@ -114,9 +139,99 @@ function GPXfooterBuilder() {
114 139
   var GPX = localStorage.getItem("GPX");
115 140
   var footer = '</trkseg></trk></gpx>';
116 141
   var ret = localStorage.setItem("GPX", GPX + footer);
117
-  return true;
142
+  console.log("GPX closed : " + GPX + footer);
143
+  return ret;
144
+}
145
+
146
+// Send GPX to Strava profile
147
+// TODO : get authentication creds from settings
148
+function SendToStrava() {
149
+  var GPX = localStorage.getItem("GPX");
150
+
151
+
152
+  /* -------------------- */
153
+  var array = [GPX]; // an array consisting of a single string
154
+  console.log('------array for blob: ' + array)
155
+  var blob = new Blob(array, { type: "application/gpx+xml" }); // the blob
156
+
157
+  // creating multipart/form-data to be sent
158
+  var data = new FormData();
159
+  data.append("file", blob, "blob.gpx");
160
+  data.append("name", "test");
161
+  data.append("description", "testdesc");
162
+  data.append("data_type", "gpx");
163
+
164
+  var url = "https://www.strava.com/api/v3/uploads";
165
+  var xhr = new XMLHttpRequest();
166
+  xhr.withCredentials = true;
167
+  xhr.timeout = 10000; // time in milliseconds
168
+
169
+  xhr.open("POST", url, false);
170
+  xhr.setRequestHeader("Authorization", "Bearer d8927033b3996efe1e5a4e62425bc2aff8f635b0");
171
+
172
+  console.log('------xhr opened with authorization')
173
+  xhr.onload = function () {
174
+    console.log('------xhr onload')
175
+    if (xhr.readyState === 4) {
176
+      console.log('------xhr request returned with ' + xhr.status);
177
+      console.log(this.responseText);
178
+      if (xhr.status == 200) {
179
+        //console.log('--> HTTP 200');
180
+        return true;
181
+      } else {
182
+        //console.log('--> HTTP ' + xhr.status);
183
+        return false;
184
+      }
185
+    }
186
+  };
187
+
188
+  xhr.send(data);
189
+  /* -------------------- */
190
+
118 191
 }
119 192
 
193
+
194
+// Build CSV
195
+function CSV(pos) {
196
+  var CSV = localStorage.getItem("CSV");
197
+  var datapoint = pos.timestamp + "," + pos.coords.lat + "," + pos.coords.long + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed;
198
+
199
+  localStorage.setItem("CSV", CSV + datapoint);
200
+
201
+}
202
+// Send CSV to web server (need configuration on serverside)
203
+// TODO : secure it ?
204
+function PostToWeb() {
205
+  var CSV = localStorage.getItem("CSV");
206
+
207
+  var url = "https://192.168.170.33/strava/upload.php";
208
+  var xhr = new XMLHttpRequest();
209
+  xhr.timeout = 10000; // time in milliseconds
210
+
211
+  xhr.open("POST", url, false);
212
+
213
+  console.log('------xhr opened')
214
+  xhr.onload = function () {
215
+    console.log('------xhr onload')
216
+    if (xhr.readyState === 4) {
217
+      console.log('------xhr request returned with ' + xhr.status);
218
+      console.log(this.responseText);
219
+      if (xhr.status == 200) {
220
+        //console.log('--> HTTP 200');
221
+        return true;
222
+      } else {
223
+        //console.log('--> HTTP ' + xhr.status);
224
+        return false;
225
+      }
226
+    }
227
+  };
228
+
229
+  //send CSV in body
230
+  xhr.send(CSV);
231
+
232
+}
233
+
234
+
120 235
 // Adding leading characters to string for nice displays
121 236
 //
122 237
 function padStart(string, max_length, padding) {
... ...
@@ -141,8 +256,15 @@ function locationSuccess(new_pos) {
141 256
   storeLocation(new_pos);
142 257
   if (prev_pos === null) {
143 258
     console.log('--- start building gpx');
144
-    // Start the GPX file
145
-    GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
259
+
260
+    if (gpx_to_strava) {
261
+      // Start the GPX file
262
+      GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
263
+    }
264
+    if (csv_to_web) {
265
+      // Start the csv file
266
+      CSV(new_pos);
267
+    }
146 268
   } else {
147 269
     //clear watch of new position to avoid overlap
148 270
     //navigator.geolocation.clearWatch(geoloc_id);
... ...
@@ -162,16 +284,27 @@ function locationSuccess(new_pos) {
162 284
     latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
163 285
     longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
164 286
     accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
287
+    //console.log("split num : " + new_pos.coords.altitude);
165 288
     altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
166 289
     timestampISO = new Date(new_pos.timestamp).toISOString();
167
-    speedString = speed.toString().substring(0, 5);
290
+    //console.log("split num : " + speed);
291
+    speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
292
+
293
+    //console.log("split num : " + getMaxSpeed(speed));
294
+    maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
168 295
 
169 296
     if (speedString == "NaN") {
170 297
       speedString = "---";
171 298
     }
172 299
 
173
-    //add a new datapoint to GPX file
174
-    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
300
+    if (gpx_to_strava) {
301
+      //add a new datapoint to GPX file
302
+      GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
303
+    }
304
+    if (csv_to_web) {
305
+      // Start the csv file
306
+      CSV(new_pos);
307
+    }
175 308
 
176 309
     console.log('GPX: ' + localStorage.getItem("GPX"));
177 310
 
... ...
@@ -181,6 +314,7 @@ function locationSuccess(new_pos) {
181 314
       'accuracy': accuracyString,
182 315
       'altitude': altitudeString,
183 316
       'speed': speedString,
317
+      'max_speed': maxSpeedString,
184 318
       'status': message
185 319
     };
186 320
 
... ...
@@ -201,29 +335,36 @@ function locationError(err) {
201 335
   //navigator.geolocation.clearWatch(geoloc_id);
202 336
 
203 337
   console.warn('location error (' + err.code + '): ' + err.message);
338
+  if (csv_to_web) {
339
+
340
+    var CSV = localStorage.getItem("CSV");
341
+    var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
342
+
343
+    localStorage.setItem("CSV", CSV + datapoint);
344
+  }
204 345
 
205 346
   // restart the watch
206 347
   //geoloc_id = navigator.geolocation.watchPosition(locationSuccess, locationError, locationOptions);
207 348
 }
208 349
 
209
-function get_coordinate() {
210
-  /*console.log('---- start geoloc');
211
-  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
212
-  */
213
-}
214 350
 
215
-function init() {
216
-  // local storage init
217
-  localStorage.clear();
218
-  // clear any other var to do
219
-  //clearInterval(locationInterval);
351
+function get_coordinate() {
352
+  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
220 353
 
354
+  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
221 355
 
222
-  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
223 356
   locationInterval = setInterval(function () {
224 357
     navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
225 358
   }, 5000);
226 359
 
360
+}
361
+
362
+function init() {
363
+  // local storage init,
364
+  // todo : clear only temporary values, not clay config (and do it on exit ?)
365
+  localStorage.clear();
366
+  // clear any other var to do
367
+  clearInterval(locationInterval);
227 368
 
228 369
 }
229 370
 
... ...
@@ -245,6 +386,19 @@ Pebble.addEventListener('appmessage', function (e) {
245 386
     case 'get':
246 387
       get_coordinate();
247 388
       break;
389
+    case 'exit':
390
+      if (gpx_to_strava) {
391
+        //End GPX file
392
+        GPXfooterBuilder();
393
+        //send to strava through API
394
+        SendToStrava();
395
+      }
396
+      if (csv_to_web) {
397
+        //CSV(new_pos);
398
+        // send CSV to web server through API
399
+        PostToWeb();
400
+      }
401
+      break;
248 402
     default:
249 403
       console.log('Sorry. I don\'t understand your request :' + dict[0]);
250 404
   }
Browse code

small updates 3

louis.jonget authored on03/10/2022 16:35:17
Showing1 changed files
... ...
@@ -6,12 +6,13 @@ var messageKeys = require('message_keys');
6 6
 
7 7
 var message;
8 8
 
9
-var locationInterval;
9
+//var locationInterval;
10 10
 var locationOptions = {
11 11
   'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
12
-  'timeout': 2000, //2s timeout
13
-  'maximumAge': 1000 // 1s cache
12
+  'timeout': 5000, //2s timeout
13
+  'maximumAge': 0 // no cache
14 14
 };
15
+var geoloc_id;
15 16
 
16 17
 // Store location in Pebble app local storage
17 18
 //
... ...
@@ -133,23 +134,28 @@ function padStart(string, max_length, padding) {
133 134
 // called in case of successful geoloc gathering and sends the coordinate to watch
134 135
 //
135 136
 function locationSuccess(new_pos) {
137
+  console.log('--- locationSuccess');
138
+  console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
139
+
136 140
   var prev_pos = getLocation();
137 141
   storeLocation(new_pos);
138 142
   if (prev_pos === null) {
139
-    GPXHeadersBuilder(timestampISO = new Date(new_pos.timestamp).toISOString(), "test", "18");
140
-    return null;
143
+    console.log('--- start building gpx');
144
+    // Start the GPX file
145
+    GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
141 146
   } else {
147
+    //clear watch of new position to avoid overlap
148
+    //navigator.geolocation.clearWatch(geoloc_id);
149
+    //console.log('--- watch geoloc cleared');
142 150
     var speed = speed_from_distance_and_time(prev_pos, new_pos);
143 151
 
144 152
     // Prepare display on watch
145 153
     // now it's only raw data
146
-    //init strings
154
+    // init strings
147 155
     var latitudeString = "";
148 156
     var longitudeString = "";
149 157
     var accuracyString = "";
150 158
     var altitudeString = "";
151
-    //var altitudeAccuracyString = "";
152
-    //var timestampString = "";
153 159
     var speedString = "";
154 160
 
155 161
     //formating for precision and max size
... ...
@@ -163,12 +169,8 @@ function locationSuccess(new_pos) {
163 169
     if (speedString == "NaN") {
164 170
       speedString = "---";
165 171
     }
166
-    // logging
167
-    /*console.log('Your current position at ' + timestampString + ' is:');
168
-    console.log('Coordinates: ' + latitudeString+ ', ' + longitudeString+' ; with a ' + accuracyString + 'm accuracy');
169
-    console.log('Altitude: ' + altitudeString + 'm ; with a ' + altitudeAccuracyString + 'm accuracy');
170
-    console.log('Speed: ' + speedString + ' km/h.');
171
-    */
172
+
173
+    //add a new datapoint to GPX file
172 174
     GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
173 175
 
174 176
     console.log('GPX: ' + localStorage.getItem("GPX"));
... ...
@@ -176,16 +178,11 @@ function locationSuccess(new_pos) {
176 178
     // Build message
177 179
     message = "OK";
178 180
     var dict = {
179
-      //'latitude': padStart(latitudeString, 12, '0'),
180
-      //'longitude': padStart(longitudeString, 12, '0'),
181 181
       'accuracy': accuracyString,
182 182
       'altitude': altitudeString,
183
-      //'altitude_accuracy': padStart(altitudeAccuracyString, 3, '0'),
184
-      //'timestamp': padStart(timestampString, 13, '0'),
185 183
       'speed': speedString,
186 184
       'status': message
187 185
     };
188
-    //console.log('Message to send: ' + JSON.stringify(dict));
189 186
 
190 187
     // Send the message
191 188
     Pebble.sendAppMessage(dict, function () {
... ...
@@ -194,129 +191,38 @@ function locationSuccess(new_pos) {
194 191
       console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
195 192
     });
196 193
   }
194
+
195
+  // restart the watch
196
+  //geoloc_id = navigator.geolocation.watchPosition(locationSuccess, locationError, locationOptions);
197 197
 }
198 198
 
199 199
 function locationError(err) {
200
+  //clear watch of new position to avoid overlap
201
+  //navigator.geolocation.clearWatch(geoloc_id);
202
+
200 203
   console.warn('location error (' + err.code + '): ' + err.message);
201
-  /* // No app when no location
202
-       Pebble.sendAppMessage({
203
-           'WEATHER_CITY_KEY': 'Loc Unavailable',
204
-           'WEATHER_TEMPERATURE_KEY': 'N/A'
205
-       });*/
204
+
205
+  // restart the watch
206
+  //geoloc_id = navigator.geolocation.watchPosition(locationSuccess, locationError, locationOptions);
206 207
 }
207 208
 
208 209
 function get_coordinate() {
209
-  console.log('---- get_coordinate');
210
+  /*console.log('---- start geoloc');
210 211
   navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
211
-
212
+  */
212 213
 }
213 214
 
214
-/*
215
-function switch_home(bool) {
216
-  var response;
217
-  console.log('---- authenticate');
218
-  if (sid != ""){
219
-    status = "";
220
-    console.log('---- get_status');
221
-    if (localStorage.getItem('username')  && localStorage.getItem('password') && localStorage.getItem('server') ){
222
-      var username=localStorage.getItem('username');
223
-      var password=localStorage.getItem('password');
224
-      var server=localStorage.getItem('server');
225
-      var xhr = new XMLHttpRequest();
226
-
227
-      url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=GetInfo&_sid="+sid;
228
-
229
-      xhr.open("GET", url,false);
230
-      xhr.send();
231
-
232
-      if(xhr.status == 200) {
233
-        response = JSON.parse(xhr.responseText);
234
-        if (response.success == true){
235
-          status = response.data.on;
236
-          console.log('------ status:'+status);
237
-          var message;
238
-          var dict;
239
-          if ( status != bool){
240
-            console.log('---- switching home mode to '+ bool);
241
-            url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=Switch&on="+bool+"&_sid="+sid;
242
-
243
-            xhr.open("GET", url,false);
244
-            xhr.send();
245
-
246
-            if(xhr.status == 200) {
247
-              response = JSON.parse(xhr.responseText);
248
-              if (response.success == true){
249
-                status=bool;
250
-                switch (status) {
251
-                  case true:
252
-                    message = "You just set Home mode ON";
253
-                    break;
254
-                  case false:
255
-                    message = "You just set Home mode OFF";
256
-                    break;
257
-                  default:
258
-                    message = "something happened, try again !";
259
-                }
260
-                // Build message
261
-                dict = {
262
-                  'status': message,
263
-                };
264
-
265
-                // Send the message
266
-                Pebble.sendAppMessage(dict, function(e) {
267
-                  console.log('sent');
268
-                }, function() {
269
-                  console.log('failed');
270
-                });
271
-              }
272
-            }else {
273
-              console.log('------Request returned error code ' + xhr.status.toString());
274
-            }
275
-          }else{
276
-            console.log('---- nothing to do, status already '+status);
277
-            switch (status) {
278
-              case true:
279
-                message = "Your Home Mode is already ON";
280
-                break;
281
-              case false:
282
-                message = "Your Home Mode is already OFF";
283
-                break;
284
-              default:
285
-                message = "something happened, try again !";
286
-            }
287
-            // Build message
288
-            dict = {
289
-              'status': message,
290
-            };
291
-
292
-            // Send the message
293
-            Pebble.sendAppMessage(dict, function(e) {
294
-              console.log('sent');
295
-            }, function() {
296
-              console.log('failed');
297
-            });
298
-          }
299
-        }
300
-      }else {
301
-        console.log('------Request returned error code ' + xhr.status.toString());
302
-      }
303
-    }else{
304
-      Pebble.showSimpleNotificationOnPebble("DSCam H-S", "You need to set your Synology account and server.");
305
-    }
306
-   }
307
-
308
-}*/
309
-
310 215
 function init() {
311 216
   // local storage init
312 217
   localStorage.clear();
313 218
   // clear any other var to do
314
-  clearInterval(locationInterval);
219
+  //clearInterval(locationInterval);
220
+
315 221
 
316
-  console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
222
+  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
317 223
   locationInterval = setInterval(function () {
318 224
     navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
319
-  }, 1000);
225
+  }, 5000);
320 226
 
321 227
 
322 228
 }
... ...
@@ -338,13 +244,7 @@ Pebble.addEventListener('appmessage', function (e) {
338 244
   switch (dict[0]) {
339 245
     case 'get':
340 246
       get_coordinate();
341
-      break;/*
342
-    case 'home_on':
343
-      switch_home(true);
344 247
       break;
345
-    case 'home_off':
346
-      switch_home(false);
347
-      break;*/
348 248
     default:
349 249
       console.log('Sorry. I don\'t understand your request :' + dict[0]);
350 250
   }
Browse code

fixed string issue on watch and completed GPX builder

louis.jonget authored on30/09/2022 22:28:02
Showing1 changed files
... ...
@@ -4,44 +4,41 @@ var clay = new Clay(clayConfig);
4 4
 
5 5
 var messageKeys = require('message_keys');
6 6
 
7
-//var sid;
8
-var status;
9
-//var retry;
10
-//retry = 1;
7
+var message;
11 8
 
12 9
 var locationInterval;
13 10
 var locationOptions = {
14
-    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
15
-    'timeout': 2000, //2s timeout
16
-    'maximumAge': 1000 // 1s cache
11
+  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
12
+  'timeout': 2000, //2s timeout
13
+  'maximumAge': 1000 // 1s cache
17 14
 };
18 15
 
19 16
 // Store location in Pebble app local storage
20 17
 //
21 18
 function storeLocation(position) {
22
-    var latitude = position.coords.latitude;
23
-    var longitude = position.coords.longitude;
24
-    var timestamp = position.timestamp;
25
-    localStorage.setItem("latitude", latitude);
26
-    localStorage.setItem("longitude", longitude);
27
-    localStorage.setItem("timestamp", timestamp);
28
-    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
19
+  var latitude = position.coords.latitude;
20
+  var longitude = position.coords.longitude;
21
+  var timestamp = position.timestamp;
22
+  localStorage.setItem("latitude", latitude);
23
+  localStorage.setItem("longitude", longitude);
24
+  localStorage.setItem("timestamp", timestamp);
25
+  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
29 26
 }
30 27
 
31 28
 // Get location from Pebble app local storage
32 29
 //
33 30
 function getLocation() {
34
-    if ( localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
35
-        var la = localStorage.getItem("latitude");
36
-        var lo = localStorage.getItem("longitude");
37
-        var ti = localStorage.getItem("timestamp");
38
-        var co = { "latitude": la, "longitude": lo };
39
-        var pos = { "coords": co, "timestamp": ti };
40
-        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
41
-        return pos;
42
-    }else{
43
-        return null;
44
-    }
31
+  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
32
+    var la = localStorage.getItem("latitude");
33
+    var lo = localStorage.getItem("longitude");
34
+    var ti = localStorage.getItem("timestamp");
35
+    var co = { "latitude": la, "longitude": lo };
36
+    var pos = { "coords": co, "timestamp": ti };
37
+    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
38
+    return pos;
39
+  } else {
40
+    return null;
41
+  }
45 42
 }
46 43
 
47 44
 
... ...
@@ -49,132 +46,168 @@ function getLocation() {
49 46
 // IMPORTANT : this is a calculation from 2D projection, altitude is not involved
50 47
 //
51 48
 function distance_on_geoid(lat1, lon1, lat2, lon2) {
52
-    // Convert degrees to radians
53
-    lat1 = lat1 * Math.PI / 180.0;
54
-    lon1 = lon1 * Math.PI / 180.0;
55
-    lat2 = lat2 * Math.PI / 180.0;
56
-    lon2 = lon2 * Math.PI / 180.0;
57
-    // radius of earth in metres
58
-    r = 6378100;
59
-    // P
60
-    rho1 = r * Math.cos(lat1);
61
-    z1 = r * Math.sin(lat1);
62
-    x1 = rho1 * Math.cos(lon1);
63
-    y1 = rho1 * Math.sin(lon1);
64
-    // Q
65
-    rho2 = r * Math.cos(lat2);
66
-    z2 = r * Math.sin(lat2);
67
-    x2 = rho2 * Math.cos(lon2);
68
-    y2 = rho2 * Math.sin(lon2);
69
-    // Dot product
70
-    dot = (x1 * x2 + y1 * y2 + z1 * z2);
71
-    cos_theta = dot / (r * r);
72
-    theta = Math.acos(cos_theta);
73
-    // Distance in Metres
74
-    return r * theta;
49
+  // Convert degrees to radians
50
+  lat1 = lat1 * Math.PI / 180.0;
51
+  lon1 = lon1 * Math.PI / 180.0;
52
+  lat2 = lat2 * Math.PI / 180.0;
53
+  lon2 = lon2 * Math.PI / 180.0;
54
+  // radius of earth in metres
55
+  r = 6378100;
56
+  // P
57
+  rho1 = r * Math.cos(lat1);
58
+  z1 = r * Math.sin(lat1);
59
+  x1 = rho1 * Math.cos(lon1);
60
+  y1 = rho1 * Math.sin(lon1);
61
+  // Q
62
+  rho2 = r * Math.cos(lat2);
63
+  z2 = r * Math.sin(lat2);
64
+  x2 = rho2 * Math.cos(lon2);
65
+  y2 = rho2 * Math.sin(lon2);
66
+  // Dot product
67
+  dot = (x1 * x2 + y1 * y2 + z1 * z2);
68
+  cos_theta = dot / (r * r);
69
+  theta = Math.acos(cos_theta);
70
+  // Distance in Metres
71
+  return r * theta;
75 72
 }
76 73
 
77 74
 // Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
78 75
 //
79 76
 function speed_from_distance_and_time(p1, p2) {
80
-    dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
81
-    // timestamp is in milliseconds
82
-    time_s = (p2.timestamp - p1.timestamp) / 1000.0;
83
-    speed_mps = dist / time_s;
84
-    speed_kph = (speed_mps * 3600.0) / 1000.0;
85
-    return speed_kph;
77
+  dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
78
+  // timestamp is in milliseconds
79
+  time_s = (p2.timestamp - p1.timestamp) / 1000.0;
80
+  speed_mps = dist / time_s;
81
+  speed_kph = (speed_mps * 3600.0) / 1000.0;
82
+  return speed_kph;
86 83
 }
87 84
 
88 85
 // split float number into an array of int (null returned instead of 0 for decimal)
89 86
 //
90 87
 function splitFloatNumber(num) {
91
-    const intStr = num.toString().split('.')[0];
92
-    const decimalStr = num.toString().split('.')[1];
93
-    return [Number(intStr), Number(decimalStr)];
88
+  const intStr = num.toString().split('.')[0];
89
+  const decimalStr = num.toString().split('.')[1];
90
+  return [Number(intStr), Number(decimalStr)];
91
+}
92
+
93
+// Build GPX headers
94
+//
95
+function GPXHeadersBuilder(timestamp, name, type) {
96
+  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
97
+  var ret = localStorage.setItem("GPX", headers);
98
+  return true;
99
+}
100
+
101
+// Build GPX footer
102
+//
103
+function GPXtrkptBuilder(lat, lon, ele, timestamp) {
104
+  var GPX = localStorage.getItem("GPX");
105
+  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
106
+  var ret = localStorage.setItem("GPX", GPX + trkpt);
107
+  return true;
108
+}
109
+
110
+// Build GPX footer
111
+//
112
+function GPXfooterBuilder() {
113
+  var GPX = localStorage.getItem("GPX");
114
+  var footer = '</trkseg></trk></gpx>';
115
+  var ret = localStorage.setItem("GPX", GPX + footer);
116
+  return true;
94 117
 }
95 118
 
119
+// Adding leading characters to string for nice displays
120
+//
96 121
 function padStart(string, max_length, padding) {
97
-    if (string.length > max_length) {
98
-        return string;
99
-    } else {
100
-        var new_str = string;
101
-        for (index = string.length; index < max_length; index++) {
102
-            new_str = "0" + new_str;
103
-        }
104
-        return new_str;
122
+  if (string.length > max_length) {
123
+    return string;
124
+  } else {
125
+    var new_str = string;
126
+    for (index = string.length; index < max_length; index++) {
127
+      new_str = "0" + new_str;
105 128
     }
129
+    return new_str;
130
+  }
106 131
 }
107 132
 
108 133
 // called in case of successful geoloc gathering and sends the coordinate to watch
109 134
 //
110 135
 function locationSuccess(new_pos) {
111
-    var prev_pos = getLocation();
112
-    storeLocation(new_pos);
113
-    if (prev_pos === null){
114
-        return null;
115
-    }else{
116
-
117
-        var speed = speed_from_distance_and_time(prev_pos, new_pos);
118
-
119
-        // Prepare display on watch
120
-        // now it's only raw data
121
-        //init strings
122
-        var latitudeString = "";
123
-        var longitudeString = "";
124
-        var accuracyString = "";
125
-        var altitudeString = "";
126
-        var altitudeAccuracyString = "";
127
-        var timestampString = "";
128
-        var speedString = "";
129
-        //formating for precision and max size
130
-        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
131
-        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
132
-        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
133
-        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
134
-        altitudeAccuracyString = splitFloatNumber(new_pos.coords.altitudeAccuracy)[0].toString().substring(0, 3);
135
-        timestampString = splitFloatNumber(new_pos.timestamp)[0].toString().substring(0, 13);
136
-        speedString = speed.toString().substring(0, 5);
137
-        // logging
138
-        console.log('Your current position at ' + timestampString + ' is:');
139
-        console.log('Coordinates: ' + latitudeString+ ', ' + longitudeString+' ; with a ' + accuracyString + 'm accuracy');
140
-        console.log('Altitude: ' + altitudeString + 'm ; with a ' + altitudeAccuracyString + 'm accuracy');
141
-        console.log('Speed: ' + speedString + ' km/h.');
142
-
143
-        // Build message
144
-        var message = "OK";
145
-        var dict = {
146
-            /*'latitude': padStart(latitudeString, 12, '0'),
147
-            'longitude': padStart(longitudeString, 12, '0'),
148
-            'accuracy': padStart(accuracyString, 4, '0'),
149
-            'altitude': padStart(altitudeString, 5, '0'),
150
-            'altitude_accuracy': padStart(altitudeAccuracyString, 3, '0'),
151
-            'timestamp': padStart(timestampString, 13, '0'),*/
152
-            'speed': padStart(speedString, 5, '0'),
153
-            'status': message
154
-        };
155
-        //console.log('Message to send: ' + JSON.stringify(dict));
156
-
157
-        // Send the message
158
-        Pebble.sendAppMessage(dict, function () {
159
-            console.log('Message sent successfully: ' + JSON.stringify(dict));
160
-        }, function (e) {
161
-            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
162
-        });
136
+  var prev_pos = getLocation();
137
+  storeLocation(new_pos);
138
+  if (prev_pos === null) {
139
+    GPXHeadersBuilder(timestampISO = new Date(new_pos.timestamp).toISOString(), "test", "18");
140
+    return null;
141
+  } else {
142
+    var speed = speed_from_distance_and_time(prev_pos, new_pos);
143
+
144
+    // Prepare display on watch
145
+    // now it's only raw data
146
+    //init strings
147
+    var latitudeString = "";
148
+    var longitudeString = "";
149
+    var accuracyString = "";
150
+    var altitudeString = "";
151
+    //var altitudeAccuracyString = "";
152
+    //var timestampString = "";
153
+    var speedString = "";
154
+
155
+    //formating for precision and max size
156
+    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
157
+    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
158
+    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
159
+    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
160
+    timestampISO = new Date(new_pos.timestamp).toISOString();
161
+    speedString = speed.toString().substring(0, 5);
162
+
163
+    if (speedString == "NaN") {
164
+      speedString = "---";
163 165
     }
166
+    // logging
167
+    /*console.log('Your current position at ' + timestampString + ' is:');
168
+    console.log('Coordinates: ' + latitudeString+ ', ' + longitudeString+' ; with a ' + accuracyString + 'm accuracy');
169
+    console.log('Altitude: ' + altitudeString + 'm ; with a ' + altitudeAccuracyString + 'm accuracy');
170
+    console.log('Speed: ' + speedString + ' km/h.');
171
+    */
172
+    GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
173
+
174
+    console.log('GPX: ' + localStorage.getItem("GPX"));
175
+
176
+    // Build message
177
+    message = "OK";
178
+    var dict = {
179
+      //'latitude': padStart(latitudeString, 12, '0'),
180
+      //'longitude': padStart(longitudeString, 12, '0'),
181
+      'accuracy': accuracyString,
182
+      'altitude': altitudeString,
183
+      //'altitude_accuracy': padStart(altitudeAccuracyString, 3, '0'),
184
+      //'timestamp': padStart(timestampString, 13, '0'),
185
+      'speed': speedString,
186
+      'status': message
187
+    };
188
+    //console.log('Message to send: ' + JSON.stringify(dict));
189
+
190
+    // Send the message
191
+    Pebble.sendAppMessage(dict, function () {
192
+      console.log('Message sent successfully: ' + JSON.stringify(dict));
193
+    }, function (e) {
194
+      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
195
+    });
196
+  }
164 197
 }
165 198
 
166 199
 function locationError(err) {
167
-    console.warn('location error (' + err.code + '): ' + err.message);
168
-    /* // No app when no location
169
-    Pebble.sendAppMessage({
170
-        'WEATHER_CITY_KEY': 'Loc Unavailable',
171
-        'WEATHER_TEMPERATURE_KEY': 'N/A'
172
-    });*/
200
+  console.warn('location error (' + err.code + '): ' + err.message);
201
+  /* // No app when no location
202
+       Pebble.sendAppMessage({
203
+           'WEATHER_CITY_KEY': 'Loc Unavailable',
204
+           'WEATHER_TEMPERATURE_KEY': 'N/A'
205
+       });*/
173 206
 }
174 207
 
175 208
 function get_coordinate() {
176
-    console.log('---- get_coordinate');
177
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
209
+  console.log('---- get_coordinate');
210
+  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
178 211
 
179 212
 }
180 213
 
... ...
@@ -274,46 +307,46 @@ function switch_home(bool) {
274 307
 
275 308
 }*/
276 309
 
277
-function init(){
278
-    // local storage init
279
-    localStorage.clear();
280
-    // clear any other var to do
281
-    clearInterval(locationInterval);
310
+function init() {
311
+  // local storage init
312
+  localStorage.clear();
313
+  // clear any other var to do
314
+  clearInterval(locationInterval);
282 315
 
283
-    console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
284
-    locationInterval = setInterval(function() {
285
-      navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
286
-    }, 1000);
316
+  console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
317
+  locationInterval = setInterval(function () {
318
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
319
+  }, 1000);
287 320
 
288 321
 
289 322
 }
290 323
 
291 324
 // Get JS readiness events
292 325
 Pebble.addEventListener('ready', function (e) {
293
-    console.log('PebbleKit JS is ready');
294
-    // Update Watch on this
295
-    Pebble.sendAppMessage({ 'JSReady': 1 });
326
+  console.log('PebbleKit JS is ready');
327
+  // Update Watch on this
328
+  Pebble.sendAppMessage({ 'JSReady': 1 });
296 329
 
297
-    init();
330
+  init();
298 331
 });
299 332
 
300 333
 // Get AppMessage events
301 334
 Pebble.addEventListener('appmessage', function (e) {
302
-    // Get the dictionary from the message
303
-    var dict = e.payload;
304
-    console.log(dict[0].toString());
305
-    switch (dict[0]) {
306
-        case 'get':
307
-            get_coordinate();
308
-            break;/*
335
+  // Get the dictionary from the message
336
+  var dict = e.payload;
337
+  console.log(dict[0].toString());
338
+  switch (dict[0]) {
339
+    case 'get':
340
+      get_coordinate();
341
+      break;/*
309 342
     case 'home_on':
310 343
       switch_home(true);
311 344
       break;
312 345
     case 'home_off':
313 346
       switch_home(false);
314 347
       break;*/
315
-        default:
316
-            console.log('Sorry. I don\'t understand your request :' + dict[0]);
317
-    }
348
+    default:
349
+      console.log('Sorry. I don\'t understand your request :' + dict[0]);
350
+  }
318 351
 
319 352
 });
Browse code

init commit

louis.jonget authored on30/09/2022 18:58:18
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,319 @@
1
+var Clay = require('pebble-clay');
2
+var clayConfig = require('./config');
3
+var clay = new Clay(clayConfig);
4
+
5
+var messageKeys = require('message_keys');
6
+
7
+//var sid;
8
+var status;
9
+//var retry;
10
+//retry = 1;
11
+
12
+var locationInterval;
13
+var locationOptions = {
14
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
15
+    'timeout': 2000, //2s timeout
16
+    'maximumAge': 1000 // 1s cache
17
+};
18
+
19
+// Store location in Pebble app local storage
20
+//
21
+function storeLocation(position) {
22
+    var latitude = position.coords.latitude;
23
+    var longitude = position.coords.longitude;
24
+    var timestamp = position.timestamp;
25
+    localStorage.setItem("latitude", latitude);
26
+    localStorage.setItem("longitude", longitude);
27
+    localStorage.setItem("timestamp", timestamp);
28
+    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
29
+}
30
+
31
+// Get location from Pebble app local storage
32
+//
33
+function getLocation() {
34
+    if ( localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
35
+        var la = localStorage.getItem("latitude");
36
+        var lo = localStorage.getItem("longitude");
37
+        var ti = localStorage.getItem("timestamp");
38
+        var co = { "latitude": la, "longitude": lo };
39
+        var pos = { "coords": co, "timestamp": ti };
40
+        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
41
+        return pos;
42
+    }else{
43
+        return null;
44
+    }
45
+}
46
+
47
+
48
+// Calculate the distance from 2 geoloc in degrees.
49
+// IMPORTANT : this is a calculation from 2D projection, altitude is not involved
50
+//
51
+function distance_on_geoid(lat1, lon1, lat2, lon2) {
52
+    // Convert degrees to radians
53
+    lat1 = lat1 * Math.PI / 180.0;
54
+    lon1 = lon1 * Math.PI / 180.0;
55
+    lat2 = lat2 * Math.PI / 180.0;
56
+    lon2 = lon2 * Math.PI / 180.0;
57
+    // radius of earth in metres
58
+    r = 6378100;
59
+    // P
60
+    rho1 = r * Math.cos(lat1);
61
+    z1 = r * Math.sin(lat1);
62
+    x1 = rho1 * Math.cos(lon1);
63
+    y1 = rho1 * Math.sin(lon1);
64
+    // Q
65
+    rho2 = r * Math.cos(lat2);
66
+    z2 = r * Math.sin(lat2);
67
+    x2 = rho2 * Math.cos(lon2);
68
+    y2 = rho2 * Math.sin(lon2);
69
+    // Dot product
70
+    dot = (x1 * x2 + y1 * y2 + z1 * z2);
71
+    cos_theta = dot / (r * r);
72
+    theta = Math.acos(cos_theta);
73
+    // Distance in Metres
74
+    return r * theta;
75
+}
76
+
77
+// Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
78
+//
79
+function speed_from_distance_and_time(p1, p2) {
80
+    dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
81
+    // timestamp is in milliseconds
82
+    time_s = (p2.timestamp - p1.timestamp) / 1000.0;
83
+    speed_mps = dist / time_s;
84
+    speed_kph = (speed_mps * 3600.0) / 1000.0;
85
+    return speed_kph;
86
+}
87
+
88
+// split float number into an array of int (null returned instead of 0 for decimal)
89
+//
90
+function splitFloatNumber(num) {
91
+    const intStr = num.toString().split('.')[0];
92
+    const decimalStr = num.toString().split('.')[1];
93
+    return [Number(intStr), Number(decimalStr)];
94
+}
95
+
96
+function padStart(string, max_length, padding) {
97
+    if (string.length > max_length) {
98
+        return string;
99
+    } else {
100
+        var new_str = string;
101
+        for (index = string.length; index < max_length; index++) {
102
+            new_str = "0" + new_str;
103
+        }
104
+        return new_str;
105
+    }
106
+}
107
+
108
+// called in case of successful geoloc gathering and sends the coordinate to watch
109
+//
110
+function locationSuccess(new_pos) {
111
+    var prev_pos = getLocation();
112
+    storeLocation(new_pos);
113
+    if (prev_pos === null){
114
+        return null;
115
+    }else{
116
+
117
+        var speed = speed_from_distance_and_time(prev_pos, new_pos);
118
+
119
+        // Prepare display on watch
120
+        // now it's only raw data
121
+        //init strings
122
+        var latitudeString = "";
123
+        var longitudeString = "";
124
+        var accuracyString = "";
125
+        var altitudeString = "";
126
+        var altitudeAccuracyString = "";
127
+        var timestampString = "";
128
+        var speedString = "";
129
+        //formating for precision and max size
130
+        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
131
+        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
132
+        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
133
+        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
134
+        altitudeAccuracyString = splitFloatNumber(new_pos.coords.altitudeAccuracy)[0].toString().substring(0, 3);
135
+        timestampString = splitFloatNumber(new_pos.timestamp)[0].toString().substring(0, 13);
136
+        speedString = speed.toString().substring(0, 5);
137
+        // logging
138
+        console.log('Your current position at ' + timestampString + ' is:');
139
+        console.log('Coordinates: ' + latitudeString+ ', ' + longitudeString+' ; with a ' + accuracyString + 'm accuracy');
140
+        console.log('Altitude: ' + altitudeString + 'm ; with a ' + altitudeAccuracyString + 'm accuracy');
141
+        console.log('Speed: ' + speedString + ' km/h.');
142
+
143
+        // Build message
144
+        var message = "OK";
145
+        var dict = {
146
+            /*'latitude': padStart(latitudeString, 12, '0'),
147
+            'longitude': padStart(longitudeString, 12, '0'),
148
+            'accuracy': padStart(accuracyString, 4, '0'),
149
+            'altitude': padStart(altitudeString, 5, '0'),
150
+            'altitude_accuracy': padStart(altitudeAccuracyString, 3, '0'),
151
+            'timestamp': padStart(timestampString, 13, '0'),*/
152
+            'speed': padStart(speedString, 5, '0'),
153
+            'status': message
154
+        };
155
+        //console.log('Message to send: ' + JSON.stringify(dict));
156
+
157
+        // Send the message
158
+        Pebble.sendAppMessage(dict, function () {
159
+            console.log('Message sent successfully: ' + JSON.stringify(dict));
160
+        }, function (e) {
161
+            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
162
+        });
163
+    }
164
+}
165
+
166
+function locationError(err) {
167
+    console.warn('location error (' + err.code + '): ' + err.message);
168
+    /* // No app when no location
169
+    Pebble.sendAppMessage({
170
+        'WEATHER_CITY_KEY': 'Loc Unavailable',
171
+        'WEATHER_TEMPERATURE_KEY': 'N/A'
172
+    });*/
173
+}
174
+
175
+function get_coordinate() {
176
+    console.log('---- get_coordinate');
177
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
178
+
179
+}
180
+
181
+/*
182
+function switch_home(bool) {
183
+  var response;
184
+  console.log('---- authenticate');
185
+  if (sid != ""){
186
+    status = "";
187
+    console.log('---- get_status');
188
+    if (localStorage.getItem('username')  && localStorage.getItem('password') && localStorage.getItem('server') ){
189
+      var username=localStorage.getItem('username');
190
+      var password=localStorage.getItem('password');
191
+      var server=localStorage.getItem('server');
192
+      var xhr = new XMLHttpRequest();
193
+
194
+      url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=GetInfo&_sid="+sid;
195
+
196
+      xhr.open("GET", url,false);
197
+      xhr.send();
198
+
199
+      if(xhr.status == 200) {
200
+        response = JSON.parse(xhr.responseText);
201
+        if (response.success == true){
202
+          status = response.data.on;
203
+          console.log('------ status:'+status);
204
+          var message;
205
+          var dict;
206
+          if ( status != bool){
207
+            console.log('---- switching home mode to '+ bool);
208
+            url = server + "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=Switch&on="+bool+"&_sid="+sid;
209
+
210
+            xhr.open("GET", url,false);
211
+            xhr.send();
212
+
213
+            if(xhr.status == 200) {
214
+              response = JSON.parse(xhr.responseText);
215
+              if (response.success == true){
216
+                status=bool;
217
+                switch (status) {
218
+                  case true:
219
+                    message = "You just set Home mode ON";
220
+                    break;
221
+                  case false:
222
+                    message = "You just set Home mode OFF";
223
+                    break;
224
+                  default:
225
+                    message = "something happened, try again !";
226
+                }
227
+                // Build message
228
+                dict = {
229
+                  'status': message,
230
+                };
231
+
232
+                // Send the message
233
+                Pebble.sendAppMessage(dict, function(e) {
234
+                  console.log('sent');
235
+                }, function() {
236
+                  console.log('failed');
237
+                });
238
+              }
239
+            }else {
240
+              console.log('------Request returned error code ' + xhr.status.toString());
241
+            }
242
+          }else{
243
+            console.log('---- nothing to do, status already '+status);
244
+            switch (status) {
245
+              case true:
246
+                message = "Your Home Mode is already ON";
247
+                break;
248
+              case false:
249
+                message = "Your Home Mode is already OFF";
250
+                break;
251
+              default:
252
+                message = "something happened, try again !";
253
+            }
254
+            // Build message
255
+            dict = {
256
+              'status': message,
257
+            };
258
+
259
+            // Send the message
260
+            Pebble.sendAppMessage(dict, function(e) {
261
+              console.log('sent');
262
+            }, function() {
263
+              console.log('failed');
264
+            });
265
+          }
266
+        }
267
+      }else {
268
+        console.log('------Request returned error code ' + xhr.status.toString());
269
+      }
270
+    }else{
271
+      Pebble.showSimpleNotificationOnPebble("DSCam H-S", "You need to set your Synology account and server.");
272
+    }
273
+   }
274
+
275
+}*/
276
+
277
+function init(){
278
+    // local storage init
279
+    localStorage.clear();
280
+    // clear any other var to do
281
+    clearInterval(locationInterval);
282
+
283
+    console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
284
+    locationInterval = setInterval(function() {
285
+      navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
286
+    }, 1000);
287
+
288
+
289
+}
290
+
291
+// Get JS readiness events
292
+Pebble.addEventListener('ready', function (e) {
293
+    console.log('PebbleKit JS is ready');
294
+    // Update Watch on this
295
+    Pebble.sendAppMessage({ 'JSReady': 1 });
296
+
297
+    init();
298
+});
299
+
300
+// Get AppMessage events
301
+Pebble.addEventListener('appmessage', function (e) {
302
+    // Get the dictionary from the message
303
+    var dict = e.payload;
304
+    console.log(dict[0].toString());
305
+    switch (dict[0]) {
306
+        case 'get':
307
+            get_coordinate();
308
+            break;/*
309
+    case 'home_on':
310
+      switch_home(true);
311
+      break;
312
+    case 'home_off':
313
+      switch_home(false);
314
+      break;*/
315
+        default:
316
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
317
+    }
318
+
319
+});