@signalk/freeboard-sk 2.7.0 → 2.8.0
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/CHANGELOG.md +12 -0
- package/package.json +3 -2
- package/plugin/alarms/alarms.js +56 -11
- package/plugin/index.js +6 -19
- package/plugin/openApi.json +8 -37
- package/plugin/weather/openweather.js +4 -4
- package/plugin/weather/weather-service.js +3 -3
- package/public/{327.7a922d3e3f05f7c0.js → 327.237df92a43b40d40.js} +1 -1
- package/public/3rdpartylicenses.txt +57 -0
- package/public/assets/help/img/settings_vessels_1.png +0 -0
- package/public/assets/help/index.html +6 -3
- package/public/index.html +1 -1
- package/public/main.b0a21edaea82d2e2.js +1 -0
- package/public/{runtime.3895660a09267773.js → runtime.5633b29a06dd408a.js} +1 -1
- package/public/main.e7d0c5c6304e80c5.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# CHANGELOG: Freeboard
|
|
2
2
|
|
|
3
|
+
### v2.8.0
|
|
4
|
+
|
|
5
|
+
- **Added**: Option to display laylines when destination is active. (#149)
|
|
6
|
+
- **Added**: Support for Signal K server "Features" API.
|
|
7
|
+
- **Updated**: Measure function displays both segment details and total distance. (#153)
|
|
8
|
+
- **Updated**: Clearing an alarm sets alarm state to normal rather than `null`.
|
|
9
|
+
- **Fixed**: Inverted label color not correctly applied after feature update.
|
|
10
|
+
|
|
11
|
+
### v2.7.1
|
|
12
|
+
|
|
13
|
+
- **Added**: Set a default waypoint name when adding a waypoint at vessel position. (#146)
|
|
14
|
+
|
|
3
15
|
### v2.7.0
|
|
4
16
|
|
|
5
17
|
- **Added**: OpenWeather OneCall v3.0 support. _(v2.5 is deprecated April 2024)_
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signalk/freeboard-sk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Openlayers chart plotter implementation for Signal K",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"signalk-webapp",
|
|
@@ -87,6 +87,7 @@
|
|
|
87
87
|
"proj4": "2.6.2",
|
|
88
88
|
"protractor": "~7.0.0",
|
|
89
89
|
"rxjs": "~6.6.3",
|
|
90
|
+
"semver": "^7.6.0",
|
|
90
91
|
"signalk-client-angular": "^2.0.3",
|
|
91
92
|
"signalk-worker-angular": "^1.1.4",
|
|
92
93
|
"simplify-ts": "^1.0.2",
|
|
@@ -97,4 +98,4 @@
|
|
|
97
98
|
"xml2js": "^0.6.2",
|
|
98
99
|
"zone.js": "~0.14.4"
|
|
99
100
|
}
|
|
100
|
-
}
|
|
101
|
+
}
|
package/plugin/alarms/alarms.js
CHANGED
|
@@ -16,6 +16,7 @@ const STANDARD_ALARMS = [
|
|
|
16
16
|
];
|
|
17
17
|
let server;
|
|
18
18
|
let pluginId;
|
|
19
|
+
const ALARM_API_PATH = '/signalk/v1/api/alarms';
|
|
19
20
|
const initAlarms = (app, id) => {
|
|
20
21
|
server = app;
|
|
21
22
|
pluginId = id;
|
|
@@ -32,8 +33,8 @@ const initAlarms = (app, id) => {
|
|
|
32
33
|
exports.initAlarms = initAlarms;
|
|
33
34
|
const initAlarmEndpoints = () => {
|
|
34
35
|
server.debug(`** Registering Alarm Action API endpoint(s) **`);
|
|
35
|
-
server.
|
|
36
|
-
server.debug(`**
|
|
36
|
+
server.post(`${ALARM_API_PATH}/:alarmType`, (req, res, next) => {
|
|
37
|
+
server.debug(`** POST ${ALARM_API_PATH}/${req.params.alarmType}`);
|
|
37
38
|
if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
|
|
38
39
|
next();
|
|
39
40
|
return;
|
|
@@ -57,14 +58,59 @@ const initAlarmEndpoints = () => {
|
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
});
|
|
60
|
-
server.
|
|
61
|
-
server.debug(`**
|
|
61
|
+
server.post(`${ALARM_API_PATH}/:alarmType/silence`, (req, res) => {
|
|
62
|
+
server.debug(`** POST ${req.path}`);
|
|
63
|
+
if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
|
|
64
|
+
res.status(200).json({
|
|
65
|
+
state: 'COMPLETED',
|
|
66
|
+
statusCode: 200,
|
|
67
|
+
message: `Unsupported Alarm (${req.params.alarmType}).`
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const al = server.getSelfPath(`notifications.${req.params.alarmType}`);
|
|
73
|
+
if (al && al.value) {
|
|
74
|
+
server.debug('Alarm value....');
|
|
75
|
+
if (al.value.method && al.value.method.includes('sound')) {
|
|
76
|
+
server.debug('Alarm has sound... silence!!!');
|
|
77
|
+
al.value.method = al.value.method.filter((i) => i !== 'sound');
|
|
78
|
+
const r = handlePutAlarmState('vessels.self', `notifications.${req.params.alarmType}`, al.value);
|
|
79
|
+
res.status(200).json(r);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
server.debug('Alarm has no sound... no action required.');
|
|
83
|
+
res.status(200).json({
|
|
84
|
+
state: 'COMPLETED',
|
|
85
|
+
statusCode: 200,
|
|
86
|
+
message: `Alarm (${req.params.alarmType}) is already silent.`
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
throw new Error(`Alarm (${req.params.alarmType}) has no value or was not found!`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
res.status(400).json({
|
|
96
|
+
state: 'FAILED',
|
|
97
|
+
statusCode: 400,
|
|
98
|
+
message: e.message
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
server.delete(`${ALARM_API_PATH}/:alarmType`, (req, res, next) => {
|
|
103
|
+
server.debug(`** DELETE ${ALARM_API_PATH}/${req.params.alarmType}`);
|
|
62
104
|
if (!STANDARD_ALARMS.includes(req.params.alarmType)) {
|
|
63
105
|
next();
|
|
64
106
|
return;
|
|
65
107
|
}
|
|
66
108
|
try {
|
|
67
|
-
const r = handlePutAlarmState('vessels.self', `notifications.${req.params.alarmType}`,
|
|
109
|
+
const r = handlePutAlarmState('vessels.self', `notifications.${req.params.alarmType}`, {
|
|
110
|
+
message: '',
|
|
111
|
+
method: [],
|
|
112
|
+
state: server_api_1.ALARM_STATE.normal
|
|
113
|
+
});
|
|
68
114
|
res.status(200).json(r);
|
|
69
115
|
}
|
|
70
116
|
catch (e) {
|
|
@@ -94,16 +140,16 @@ const handlePutAlarmState = (context, path, value) => {
|
|
|
94
140
|
server.debug(JSON.stringify(alarmType));
|
|
95
141
|
let noti;
|
|
96
142
|
if (value) {
|
|
97
|
-
const alm =
|
|
143
|
+
const alm = value.state === server_api_1.ALARM_STATE.normal ? null : buildAlarmData();
|
|
98
144
|
noti = {
|
|
99
145
|
path: `notifications.${alarmType}`,
|
|
100
146
|
value: {
|
|
101
147
|
state: value.state ?? null,
|
|
102
148
|
method: value.method ?? null,
|
|
103
|
-
message:
|
|
149
|
+
message: value.message
|
|
104
150
|
}
|
|
105
151
|
};
|
|
106
|
-
if (alm.data) {
|
|
152
|
+
if (alm && alm.data) {
|
|
107
153
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
154
|
noti.value.data = alm.data;
|
|
109
155
|
}
|
|
@@ -129,10 +175,9 @@ const handlePutAlarmState = (context, path, value) => {
|
|
|
129
175
|
};
|
|
130
176
|
}
|
|
131
177
|
};
|
|
132
|
-
const
|
|
178
|
+
const buildAlarmData = () => {
|
|
133
179
|
const pos = server.getSelfPath('navigation.position');
|
|
134
180
|
return {
|
|
135
|
-
message: message,
|
|
136
181
|
data: {
|
|
137
182
|
position: pos ? pos.value : null
|
|
138
183
|
}
|
|
@@ -143,5 +188,5 @@ const emitNotification = (msg) => {
|
|
|
143
188
|
const delta = {
|
|
144
189
|
updates: [{ values: [msg] }]
|
|
145
190
|
};
|
|
146
|
-
server.handleMessage(pluginId, delta);
|
|
191
|
+
server.handleMessage(pluginId, delta, server_api_1.SKVersion.v2);
|
|
147
192
|
};
|
package/plugin/index.js
CHANGED
|
@@ -7,19 +7,6 @@ const openapi = require("./openApi.json");
|
|
|
7
7
|
const defaultPollInterval = 60;
|
|
8
8
|
const CONFIG_SCHEMA = {
|
|
9
9
|
properties: {
|
|
10
|
-
alarms: {
|
|
11
|
-
type: 'object',
|
|
12
|
-
title: 'Standard Alarms.',
|
|
13
|
-
description: 'Standard Alarms request handler (MOB, etc.)',
|
|
14
|
-
properties: {
|
|
15
|
-
enable: {
|
|
16
|
-
type: 'boolean',
|
|
17
|
-
default: true,
|
|
18
|
-
title: 'Enable Standard Alarms',
|
|
19
|
-
description: ' '
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
10
|
weather: {
|
|
24
11
|
type: 'object',
|
|
25
12
|
title: 'Weather API.',
|
|
@@ -34,8 +21,8 @@ const CONFIG_SCHEMA = {
|
|
|
34
21
|
apiVersion: {
|
|
35
22
|
type: 'number',
|
|
36
23
|
title: 'API Version',
|
|
37
|
-
default:
|
|
38
|
-
enum: [
|
|
24
|
+
default: 3,
|
|
25
|
+
enum: [3, 2],
|
|
39
26
|
description: 'Note: v2 API not supported after April 2024!'
|
|
40
27
|
},
|
|
41
28
|
apiKey: {
|
|
@@ -108,7 +95,7 @@ module.exports = (server) => {
|
|
|
108
95
|
},
|
|
109
96
|
weather: {
|
|
110
97
|
enable: false,
|
|
111
|
-
apiVersion:
|
|
98
|
+
apiVersion: 3,
|
|
112
99
|
apiKey: '',
|
|
113
100
|
pollInterval: defaultPollInterval
|
|
114
101
|
},
|
|
@@ -145,19 +132,19 @@ module.exports = (server) => {
|
|
|
145
132
|
}
|
|
146
133
|
settings.weather = options.weather ?? {
|
|
147
134
|
enable: false,
|
|
148
|
-
apiVersion:
|
|
135
|
+
apiVersion: 3,
|
|
149
136
|
apiKey: '',
|
|
150
137
|
pollInterval: defaultPollInterval
|
|
151
138
|
};
|
|
152
139
|
settings.weather.enable = options.weather.enable ?? false;
|
|
153
|
-
settings.weather.apiVersion = options.weather.apiVersion ??
|
|
140
|
+
settings.weather.apiVersion = options.weather.apiVersion ?? 3;
|
|
154
141
|
settings.weather.apiKey = options.weather.apiKey ?? '';
|
|
155
142
|
settings.weather.pollInterval =
|
|
156
143
|
options.weather.pollInterval ?? defaultPollInterval;
|
|
157
144
|
settings.alarms = options.alarms ?? {
|
|
158
145
|
enable: true
|
|
159
146
|
};
|
|
160
|
-
settings.alarms.enable =
|
|
147
|
+
settings.alarms.enable = true;
|
|
161
148
|
settings.pypilot = options.pypilot ?? {
|
|
162
149
|
enable: false,
|
|
163
150
|
host: 'localhost',
|
package/plugin/openApi.json
CHANGED
|
@@ -16,14 +16,10 @@
|
|
|
16
16
|
},
|
|
17
17
|
"servers": [
|
|
18
18
|
{
|
|
19
|
-
"url": "/
|
|
19
|
+
"url": "/"
|
|
20
20
|
}
|
|
21
21
|
],
|
|
22
22
|
"tags": [
|
|
23
|
-
{
|
|
24
|
-
"name": "Alarms",
|
|
25
|
-
"description": "Raise and clear Signal K alarms."
|
|
26
|
-
},
|
|
27
23
|
{
|
|
28
24
|
"name": "OpenWeather",
|
|
29
25
|
"description": "Weather data from OpenWeather service."
|
|
@@ -470,7 +466,7 @@
|
|
|
470
466
|
},
|
|
471
467
|
"security": [{ "cookieAuth": [] }, { "bearerAuth": [] }],
|
|
472
468
|
"paths": {
|
|
473
|
-
"/meteo/{id}": {
|
|
469
|
+
"/signalk/v2/api/meteo/{id}": {
|
|
474
470
|
"parameters": [
|
|
475
471
|
{
|
|
476
472
|
"$ref": "#/components/parameters/StationIdParam"
|
|
@@ -493,7 +489,7 @@
|
|
|
493
489
|
}
|
|
494
490
|
}
|
|
495
491
|
},
|
|
496
|
-
"/meteo/{id}/observations": {
|
|
492
|
+
"/signalk/v2/api/meteo/{id}/observations": {
|
|
497
493
|
"parameters": [
|
|
498
494
|
{
|
|
499
495
|
"$ref": "#/components/parameters/StationIdParam"
|
|
@@ -519,7 +515,7 @@
|
|
|
519
515
|
}
|
|
520
516
|
}
|
|
521
517
|
},
|
|
522
|
-
"/meteo/{id}/observations/{entryId}": {
|
|
518
|
+
"/signalk/v2/api/meteo/{id}/observations/{entryId}": {
|
|
523
519
|
"parameters": [
|
|
524
520
|
{
|
|
525
521
|
"$ref": "#/components/parameters/StationIdParam"
|
|
@@ -545,7 +541,7 @@
|
|
|
545
541
|
}
|
|
546
542
|
}
|
|
547
543
|
},
|
|
548
|
-
"/meteo/{id}/forecasts": {
|
|
544
|
+
"/signalk/v2/api/meteo/{id}/forecasts": {
|
|
549
545
|
"parameters": [
|
|
550
546
|
{
|
|
551
547
|
"$ref": "#/components/parameters/StationIdParam"
|
|
@@ -571,7 +567,7 @@
|
|
|
571
567
|
}
|
|
572
568
|
}
|
|
573
569
|
},
|
|
574
|
-
"/meteo/{id}/forecasts/{entryId}": {
|
|
570
|
+
"/signalk/v2/api/meteo/{id}/forecasts/{entryId}": {
|
|
575
571
|
"parameters": [
|
|
576
572
|
{
|
|
577
573
|
"$ref": "#/components/parameters/StationIdParam"
|
|
@@ -597,7 +593,7 @@
|
|
|
597
593
|
}
|
|
598
594
|
}
|
|
599
595
|
},
|
|
600
|
-
"/meteo/{id}/warnings": {
|
|
596
|
+
"/signalk/v2/api/meteo/{id}/warnings": {
|
|
601
597
|
"parameters": [
|
|
602
598
|
{
|
|
603
599
|
"$ref": "#/components/parameters/StationIdParam"
|
|
@@ -623,7 +619,7 @@
|
|
|
623
619
|
}
|
|
624
620
|
}
|
|
625
621
|
},
|
|
626
|
-
"/meteo/{id}/warnings/{entryId}": {
|
|
622
|
+
"/signalk/v2/api/meteo/{id}/warnings/{entryId}": {
|
|
627
623
|
"parameters": [
|
|
628
624
|
{
|
|
629
625
|
"$ref": "#/components/parameters/StationIdParam"
|
|
@@ -648,31 +644,6 @@
|
|
|
648
644
|
}
|
|
649
645
|
}
|
|
650
646
|
}
|
|
651
|
-
},
|
|
652
|
-
"/notifications/{alarmType}": {
|
|
653
|
-
"parameters": [
|
|
654
|
-
{
|
|
655
|
-
"$ref": "#/components/parameters/AlarmTypeParam"
|
|
656
|
-
}
|
|
657
|
-
],
|
|
658
|
-
"put": {
|
|
659
|
-
"tags": ["Alarms"],
|
|
660
|
-
"summary": "Raise alarm.",
|
|
661
|
-
"responses": {
|
|
662
|
-
"default": {
|
|
663
|
-
"$ref": "#/components/responses/200OKResponse"
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
},
|
|
667
|
-
"delete": {
|
|
668
|
-
"tags": ["Alarms"],
|
|
669
|
-
"summary": "Clear alarm.",
|
|
670
|
-
"responses": {
|
|
671
|
-
"default": {
|
|
672
|
-
"$ref": "#/components/responses/200OKResponse"
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
647
|
}
|
|
677
648
|
}
|
|
678
649
|
}
|
|
@@ -57,13 +57,13 @@ class OpenWeather {
|
|
|
57
57
|
},
|
|
58
58
|
outside: {
|
|
59
59
|
uvIndex: current.uvi ?? null,
|
|
60
|
-
cloudCover: current.clouds ?? null,
|
|
60
|
+
cloudCover: current.clouds / 100 ?? null,
|
|
61
61
|
horizontalVisibility: current.visibility ?? null,
|
|
62
62
|
temperature: current.temp ?? null,
|
|
63
63
|
feelsLikeTemperature: current.feels_like ?? null,
|
|
64
64
|
dewPointTemperature: current.dew_point ?? null,
|
|
65
65
|
pressure: current.pressure ? current.pressure * 100 : null,
|
|
66
|
-
absoluteHumidity: current.humidity ?? null,
|
|
66
|
+
absoluteHumidity: current.humidity / 100 ?? null,
|
|
67
67
|
precipitationType: current.rain && typeof current.rain['1h'] !== 'undefined'
|
|
68
68
|
? 'rain'
|
|
69
69
|
: current.snow && typeof current.snow['1h'] !== 'undefined'
|
|
@@ -119,10 +119,10 @@ class OpenWeather {
|
|
|
119
119
|
}
|
|
120
120
|
forecast.outside.dewPointTemperature = f.dew_point ?? null;
|
|
121
121
|
forecast.outside.uvIndex = f.uvi ?? null;
|
|
122
|
-
forecast.outside.cloudCover = f.clouds ?? null;
|
|
122
|
+
forecast.outside.cloudCover = f.clouds / 100 ?? null;
|
|
123
123
|
forecast.outside.pressure =
|
|
124
124
|
typeof f.pressure !== 'undefined' ? f.pressure * 100 : null;
|
|
125
|
-
forecast.outside.absoluteHumidity = f.humidity ?? null;
|
|
125
|
+
forecast.outside.absoluteHumidity = f.humidity / 100 ?? null;
|
|
126
126
|
forecast.wind.speedTrue = f.wind_speed ?? null;
|
|
127
127
|
forecast.wind.directionTrue =
|
|
128
128
|
typeof f.wind_deg !== 'undefined'
|
|
@@ -457,7 +457,7 @@ const buildObservationMetas = (pathRoot) => {
|
|
|
457
457
|
path: `${pathRoot}.outside.cloudCover`,
|
|
458
458
|
value: {
|
|
459
459
|
description: 'Cloud clover.',
|
|
460
|
-
units: '
|
|
460
|
+
units: 'ratio'
|
|
461
461
|
}
|
|
462
462
|
});
|
|
463
463
|
metas.push({
|
|
@@ -517,14 +517,14 @@ const buildObservationMetas = (pathRoot) => {
|
|
|
517
517
|
path: `${pathRoot}.outside.relativeHumidity`,
|
|
518
518
|
value: {
|
|
519
519
|
description: 'Relative humidity.',
|
|
520
|
-
units: '
|
|
520
|
+
units: 'ratio'
|
|
521
521
|
}
|
|
522
522
|
});
|
|
523
523
|
metas.push({
|
|
524
524
|
path: `${pathRoot}.outside.absoluteHumidity`,
|
|
525
525
|
value: {
|
|
526
526
|
description: 'Absolute humidity.',
|
|
527
|
-
units: '
|
|
527
|
+
units: 'ratio'
|
|
528
528
|
}
|
|
529
529
|
});
|
|
530
530
|
metas.push({
|