signalk-racer 0.9.8 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ReleaseNotes.md +3 -0
- package/index.js +62 -73
- package/package.json +1 -1
package/ReleaseNotes.md
CHANGED
package/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
module.exports = (app) => {
|
|
3
2
|
const state = {};
|
|
4
3
|
const geolib = require('geolib')
|
|
@@ -136,10 +135,13 @@ module.exports = (app) => {
|
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
function toOtherEnd(end) {
|
|
139
|
-
switch(end) {
|
|
140
|
-
case 'port' :
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
switch (end) {
|
|
139
|
+
case 'port' :
|
|
140
|
+
return 'stb';
|
|
141
|
+
case 'stb' :
|
|
142
|
+
return 'port';
|
|
143
|
+
default:
|
|
144
|
+
return null;
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
147
|
|
|
@@ -170,9 +172,9 @@ module.exports = (app) => {
|
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
function complete(callback, statusCode, message, details) {
|
|
173
|
-
const result = {state: '
|
|
175
|
+
const result = {state: statusCode === 200 ? 'SUCCESS' : 'FAILURE', statusCode, message, details};
|
|
174
176
|
app.debug(JSON.stringify(result));
|
|
175
|
-
|
|
177
|
+
return result;
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
// Put an absolute position
|
|
@@ -180,30 +182,26 @@ module.exports = (app) => {
|
|
|
180
182
|
app.debug(`putStartLineEnd: ${end} ${JSON.stringify(position)}`);
|
|
181
183
|
|
|
182
184
|
try {
|
|
183
|
-
if (!end || !position || typeof position.latitude !== 'number' || typeof position.longitude !== 'number'
|
|
184
|
-
complete(callback, 400, 'Failed to put start line end: !end || !position');
|
|
185
|
-
return;
|
|
185
|
+
if (!end || !position || typeof position.latitude !== 'number' || typeof position.longitude !== 'number') {
|
|
186
|
+
return complete(callback, 400, 'Failed to put start line end: !end || !position');
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
end = end.toLowerCase();
|
|
189
190
|
if (end !== 'port' && end !== 'stb') {
|
|
190
|
-
complete(callback, 400, 'Failed to put start line end: unknown end');
|
|
191
|
-
return;
|
|
191
|
+
return complete(callback, 400, 'Failed to put start line end: unknown end');
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
let startLine = state.startLine;
|
|
195
195
|
if (startLine) {
|
|
196
196
|
// We have a line, check if this end is the same?
|
|
197
197
|
if (startLine[end].latitude === position.latitude && startLine[end].longitude === position.longitude) {
|
|
198
|
-
complete(callback, 304, 'Put start line end: unchanged line end');
|
|
199
|
-
return;
|
|
198
|
+
return complete(callback, 304, 'Put start line end: unchanged line end');
|
|
200
199
|
}
|
|
201
200
|
} else {
|
|
202
201
|
// We don't have a line, so check if this is just an update for one end of the line?
|
|
203
202
|
const thisEnd = app.getSelfPath(`navigation.racing.startLine${camelCase(end)}`);
|
|
204
203
|
if (thisEnd && thisEnd.value.lat === position.latitude && thisEnd.value.longitude === position.longitude) {
|
|
205
|
-
complete(callback, 304, 'Put start line end: unchanged end');
|
|
206
|
-
return;
|
|
204
|
+
return complete(callback, 304, 'Put start line end: unchanged end');
|
|
207
205
|
}
|
|
208
206
|
|
|
209
207
|
// If we now have both ends, we have a line!
|
|
@@ -237,7 +235,7 @@ module.exports = (app) => {
|
|
|
237
235
|
|
|
238
236
|
// Set/create the waypoint if we are configured to do so
|
|
239
237
|
if (state.options.updateStartLineWaypoint || updateWaypoint) {
|
|
240
|
-
const waypointConfig
|
|
238
|
+
const waypointConfig = `startLine${camelCase(end)}`;
|
|
241
239
|
app.debug(`waypointConfig: ${waypointConfig}`);
|
|
242
240
|
const waypointName = state.options[waypointConfig];
|
|
243
241
|
app.debug(`waypointName: ${waypointName}`);
|
|
@@ -268,6 +266,11 @@ module.exports = (app) => {
|
|
|
268
266
|
coordinates: [position.longitude, position.latitude]
|
|
269
267
|
},
|
|
270
268
|
properties: {}
|
|
269
|
+
},
|
|
270
|
+
type: end === 'port' ? 'start-pin' : 'start-boat',
|
|
271
|
+
position: {
|
|
272
|
+
latitude: position.latitude,
|
|
273
|
+
longitude: position.longitude
|
|
271
274
|
}
|
|
272
275
|
}
|
|
273
276
|
|
|
@@ -283,36 +286,33 @@ module.exports = (app) => {
|
|
|
283
286
|
app.debug('startline waypoint not updated');
|
|
284
287
|
}
|
|
285
288
|
|
|
286
|
-
// Complete the handler successfully
|
|
287
|
-
complete(callback, 200, 'Put start line end: OK');
|
|
288
289
|
|
|
289
290
|
// If we have a startLine, then process position against the new line
|
|
290
291
|
if (startLine)
|
|
291
292
|
processPosition(null);
|
|
293
|
+
// Complete the handler successfully
|
|
294
|
+
return complete(callback, 200, 'Put start line end: OK');
|
|
292
295
|
} catch (err) {
|
|
293
|
-
complete(callback, 500,
|
|
296
|
+
return complete(callback, 500, 'Put start line end: Failed ' + JSON.stringify(err));
|
|
294
297
|
}
|
|
295
|
-
|
|
296
|
-
return { state: 'PENDING' }
|
|
297
298
|
}
|
|
298
299
|
|
|
299
300
|
async function setStartLine(context, path, args, callback) {
|
|
300
301
|
try {
|
|
301
302
|
app.debug('setStartLine:', JSON.stringify(args));
|
|
302
303
|
if (!args || !args.end || typeof args.end !== 'string') {
|
|
303
|
-
complete(callback, 400,
|
|
304
|
-
return;
|
|
304
|
+
return complete(callback, 400, 'Failed to set the startLine: !end');
|
|
305
305
|
}
|
|
306
306
|
const end = args.end.toLowerCase();
|
|
307
307
|
if (end !== 'port' && end !== 'stb') {
|
|
308
|
-
complete(callback, 400,
|
|
309
|
-
return;
|
|
308
|
+
return complete(callback, 400, 'Failed to set the startLine: unknown end');
|
|
310
309
|
}
|
|
311
310
|
|
|
312
311
|
// Get the position either as arg or as the current bow position
|
|
313
312
|
let position = args.position;
|
|
314
|
-
if (position === 'bow') {
|
|
313
|
+
if (position === 'bow' || !position && !args.delta && !args.rotate ) {
|
|
315
314
|
position = app.getSelfPath('navigation.position');
|
|
315
|
+
app.debug('bowPosition:' + JSON.stringify(position));
|
|
316
316
|
if (position)
|
|
317
317
|
position = bowPosition(position.value);
|
|
318
318
|
}
|
|
@@ -332,7 +332,7 @@ module.exports = (app) => {
|
|
|
332
332
|
app.debug(`initialBearing: ${initialBearing} currentDistance: ${currentDistance}`);
|
|
333
333
|
|
|
334
334
|
const newDistance = args.delta && typeof args.delta === 'number' ? (currentDistance + args.delta) : currentDistance;
|
|
335
|
-
const newBearing = args.rotate && typeof args.rotate === 'number'? (initialBearing + toDegrees(args.rotate)) : initialBearing;
|
|
335
|
+
const newBearing = args.rotate && typeof args.rotate === 'number' ? (initialBearing + toDegrees(args.rotate)) : initialBearing;
|
|
336
336
|
app.debug(`newDistance: ${newDistance} newBearing: ${newBearing}`);
|
|
337
337
|
|
|
338
338
|
const newPosition = geolib.computeDestinationPoint(otherEnd, newDistance, newBearing);
|
|
@@ -342,11 +342,10 @@ module.exports = (app) => {
|
|
|
342
342
|
|
|
343
343
|
if (position)
|
|
344
344
|
return putStartLineEnd(end, position, callback, args.updateWaypoint === true);
|
|
345
|
-
complete(callback, 500,
|
|
345
|
+
return complete(callback, 500, 'Failed to set the startLine: No position');
|
|
346
346
|
} catch (err) {
|
|
347
|
-
complete(callback, 500,
|
|
347
|
+
return complete(callback, 500, 'Failed to set the startLine: ' + JSON.stringify(err));
|
|
348
348
|
}
|
|
349
|
-
return { state: 'PENDING' }
|
|
350
349
|
}
|
|
351
350
|
|
|
352
351
|
function setTimer() {
|
|
@@ -358,7 +357,7 @@ module.exports = (app) => {
|
|
|
358
357
|
return;
|
|
359
358
|
}
|
|
360
359
|
state.timeToStart--;
|
|
361
|
-
sendDeltas([{
|
|
360
|
+
sendDeltas([{path: 'navigation.racing.timeToStart', value: state.timeToStart}]);
|
|
362
361
|
}, 1000);
|
|
363
362
|
}
|
|
364
363
|
|
|
@@ -367,13 +366,11 @@ module.exports = (app) => {
|
|
|
367
366
|
try {
|
|
368
367
|
app.debug('startTimerCommand:', JSON.stringify(args));
|
|
369
368
|
if (!args || !args.command || typeof args.command !== 'string') {
|
|
370
|
-
complete(callback, 400,
|
|
371
|
-
return;
|
|
369
|
+
return complete(callback, 400, 'Failed to command timer: no command');
|
|
372
370
|
}
|
|
373
371
|
const command = args.command.toLowerCase();
|
|
374
372
|
|
|
375
|
-
switch (command)
|
|
376
|
-
{
|
|
373
|
+
switch (command) {
|
|
377
374
|
case 'start': {
|
|
378
375
|
const now = new Date();
|
|
379
376
|
const timeToStart = state.timeToStart ?? state.options.timer ?? 300;
|
|
@@ -389,8 +386,7 @@ module.exports = (app) => {
|
|
|
389
386
|
]);
|
|
390
387
|
|
|
391
388
|
setTimer();
|
|
392
|
-
complete(callback, 200,
|
|
393
|
-
break;
|
|
389
|
+
return complete(callback, 200, 'start timer: OK');
|
|
394
390
|
}
|
|
395
391
|
case 'reset': {
|
|
396
392
|
state.timerRunning = false;
|
|
@@ -401,14 +397,12 @@ module.exports = (app) => {
|
|
|
401
397
|
{path: 'navigation.racing.timeToStart', value: state.timeToStart},
|
|
402
398
|
{path: 'navigation.racing.startTime', value: null}
|
|
403
399
|
]);
|
|
404
|
-
complete(callback, 200,
|
|
405
|
-
break;
|
|
400
|
+
return complete(callback, 200, 'reset timer: OK');
|
|
406
401
|
}
|
|
407
402
|
|
|
408
403
|
case 'sync': {
|
|
409
404
|
if (!state.timerRunning || state.timeToStart == null) {
|
|
410
|
-
complete(callback, 500,
|
|
411
|
-
return;
|
|
405
|
+
return complete(callback, 500, 'sync timer: !running');
|
|
412
406
|
}
|
|
413
407
|
|
|
414
408
|
const rounded = Math.round(state.timeToStart / 60) * 60;
|
|
@@ -416,24 +410,21 @@ module.exports = (app) => {
|
|
|
416
410
|
state.startTime = new Date(Date.now() + rounded * 1000).toISOString();
|
|
417
411
|
|
|
418
412
|
sendDeltas([
|
|
419
|
-
{
|
|
420
|
-
{
|
|
413
|
+
{path: 'navigation.racing.timeToStart', value: state.timeToStart},
|
|
414
|
+
{path: 'navigation.racing.startTime', value: state.startTime}
|
|
421
415
|
]);
|
|
422
|
-
complete(callback, 200,
|
|
423
|
-
break;
|
|
416
|
+
return complete(callback, 200, 'sync timer: OK');
|
|
424
417
|
}
|
|
425
418
|
|
|
426
419
|
case 'set': {
|
|
427
420
|
const input = args.startTime;
|
|
428
421
|
if (!input) {
|
|
429
|
-
complete(callback, 400,
|
|
430
|
-
return;
|
|
422
|
+
return complete(callback, 400, 'reset timer: !startTime');
|
|
431
423
|
}
|
|
432
424
|
|
|
433
425
|
const inputTime = new Date(input);
|
|
434
426
|
if (isNaN(inputTime)) {
|
|
435
|
-
complete(callback, 400,
|
|
436
|
-
return;
|
|
427
|
+
return complete(callback, 400, 'reset timer: invalid startTime');
|
|
437
428
|
}
|
|
438
429
|
|
|
439
430
|
const now = new Date();
|
|
@@ -444,11 +435,10 @@ module.exports = (app) => {
|
|
|
444
435
|
state.timeToStart = 0;
|
|
445
436
|
state.startTime = null;
|
|
446
437
|
sendDeltas([
|
|
447
|
-
{
|
|
448
|
-
{
|
|
438
|
+
{path: 'navigation.racing.timeToStart', value: 0},
|
|
439
|
+
{path: 'navigation.racing.startTime', value: null}
|
|
449
440
|
]);
|
|
450
|
-
complete(callback, 200,
|
|
451
|
-
return;
|
|
441
|
+
return complete(callback, 200, 'set timer: 0K');
|
|
452
442
|
}
|
|
453
443
|
|
|
454
444
|
state.timerRunning = true;
|
|
@@ -456,19 +446,18 @@ module.exports = (app) => {
|
|
|
456
446
|
state.startTime = inputTime.toISOString();
|
|
457
447
|
|
|
458
448
|
sendDeltas([
|
|
459
|
-
{
|
|
460
|
-
{
|
|
449
|
+
{path: 'navigation.racing.timeToStart', value: state.timeToStart},
|
|
450
|
+
{path: 'navigation.racing.startTime', value: state.startTime}
|
|
461
451
|
]);
|
|
462
452
|
|
|
463
453
|
setTimer();
|
|
464
|
-
complete(callback, 200,
|
|
465
|
-
break;
|
|
454
|
+
return complete(callback, 200, 'set timer: OK');
|
|
466
455
|
}
|
|
467
456
|
|
|
468
457
|
case 'adjust': {
|
|
469
458
|
const delta = Number(args.delta);
|
|
470
459
|
if (isNaN(delta) || state.timeToStart == null || !state.startTime) {
|
|
471
|
-
cb(null, {
|
|
460
|
+
cb(null, {state: 'FAILED', message: 'Cannot adjust: invalid state or delta'});
|
|
472
461
|
return;
|
|
473
462
|
}
|
|
474
463
|
|
|
@@ -480,22 +469,19 @@ module.exports = (app) => {
|
|
|
480
469
|
state.startTime = adjustedStart;
|
|
481
470
|
|
|
482
471
|
sendDeltas([
|
|
483
|
-
{
|
|
484
|
-
{
|
|
472
|
+
{path: 'navigation.racing.timeToStart', value: state.timeToStart},
|
|
473
|
+
{path: 'navigation.racing.startTime', value: adjustedStart}
|
|
485
474
|
]);
|
|
486
|
-
complete(callback, 200,
|
|
487
|
-
break;
|
|
475
|
+
return complete(callback, 200, 'adjust timer: OK');
|
|
488
476
|
}
|
|
489
477
|
|
|
490
478
|
default : {
|
|
491
|
-
complete(callback, 400,
|
|
492
|
-
return;
|
|
479
|
+
return complete(callback, 400, 'Failed to command timer: unknown command');
|
|
493
480
|
}
|
|
494
481
|
}
|
|
495
482
|
} catch (err) {
|
|
496
|
-
complete(callback, 500,
|
|
483
|
+
return complete(callback, 500, 'Failed to command timer: ' + JSON.stringify(err));
|
|
497
484
|
}
|
|
498
|
-
return { state: 'PENDING' }
|
|
499
485
|
}
|
|
500
486
|
|
|
501
487
|
function findLineAndThenProcess(position, alwaysFindLine = false) {
|
|
@@ -613,8 +599,7 @@ module.exports = (app) => {
|
|
|
613
599
|
sendDeltas([
|
|
614
600
|
{path: 'navigation.racing.distanceStartline', value: distanceToLine},
|
|
615
601
|
]);
|
|
616
|
-
}
|
|
617
|
-
else if (state.distanceToLine) {
|
|
602
|
+
} else if (state.distanceToLine) {
|
|
618
603
|
state.distanceToLine = null;
|
|
619
604
|
sendDeltas([
|
|
620
605
|
{path: 'navigation.racing.distanceStartline', value: null},
|
|
@@ -841,8 +826,8 @@ module.exports = (app) => {
|
|
|
841
826
|
{
|
|
842
827
|
context: 'vessels.' + app.selfId,
|
|
843
828
|
subscribe: [
|
|
844
|
-
{
|
|
845
|
-
{
|
|
829
|
+
{path: 'navigation.racing.startLinePort', policy: 'instant'},
|
|
830
|
+
{path: 'navigation.racing.startLineStb', policy: 'instant'},
|
|
846
831
|
]
|
|
847
832
|
},
|
|
848
833
|
unsubscribes,
|
|
@@ -857,10 +842,14 @@ module.exports = (app) => {
|
|
|
857
842
|
if (u.source && u.source.label && u.source.label !== 'signalk-racer') {
|
|
858
843
|
switch (v.path) {
|
|
859
844
|
case 'navigation.racing.startLinePort' :
|
|
860
|
-
putStartLineEnd('port', v.value, ignored => {
|
|
845
|
+
putStartLineEnd('port', v.value, ignored => {
|
|
846
|
+
}, false).then(ignored => {
|
|
847
|
+
});
|
|
861
848
|
break;
|
|
862
849
|
case 'navigation.racing.startLineStb' :
|
|
863
|
-
putStartLineEnd('port', v.value, ignored => {
|
|
850
|
+
putStartLineEnd('port', v.value, ignored => {
|
|
851
|
+
}, false).then(ignored => {
|
|
852
|
+
});
|
|
864
853
|
break;
|
|
865
854
|
}
|
|
866
855
|
}
|