@angelrove/forecast-utils 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1046 -0
- package/dist/types/OpenMeteo/conf.d.ts +13 -0
- package/dist/types/OpenMeteo/current/fetchParams.d.ts +1 -0
- package/dist/types/OpenMeteo/current/transformer.d.ts +13 -0
- package/dist/types/OpenMeteo/current/useForecastCurrent.d.ts +14 -0
- package/dist/types/OpenMeteo/daily/fetchParams.d.ts +1 -0
- package/dist/types/OpenMeteo/daily/transformer.d.ts +9 -0
- package/dist/types/OpenMeteo/daily/useForecastDaily.d.ts +14 -0
- package/dist/types/OpenMeteo/helpers.d.ts +10 -0
- package/dist/types/OpenMeteo/hourly/fetchParams.d.ts +1 -0
- package/dist/types/OpenMeteo/hourly/useForecastHourly.d.ts +15 -0
- package/dist/types/OpenMeteo/weatherSymbol/lib/WeatherCodesEn.d.ts +43 -0
- package/dist/types/OpenMeteo/weatherSymbol/lib/WeatherCodesEs.d.ts +43 -0
- package/dist/types/OpenMeteo/weatherSymbol/lib/getWeatherCodeEntry.d.ts +7 -0
- package/dist/types/OpenMeteo/weatherSymbol/weatherSymbol.d.ts +13 -0
- package/dist/types/astronomy/moon/MoonCalc.d.ts +63 -0
- package/dist/types/astronomy/moon/parseBasicData.d.ts +8 -0
- package/dist/types/astronomy/sun/SunCalc.d.ts +73 -0
- package/dist/types/astronomy/sun/helpers.d.ts +0 -0
- package/dist/types/astronomy/timeZoneInfo.d.ts +10 -0
- package/dist/types/astronomy/timehelpers.d.ts +27 -0
- package/dist/types/astronomy/types.d.ts +43 -0
- package/dist/types/geolocation/getGeolocation.d.ts +12 -0
- package/dist/types/geolocation/lib/geolocation.d.ts +10 -0
- package/dist/types/geolocation/lib/geolocationCapacitor.d.ts +10 -0
- package/dist/types/geolocation/lib/reversegeocoding.d.ts +19 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/utils/degreesToCompass.d.ts +11 -0
- package/dist/types/utils/warning.d.ts +46 -0
- package/dist/types/utils/wind/WindArrow.d.ts +32 -0
- package/dist/types/utils/wind/windArrowTx.d.ts +9 -0
- package/dist/types/utils/wind/windLevel.d.ts +29 -0
- package/package.json +40 -0
- package/src/OpenMeteo/conf.js +47 -0
- package/src/OpenMeteo/current/fetchParams.js +21 -0
- package/src/OpenMeteo/current/transformer.js +37 -0
- package/src/OpenMeteo/current/useForecastCurrent.js +34 -0
- package/src/OpenMeteo/daily/fetchParams.js +9 -0
- package/src/OpenMeteo/daily/transformer.js +21 -0
- package/src/OpenMeteo/daily/useForecastDaily.js +38 -0
- package/src/OpenMeteo/helpers.js +19 -0
- package/src/OpenMeteo/hourly/fetchParams.js +12 -0
- package/src/OpenMeteo/hourly/useForecastHourly.js +42 -0
- package/src/OpenMeteo/weatherSymbol/lib/WeatherCodesEn.js +89 -0
- package/src/OpenMeteo/weatherSymbol/lib/WeatherCodesEs.js +81 -0
- package/src/OpenMeteo/weatherSymbol/lib/getWeatherCodeEntry.js +12 -0
- package/src/OpenMeteo/weatherSymbol/weatherSymbol.js +60 -0
- package/src/astronomy/moon/MoonCalc.js +171 -0
- package/src/astronomy/moon/parseBasicData.js +38 -0
- package/src/astronomy/sun/SunCalc.js +167 -0
- package/src/astronomy/sun/helpers.js +0 -0
- package/src/astronomy/timeZoneInfo.js +89 -0
- package/src/astronomy/timehelpers.js +69 -0
- package/src/astronomy/types.js +30 -0
- package/src/geolocation/getGeolocation.js +49 -0
- package/src/geolocation/lib/geolocation.js +44 -0
- package/src/geolocation/lib/geolocationCapacitor.js +21 -0
- package/src/geolocation/lib/reversegeocoding.js +109 -0
- package/src/index.js +38 -0
- package/src/utils/degreesToCompass.js +51 -0
- package/src/utils/warning.js +130 -0
- package/src/utils/wind/WindArrow.jsx +53 -0
- package/src/utils/wind/windArrowTx.js +24 -0
- package/src/utils/wind/windLevel.js +49 -0
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@angelrove/forecast-utils",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"author": "Jose Angel Romero Vegas",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "Utilidades para obtener datos de previsión meteorológica (Open-Meteo API) y de astronomía (SunCalc API).",
|
|
7
|
+
"homepage": "https://github.com/angelrove/OpenMeteoForecast",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"docs:md": "bunx jsdoc2md $(cat doc-files.txt) > README.md"
|
|
11
|
+
},
|
|
12
|
+
"types": "dist/types/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./src/index.js",
|
|
16
|
+
"require": "./src/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": ["src", "dist"],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"forecast",
|
|
22
|
+
"weather",
|
|
23
|
+
"open-meteo",
|
|
24
|
+
"astronomy",
|
|
25
|
+
"react",
|
|
26
|
+
"hooks",
|
|
27
|
+
"JavaScript"
|
|
28
|
+
],
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": "^19.1.0",
|
|
31
|
+
"suncalc3": "^2.0.5",
|
|
32
|
+
"swr": "^2.3.3",
|
|
33
|
+
"@capacitor/geolocation": "^7.1.2"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@biomejs/biome": "1.9.4",
|
|
37
|
+
"jsdoc-to-markdown": "^9.1.1"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {}
|
|
40
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const ApiInfo = {
|
|
2
|
+
host: "https://api.open-meteo.com/v1",
|
|
3
|
+
pathMain: "/forecast?timezone=auto&",
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} url
|
|
8
|
+
*/
|
|
9
|
+
export async function fetcher(url) {
|
|
10
|
+
devLog("OpemMeteo", url);
|
|
11
|
+
return fetch(url).then((res) => res.json());
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get path for OpenMeteo API
|
|
16
|
+
*
|
|
17
|
+
* @param {number} lat
|
|
18
|
+
* @param {number} lon
|
|
19
|
+
* @param {string} path
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
export function getPath(lat, lon, path) {
|
|
23
|
+
return (
|
|
24
|
+
ApiInfo.host +
|
|
25
|
+
ApiInfo.pathMain +
|
|
26
|
+
"latitude=" +
|
|
27
|
+
lat +
|
|
28
|
+
"&longitude=" +
|
|
29
|
+
lon +
|
|
30
|
+
"&" +
|
|
31
|
+
path
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Console log for development
|
|
37
|
+
*
|
|
38
|
+
* @param {string} title
|
|
39
|
+
* @param {string} url
|
|
40
|
+
*/
|
|
41
|
+
function devLog(title, url) {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
if (import.meta.env.MODE === "development") {
|
|
44
|
+
// console.log('%c> fetch [' + title + ']:', 'color:#9e9', url);
|
|
45
|
+
console.log("> fetch [" + title + "]:", url);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// hourlyParams
|
|
2
|
+
|
|
3
|
+
import { fetchParams as hourlyParams } from "../hourly/fetchParams.js";
|
|
4
|
+
|
|
5
|
+
export const fetchParams =
|
|
6
|
+
"current=" +
|
|
7
|
+
"temperature_2m," +
|
|
8
|
+
"apparent_temperature," +
|
|
9
|
+
"relative_humidity_2m," +
|
|
10
|
+
"weather_code," +
|
|
11
|
+
"wind_speed_10m," +
|
|
12
|
+
"wind_direction_10m," +
|
|
13
|
+
"precipitation&" +
|
|
14
|
+
"&forecast_days=2" +
|
|
15
|
+
"&daily=" +
|
|
16
|
+
"temperature_2m_max," +
|
|
17
|
+
"temperature_2m_min," +
|
|
18
|
+
"precipitation_sum," +
|
|
19
|
+
"showers_sum" +
|
|
20
|
+
"&" +
|
|
21
|
+
hourlyParams;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transforms the OpenMeteo API data into a more usable format.
|
|
3
|
+
*
|
|
4
|
+
* @param {{current: any, daily: any, hourly: any, latitude: number, longitude: number}} data - The data object to transform.
|
|
5
|
+
* @returns {Object|null} - The transformed data object or null if the input is invalid.
|
|
6
|
+
*/
|
|
7
|
+
export default function transformer(data) {
|
|
8
|
+
if (!data) return null;
|
|
9
|
+
|
|
10
|
+
const current = data.current;
|
|
11
|
+
const daily = data.daily;
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
city: null,
|
|
15
|
+
country: null,
|
|
16
|
+
time: new Date().toTimeString(),
|
|
17
|
+
latitude: data.latitude,
|
|
18
|
+
longitude: data.longitude,
|
|
19
|
+
weather: {
|
|
20
|
+
weathercode: current.weather_code,
|
|
21
|
+
precipitation: current.precipitation,
|
|
22
|
+
temperature: current.temperature_2m,
|
|
23
|
+
feels_like: current.apparent_temperature,
|
|
24
|
+
humidity: current.relative_humidity_2m,
|
|
25
|
+
wind: {
|
|
26
|
+
speed: Math.round(current.wind_speed_10m),
|
|
27
|
+
deg: current.wind_direction_10m,
|
|
28
|
+
// gust: ,
|
|
29
|
+
},
|
|
30
|
+
tem_max: daily.temperature_2m_max[0],
|
|
31
|
+
tem_min: daily.temperature_2m_min[0],
|
|
32
|
+
precipitation_sum: daily.precipitation_sum,
|
|
33
|
+
showers_sum: daily.showers_sum,
|
|
34
|
+
hourly: data.hourly,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module OpenMeteo:current
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import useSWR from "swr";
|
|
6
|
+
import { fetcher, getPath } from "../conf.js";
|
|
7
|
+
import { fetchParams } from "./fetchParams.js";
|
|
8
|
+
import transformer from "./transformer.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Custom hook to fetch current weather data from OpenMeteo API.
|
|
12
|
+
*
|
|
13
|
+
* @param {number} lat
|
|
14
|
+
* @param {number} lon
|
|
15
|
+
* @param {number} refreshIntervalMin
|
|
16
|
+
* @returns {{ data: any, apiUrl: string, isLoading: boolean, isError: any }}
|
|
17
|
+
*/
|
|
18
|
+
export function useForecastCurrent(lat, lon, refreshIntervalMin = 0) {
|
|
19
|
+
if (!lat || !lon) {
|
|
20
|
+
throw new Error("useForecastCurrent: invalid coordinates");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const apiUrl = getPath(lat, lon, fetchParams);
|
|
24
|
+
const { data, error, isLoading } = useSWR(apiUrl, fetcher, {
|
|
25
|
+
refreshInterval: refreshIntervalMin * 60 * 1000,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
data: data ? transformer(data) : null,
|
|
30
|
+
apiUrl: apiUrl,
|
|
31
|
+
isLoading,
|
|
32
|
+
isError: error,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transforms the OpenMeteo API data into a more usable format.
|
|
3
|
+
*
|
|
4
|
+
* @param {{daily: any}} data - The data object to transform.
|
|
5
|
+
* @returns {Object|null} - The transformed data object or null if the input is invalid.
|
|
6
|
+
*/
|
|
7
|
+
export default function transformer(data) {
|
|
8
|
+
if (!data) return null;
|
|
9
|
+
|
|
10
|
+
const newData = {
|
|
11
|
+
time: data.daily.time,
|
|
12
|
+
weathercode: data.daily.weather_code,
|
|
13
|
+
tempMax: data.daily.temperature_2m_max,
|
|
14
|
+
tempMin: data.daily.temperature_2m_min,
|
|
15
|
+
windDirection: data.daily.winddirection_10m_dominant,
|
|
16
|
+
windSpeed: data.daily.windspeed_10m_max,
|
|
17
|
+
precipitation_sum: data.daily.precipitation_sum,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return newData;
|
|
21
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module OpenMeteo:daily
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import useSWR from "swr";
|
|
6
|
+
import { fetcher, getPath } from "../conf.js";
|
|
7
|
+
import { fetchParams } from "./fetchParams.js";
|
|
8
|
+
import transformer from "./transformer.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Custom hook to fetch daily forecast (10 days) data from OpenMeteo API.
|
|
12
|
+
* https://api.open-meteo.com/v1/forecast?timezone=auto&latitude=36.6644363&longitude=-4.5108962&forecast_days=10&daily=weathercode
|
|
13
|
+
*
|
|
14
|
+
* @param {number} lat
|
|
15
|
+
* @param {number} lon
|
|
16
|
+
* @param {number} refreshIntervalMin
|
|
17
|
+
* @returns {{ data: any, isLoading: boolean, isError: any }}
|
|
18
|
+
*/
|
|
19
|
+
export function useForecastDaily(lat, lon, refreshIntervalMin = 0) {
|
|
20
|
+
// Validate --
|
|
21
|
+
if (!lat || !lon) {
|
|
22
|
+
throw new Error("useForecastDaily: invalid coordinates");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Fetch --
|
|
26
|
+
const apiUrl = getPath(lat, lon, fetchParams);
|
|
27
|
+
// console.log(apiUrl);
|
|
28
|
+
const { data, error, isLoading } = useSWR(apiUrl, fetcher, {
|
|
29
|
+
refreshInterval: refreshIntervalMin * 60 * 1000,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Return --
|
|
33
|
+
return {
|
|
34
|
+
data: data ? transformer(data) : null,
|
|
35
|
+
isLoading,
|
|
36
|
+
isError: error,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the start and end dates based on the number of days from today.
|
|
3
|
+
*
|
|
4
|
+
* @param {number} numDay
|
|
5
|
+
* @returns {{startDate: string, endDate: string}} - An object containing the start and end dates in YYYY-MM-DD format.
|
|
6
|
+
*/
|
|
7
|
+
export function getDatesFromNumDays(numDay) {
|
|
8
|
+
// Dates: Today / End ---
|
|
9
|
+
const startDate = new Date();
|
|
10
|
+
startDate.setDate(startDate.getDate() + numDay);
|
|
11
|
+
|
|
12
|
+
const endDate = new Date();
|
|
13
|
+
endDate.setDate(endDate.getDate() + numDay + 1);
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
startDate: startDate.toISOString().split("T")[0],
|
|
17
|
+
endDate: endDate.toISOString().split("T")[0],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const fetchParams =
|
|
2
|
+
"hourly=" +
|
|
3
|
+
"weathercode," +
|
|
4
|
+
"temperature_2m," +
|
|
5
|
+
"windspeed_10m," +
|
|
6
|
+
"winddirection_10m," +
|
|
7
|
+
"relativehumidity_2m," +
|
|
8
|
+
"apparent_temperature," +
|
|
9
|
+
"precipitation," +
|
|
10
|
+
"freezing_level_height," +
|
|
11
|
+
"is_day";
|
|
12
|
+
// 'cloudcover,' +
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module OpenMeteo:hourly
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import useSWR from "swr";
|
|
6
|
+
import { fetcher, getPath } from "../conf.js";
|
|
7
|
+
import { getDatesFromNumDays } from "../helpers.js";
|
|
8
|
+
import { fetchParams } from "./fetchParams.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Custom hook to fetch hourly forecast data for a given location and number of days from OpenMeteo API.
|
|
12
|
+
*
|
|
13
|
+
* @param {{ latitude: number, longitude: number }} location
|
|
14
|
+
* @param {number} dayNum - Number of days from today: -1 = 24 hours, 0 = today, 1 = tomorrow, ...
|
|
15
|
+
* @returns {{ data: any, isLoading: boolean, isError: any }}
|
|
16
|
+
*/
|
|
17
|
+
export function useForecastHourly(location, dayNum) {
|
|
18
|
+
if (!location.latitude || !location.longitude) {
|
|
19
|
+
throw new Error("useForecastHourly: invalid coordinates");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Fetch ---
|
|
23
|
+
const dates = getDatesFromNumDays(dayNum);
|
|
24
|
+
|
|
25
|
+
let apiUrl =
|
|
26
|
+
"start_date=" +
|
|
27
|
+
dates.startDate +
|
|
28
|
+
"&" +
|
|
29
|
+
"end_date=" +
|
|
30
|
+
dates.endDate +
|
|
31
|
+
"&" +
|
|
32
|
+
fetchParams;
|
|
33
|
+
apiUrl = getPath(location.latitude, location.longitude, apiUrl);
|
|
34
|
+
|
|
35
|
+
const { data, error, isLoading } = useSWR(apiUrl, fetcher);
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
data: data,
|
|
39
|
+
isLoading,
|
|
40
|
+
isError: error,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WMO Weather interpretation codes (WW)
|
|
3
|
+
*
|
|
4
|
+
* @link https://open-meteo.com/en/docs?hourly=temperature_2m,weather_code&daily=weather_code#weather_variable_documentation
|
|
5
|
+
* @link https://www.meteomatics.com/en/api/available-parameters/derived-weather-and-convenience-parameters/general-weather-state/
|
|
6
|
+
*
|
|
7
|
+
* Code Description
|
|
8
|
+
* 0 Clear sky
|
|
9
|
+
* 1, 2, 3 Mainly clear, partly cloudy, and overcast
|
|
10
|
+
* 45, 48 Fog and depositing rime fog
|
|
11
|
+
* 51, 53, 55 Drizzle: Light, moderate, and dense intensity
|
|
12
|
+
* 56, 57 Freezing Drizzle: Light and dense intensity
|
|
13
|
+
* 61, 63, 65 Rain: Slight, moderate and heavy intensity
|
|
14
|
+
* 66, 67 Freezing Rain: Light and heavy intensity
|
|
15
|
+
* 71, 73, 75 Snow fall: Slight, moderate, and heavy intensity
|
|
16
|
+
* 77 Snow grains
|
|
17
|
+
* 80, 81, 82 Rain showers: Slight, moderate, and violent
|
|
18
|
+
* 85, 86 Snow showers slight and heavy
|
|
19
|
+
* 95 * Thunderstorm: Slight or moderate
|
|
20
|
+
* 96, 99 * Thunderstorm with slight and heavy hail
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} WeatherCodeEntry
|
|
25
|
+
* @property {number} code - WMO Weather interpretation codes (WW).
|
|
26
|
+
* @property {string} icon - Icon name.
|
|
27
|
+
* @property {string} description - Description.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/** @type {WeatherCodeEntry[]} */
|
|
31
|
+
export const weatherCodes = [
|
|
32
|
+
{ code: 0, icon: "0", description: "Clear sky" },
|
|
33
|
+
{ code: 1, icon: "0", description: "Mainly clear" },
|
|
34
|
+
|
|
35
|
+
{ code: 2, icon: "2", description: "Partly cloudy" },
|
|
36
|
+
{ code: 3, icon: "3", description: "Overcast" },
|
|
37
|
+
|
|
38
|
+
// Niebla
|
|
39
|
+
{ code: 45, icon: "45", description: "Fog" },
|
|
40
|
+
{ code: 48, icon: "48", description: "Fog and depositing rime fog" },
|
|
41
|
+
|
|
42
|
+
// Llovizna
|
|
43
|
+
{ code: 51, icon: "51", description: "Drizzle: Light" },
|
|
44
|
+
{ code: 53, icon: "51", description: "Drizzle: moderate" },
|
|
45
|
+
{ code: 55, icon: "51", description: "Drizzle: dense intensity" },
|
|
46
|
+
|
|
47
|
+
// Llovizna congelante
|
|
48
|
+
{ code: 56, icon: "51", description: "Freezing Drizzle: Light" },
|
|
49
|
+
{ code: 57, icon: "51", description: "Freezing Drizzle: dense intensity" },
|
|
50
|
+
|
|
51
|
+
// Lluvia
|
|
52
|
+
{ code: 61, icon: "51", description: "Rain: Slight" },
|
|
53
|
+
{ code: 63, icon: "63", description: "Rain: moderate and heavy intensity" },
|
|
54
|
+
{ code: 65, icon: "65", description: "Rain: heavy intensity" },
|
|
55
|
+
|
|
56
|
+
// Lluvia helada
|
|
57
|
+
{ code: 66, icon: "63", description: "Freezing Rain: Light" },
|
|
58
|
+
{ code: 67, icon: "65", description: "Freezing Rain: Heavy intensity" },
|
|
59
|
+
|
|
60
|
+
// Chubascos de lluvia
|
|
61
|
+
{ code: 80, icon: "80", description: "Snow fall: slight" },
|
|
62
|
+
{ code: 81, icon: "81", description: "Snow fall: moderate" },
|
|
63
|
+
{ code: 82, icon: "82", description: "Snow fall: heavy intensity" },
|
|
64
|
+
|
|
65
|
+
// Tormenta
|
|
66
|
+
{ code: 95, icon: "95", description: "Snow grains" },
|
|
67
|
+
{ code: 96, icon: "95", description: "Rain showers: slight" },
|
|
68
|
+
{ code: 99, icon: "99", description: "Rain showers: moderate" },
|
|
69
|
+
|
|
70
|
+
// Nieve
|
|
71
|
+
{ code: 71, icon: "71", description: "Rain showers: violent" },
|
|
72
|
+
{ code: 73, icon: "71", description: "Snow showers slight" },
|
|
73
|
+
{ code: 75, icon: "75", description: "Snow showers heavy" },
|
|
74
|
+
|
|
75
|
+
// Chubascos de nieve
|
|
76
|
+
{ code: 85, icon: "85", description: "Thunderstorm: Slight or moderate" },
|
|
77
|
+
{
|
|
78
|
+
code: 86,
|
|
79
|
+
icon: "86",
|
|
80
|
+
description: "Thunderstorm with slight and heavy hail",
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// Granizo
|
|
84
|
+
{
|
|
85
|
+
code: 77,
|
|
86
|
+
icon: "77",
|
|
87
|
+
description: "Thunderstorm with slight and heavy hail",
|
|
88
|
+
},
|
|
89
|
+
];
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WMO Weather interpretation codes (WW)
|
|
3
|
+
*
|
|
4
|
+
* @link https://open-meteo.com/en/docs?hourly=temperature_2m,weather_code&daily=weather_code#weather_variable_documentation
|
|
5
|
+
* @link https://www.meteomatics.com/en/api/available-parameters/derived-weather-and-convenience-parameters/general-weather-state/
|
|
6
|
+
*
|
|
7
|
+
* Code Description
|
|
8
|
+
* 0 Clear sky
|
|
9
|
+
* 1, 2, 3 Mainly clear, partly cloudy, and overcast
|
|
10
|
+
* 45, 48 Fog and depositing rime fog
|
|
11
|
+
* 51, 53, 55 Drizzle: Light, moderate, and dense intensity
|
|
12
|
+
* 56, 57 Freezing Drizzle: Light and dense intensity
|
|
13
|
+
* 61, 63, 65 Rain: Slight, moderate and heavy intensity
|
|
14
|
+
* 66, 67 Freezing Rain: Light and heavy intensity
|
|
15
|
+
* 71, 73, 75 Snow fall: Slight, moderate, and heavy intensity
|
|
16
|
+
* 77 Snow grains
|
|
17
|
+
* 80, 81, 82 Rain showers: Slight, moderate, and violent
|
|
18
|
+
* 85, 86 Snow showers slight and heavy
|
|
19
|
+
* 95 * Thunderstorm: Slight or moderate
|
|
20
|
+
* 96, 99 * Thunderstorm with slight and heavy hail
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} WeatherCodeEntry
|
|
25
|
+
* @property {number} code - WMO Weather interpretation codes (WW).
|
|
26
|
+
* @property {string} icon - Icon name.
|
|
27
|
+
* @property {string} description - Description.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/** @type {WeatherCodeEntry[]} */
|
|
31
|
+
export const weatherCodes = [
|
|
32
|
+
{ code: 0, icon: "0", description: "Cielo despejado" },
|
|
33
|
+
{ code: 1, icon: "0", description: "Principalmente despejado" },
|
|
34
|
+
|
|
35
|
+
{ code: 2, icon: "2", description: "Parcialmente nublado" },
|
|
36
|
+
{ code: 3, icon: "3", description: "Cubierto" },
|
|
37
|
+
|
|
38
|
+
// Niebla
|
|
39
|
+
{ code: 45, icon: "45", description: "Niebla" },
|
|
40
|
+
{ code: 48, icon: "48", description: "Niebla ligera con escarcha" },
|
|
41
|
+
|
|
42
|
+
// Llovizna
|
|
43
|
+
{ code: 51, icon: "51", description: "Llovizna débil" },
|
|
44
|
+
{ code: 53, icon: "51", description: "Llovizna moderada" },
|
|
45
|
+
{ code: 55, icon: "51", description: "Llovizna densa" },
|
|
46
|
+
|
|
47
|
+
// Llovizna congelante
|
|
48
|
+
{ code: 56, icon: "51", description: "Llovizna débil, congelándose" },
|
|
49
|
+
{ code: 57, icon: "51", description: "Llovizna densa, congelándose" },
|
|
50
|
+
|
|
51
|
+
// Lluvia
|
|
52
|
+
{ code: 61, icon: "51", description: "Lluvia ligera" },
|
|
53
|
+
{ code: 63, icon: "63", description: "Lluvia moderada o fuerte" },
|
|
54
|
+
{ code: 65, icon: "65", description: "Lluvia fuerte" },
|
|
55
|
+
|
|
56
|
+
// Lluvia helada
|
|
57
|
+
{ code: 66, icon: "63", description: "Lluvia helada ligera" },
|
|
58
|
+
{ code: 67, icon: "65", description: "Lluvia moderada o fuerte" },
|
|
59
|
+
|
|
60
|
+
// Chubascos de lluvia
|
|
61
|
+
{ code: 80, icon: "80", description: "Chubascos débiles" },
|
|
62
|
+
{ code: 81, icon: "81", description: "Chubascos moderados" },
|
|
63
|
+
{ code: 82, icon: "82", description: "Chubascos fuertes" },
|
|
64
|
+
|
|
65
|
+
// Tormenta
|
|
66
|
+
{ code: 95, icon: "95", description: "Tormenta" },
|
|
67
|
+
{ code: 96, icon: "95", description: "Tormenta con algo de granizo" },
|
|
68
|
+
{ code: 99, icon: "99", description: "Tormenta fuerte, con granizo" },
|
|
69
|
+
|
|
70
|
+
// Nieve
|
|
71
|
+
{ code: 71, icon: "71", description: "Nieve ligera" },
|
|
72
|
+
{ code: 73, icon: "71", description: "Nevada moderada" },
|
|
73
|
+
{ code: 75, icon: "75", description: "Fuertes nevadas" },
|
|
74
|
+
|
|
75
|
+
// Chubascos de nieve
|
|
76
|
+
{ code: 85, icon: "85", description: "Chubascos de nieve débil" },
|
|
77
|
+
{ code: 86, icon: "86", description: "Chubascos de nieve fuertes" },
|
|
78
|
+
|
|
79
|
+
// Granizo
|
|
80
|
+
{ code: 77, icon: "77", description: "Granizo" },
|
|
81
|
+
];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { weatherCodes } from "./WeatherCodesEs.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns weather code info o undefined if not found.
|
|
6
|
+
*
|
|
7
|
+
* @param {number} code - WMO Weather interpretation code.
|
|
8
|
+
* @returns {WeatherCodeEntry | undefined}
|
|
9
|
+
*/
|
|
10
|
+
export function getWeatherCodeEntry(code) {
|
|
11
|
+
return weatherCodes.find((entry) => entry.code === code);
|
|
12
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module OpenMeteo:weatherSymbol
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { getWeatherCodeEntry } from "./lib/getWeatherCodeEntry.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get weather symbol and description based on the weather code.
|
|
9
|
+
*
|
|
10
|
+
* @param {any} code
|
|
11
|
+
* @param {number} [precipitation]
|
|
12
|
+
* @param {boolean} night
|
|
13
|
+
* @param {boolean} dark
|
|
14
|
+
* @returns {{ icon: string, description: string }}
|
|
15
|
+
*/
|
|
16
|
+
export function weatherSymbol(
|
|
17
|
+
code,
|
|
18
|
+
precipitation = undefined,
|
|
19
|
+
night = false,
|
|
20
|
+
dark = false,
|
|
21
|
+
) {
|
|
22
|
+
// Parse code ---
|
|
23
|
+
let msgPlus = "";
|
|
24
|
+
let theCode = code;
|
|
25
|
+
if (precipitation && precipitation > 0.8) {
|
|
26
|
+
if (theCode === 63) theCode = 65;
|
|
27
|
+
if (theCode === 95) msgPlus = " y lluvia fuerte";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Get weather entry ---
|
|
31
|
+
const weatherCodeEntry = getWeatherCodeEntry(theCode);
|
|
32
|
+
if (!weatherCodeEntry) {
|
|
33
|
+
return {
|
|
34
|
+
icon: "ws/icon_error.webp",
|
|
35
|
+
description: "???",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Icon file ---
|
|
40
|
+
const iconKey = weatherCodeEntry.icon;
|
|
41
|
+
let iconFile = "icon_" + iconKey;
|
|
42
|
+
|
|
43
|
+
// Night
|
|
44
|
+
const nightIcons = ["0", "2", "48", "80", "85"];
|
|
45
|
+
if (night && nightIcons.includes(iconKey)) {
|
|
46
|
+
iconFile = iconFile + "_night";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Light / Dark
|
|
50
|
+
if (dark) {
|
|
51
|
+
iconFile = "dark/" + iconFile;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Return ---
|
|
55
|
+
const ext = ".webp";
|
|
56
|
+
return {
|
|
57
|
+
icon: "ws/" + iconFile + ext,
|
|
58
|
+
description: weatherCodeEntry.description + msgPlus,
|
|
59
|
+
};
|
|
60
|
+
}
|