138 lines
4.9 KiB
JavaScript
138 lines
4.9 KiB
JavaScript
const dotenv = require("dotenv");
|
|
const path = require("path");
|
|
const fs = require("fs");
|
|
|
|
dotenv.config({ path: path.resolve(__dirname, "..", ".env"), quiet: true });
|
|
|
|
const SIGNALK_FILES = process.env.SIGNALK_FILES || path.resolve(__dirname);
|
|
|
|
function checkFolder(dirPath) {
|
|
try {
|
|
fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);
|
|
} catch (err) {
|
|
if (err.code === 'ENOENT') {
|
|
fs.mkdirSync(dirPath, {
|
|
recursive: true,
|
|
mode: 0o777
|
|
});
|
|
} else {
|
|
throw new Error(`Permission denied for ${dirPath}`);
|
|
}
|
|
}
|
|
return dirPath;
|
|
}
|
|
|
|
const paths = {
|
|
base: SIGNALK_FILES,
|
|
|
|
logs: checkFolder(path.join(SIGNALK_FILES, "logs")),
|
|
hourlyArchive: path.join(SIGNALK_FILES, "logs", "hourly_archive.json"),
|
|
logsReferences: path.join(SIGNALK_FILES, "logs", "logs_references.json"),
|
|
savedDatas: checkFolder(path.join(SIGNALK_FILES, "logs", "saved_datas")),
|
|
|
|
private: checkFolder(path.join(SIGNALK_FILES, "private")),
|
|
authorizedAdmins: path.join(SIGNALK_FILES, "private", "authorized_admins.txt"),
|
|
telegramUsers: path.join(SIGNALK_FILES, "private", "telegram_users.json"),
|
|
|
|
sensorsReferences: path.join(__dirname, "sensors", "sensors.references.json")
|
|
};
|
|
|
|
const config = {
|
|
telegramBotToken: process.env.TELEGRAM_BOT_TOKEN,
|
|
mapboxKey: process.env.MAPBOX_KEY,
|
|
cloudUrl: process.env.CLOUD_URL || "https://realtime.mebcloud.it",
|
|
cloudApiKey: process.env.CLOUD_API_KEY,
|
|
realtimeUrl: process.env.REALTIME_URL || 'http://realtime:3002',
|
|
paths
|
|
};
|
|
|
|
/**
|
|
* Carica la configurazione sensori dal server (con fallback locale).
|
|
* Se viene fornito un ticket, usa l'endpoint autenticato /sensors/data/references.
|
|
* Altrimenti usa l'endpoint pubblico /sensors/references (legacy).
|
|
*
|
|
* @param {string|null} ticket - Ticket di autenticazione (opzionale)
|
|
* @returns {Promise<Object|null>} { items, version, isActive } o null
|
|
*/
|
|
async function loadSensorReferencesFromServer(ticket = null) {
|
|
// Tentativo 1: Endpoint autenticato (con ticket)
|
|
if (ticket) {
|
|
const authUrl = config.realtimeUrl + '/sensors/data/references';
|
|
try {
|
|
const controller = new AbortController();
|
|
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
|
|
const res = await fetch(authUrl, {
|
|
signal: controller.signal,
|
|
headers: { 'Authorization': `Bearer ${ticket}` }
|
|
});
|
|
clearTimeout(timeout);
|
|
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
console.log(`[MEB] Sensor references caricati (autenticato, v: ${data.version})`);
|
|
return data;
|
|
}
|
|
console.warn(`[MEB] Endpoint autenticato HTTP ${res.status}, provo fallback pubblico`);
|
|
} catch (err) {
|
|
console.warn(`[MEB] Endpoint autenticato fallito: ${err.message}, provo fallback pubblico`);
|
|
}
|
|
}
|
|
|
|
// Tentativo 2: Endpoint pubblico (legacy)
|
|
const publicUrl = config.realtimeUrl + '/sensors/references';
|
|
try {
|
|
const controller = new AbortController();
|
|
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
|
|
const res = await fetch(publicUrl, { signal: controller.signal });
|
|
clearTimeout(timeout);
|
|
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
console.log(`[MEB] Sensor references caricati dal server (versione: ${data.version})`);
|
|
return data;
|
|
}
|
|
console.warn(`[MEB] Server sensor refs HTTP ${res.status}, uso fallback locale`);
|
|
} catch (err) {
|
|
console.warn(`[MEB] Impossibile caricare sensor refs dal server: ${err.message}`);
|
|
}
|
|
|
|
// Tentativo 3: File locale
|
|
try {
|
|
const raw = fs.readFileSync(paths.sensorsReferences, 'utf-8');
|
|
const data = JSON.parse(raw);
|
|
console.log(`[MEB] Sensor references caricati da file locale (versione: ${data.version})`);
|
|
return data;
|
|
} catch (err) {
|
|
console.error(`[MEB] Nessuna sorgente sensor refs disponibile: ${err.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Controlla se la versione dei sensor references sul server e' cambiata.
|
|
* Ritorna la nuova versione se diversa, null altrimenti.
|
|
*/
|
|
async function checkSensorReferencesVersion(currentVersion) {
|
|
const url = config.realtimeUrl + '/sensors/references/version';
|
|
try {
|
|
const controller = new AbortController();
|
|
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
|
|
const res = await fetch(url, { signal: controller.signal });
|
|
clearTimeout(timeout);
|
|
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
if (data.version && data.version !== currentVersion) {
|
|
return data.version;
|
|
}
|
|
}
|
|
} catch {
|
|
// Silenzioso: il polling della versione non e' critico
|
|
}
|
|
return null;
|
|
}
|
|
|
|
module.exports = { config, paths, loadSensorReferencesFromServer, checkSensorReferencesVersion }; |