diff --git a/README.md b/README.md index 2c17438..792c074 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,46 @@ In questa repository è presente il plugin MEB per SignalK. -Ulteriori informazioni verranno aggiunte nelle prossime versioni \ No newline at end of file +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= \ No newline at end of file diff --git a/plugin/bot/telegram.core.js b/plugin/bot/telegram.core.js index bc51d8a..ead4f21 100644 --- a/plugin/bot/telegram.core.js +++ b/plugin/bot/telegram.core.js @@ -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); } diff --git a/plugin/config.js b/plugin/config.js index 8d1aafa..af6fcf3 100644 --- a/plugin/config.js +++ b/plugin/config.js @@ -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 }; \ No newline at end of file +const config = { + telegramBotToken: process.env.TELEGRAM_BOT_TOKEN, + paths +}; + +module.exports = { config, paths }; \ No newline at end of file diff --git a/plugin/datasetModels/graphsCore.js b/plugin/datasetModels/graphsCore.js index 1391ce9..f6724ea 100644 --- a/plugin/datasetModels/graphsCore.js +++ b/plugin/datasetModels/graphsCore.js @@ -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 = { diff --git a/plugin/index.cjs b/plugin/index.cjs index c6d7b83..db2e134 100644 --- a/plugin/index.cjs +++ b/plugin/index.cjs @@ -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); diff --git a/plugin/sensors.references.json b/plugin/sensors.references.json deleted file mode 100644 index 6690683..0000000 --- a/plugin/sensors.references.json +++ /dev/null @@ -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" - } - ] -} \ No newline at end of file