Aggiunge 2 nuove variabili d'ambiente:

- SIGNALK_FILES, per specificare dove verranno salvati i file generati dal plugin
- HOST_NAME, per specificare il nome del dispositivo che sta hostando il plugin.

Inoltre, migliora il codice e lo adatta al nuovo path variabile SIGNALK_FILES
This commit is contained in:
Giuseppe Raffa
2026-01-06 18:08:25 +01:00
parent ff1566d36b
commit 8d96d35b24
6 changed files with 106 additions and 81 deletions

View File

@@ -1,2 +1,46 @@
In questa repository è presente il plugin MEB per SignalK.
Ulteriori informazioni verranno aggiunte nelle prossime versioni
Ulteriori informazioni verranno aggiunte nelle prossime versioni
# Variabili d'Ambiente
Prima di avviare il plugin sul SignalK, è necessario configurare il file di variabili d'ambiente.
**Ricorda**:
Inserisci i valori di chiavi, percorsi di file o altro subito dopo il simbolo di uguale, senza parentesi, virgolette o altro
_Una volta creato il file env, aggiungi:_
### Chiave di Criptazione
Utilizzata per criptare i dati come i riferimenti dei log, i file di log registrati o gli utenti admin.
Aggiungi nel file env una riga come questa:
CRYPTOKEY=
### Nome dell'Host
Usato per identificare meglio, sopratutto nei casi di test temporanei, il dispositivo in cui il server SignalK è attivo.
Aggiungi nel file env una riga come questa:
HOST_NAME=
### Token Telegram
Il plugin anima un Bot Telegram. Per ragioni di sicurezza, il token che è l'identificativo del bot deve essere protetto e salvato all'interno delle variabili d'ambiente.
Aggiungi nel file env una riga come questa:
TELEGRAM_BOT_TOKEN=
### Percorso dei file
Il plugin genera file all'interno del server SignalK, come i log o file criptati. Specifica il percorso globale all'interno del tuo dispositivo nel quale vuoi che il plugin inserisca e modifichi i dati generati.
Aggiungi nel file env una riga come questa:
SIGNALK_FILES=

View File

@@ -5,6 +5,7 @@
const fs = require("fs");
const path = require("path");
const { paths } = require("../config.js");
const {
encrypt,
decrypt,
@@ -64,9 +65,9 @@ const CONFIG = {
fileExpirationTime: 10
};
const telegram_users_file = path.join(__dirname, "..", "telegram_users.json");
const logs_references_file = path.join(__dirname, "..", "datasetModels/logs_references.json");
const authorized_admins_file = path.join(__dirname, "..", "authorized_admins.txt");
const telegram_users_file = paths.telegramUsers;
const logs_references_file = paths.logsReferences;
const authorized_admins_file = paths.authorizedAdmins;
let app = null;
@@ -287,13 +288,24 @@ function getCurrentPosition() {
}
async function send(message) {
if (!bot) return;
if (!bot) {
console.warn('[Telegram] send() chiamato ma bot non inizializzato');
return;
}
const users = loadUsers();
const loggedUsers = users.filter(u => u.hasLoggedYet && u.chatID);
console.log(`[Telegram] send() - Utenti totali: ${users.length}, Utenti loggati: ${loggedUsers.length}`);
if (loggedUsers.length === 0) {
console.warn('[Telegram] Nessun utente loggato a cui inviare il messaggio');
return;
}
for (const user of loggedUsers) {
try {
await bot.sendMessage(user.chatID, message);
console.log(`[Telegram] Messaggio inviato a ${user.chatID}`);
} catch (error) {
console.error(`[Telegram] Send error to ${user.chatID}:`, error.message);
}

View File

@@ -1,11 +1,46 @@
const dotenv = require("dotenv");
const path = require("path");
const fs = require("fs");
// Carica il file .env dalla root del plugin
dotenv.config({ path: path.resolve(__dirname, "..", ".env"), quiet: true });
const config = {
telegramBotToken: process.env.TELEGRAM_BOT_TOKEN,
// Base path per tutti i file generati dal server
const SIGNALK_FILES = process.env.SIGNALK_FILES || path.resolve(__dirname, "..", "data");
// Crea le directory necessarie se non esistono
function ensureDir(dirPath) {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
console.log(`[Config] Creata directory: ${dirPath}`);
}
return dirPath;
}
// Paths per i vari tipi di file
const paths = {
// Base
base: SIGNALK_FILES,
// Logs: hourly_archive.json, logs_references.json, saved_datas/
logs: ensureDir(path.join(SIGNALK_FILES, "logs")),
hourlyArchive: path.join(SIGNALK_FILES, "logs", "hourly_archive.json"),
logsReferences: path.join(SIGNALK_FILES, "logs", "logs_references.json"),
savedDatas: ensureDir(path.join(SIGNALK_FILES, "logs", "saved_datas")),
// Private: authorized_admins.txt, telegram_users.json
private: ensureDir(path.join(SIGNALK_FILES, "private")),
authorizedAdmins: path.join(SIGNALK_FILES, "private", "authorized_admins.txt"),
telegramUsers: path.join(SIGNALK_FILES, "private", "telegram_users.json"),
// Sensors: sensors.references.json
sensors: ensureDir(path.join(SIGNALK_FILES, "sensors")),
sensorsReferences: path.join(SIGNALK_FILES, "sensors", "sensors.references.json")
};
module.exports = { config };
const config = {
telegramBotToken: process.env.TELEGRAM_BOT_TOKEN,
paths
};
module.exports = { config, paths };

View File

@@ -1,7 +1,8 @@
const fs = require('fs');
const path = require('path');
const { paths } = require('../config.js');
const ARCHIVE_FILE = path.join(__dirname, 'hourly_archive.json');
const ARCHIVE_FILE = paths.hourlyArchive;
// Cache dati OpenMeteo condivisi (evita chiamate duplicate)
let sharedWeatherData = {

View File

@@ -1,4 +1,4 @@
const { config } = require("./config.js");
const { config, paths } = require("./config.js");
const { setupRoutes, getOpenApiSpec } = require("./tools/routes.js");
const { aisStream } = require("./api_models/aisstream.js")
const mapHandler = require("./tools/map.handler.js");
@@ -81,8 +81,8 @@ const state = {
startTime: null
};
const logsDirectory = dataUtils.getDirectory(__dirname + '/datasetModels/saved_datas');
const logsReferencesFile = path.join(__dirname, 'datasetModels/logs_references.json');
const logsDirectory = dataUtils.getDirectory(paths.savedDatas);
const logsReferencesFile = paths.logsReferences;
const lastCallRef = { current: null };
@@ -506,7 +506,8 @@ module.exports = function (app) {
if (config.telegramBotToken) {
try {
await linkBot(app);
await send("✅ Computer di bordo attivo e pronto.");
let deviceName = process.env.HOST_NAME || 'Dispositivo Sconosciuto';
await send(`Il bot è di nuovo disponibile. (Avviato da ${deviceName})`);
console.log('[MEB TELEGRAM] Bot avviato con app.intervalControl disponibile');
} catch (error) {
console.error('[ERROR] Errore nell\'avvio del bot telegram', error);

View File

@@ -1,68 +0,0 @@
{
"production": [
{
"collection": "temperature",
"main_path": "meb.temperature",
"elements": null
},
{
"collection": "wind",
"main_path": "meb.wind",
"elements": [
{"direction": "direction"},
{"speed": "speed"}
]
},
{
"collection": "waves",
"main_path": "meb.waves",
"elements": [
{"direction": "direction"},
{"height": "height"},
{"period": "period"}
]
},
{
"collection": "position",
"main_path": "navigation",
"elements": [
{"latitude": "position.latitude"},
{"longitude": "position.longitude"},
{"headingTrue": "headingTrue"},
{"speedOverGround": "speedOverGround"},
{"courseOverGround": "courseOverGroundTrue"}
]
},
{
"collection": "service_battery",
"main_path": "electrical.batteries.service",
"elements": [
{"voltage": "Voltage"},
{"current": "current"},
{"stateOfCharge": "stateOfCharge"}
]
},
{
"collection": "traction_battery",
"main_path": "electrical.batteries.traction",
"elements": [
{"voltage": "Voltage"},
{"current": "current"},
{"stateOfCharge": "stateOfCharge"},
{"temperature": "temperature"},
{"power": "power"}
]
},
{
"collection": "engine",
"main_path": "propulsion.0",
"elements": [
{"proipultionShaftSpeed": "revolutions"}
]
},
{
"collection": "system",
"main_path": "system.uptime"
}
]
}