const axios = require('axios'); const TIMEOUT = 10000; const HEADERS = { Accept: "application/json, text/plain;q=0.9,*/*;q=0.8" }; // Parametri API const FORECAST_PARAMS = { current: [ 'temperature_2m', 'wind_speed_10m', 'wind_direction_10m', 'wind_gusts_10m', 'precipitation', 'rain', 'relative_humidity_2m', 'pressure_msl' ], hourly: [ 'temperature_2m', 'precipitation_probability', 'precipitation', 'rain', 'wind_speed_10m', 'cloud_cover', 'wind_direction_10m', 'relative_humidity_2m', 'pressure_msl' ] }; const MARINE_PARAMS = { current: [ 'wave_height', 'wave_direction', 'wave_period', 'wave_peak_period', 'ocean_current_velocity', 'ocean_current_direction' ], hourly: [ 'wave_height', 'wave_direction', 'wave_period', 'wave_peak_period', 'ocean_current_velocity', 'ocean_current_direction' ] }; // Unità di misura globali (aggiornate da OpenMeteo) let globalUnits = { forecast: { temperature: '°C', humidity: '%', pressure: 'hPa', windSpeed: 'km/h', windDirection: '°', windGusts: 'km/h', rain: 'mm', precipitation: 'mm' }, waves: { waveHeight: 'm', wavePeriod: 's', waveDirection: '°', wavePeakPeriod: 's' } }; /** * Ottiene le unità di misura globali */ function getUnits() { return globalUnits; } /** * Formatta un valore con la sua unità */ function formatWithUnit(value, unitKey, category = 'forecast') { if (value === null || value === undefined) return 'n/d'; const unit = globalUnits[category]?.[unitKey] || ''; return `${value}${unit}`; } async function getForecast(location) { if (!location?.latitude || !location?.longitude) { console.warn('[OpenMeteo] Coordinate non valide per forecast'); return null; } const currentParams = FORECAST_PARAMS.current.join(","); const hourlyParams = FORECAST_PARAMS.hourly.join(","); const api = `https://api.open-meteo.com/v1/forecast?latitude=${location.latitude}&longitude=${location.longitude}&hourly=${hourlyParams}¤t=${currentParams}`; try { const response = await axios.get(api, { headers: HEADERS, timeout: TIMEOUT, validateStatus: (status) => status === 200 }); const { data } = response; if (!data?.current) { console.warn('[OpenMeteo Forecast] Risposta senza dati current'); return null; } // Aggiorna unità globali da API response if (data.current_units) { globalUnits.forecast = { temperature: data.current_units.temperature_2m || '°C', humidity: data.current_units.relative_humidity_2m || '%', pressure: data.current_units.pressure_msl || 'hPa', windSpeed: data.current_units.wind_speed_10m || 'km/h', windDirection: data.current_units.wind_direction_10m || '°', windGusts: data.current_units.wind_gusts_10m || 'km/h', rain: data.current_units.rain || 'mm', precipitation: data.current_units.precipitation || 'mm' }; } return { temperature: data.current.temperature_2m ?? null, humidity: data.current.relative_humidity_2m ?? null, pressure: data.current.pressure_msl ?? null, windSpeed: data.current.wind_speed_10m ?? null, windDirection: data.current.wind_direction_10m ?? null, windGusts: data.current.wind_gusts_10m ?? null, rain: data.current.rain ?? null, precipitation: data.current.precipitation ?? null, // Unità di misura units: globalUnits.forecast, // Dati orari per grafici hourly: { time: data.hourly?.time, temperature: data.hourly?.temperature_2m, humidity: data.hourly?.relative_humidity_2m, windSpeed: data.hourly?.wind_speed_10m }, hourlyUnits: data.hourly_units || null }; } catch (error) { console.error(`[OpenMeteo Forecast] Errore: ${error.message}`); return null; } } async function getSeaConditions(location) { if (!location?.latitude || !location?.longitude) { console.warn('[OpenMeteo] Coordinate non valide per onde'); return null; } const currentParams = MARINE_PARAMS.current.join(","); const hourlyParams = MARINE_PARAMS.hourly.join(","); const api = `https://marine-api.open-meteo.com/v1/marine?latitude=${location.latitude}&longitude=${location.longitude}&hourly=${hourlyParams}¤t=${currentParams}&models=ecmwf_wam`; try { const response = await axios.get(api, { headers: HEADERS, timeout: TIMEOUT, validateStatus: (status) => status === 200 }); const { data } = response; if (!data?.current) { console.warn('[OpenMeteo Marine] Risposta senza dati current'); return null; } // Aggiorna unità globali da API response if (data.current_units) { globalUnits.waves = { waveHeight: data.current_units.wave_height || 'm', wavePeriod: data.current_units.wave_period || 's', waveDirection: data.current_units.wave_direction || '°', wavePeakPeriod: data.current_units.wave_peak_period || 's', currentVelocity: data.current_units.ocean_current_velocity || 'm/s', currentDirection: data.current_units.ocean_current_direction || '°' }; } return { waveHeight: data.current.wave_height ?? null, wavePeriod: data.current.wave_period ?? null, waveDirection: data.current.wave_direction ?? null, wavePeakPeriod: data.current.wave_peak_period ?? null, currentDirection: data.current.ocean_current_direction ?? null, currentVelocity: data.current.ocean_current_velocity ?? null, // Unità di misura units: globalUnits.waves, // Dati orari per grafici hourly: { time: data.hourly?.time, waveHeight: data.hourly?.wave_height, wavePeriod: data.hourly?.wave_period, waveDirection: data.hourly?.wave_direction, currentDirection: data.hourly?.ocean_current_direction, currentVelocity: data.hourly?.ocean_current_velocity }, hourlyUnits: data.hourly_units || null }; } catch (error) { console.error(`[OpenMeteo Marine] Errore: ${error.message}`); return null; } } module.exports = { getSeaConditions, getForecast, getUnits, formatWithUnit };