246 lines
7.9 KiB
JavaScript
246 lines
7.9 KiB
JavaScript
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, options = { mode: 'both' }) {
|
|
|
|
const mode = options.mode || 'both';
|
|
const params = [];
|
|
|
|
const currentParams = FORECAST_PARAMS.current.join(",");
|
|
const hourlyParams = FORECAST_PARAMS.hourly.join(",");
|
|
|
|
if (mode === 'both' || mode === 'current') {
|
|
params.push('current=' + currentParams);
|
|
}
|
|
|
|
if (mode === 'both' || mode === 'hourly') {
|
|
params.push('hourly=' + hourlyParams);
|
|
}
|
|
|
|
if (!location?.latitude || !location?.longitude) {
|
|
console.warn('[OpenMeteo] Coordinate non valide per forecast');
|
|
return null;
|
|
}
|
|
|
|
const api = `https://api.open-meteo.com/v1/forecast?latitude=${location.latitude}&longitude=${location.longitude}&${params.join('&')}`;
|
|
|
|
try {
|
|
const response = await axios.get(api, {
|
|
headers: HEADERS,
|
|
timeout: TIMEOUT,
|
|
validateStatus: (status) => status === 200
|
|
});
|
|
|
|
const { data } = response;
|
|
|
|
// 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 {
|
|
timestamp: Date.now(),
|
|
temperature: data.current?.temperature_2m ?? null,
|
|
humidity: data.current?.relative_humidity_2m ?? null,
|
|
pressure: data.current?.pressure_msl ?? null,
|
|
|
|
// Refactored to match sensorsReferences.json hierarchy
|
|
wind: {
|
|
speed: data.current?.wind_speed_10m ?? null,
|
|
direction: data.current?.wind_direction_10m ?? null,
|
|
gusts: data.current?.wind_gusts_10m ?? null,
|
|
},
|
|
|
|
rain: data.current?.rain ?? null,
|
|
precipitation: data.current?.precipitation ?? null, // Keeping simple properties flat
|
|
|
|
// Unita di misura
|
|
units: globalUnits.forecast,
|
|
// Parametri orari
|
|
hourly: data.hourly ? {
|
|
time: data.hourly?.time,
|
|
temperature: data.hourly?.temperature_2m,
|
|
pressure: data.hourly?.pressure_msl,
|
|
precipitationProbability: data.hourly?.precipitation_probability,
|
|
precipitation: data.hourly?.precipitation,
|
|
rain: data.hourly?.rain,
|
|
cloudCover: data.hourly?.cloud_cover,
|
|
windDirection: data.hourly?.wind_direction_10m,
|
|
humidity: data.hourly?.relative_humidity_2m,
|
|
windSpeed: data.hourly?.wind_speed_10m
|
|
} : null,
|
|
hourlyUnits: data.hourly_units || null
|
|
};
|
|
} catch (error) {
|
|
console.error(`[OpenMeteo Forecast] Errore: ${error.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function getSeaConditions(location, options = { mode: 'both' }) {
|
|
|
|
const mode = options.mode || 'both';
|
|
const params = [];
|
|
|
|
const currentParams = MARINE_PARAMS.current.join(",");
|
|
const hourlyParams = MARINE_PARAMS.hourly.join(",");
|
|
|
|
if (mode === 'both' || mode === 'current') {
|
|
params.push('current=' + currentParams);
|
|
}
|
|
|
|
if (mode === 'both' || mode === 'hourly') {
|
|
params.push('hourly=' + hourlyParams);
|
|
}
|
|
|
|
if (!location?.latitude || !location?.longitude) {
|
|
console.warn('[OpenMeteo] Coordinate non valide per onde');
|
|
return null;
|
|
}
|
|
|
|
const api = `https://marine-api.open-meteo.com/v1/marine?latitude=${location.latitude}&longitude=${location.longitude}&${params.join('&')}&models=ecmwf_wam`;
|
|
|
|
try {
|
|
const response = await axios.get(api, {
|
|
headers: HEADERS,
|
|
timeout: TIMEOUT,
|
|
validateStatus: (status) => status === 200
|
|
});
|
|
|
|
const { data } = response;
|
|
|
|
// 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 {
|
|
// Refactored to match sensorsReferences.json hierarchy
|
|
waves: {
|
|
height: data.current?.wave_height ?? null,
|
|
period: data.current?.wave_period ?? null,
|
|
direction: data.current?.wave_direction ?? null,
|
|
peakPeriod: data.current?.wave_peak_period ?? null
|
|
},
|
|
|
|
// Keeping these flat essentially
|
|
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: data.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
|
|
} : null,
|
|
hourlyUnits: data.hourly_units || null
|
|
};
|
|
} catch (error) {
|
|
console.error(`[OpenMeteo Marine] Errore: ${error.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
module.exports = { getSeaConditions, getForecast, getUnits, formatWithUnit }; |