@signalk/freeboard-sk 2.19.7 → 2.19.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalk/freeboard-sk",
3
- "version": "2.19.7",
3
+ "version": "2.19.9",
4
4
  "description": "Openlayers chart plotter implementation for Signal K",
5
5
  "keywords": [
6
6
  "signalk-webapp",
@@ -40,7 +40,7 @@
40
40
  ],
41
41
  "license": "Apache-v2",
42
42
  "dependencies": {
43
- "@signalk/server-api": "^2.9.0",
43
+ "@signalk/server-api": "^2.22.0",
44
44
  "geolib": "^3.3.3",
45
45
  "google-protobuf": "^4.0.1",
46
46
  "tslib": "^2.0.0",
@@ -70,6 +70,7 @@
70
70
  "@types/xml2js": "^0.4.14",
71
71
  "@typescript-eslint/eslint-plugin": "^8.46.3",
72
72
  "@typescript-eslint/parser": "^8.46.3",
73
+ "baseline-browser-mapping": "^2.9.18",
73
74
  "buffer": "^6.0.3",
74
75
  "eslint": "^9.17.0",
75
76
  "events": "^3.3.0",
@@ -81,7 +82,7 @@
81
82
  "karma-jasmine-html-reporter": "~2.1.0",
82
83
  "ng-packagr": "^21.0.0",
83
84
  "ngeohash": "^0.6.3",
84
- "ol": "^10.2.1",
85
+ "ol": "^10.7.0",
85
86
  "ol-mapbox-style": "^12.3.5",
86
87
  "pmtiles": "^2.7.0",
87
88
  "prettier": "^3.6.2",
@@ -63,14 +63,14 @@ class AreaAlarmManager {
63
63
  */
64
64
  silence(id) {
65
65
  // clean up notification
66
- const n = server.getSelfPath(`notifications.area.${id}`);
67
- if (n.value && Array.isArray(n.value.method)) {
66
+ const n = getSelfPathValue(`notifications.area.${id}`);
67
+ if (n?.value && Array.isArray(n.value.method)) {
68
68
  const m = n.value.method.filter((i) => i !== 'sound');
69
69
  n.value.method = m;
70
70
  }
71
71
  emitNotification({
72
72
  path: `notifications.area.${id}`,
73
- value: n.value
73
+ value: n?.value
74
74
  });
75
75
  }
76
76
  /**
@@ -140,6 +140,9 @@ let pluginId;
140
140
  let unsubscribes = [];
141
141
  const alarmAreas = new Map();
142
142
  const alarmManager = new AreaAlarmManager();
143
+ const getSelfPathValue = (path) => {
144
+ return server.getSelfPath(path);
145
+ };
143
146
  const initAlarms = (app, id) => {
144
147
  server = app;
145
148
  pluginId = id;
@@ -196,7 +199,7 @@ const handleDeltaMessage = (delta) => {
196
199
  });
197
200
  });
198
201
  };
199
- const initAlarmEndpoints = () => {
202
+ const initAlarmEndpoints = async () => {
200
203
  server.debug(`** Registering Alarm Action API endpoint(s) **`);
201
204
  // list area alarms
202
205
  server.get(`${ALARM_API_PATH}/area`, async (req, res, next) => {
@@ -348,106 +351,111 @@ const initAlarmEndpoints = () => {
348
351
  });
349
352
  }
350
353
  });
351
- // standard alarms
352
- server.post(`${ALARM_API_PATH}/:alarmType`, (req, res, next) => {
353
- server.debug(`** ${req.method} ${ALARM_API_PATH}/${req.params.alarmType}`);
354
- if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
355
- next();
356
- return;
357
- }
358
- try {
359
- const id = uuid.v4();
360
- const msg = req.body.message
361
- ? req.body.message
362
- : req.params.alarmType;
363
- const r = handleAlarm('vessels.self', `notifications.${req.params.alarmType}.${id}`, Object.assign({
364
- message: msg,
365
- method: [server_api_1.ALARM_METHOD.sound, server_api_1.ALARM_METHOD.visual],
366
- state: server_api_1.ALARM_STATE.emergency
367
- }, buildAlarmData()));
368
- res.status(r.statusCode).json(Object.assign(r, { id: id }));
369
- }
370
- catch (e) {
371
- res.status(400).json({
372
- state: 'FAILED',
373
- statusCode: 400,
374
- message: e.message
375
- });
376
- }
377
- });
378
- server.post(`${ALARM_API_PATH}/:alarmType/:id/silence`, (req, res) => {
379
- server.debug(`** ${req.method} ${req.path}`);
380
- if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
381
- res.status(200).json({
382
- state: 'COMPLETED',
383
- statusCode: 200,
384
- message: `Unsupported Alarm (${req.params.alarmType}).`
385
- });
386
- return;
387
- }
388
- try {
389
- const al = server.getSelfPath(`notifications.${req.params.alarmType}.${req.params.id}`);
390
- if (al && al.value) {
391
- server.debug('Alarm value....');
392
- if (al.value.method && al.value.method.includes('sound')) {
393
- server.debug('Alarm has sound... silence!!!');
394
- al.value.method = al.value.method.filter((i) => i !== 'sound');
395
- const r = handleAlarm('vessels.self', `notifications.${req.params.alarmType}.${req.params.id}`, al.value);
396
- res.status(r.statusCode).json(r);
354
+ const f = await server.getFeatures();
355
+ // test for notifications API
356
+ if (!f.apis.includes('notifications')) {
357
+ // standard alarms
358
+ server.post(`${ALARM_API_PATH}/:alarmType`, (req, res, next) => {
359
+ server.debug(`** ${req.method} ${ALARM_API_PATH}/${req.params.alarmType}`);
360
+ if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
361
+ next();
362
+ return;
363
+ }
364
+ try {
365
+ const id = uuid.v4();
366
+ const msg = req.body.message
367
+ ? req.body.message
368
+ : req.params.alarmType;
369
+ const r = handleAlarm('vessels.self', `notifications.${req.params.alarmType}.${id}`, Object.assign({
370
+ message: msg,
371
+ method: [server_api_1.ALARM_METHOD.sound, server_api_1.ALARM_METHOD.visual],
372
+ state: server_api_1.ALARM_STATE.emergency
373
+ }, buildAlarmData()));
374
+ res.status(r.statusCode).json(Object.assign(r, { id: id }));
375
+ }
376
+ catch (e) {
377
+ res.status(400).json({
378
+ state: 'FAILED',
379
+ statusCode: 400,
380
+ message: e.message
381
+ });
382
+ }
383
+ });
384
+ server.post(`${ALARM_API_PATH}/:alarmType/:id/silence`, (req, res) => {
385
+ server.debug(`** ${req.method} ${req.path}`);
386
+ if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
387
+ res.status(200).json({
388
+ state: 'COMPLETED',
389
+ statusCode: 200,
390
+ message: `Unsupported Alarm (${req.params.alarmType}).`
391
+ });
392
+ return;
393
+ }
394
+ try {
395
+ const al = getSelfPathValue(`notifications.${req.params.alarmType}.${req.params.id}`);
396
+ if (al?.value) {
397
+ server.debug('Alarm value....');
398
+ if (al.value.method &&
399
+ al.value.method.includes(server_api_1.ALARM_METHOD.sound)) {
400
+ server.debug('Alarm has sound... silence!!!');
401
+ al.value.method = al.value.method.filter((i) => i !== server_api_1.ALARM_METHOD.sound);
402
+ const r = handleAlarm('vessels.self', `notifications.${req.params.alarmType}.${req.params.id}`, al.value);
403
+ res.status(r.statusCode).json(r);
404
+ }
405
+ else {
406
+ server.debug('Alarm has no sound... no action required.');
407
+ res.status(200).json({
408
+ state: 'COMPLETED',
409
+ statusCode: 200,
410
+ message: `Alarm (${req.params.alarmType}) is already silent.`
411
+ });
412
+ }
397
413
  }
398
414
  else {
399
- server.debug('Alarm has no sound... no action required.');
400
- res.status(200).json({
401
- state: 'COMPLETED',
402
- statusCode: 200,
403
- message: `Alarm (${req.params.alarmType}) is already silent.`
404
- });
415
+ throw new Error(`Alarm (${req.params.alarmType}.${req.params.id}) has no value or was not found!`);
405
416
  }
406
417
  }
407
- else {
408
- throw new Error(`Alarm (${req.params.alarmType}.${req.params.id}) has no value or was not found!`);
418
+ catch (e) {
419
+ res.status(400).json({
420
+ state: 'FAILED',
421
+ statusCode: 400,
422
+ message: e.message
423
+ });
409
424
  }
410
- }
411
- catch (e) {
412
- res.status(400).json({
413
- state: 'FAILED',
414
- statusCode: 400,
415
- message: e.message
416
- });
417
- }
418
- });
419
- server.delete(`${ALARM_API_PATH}/:alarmType/:id`, (req, res, next) => {
420
- server.debug(`** ${req.method} ${ALARM_API_PATH}/${req.params.alarmType}`);
421
- if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
422
- next();
423
- return;
424
- }
425
- try {
426
- const r = handleAlarm('vessels.self', `notifications.${req.params.alarmType}.${req.params.id}`, {
427
- message: '',
428
- method: [],
429
- state: server_api_1.ALARM_STATE.normal
430
- });
431
- res.status(r.statusCode).json(r);
432
- }
433
- catch (e) {
434
- res.status(400).json({
435
- state: 'FAILED',
436
- statusCode: 400,
437
- message: e.message
438
- });
439
- }
440
- });
425
+ });
426
+ server.delete(`${ALARM_API_PATH}/:alarmType/:id`, (req, res, next) => {
427
+ server.debug(`** ${req.method} ${ALARM_API_PATH}/${req.params.alarmType}`);
428
+ if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
429
+ next();
430
+ return;
431
+ }
432
+ try {
433
+ const r = handleAlarm('vessels.self', `notifications.${req.params.alarmType}.${req.params.id}`, {
434
+ message: '',
435
+ method: [],
436
+ state: server_api_1.ALARM_STATE.normal
437
+ });
438
+ res.status(r.statusCode).json(r);
439
+ }
440
+ catch (e) {
441
+ res.status(400).json({
442
+ state: 'FAILED',
443
+ statusCode: 400,
444
+ message: e.message
445
+ });
446
+ }
447
+ });
448
+ }
441
449
  };
442
450
  const handleV1PutRequest = (context, path, value, cb) => {
443
451
  cb(handleAlarm(context, path, value));
444
452
  };
445
453
  const buildAlarmData = () => {
446
- const pos = server.getSelfPath('navigation.position');
454
+ const pos = getSelfPathValue('navigation.position');
447
455
  const r = {
448
456
  createdAt: new Date().toISOString()
449
457
  };
450
- if (pos) {
458
+ if (pos?.value) {
451
459
  r.position = pos.value;
452
460
  }
453
461
  return r;
@@ -552,7 +560,8 @@ const validateAreaBody = (body) => {
552
560
  * @returns true if valid
553
561
  */
554
562
  const isValidPosition = (position) => {
555
- return 'latitude' in position &&
563
+ return position &&
564
+ 'latitude' in position &&
556
565
  'longitude' in position &&
557
566
  typeof position.latitude === 'number' &&
558
567
  position.latitude >= -90 &&
package/plugin/index.js CHANGED
@@ -49,7 +49,8 @@ module.exports = (server) => {
49
49
  settings.alarms = options.alarms ?? {
50
50
  enable: true
51
51
  };
52
- settings.alarms.enable = true;
52
+ // const f = await server.getFeatures();
53
+ settings.alarms.enable = true; //!f.apis.includes('notifications' as any);
53
54
  server.debug(`Applied config: ${JSON.stringify(settings)}`);
54
55
  if (settings.alarms.enable) {
55
56
  (0, alarms_1.initAlarms)(server, plugin.id);
@@ -120,7 +120,7 @@
120
120
  >
121
121
  </div>
122
122
 
123
- <div
123
+ <!--<div
124
124
  class="panel"
125
125
  id="deprecations"
126
126
  style="background-color: rgba(255, 0, 0, 0.4)"
@@ -142,7 +142,7 @@
142
142
  >
143
143
  </li>
144
144
  </ul>
145
- </div>
145
+ </div>-->
146
146
 
147
147
  <div class="panel" id="server">
148
148
  <h3>Signal K Server</h3>
@@ -281,13 +281,42 @@
281
281
  alt=""
282
282
  />.<br />
283
283
  <img src="./img/screen.png" style="height: 400px" alt="" />
284
- <br />
285
- The menu bar along the left of the screen provides access to functions
286
- and menus that allow you control the map display. <br />
287
- The buttons along the right side provide access to quick-actions and
288
- experiments.
289
284
  <br />&nbsp;<br />
285
+ <b>Status Area:</b>
286
+ Provides visual indication of the following conditions.
287
+ <ul>
288
+ <li class="nobullet">
289
+ <i class="material-icons"
290
+ >signal_wifi_statusbar_connected_no_internet_4</i
291
+ >
292
+ <b>No server messages:</b>
293
+ Indicates there may be an issue on the server as messages no have
294
+ been received over the open connection in the last 8-10 seconds.
295
+ </li>
296
+ <li class="nobullet">
297
+ <i class="material-icons">directions_boat</i>
298
+ <b>Vessels hidden:</b>
299
+ Indicates vessels are not being displayed.
300
+ </li>
301
+ <li class="nobullet">
302
+ <i class="material-icons">local_offer</i>
303
+ <b>Notes hidden:</b>
304
+ Indicates notes are not being displayed.
305
+ </li>
306
+ <li class="nobullet">
307
+ <i class="material-icons">compare_arrows</i>
308
+ <b>Course hidden:</b>
309
+ Indicates course information is not being displayed.
310
+ </li>
311
+ <li class="nobullet">
312
+ <i class="material-icons">visibility_off</i>
313
+ <b>Wake lock off:</b>
314
+ Indicates that the device wake lock is off.
315
+ </li>
316
+ </ul>
317
+ <br />
290
318
  <b>Left menu bar:</b>
319
+ Provides access to functions that allow you control the map display.
291
320
  <ul>
292
321
  <li class="nobullet">
293
322
  <i class="material-icons">menu</i>
@@ -377,6 +406,7 @@
377
406
  </ul>
378
407
  <br />
379
408
  <b>Right menu bar:</b>
409
+ Provides access to quick-actions and experiments.
380
410
  <ul>
381
411
  <li class="nobullet">
382
412
  <i class="material-icons">av_timer</i>
@@ -569,7 +599,7 @@
569
599
  can set a destination in the following ways:
570
600
  <ol>
571
601
  <li>
572
- <b>Activate a Route:</b> Once activaed select a point along the
602
+ <b>Activate a Route:</b> Once activated, select a point along the
573
603
  route.
574
604
  </li>
575
605
  <li><b>Go To Waypoint:</b> Select a waypoint as a destination.</li>
@@ -879,9 +909,18 @@
879
909
  <div style="padding-left: 20px">
880
910
  <ul>
881
911
  <li>
882
- <b>Set the destination point:</b> If displayed route is the
883
- <i>Active Route</i>, click a point to set it as the current
884
- destination along the route.
912
+ <i class="material-icons">near_me</i
913
+ ><b>Nearest:</b> Activate the route starting at the point
914
+ nearest the vessel.
915
+ </li>
916
+ <li>
917
+ <i class="material-icons">clear_all</i
918
+ ><b>Clear:</b> De-activate the route.
919
+ </li>
920
+ <li>
921
+ <b>Start at / Set the selected point:</b>
922
+ Click <i class="material-icons">near_me</i> next to the
923
+ point to set as the current destination along the route.
885
924
  </li>
886
925
  <li>
887
926
  <b>Re-order points:</b> Use the handle to drag points to a
@@ -902,7 +941,7 @@
902
941
  can add, edit or delete notes.
903
942
  </li>
904
943
  <li>
905
- <b>Activate: </b> Clicking
944
+ <b>Start: </b> Clicking
906
945
  <i class="material-icons">near_me</i> sends a message to the
907
946
  server to set this route as the <i>Active Route</i>.<br />
908
947
  The start of the route is set as the current destination.
package/public/index.html CHANGED
@@ -54,5 +54,5 @@
54
54
  </div>
55
55
  </div>
56
56
  </app-root>
57
- <link rel="modulepreload" href="chunk-FDERIQAA.js"><script src="polyfills-5CFQRCPP.js" type="module"></script><script src="main-ZOI63BYP.js" type="module"></script></body>
57
+ <link rel="modulepreload" href="chunk-FDERIQAA.js"><script src="polyfills-5CFQRCPP.js" type="module"></script><script src="main-LF4KQTMA.js" type="module"></script></body>
58
58
  </html>