Skip to content

Commit 0db9d06

Browse files
committed
Update plugin
- Add metadata configuration - Add matadata available keys - Deprecated metadata client_id - Update metadata platform - Reduce memory footprint
1 parent b9df3a7 commit 0db9d06

File tree

1 file changed

+163
-13
lines changed

1 file changed

+163
-13
lines changed

index.js

Lines changed: 163 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2019-2021 Ilker Temir <ilker@ilkertemir.com>
3-
* Copyright 2021-2024 Francois Lacroix <xbgmsharp@gmail.com>
3+
* Copyright 2021-2025 Francois Lacroix <xbgmsharp@gmail.com>
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -44,8 +44,6 @@ module.exports = function (app) {
4444
var statusProcess;
4545
var db;
4646
var API;
47-
var host;
48-
var token;
4947
var gpsSource;
5048
var status = null;
5149
var metrics = {};
@@ -60,11 +58,12 @@ module.exports = function (app) {
6058
var angleSpeedApparent = 0;
6159
var previousSpeeds = [];
6260
var previousCOGs = [];
61+
var retrieveMonitoringConfigInProgress = false;
6362

6463
var metadata = {
6564
name: app.getSelfPath("name") ? app.getSelfPath("name") : null,
6665
mmsi: app.getSelfPath("mmsi") ? app.getSelfPath("mmsi") : null,
67-
client_id: app.selfContext,
66+
//client_id: app.selfContext,
6867
length: app.getSelfPath("design.length.value.overall")
6968
? app.getSelfPath("design.length.value.overall")
7069
: null,
@@ -81,7 +80,8 @@ module.exports = function (app) {
8180
signalk_version: app.config.version,
8281
time: new Date().toISOString(),
8382
platform: null,
84-
configuration: null,
83+
//configuration: null,
84+
available_keys: null,
8585
};
8686

8787
plugin.id = "signalk-postgsail";
@@ -97,23 +97,23 @@ module.exports = function (app) {
9797

9898
metadata.platform = findPlatform();
9999
app.debug(`Running on ${metadata.platform}`);
100-
metadata.configuration = options;
101100
app.setPluginStatus("PostgSail started. Please wait for a status update.");
101+
configuration = options;
102+
monitoringConfiguration = options?.monitoring == null ? null : options.monitoring;
102103

103-
host = options.host;
104-
token = options.token;
105104
gpsSource = options.source;
106105
app.debug(`host ${options.host}, token:${options.token}`);
107106

108107
API = axios.create({
109-
baseURL: host,
108+
baseURL: options.host,
110109
timeout: 50000,
111110
headers: {
112-
Authorization: `Bearer ${token}`,
111+
Authorization: `Bearer ${options.token}`,
113112
"User-Agent": `postgsail.signalk v${metadata.plugin_version}`,
114113
},
115114
httpsAgent: new https.Agent({ KeepAlive: true }),
116115
});
116+
getConfiguration();
117117
sendMetadata();
118118

119119
let dbFile = filePath.join(app.getDataDirPath(), "postgsail.sqlite3");
@@ -175,7 +175,6 @@ module.exports = function (app) {
175175
} else {
176176
message = `no data in the queue,`;
177177
}
178-
179178
if (lastSuccessfulUpdate) {
180179
let since = timeSince(lastSuccessfulUpdate);
181180
message += ` last connection to the server was ${since} ago.`;
@@ -194,6 +193,8 @@ module.exports = function (app) {
194193
app.setPluginError(
195194
"No navigation.state path, please install signalk-autostate."
196195
);
196+
} else {
197+
app.setPluginError("");
197198
}
198199
}
199200
app.setPluginStatus(message);
@@ -258,7 +259,7 @@ module.exports = function (app) {
258259
return platform;
259260
}
260261

261-
let platform = null;
262+
let platform = "";
262263
try {
263264
const cpuInfo = fs.readFileSync("/proc/cpuinfo", {
264265
encoding: "utf8",
@@ -284,10 +285,99 @@ module.exports = function (app) {
284285
return platform;
285286
}
286287

288+
function saveConfiguration() {
289+
app.savePluginOptions(configuration, () => {
290+
app.debug("Plugin options saved");
291+
});
292+
}
293+
294+
function loadConfiguration() {
295+
let options = app.readPluginOptions();
296+
app.debug("loadConfiguration", options);
297+
configuration = options.configuration;
298+
}
299+
300+
function getConfiguration(update = false) {
301+
if (retrieveMonitoringConfigInProgress) {
302+
app.debug("Monitoring configuration retrieval already in progress");
303+
return;
304+
}
305+
retrieveMonitoringConfigInProgress = true;
306+
let url = "/metadata?select=configuration";
307+
if (update && configuration?.monitoring?.update_at) {
308+
url += "&configuration->>update_at=gt." + configuration.monitoring.update_at;
309+
}
310+
app.debug("Retrieving monitoring configuration", url);
311+
API.get(url)
312+
.then(function (response) {
313+
//console.log(response);
314+
//app.debug(response);
315+
if (
316+
response &&
317+
response.status == 200 &&
318+
Array.isArray(response.data) &&
319+
response.data.length > 0
320+
) {
321+
app.debug("Successfully retrieved monitoring configuration");
322+
app.debug("Server monitoring configuration", response.data[0].configuration);
323+
app.debug("Local current configuration", configuration);
324+
if (typeof response.data[0].configuration !== "object") {
325+
app.debug("Invalid monitoring configuration, ignore");
326+
return;
327+
}
328+
configuration["monitoring"] = response.data[0].configuration;
329+
saveConfiguration();
330+
retrieveMonitoringConfigInProgress = false;
331+
}
332+
})
333+
.catch(function (error) {
334+
app.debug(error);
335+
app.debug("Retrieving monitoring configuration failed");
336+
console.log(
337+
"signalk-postgsail - Retrieving monitoring configuration failed"
338+
);
339+
app.debug(
340+
"Failed to get monitoring configuration, trying to load from local storage"
341+
);
342+
loadConfiguration();
343+
retrieveMonitoringConfigInProgress = false;
344+
});
345+
}
346+
287347
function sendMetadata() {
348+
function getAllKeys(obj, parentKey = "", result = []) {
349+
for (let key in obj) {
350+
if (obj.hasOwnProperty(key)) {
351+
const newKey = parentKey ? `${parentKey}.${key}` : key;
352+
if (obj[key] !== null && typeof obj[key] === "object") {
353+
if (obj[key]["$source"]) {
354+
if (
355+
obj[key].value !== null &&
356+
typeof obj[key].value === "number"
357+
) {
358+
result.push({
359+
key: newKey,
360+
unit: obj[key]?.meta?.units ?? null,
361+
});
362+
}
363+
} else {
364+
getAllKeys(obj[key], newKey, result);
365+
}
366+
}
367+
}
368+
}
369+
return result;
370+
}
371+
372+
let self = app.getPath("self");
373+
let dataModel = app.getPath(self);
374+
let availableKeys = getAllKeys(dataModel);
375+
//console.log(availableKeys);
376+
app.debug('available_keys: ', availableKeys);
377+
metadata.available_keys = availableKeys;
288378
// Update metadata time
289379
metadata.time = new Date().toISOString();
290-
app.debug("DEBUG: metadata:", metadata);
380+
app.debug("Sending metadata to the server: ", metadata);
291381
API.post("/metadata?on_conflict=vessel_id", metadata, {
292382
headers: {
293383
Prefer: "return=headers-only,resolution=merge-duplicates",
@@ -300,6 +390,7 @@ module.exports = function (app) {
300390
//app.debug(response);
301391
lastSuccessfulUpdate = Date.now();
302392
submitDataToServer();
393+
getConfiguration(true)
303394
}
304395
})
305396
.catch(function (error) {
@@ -358,6 +449,16 @@ module.exports = function (app) {
358449
return;
359450
}
360451

452+
let monitoringDataInJson = null;
453+
if (configuration?.monitoring) {
454+
let monitoringData = getMonitoringData(configuration.monitoring);
455+
//monitoringDataInJson = JSON.stringify(monitoringData);
456+
metrics = Object.assign(metrics, monitoringData);
457+
} else {
458+
getConfiguration();
459+
monitoringDataInJson = null;
460+
}
461+
361462
let values = [
362463
new Date().toISOString(),
363464
null,
@@ -843,8 +944,11 @@ module.exports = function (app) {
843944
/* Skip String, Object (typeof?) or skip Moon, Sun, Course */
844945
// environment.moon.*
845946
// environment.sunlight.*
947+
// environment.forecast.*
846948
// navigation.courseGreatCircle.*
847949
// design.*
950+
// entertainment.*
951+
// observations.*
848952

849953
// Debug
850954
//app.debug(`default: path '${path}' is invalid?, '${value}'`);
@@ -876,5 +980,51 @@ module.exports = function (app) {
876980
return Number(n) === n;
877981
};
878982

983+
function getMonitoringData(configuration) {
984+
let data = {
985+
sog: getKeyValue('navigation.speedOverGround', 60),
986+
cog: getKeyValue('navigation.courseOverGroundTrue', 60),
987+
heading: getKeyValue('navigation.headingTrue', 60),
988+
anchor: {
989+
position: getKeyValue('navigation.anchor.position', 60),
990+
radius: getKeyValue('navigation.anchor.maxRadius', 60)
991+
},
992+
water: {
993+
depth: getKeyValue(configuration.depthKey, 10),
994+
temperature:getKeyValue(configuration.waterTemperatureKey, 90)
995+
},
996+
wind: {
997+
speed: getKeyValue(configuration.windSpeedKey, 90),
998+
direction: getKeyValue(configuration.windDirectionKey, 90)
999+
},
1000+
temperature: {
1001+
inside: getKeyValue(configuration.insidePressureKey, 90),
1002+
outside: getKeyValue(configuration.outsidePressureKey, 90)
1003+
},
1004+
temperature: {
1005+
inside: getKeyValue(configuration.insideTemperatureKey, 90),
1006+
outside: getKeyValue(configuration.outsideTemperatureKey, 90)
1007+
},
1008+
humidity: {
1009+
inside: getKeyValue(configuration.insideHumidityKey, 90),
1010+
outside: getKeyValue(configuration.outsideHumidityKey, 90)
1011+
},
1012+
battery: {
1013+
voltage: getKeyValue(configuration.batteryVoltageKey, 60),
1014+
charge: getKeyValue(configuration.batteryChargeKey, 60)
1015+
}
1016+
};
1017+
1018+
for (let i = 0; i < configuration?.additionalDataKeys?.length; i++) {
1019+
let key = configuration.additionalDataKeys[i];
1020+
let value = getKeyValue(key, 90);
1021+
if (value) {
1022+
data[key] = value;
1023+
}
1024+
}
1025+
1026+
return data;
1027+
}
1028+
8791029
return plugin;
8801030
};

0 commit comments

Comments
 (0)