const settingsSchema = require('./config/skSettings.js') const configManager = require('./config/configManager.js') const routes = require('./routes/main.js') const openmeteo = require('./cores/openmeteo.js') const skFlow = require('./config/skFlow.js') const telegram = require('./telegram/core.js') const recorder = require('./cores/logs.local.js') const realtime = require('./cores/realtime/core.js') const { LOG_PATHS } = require('./rules') module.exports = function(app) { const plugin = {}; plugin.id = 'meb.plugin'; plugin.name = 'MEB Plugin'; plugin.description = 'MEB custom plugin'; plugin.version = '1.5.0'; plugin.start = async function(options) { // Inizializza il gestore della configurazione con le opzioni del plugin configManager.init(options); // Setup routing if (process.env.NODE_ENV === 'development') { app.debug('Running in DEVELOPMENT mode: routes will be reloaded on every request'); app.use('/meb', (req, res, next) => { const path = require('path'); const routesPath = path.resolve(__dirname, 'routes'); Object.keys(require.cache).forEach(key => { if (key.startsWith(routesPath)) { delete require.cache[key]; } }); require('./routes/main.js')(req, res, next); }); } else { app.debug('Running in PRODUCTION mode: routes are cached'); app.use('/meb', routes); } // Inizializza il modulo per la pubblicazione dei dati Signal K skFlow.init(app); // Inizializza il bot Telegram telegram.init(); // Avvia la connessione realtime al server realtime.init(); // Inizializza e avvia subito la registrazione log (1 riga/secondo) recorder.init(LOG_PATHS); try { await recorder.startRecording(); } catch (err) { console.warn('[INDEX] Errore avvio recording, proseguo:', err.message); } // ===== Weather & Forecast ===== const fetchWeather = async () => { try { const position = skFlow.get('navigation.position'); if (position) { await openmeteo.fetchCurrentWeather(position); } } catch (err) { console.error('[INDEX] Errore fetchCurrentWeather:', err.message); } }; const fetchForecasts = async () => { try { const position = skFlow.get('navigation.position'); if (position) { await openmeteo.fetchHourlyForecasts(position); } } catch (err) { console.error('[INDEX] Errore fetchHourlyForecasts:', err.message); } }; // Intervalli: current ogni 5 min, hourly ogni 1 ora const startWeatherIntervals = () => { setInterval(fetchWeather, 5 * 60 * 1000); setInterval(fetchForecasts, 60 * 60 * 1000); }; // Aspetta la posizione GPS, poi avvia il fetch meteo const position = skFlow.get('navigation.position'); if (position) { await openmeteo.fetchAll(position); startWeatherIntervals(); } else { const waitForPosition = setInterval(async () => { const pos = skFlow.get('navigation.position'); if (pos) { clearInterval(waitForPosition); await openmeteo.fetchAll(pos); startWeatherIntervals(); } }, 2000); } } plugin.stop = function() { recorder.stopRecording(); realtime.stop(); app.debug('Plugin stopped'); } plugin.schema = settingsSchema return plugin; }