@idm-plugin/meteo2 0.0.4 → 0.0.5
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/dist/index.js +158 -125
- package/dist/index.umd.cjs +1 -1
- package/dist/openmeteo/src/index.d.ts +4 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import
|
|
1
|
+
var T = Object.defineProperty;
|
|
2
|
+
var F = (d, e, s) => e in d ? T(d, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : d[e] = s;
|
|
3
|
+
var S = (d, e, s) => (F(d, typeof e != "symbol" ? e + "" : e, s), s);
|
|
4
|
+
import D from "@log4js-node/log4js-api";
|
|
5
5
|
import f from "moment";
|
|
6
6
|
import O from "got";
|
|
7
|
-
import { fetchWeatherApi as
|
|
8
|
-
let
|
|
7
|
+
import { fetchWeatherApi as b } from "openmeteo";
|
|
8
|
+
let l;
|
|
9
9
|
try {
|
|
10
|
-
|
|
10
|
+
l = D.getLogger("meteo");
|
|
11
11
|
} catch {
|
|
12
12
|
} finally {
|
|
13
13
|
}
|
|
14
|
-
var H = /* @__PURE__ */ ((
|
|
15
|
-
class
|
|
14
|
+
var H = /* @__PURE__ */ ((d) => (d.Arome = "arome", d.IconEU = "iconEu", d.GFS = "gfs", d.GFSWave = "gfsWave", d.NamConus = "namConus", d.NamHawaii = "namHawaii", d.NamAlaska = "namAlaska", d.Geos5 = "geos5", d))(H || {});
|
|
15
|
+
class g {
|
|
16
16
|
/**
|
|
17
17
|
* 点查海洋气象要素(全量)
|
|
18
18
|
* @param lng
|
|
@@ -22,7 +22,7 @@ class q {
|
|
|
22
22
|
* @param source
|
|
23
23
|
* @param options
|
|
24
24
|
*/
|
|
25
|
-
static async queryPointMeteo(e, s, t, o = !1,
|
|
25
|
+
static async queryPointMeteo(e, s, t, o = !1, r = "", u = {}) {
|
|
26
26
|
typeof t == "number" && (t = t < 1e12 ? t * 1e3 : t);
|
|
27
27
|
const c = f(t), a = {
|
|
28
28
|
searchParams: {
|
|
@@ -30,18 +30,18 @@ class q {
|
|
|
30
30
|
lat: s,
|
|
31
31
|
ts: c.valueOf(),
|
|
32
32
|
params: o ? "watertemp" : void 0,
|
|
33
|
-
source:
|
|
33
|
+
source: r == null ? void 0 : r.toLowerCase()
|
|
34
34
|
},
|
|
35
35
|
timeout: 3e4
|
|
36
|
-
},
|
|
37
|
-
c.isBefore(
|
|
38
|
-
const m = "https://aod4idm.idmwx.com/api/ocean/point",
|
|
39
|
-
if (
|
|
36
|
+
}, _ = f(), n = _.valueOf();
|
|
37
|
+
c.isBefore(_.subtract(1, "month")) && (l == null || l.warn("[%s] get history meteo on %s: %j", u.requestId, c.format(), a));
|
|
38
|
+
const m = "https://aod4idm.idmwx.com/api/ocean/point", i = await O.get(m, a).json(), h = f().valueOf();
|
|
39
|
+
if (l == null || l.info("[%s] get meteo(cost: %d ms) from %s with options: %j", u.requestId, h - n, m, a), (i == null ? void 0 : i.code) === 0)
|
|
40
40
|
return {
|
|
41
|
-
...
|
|
42
|
-
source:
|
|
41
|
+
...i.data,
|
|
42
|
+
source: r
|
|
43
43
|
};
|
|
44
|
-
|
|
44
|
+
l == null || l.warn("[%s] get meteo failed: %j", u.requestId, i);
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* 点查海洋气象要素(指定要素组合)
|
|
@@ -57,7 +57,7 @@ class q {
|
|
|
57
57
|
* @param source
|
|
58
58
|
* @param options
|
|
59
59
|
*/
|
|
60
|
-
static async queryPointFactor(e, s, t, o = "wind,wave,current,watertemp,visibility",
|
|
60
|
+
static async queryPointFactor(e, s, t, o = "wind,wave,current,watertemp,visibility", r = "", u = {}) {
|
|
61
61
|
typeof t == "number" && (t = t < 1e12 ? t * 1e3 : t);
|
|
62
62
|
const c = f(t), a = {
|
|
63
63
|
searchParams: {
|
|
@@ -65,28 +65,28 @@ class q {
|
|
|
65
65
|
lat: s,
|
|
66
66
|
ts: c.valueOf(),
|
|
67
67
|
params: o,
|
|
68
|
-
source:
|
|
68
|
+
source: r == null ? void 0 : r.toLowerCase()
|
|
69
69
|
},
|
|
70
70
|
timeout: 3e4
|
|
71
|
-
},
|
|
72
|
-
c.isBefore(
|
|
73
|
-
const m = "https://aod4idm.idmwx.com/api/ocean/factor",
|
|
74
|
-
if (
|
|
71
|
+
}, _ = f(), n = _.valueOf();
|
|
72
|
+
c.isBefore(_.subtract(1, "month")) && (l == null || l.warn("[%s] get history factors on %s: %j", u.requestId, c.format(), a));
|
|
73
|
+
const m = "https://aod4idm.idmwx.com/api/ocean/factor", i = await O.get(m, a).json(), h = f().valueOf();
|
|
74
|
+
if (l == null || l.info("[%s] get factors(cost: %d ms) from %s with options: %j", u.requestId, h - n, m, a), (i == null ? void 0 : i.code) === 0)
|
|
75
75
|
return {
|
|
76
|
-
...
|
|
77
|
-
source:
|
|
76
|
+
...i.data,
|
|
77
|
+
source: r
|
|
78
78
|
};
|
|
79
|
-
|
|
79
|
+
l == null || l.warn("[%s] get factors failed: %j", u.requestId, i);
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
82
82
|
* @see https://api.windy.com/point-forecast/docs
|
|
83
83
|
* @param key
|
|
84
84
|
*/
|
|
85
85
|
static async queryWindyPointForecast(e, s, t, o = {}) {
|
|
86
|
-
const
|
|
86
|
+
const r = "https://api.windy.com/api/point-forecast/v2", u = [];
|
|
87
87
|
try {
|
|
88
88
|
let c = f().valueOf();
|
|
89
|
-
const a = await O.post(
|
|
89
|
+
const a = await O.post(r, {
|
|
90
90
|
headers: {
|
|
91
91
|
"Content-Type": "application/json"
|
|
92
92
|
},
|
|
@@ -115,9 +115,9 @@ class q {
|
|
|
115
115
|
levels: ["surface"]
|
|
116
116
|
}
|
|
117
117
|
}).json();
|
|
118
|
-
let
|
|
119
|
-
|
|
120
|
-
const n = await O.post(
|
|
118
|
+
let _ = f().valueOf();
|
|
119
|
+
l == null || l.info("[%s] get gfs-factors(cost: %d ms) from %s", o.requestId, _ - c, r), c = _;
|
|
120
|
+
const n = await O.post(r, {
|
|
121
121
|
headers: {
|
|
122
122
|
"Content-Type": "application/json"
|
|
123
123
|
},
|
|
@@ -130,52 +130,52 @@ class q {
|
|
|
130
130
|
levels: ["surface"]
|
|
131
131
|
}
|
|
132
132
|
}).json();
|
|
133
|
-
|
|
134
|
-
for (let
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
utc: f(a.ts[
|
|
138
|
-
temp: a["temp-surface"][
|
|
139
|
-
dp_temp: a["dewpoint-surface"][
|
|
133
|
+
_ = f().valueOf(), l == null || l.info("[%s] get gfs-wave-factors(cost: %d ms) from %s", o.requestId, _ - c, r);
|
|
134
|
+
for (let i = 0; i < a.ts.length; i++) {
|
|
135
|
+
const h = this.populateUVFactor(a["wind_u-surface"][i], a["wind_v-surface"][i], !1, o);
|
|
136
|
+
h.scale = this.calculateBeaufortWindForceScale(h.speed), u.push({
|
|
137
|
+
utc: f(a.ts[i]).utc().format(),
|
|
138
|
+
temp: a["temp-surface"][i] ? Math.round((a["temp-surface"][i] - 273.15) * 100) / 100 : void 0,
|
|
139
|
+
dp_temp: a["dewpoint-surface"][i] ? Math.round((a["dewpoint-surface"][i] - 273.15) * 100) / 100 : void 0,
|
|
140
140
|
precip: {
|
|
141
|
-
inter3h: a["past3hprecip-surface"][
|
|
142
|
-
inter3hSnow: a["past3hsnowprecip-surface"][
|
|
143
|
-
inter3hConv: a["past3hconvprecip-surface"][
|
|
141
|
+
inter3h: a["past3hprecip-surface"][i] ? Math.round(a["past3hprecip-surface"][i] * 1e3 * 1e3) / 1e3 : 0,
|
|
142
|
+
inter3hSnow: a["past3hsnowprecip-surface"][i] ? Math.round(a["past3hsnowprecip-surface"][i] * 1e3 * 1e3) / 1e3 : 0,
|
|
143
|
+
inter3hConv: a["past3hconvprecip-surface"][i] ? Math.round(a["past3hconvprecip-surface"][i] * 1e3 * 1e3) / 1e3 : 0
|
|
144
144
|
},
|
|
145
|
-
wind:
|
|
145
|
+
wind: h,
|
|
146
146
|
gusts: {
|
|
147
|
-
speed: Math.round((a["gust-surface"][
|
|
148
|
-
kts: this.convertMs2Kts(a["gust-surface"][
|
|
147
|
+
speed: Math.round((a["gust-surface"][i] || 0) * 100) / 100,
|
|
148
|
+
kts: this.convertMs2Kts(a["gust-surface"][i])
|
|
149
149
|
},
|
|
150
|
-
lclouds: a["lclouds-surface"][
|
|
151
|
-
mclouds: a["mclouds-surface"][
|
|
152
|
-
hclouds: a["hclouds-surface"][
|
|
153
|
-
rh: a["rh-surface"][
|
|
154
|
-
gh: a["gh-surface"][
|
|
155
|
-
pressure: Math.round(a["pressure-surface"][
|
|
150
|
+
lclouds: a["lclouds-surface"][i] ? Math.round(a["lclouds-surface"][i] * 100) / 100 : 0,
|
|
151
|
+
mclouds: a["mclouds-surface"][i] ? Math.round(a["mclouds-surface"][i] * 100) / 100 : 0,
|
|
152
|
+
hclouds: a["hclouds-surface"][i] ? Math.round(a["hclouds-surface"][i] * 100) / 100 : 0,
|
|
153
|
+
rh: a["rh-surface"][i] ? Math.round(a["rh-surface"][i] * 100) / 100 : 0,
|
|
154
|
+
gh: a["gh-surface"][i] ? Math.round(a["gh-surface"][i] * 100) / 100 : 0,
|
|
155
|
+
pressure: Math.round(a["pressure-surface"][i] / 100 * 100) / 100
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
158
|
const m = [];
|
|
159
|
-
for (let
|
|
160
|
-
const
|
|
159
|
+
for (let i = 0; i < n.ts.length; i++) {
|
|
160
|
+
const h = this.calculateDouglasScale(n["waves_height-surface"][i], n["waves_direction-surface"][i], n["waves_period-surface"][i]), R = this.calculateDouglasScale(n["wwaves_height-surface"][i], n["wwaves_direction-surface"][i], n["wwaves_period-surface"][i]), w = this.calculateDouglasScale(n["swell1_height-surface"][i], n["swell1_direction-surface"][i], n["swell1_period-surface"][i]), A = this.calculateDouglasScale(n["swell2_height-surface"][i], n["swell2_direction-surface"][i], n["swell2_period-surface"][i]);
|
|
161
161
|
m.push({
|
|
162
|
-
utc: f(n.ts[
|
|
162
|
+
utc: f(n.ts[i]).utc().format(),
|
|
163
163
|
wave: {
|
|
164
|
-
sig:
|
|
165
|
-
wd:
|
|
166
|
-
swell:
|
|
167
|
-
swell2:
|
|
164
|
+
sig: h,
|
|
165
|
+
wd: R,
|
|
166
|
+
swell: w,
|
|
167
|
+
swell2: A
|
|
168
168
|
}
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
-
for (const
|
|
172
|
-
const
|
|
173
|
-
|
|
171
|
+
for (const i of u) {
|
|
172
|
+
const h = m.find((R) => R.utc === i.utc);
|
|
173
|
+
i.wave = h == null ? void 0 : h.wave;
|
|
174
174
|
}
|
|
175
175
|
} catch (c) {
|
|
176
|
-
|
|
176
|
+
l.warn("[%s] get-gfs-factor failed: %s", o.requestId, c);
|
|
177
177
|
}
|
|
178
|
-
return
|
|
178
|
+
return u;
|
|
179
179
|
}
|
|
180
180
|
/**
|
|
181
181
|
* 填充UV向量
|
|
@@ -185,11 +185,11 @@ class q {
|
|
|
185
185
|
* @param options
|
|
186
186
|
*/
|
|
187
187
|
static populateUVFactor(e, s, t = !1, o = {}) {
|
|
188
|
-
const
|
|
188
|
+
const r = Math.round(Math.sqrt(Math.pow(e, 2) + Math.pow(s, 2)) * 1e4) / 1e4, { degree: u, direction: c } = this.calculateUVDirection(e, s, t, o), a = this.convertMs2Kts(r);
|
|
189
189
|
return {
|
|
190
|
-
speed:
|
|
190
|
+
speed: r,
|
|
191
191
|
kts: a,
|
|
192
|
-
degree:
|
|
192
|
+
degree: u,
|
|
193
193
|
direction: c,
|
|
194
194
|
eastward: Math.round(e * 1e4) / 1e4,
|
|
195
195
|
northward: Math.round(s * 1e4) / 1e4
|
|
@@ -206,13 +206,13 @@ class q {
|
|
|
206
206
|
* @param options
|
|
207
207
|
*/
|
|
208
208
|
static calculateUVDirection(e, s, t = !1, o = {}) {
|
|
209
|
-
let
|
|
210
|
-
t && (
|
|
211
|
-
const
|
|
212
|
-
return
|
|
213
|
-
angle:
|
|
214
|
-
degree:
|
|
215
|
-
direction:
|
|
209
|
+
let r = Math.atan2(e, s) + Math.PI;
|
|
210
|
+
t && (r = Math.atan2(e, s));
|
|
211
|
+
const u = this.convert2Direction(r);
|
|
212
|
+
return r = Math.round(r / (2 * Math.PI) * 360 * 1e4) / 1e4, {
|
|
213
|
+
angle: r,
|
|
214
|
+
degree: r,
|
|
215
|
+
direction: u
|
|
216
216
|
};
|
|
217
217
|
}
|
|
218
218
|
/**
|
|
@@ -246,27 +246,27 @@ class q {
|
|
|
246
246
|
*/
|
|
247
247
|
static calculateDouglasScale(e, s, t) {
|
|
248
248
|
let o = "Calm";
|
|
249
|
-
const
|
|
249
|
+
const r = this.convert2Direction(s / 360 * 2 * Math.PI);
|
|
250
250
|
return isNaN(e) || e <= 0.1 ? o = "Calm" : e <= 0.5 ? o = "Smooth" : e <= 1.25 ? o = "Slight" : e <= 2.5 ? o = "Moderate" : e <= 4 ? o = "Rough" : e <= 6 ? o = "VeryRough" : e <= 9 ? o = "High" : e <= 14 ? o = "VeryHigh" : o = "Precipitous", {
|
|
251
251
|
degree: Math.round(s * 100) / 100,
|
|
252
252
|
scale: o,
|
|
253
|
-
direction:
|
|
253
|
+
direction: r,
|
|
254
254
|
height: Math.round(e * 1e3) / 1e3,
|
|
255
255
|
period: Math.round(t * 100) / 100
|
|
256
256
|
};
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
|
-
let
|
|
259
|
+
let y;
|
|
260
260
|
try {
|
|
261
|
-
|
|
261
|
+
y = D.getLogger("open-meteo");
|
|
262
262
|
} catch {
|
|
263
263
|
} finally {
|
|
264
264
|
}
|
|
265
|
-
class
|
|
265
|
+
class W {
|
|
266
266
|
constructor(e, s) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
267
|
+
S(this, "apikey");
|
|
268
|
+
S(this, "debug");
|
|
269
|
+
S(this, "FORECAST", {
|
|
270
270
|
OM_URL: "https://customer-api.open-meteo.com/v1/forecast",
|
|
271
271
|
ORM_URL: "https://meteo2.idmwx.com/v1/forecast",
|
|
272
272
|
OM_HISTORY_URL: "https://customer-historical-forecast-api.open-meteo.com/v1/forecast",
|
|
@@ -287,7 +287,7 @@ class k {
|
|
|
287
287
|
HOURLY: "wave_height,wave_direction,wave_period,wind_wave_height,wind_wave_direction,wind_wave_period,wind_wave_peak_period,swell_wave_height,swell_wave_direction,swell_wave_period,swell_wave_peak_period,ocean_current_velocity,ocean_current_direction,sea_level_height_msl,sea_surface_temperature"
|
|
288
288
|
}
|
|
289
289
|
});
|
|
290
|
-
|
|
290
|
+
S(this, "HISTORICAL", {
|
|
291
291
|
OM_URL: "https://customer-archive-api.open-meteo.com/v1/archive",
|
|
292
292
|
WEATHER_VARIABLES: {
|
|
293
293
|
HOURLY: "temperature_2m,apparent_temperature,precipitation,weather_code,pressure_msl,surface_pressure,wind_speed_10m,wind_direction_10m,wind_gusts_10m",
|
|
@@ -297,67 +297,68 @@ class k {
|
|
|
297
297
|
this.apikey = e || "smE3JnDLHy3TizVv", this.debug = s;
|
|
298
298
|
}
|
|
299
299
|
range(e, s, t) {
|
|
300
|
-
return Array.from({ length: (s - e) / t }, (o,
|
|
300
|
+
return Array.from({ length: (s - e) / t }, (o, r) => e + r * t);
|
|
301
301
|
}
|
|
302
302
|
async weatherForecast(e, s = {}) {
|
|
303
|
-
const t = f(), o = await
|
|
303
|
+
const t = f(), o = await b(e.url, e);
|
|
304
304
|
delete e.apikey;
|
|
305
|
-
const
|
|
306
|
-
return this.debug &&
|
|
305
|
+
const r = f();
|
|
306
|
+
return this.debug && y.info("[%s] fetch weather api (%s) cost: %d ms", s.requestId, e.url, r.diff(t, "ms")), this.parseWeatherData(o, e, s);
|
|
307
307
|
}
|
|
308
308
|
async marineForecast(e, s = {}) {
|
|
309
|
-
const t = f(), o = await
|
|
309
|
+
const t = f(), o = await b(e.url, e);
|
|
310
310
|
delete e.apikey;
|
|
311
|
-
const
|
|
312
|
-
return this.debug &&
|
|
311
|
+
const r = f();
|
|
312
|
+
return this.debug && y.info("[%s] fetch marine api (%s) cost: %d ms", s.requestId, e.url, r.diff(t, "ms")), this.parseWeatherData(o, e, s);
|
|
313
313
|
}
|
|
314
314
|
async parseWeatherData(e, s, t = {}) {
|
|
315
|
-
var
|
|
316
|
-
const o = [],
|
|
317
|
-
for (const
|
|
318
|
-
const
|
|
319
|
-
timezone:
|
|
315
|
+
var u, c, a, _, n, m;
|
|
316
|
+
const o = [], r = Math.pow(10, t.precision || 6);
|
|
317
|
+
for (const i of e) {
|
|
318
|
+
const h = i.timezone(), R = i.current(), w = i.hourly(), A = i.daily(), M = {
|
|
319
|
+
timezone: h
|
|
320
320
|
};
|
|
321
321
|
if (R) {
|
|
322
322
|
const I = f();
|
|
323
|
-
|
|
324
|
-
time: f.unix(Number(R.time())
|
|
323
|
+
M.current = {
|
|
324
|
+
time: f.unix(Number(R.time())).utc().format()
|
|
325
325
|
};
|
|
326
326
|
for (let p = 0; p < R.variablesLength(); p++) {
|
|
327
327
|
const v = R.variables(p).value();
|
|
328
|
-
|
|
328
|
+
M.current[s.current[p]] = Number.isNaN(v) ? v : Math.round(v * r) / r;
|
|
329
329
|
}
|
|
330
330
|
const E = f();
|
|
331
|
-
this.debug &&
|
|
331
|
+
this.debug && y.info("[%s] fetch current variables cost: %d ms", t.requestId, E.diff(I, "ms"));
|
|
332
332
|
}
|
|
333
333
|
if (w) {
|
|
334
|
-
const I = f(), E = f.unix(Number(w.time())
|
|
335
|
-
|
|
334
|
+
const I = f(), E = f.unix(Number(w.time()));
|
|
335
|
+
M.hourly = {
|
|
336
336
|
date: E.utc().format(),
|
|
337
|
-
time: this.range(Number(
|
|
337
|
+
// time: this.range(Number(hourly.time()), Number(hourly.timeEnd()), hourly.interval()).map((t) => moment.unix(t + utcOffsetSeconds).diff(st, 'h')),
|
|
338
|
+
time: this.range(Number(w.time()), Number(w.timeEnd()), w.interval()).map((v) => f.unix(v).diff(E, "h"))
|
|
338
339
|
};
|
|
339
340
|
for (let v = 0; v < w.variablesLength(); v++) {
|
|
340
|
-
const L = (a = (c = (
|
|
341
|
-
|
|
341
|
+
const L = (a = (c = (u = w.variables(v).valuesArray()) == null ? void 0 : u.toString()) == null ? void 0 : c.split(",")) == null ? void 0 : a.map((N) => Number.isNaN(N) ? N : Math.round(Number(N) * r) / r);
|
|
342
|
+
M.hourly[s.hourly[v]] = L;
|
|
342
343
|
}
|
|
343
344
|
const p = f();
|
|
344
|
-
this.debug &&
|
|
345
|
+
this.debug && y.info("[%s] fetch hourly variables cost: %d ms", t.requestId, p.diff(I, "ms"));
|
|
345
346
|
}
|
|
346
|
-
if (
|
|
347
|
+
if (A) {
|
|
347
348
|
const I = f();
|
|
348
|
-
|
|
349
|
-
time: this.range(Number(
|
|
350
|
-
(p) => f.unix(p
|
|
349
|
+
M.daily = {
|
|
350
|
+
time: this.range(Number(A.time()), Number(A.timeEnd()), A.interval()).map(
|
|
351
|
+
(p) => f.unix(p).utc().format()
|
|
351
352
|
)
|
|
352
353
|
};
|
|
353
|
-
for (let p = 0; p <
|
|
354
|
-
const v = (m = (n = (
|
|
355
|
-
|
|
354
|
+
for (let p = 0; p < A.variablesLength(); p++) {
|
|
355
|
+
const v = (m = (n = (_ = A.variables(p).valuesArray()) == null ? void 0 : _.toString()) == null ? void 0 : n.split(",")) == null ? void 0 : m.map((L) => Number.isNaN(L) ? L : Math.round(Number(L) * r) / r);
|
|
356
|
+
M.daily[s.daily[p]] = v;
|
|
356
357
|
}
|
|
357
358
|
const E = f();
|
|
358
|
-
this.debug &&
|
|
359
|
+
this.debug && y.info("[%s] fetch daily variables cost: %d ms", t.requestId, E.diff(I, "ms"));
|
|
359
360
|
}
|
|
360
|
-
o.push(
|
|
361
|
+
o.push(M);
|
|
361
362
|
}
|
|
362
363
|
return o;
|
|
363
364
|
}
|
|
@@ -370,26 +371,26 @@ class k {
|
|
|
370
371
|
*/
|
|
371
372
|
prepare(e, s, t, o = {}) {
|
|
372
373
|
e ? (t.start_date = e.utc().set({ minute: 0, second: 0, millisecond: 0 }).format("YYYY-MM-DD"), t.end_date = e.clone().add(o.forecastDays ?? 1, "d").utc().format("YYYY-MM-DD")) : t.forecast_days = o.forecastDays;
|
|
373
|
-
const
|
|
374
|
-
return s ? (t.url = o.selfHosted ? this.FORECAST.ORM_MARINE_URL : this.FORECAST.OM_MARINE_URL, e != null && e.isBefore(
|
|
374
|
+
const r = f().subtract(1, "d");
|
|
375
|
+
return s ? (t.url = o.selfHosted ? this.FORECAST.ORM_MARINE_URL : this.FORECAST.OM_MARINE_URL, e != null && e.isBefore(r) && (t.url = this.FORECAST.OM_MARINE_URL)) : (t.url = o.selfHosted ? this.FORECAST.ORM_URL : this.FORECAST.OM_URL, e != null && e.isBefore(r) && (t.url = this.FORECAST.OM_HISTORY_URL)), t;
|
|
375
376
|
}
|
|
376
|
-
async spotForecast(e, s, t, o = !0,
|
|
377
|
+
async spotForecast(e, s, t, o = !0, r = !0, u = !1, c = {
|
|
377
378
|
forecastDays: 1,
|
|
378
379
|
precision: 6,
|
|
379
380
|
selfHosted: !0
|
|
380
381
|
}) {
|
|
381
|
-
var
|
|
382
|
+
var i, h, R, w, A, M;
|
|
382
383
|
const a = {
|
|
383
384
|
apikey: this.apikey,
|
|
384
385
|
latitude: e,
|
|
385
386
|
longitude: s,
|
|
386
387
|
cell_selection: "sea",
|
|
387
388
|
wind_speed_unit: "kn",
|
|
388
|
-
models: ((
|
|
389
|
+
models: ((i = c.weatherModels) == null ? void 0 : i.split(",")) || ["best_match"],
|
|
389
390
|
timezone: "auto"
|
|
390
391
|
};
|
|
391
|
-
|
|
392
|
-
const
|
|
392
|
+
r && (a.daily = o ? ((h = this.FORECAST.WEATHER_VARIABLES.SIMPLE.DAILY) == null ? void 0 : h.split(",")) || [] : ((R = this.FORECAST.WEATHER_VARIABLES.NORMAL.DAILY) == null ? void 0 : R.split(",")) || []), t || (c.forecastDays = c.forecastDays || 1, u = !0), u && (a.hourly = o ? ((w = this.FORECAST.WEATHER_VARIABLES.SIMPLE.HOURLY) == null ? void 0 : w.split(",")) || [] : ((A = this.FORECAST.WEATHER_VARIABLES.NORMAL.HOURLY) == null ? void 0 : A.split(",")) || []), this.prepare(t, !1, a, c);
|
|
393
|
+
const _ = await this.weatherForecast(a, c), n = {
|
|
393
394
|
apikey: this.apikey,
|
|
394
395
|
latitude: e,
|
|
395
396
|
longitude: s,
|
|
@@ -398,15 +399,47 @@ class k {
|
|
|
398
399
|
wind_speed_unit: "kn",
|
|
399
400
|
models: ((M = c.marineModels) == null ? void 0 : M.split(",")) || ["best_match"]
|
|
400
401
|
};
|
|
401
|
-
|
|
402
|
+
r && (n.daily = this.FORECAST.MARINE_VARIABLES.DAILY.split(",")), t || (c.forecastDays = c.forecastDays || 1, u = !0), u && (n.hourly = this.FORECAST.MARINE_VARIABLES.HOURLY.split(",")), this.prepare(t, !0, n, c);
|
|
402
403
|
const m = await this.marineForecast(n, c);
|
|
403
|
-
return { weather:
|
|
404
|
+
return { weather: _, marine: m };
|
|
404
405
|
}
|
|
405
|
-
async spotHistorical(
|
|
406
|
+
async spotHistorical(e, s, t, o, r = !1, u = {
|
|
407
|
+
precision: 6
|
|
408
|
+
}) {
|
|
409
|
+
var n, m;
|
|
410
|
+
const c = {
|
|
411
|
+
apikey: this.apikey,
|
|
412
|
+
latitude: e,
|
|
413
|
+
longitude: s,
|
|
414
|
+
cell_selection: "sea",
|
|
415
|
+
wind_speed_unit: "kn",
|
|
416
|
+
models: ((n = u.weatherModels) == null ? void 0 : n.split(",")) || ["best_match"],
|
|
417
|
+
timezone: "auto",
|
|
418
|
+
hourly: this.HISTORICAL.WEATHER_VARIABLES.HOURLY.split(","),
|
|
419
|
+
daily: this.HISTORICAL.WEATHER_VARIABLES.DAILY.split(","),
|
|
420
|
+
url: this.HISTORICAL.OM_URL
|
|
421
|
+
}, a = await this.weatherForecast(c, u);
|
|
422
|
+
let _;
|
|
423
|
+
if (r) {
|
|
424
|
+
const i = {
|
|
425
|
+
apikey: this.apikey,
|
|
426
|
+
latitude: e,
|
|
427
|
+
longitude: s,
|
|
428
|
+
cell_selection: "sea",
|
|
429
|
+
timezone: "auto",
|
|
430
|
+
wind_speed_unit: "kn",
|
|
431
|
+
models: ((m = u.marineModels) == null ? void 0 : m.split(",")) || ["best_match"],
|
|
432
|
+
daily: this.FORECAST.MARINE_VARIABLES.DAILY.split(","),
|
|
433
|
+
hourly: this.FORECAST.MARINE_VARIABLES.HOURLY.split(","),
|
|
434
|
+
url: this.FORECAST.OM_MARINE_URL
|
|
435
|
+
};
|
|
436
|
+
_ = await this.marineForecast(i, u);
|
|
437
|
+
}
|
|
438
|
+
return { weather: a, marine: _ };
|
|
406
439
|
}
|
|
407
440
|
}
|
|
408
441
|
export {
|
|
409
|
-
|
|
410
|
-
|
|
442
|
+
g as MeteoHelper,
|
|
443
|
+
W as MeteoHelper2,
|
|
411
444
|
H as WindyModel
|
|
412
445
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(_,p){typeof exports=="object"&&typeof module<"u"?p(exports,require("@log4js-node/log4js-api"),require("moment"),require("got"),require("openmeteo")):typeof define=="function"&&define.amd?define(["exports","@log4js-node/log4js-api","moment","got","openmeteo"],p):(_=typeof globalThis<"u"?globalThis:_||self,p(_["idm-plugin-rabbitmq"]={},_["@log4js-node/log4js-api"],_.moment,_.got,_.openmeteo))})(this,function(_,p,o,D,F){"use strict";var Y=Object.defineProperty;var g=(_,p,o)=>p in _?Y(_,p,{enumerable:!0,configurable:!0,writable:!0,value:o}):_[p]=o;var b=(_,p,o)=>(g(_,typeof p!="symbol"?p+"":p,o),o);let u;try{u=p.getLogger("meteo")}catch{}finally{}var H=(w=>(w.Arome="arome",w.IconEU="iconEu",w.GFS="gfs",w.GFSWave="gfsWave",w.NamConus="namConus",w.NamHawaii="namHawaii",w.NamAlaska="namAlaska",w.Geos5="geos5",w))(H||{});class x{static async queryPointMeteo(e,s,t,c=!1,r="",l={}){typeof t=="number"&&(t=t<1e12?t*1e3:t);const n=o(t),a={searchParams:{lng:e,lat:s,ts:n.valueOf(),params:c?"watertemp":void 0,source:r==null?void 0:r.toLowerCase()},timeout:3e4},h=o(),f=h.valueOf();n.isBefore(h.subtract(1,"month"))&&(u==null||u.warn("[%s] get history meteo on %s: %j",l.requestId,n.format(),a));const m="https://aod4idm.idmwx.com/api/ocean/point",i=await D.get(m,a).json(),d=o().valueOf();if(u==null||u.info("[%s] get meteo(cost: %d ms) from %s with options: %j",l.requestId,d-f,m,a),(i==null?void 0:i.code)===0)return{...i.data,source:r};u==null||u.warn("[%s] get meteo failed: %j",l.requestId,i)}static async queryPointFactor(e,s,t,c="wind,wave,current,watertemp,visibility",r="",l={}){typeof t=="number"&&(t=t<1e12?t*1e3:t);const n=o(t),a={searchParams:{lng:e,lat:s,ts:n.valueOf(),params:c,source:r==null?void 0:r.toLowerCase()},timeout:3e4},h=o(),f=h.valueOf();n.isBefore(h.subtract(1,"month"))&&(u==null||u.warn("[%s] get history factors on %s: %j",l.requestId,n.format(),a));const m="https://aod4idm.idmwx.com/api/ocean/factor",i=await D.get(m,a).json(),d=o().valueOf();if(u==null||u.info("[%s] get factors(cost: %d ms) from %s with options: %j",l.requestId,d-f,m,a),(i==null?void 0:i.code)===0)return{...i.data,source:r};u==null||u.warn("[%s] get factors failed: %j",l.requestId,i)}static async queryWindyPointForecast(e,s,t,c={}){const r="https://api.windy.com/api/point-forecast/v2",l=[];try{let n=o().valueOf();const a=await D.post(r,{headers:{"Content-Type":"application/json"},json:{lat:e,lon:s,key:t,model:"gfs",parameters:["temp","dewpoint","precip","convPrecip","snowPrecip","wind","windGust","cape","ptype","lclouds","mclouds","hclouds","rh","gh","pressure"],levels:["surface"]}}).json();let h=o().valueOf();u==null||u.info("[%s] get gfs-factors(cost: %d ms) from %s",c.requestId,h-n,r),n=h;const f=await D.post(r,{headers:{"Content-Type":"application/json"},json:{lat:e,lon:s,key:t,model:"gfsWave",parameters:["waves","windWaves","swell1","swell2"],levels:["surface"]}}).json();h=o().valueOf(),u==null||u.info("[%s] get gfs-wave-factors(cost: %d ms) from %s",c.requestId,h-n,r);for(let i=0;i<a.ts.length;i++){const d=this.populateUVFactor(a["wind_u-surface"][i],a["wind_v-surface"][i],!1,c);d.scale=this.calculateBeaufortWindForceScale(d.speed),l.push({utc:o(a.ts[i]).utc().format(),temp:a["temp-surface"][i]?Math.round((a["temp-surface"][i]-273.15)*100)/100:void 0,dp_temp:a["dewpoint-surface"][i]?Math.round((a["dewpoint-surface"][i]-273.15)*100)/100:void 0,precip:{inter3h:a["past3hprecip-surface"][i]?Math.round(a["past3hprecip-surface"][i]*1e3*1e3)/1e3:0,inter3hSnow:a["past3hsnowprecip-surface"][i]?Math.round(a["past3hsnowprecip-surface"][i]*1e3*1e3)/1e3:0,inter3hConv:a["past3hconvprecip-surface"][i]?Math.round(a["past3hconvprecip-surface"][i]*1e3*1e3)/1e3:0},wind:d,gusts:{speed:Math.round((a["gust-surface"][i]||0)*100)/100,kts:this.convertMs2Kts(a["gust-surface"][i])},lclouds:a["lclouds-surface"][i]?Math.round(a["lclouds-surface"][i]*100)/100:0,mclouds:a["mclouds-surface"][i]?Math.round(a["mclouds-surface"][i]*100)/100:0,hclouds:a["hclouds-surface"][i]?Math.round(a["hclouds-surface"][i]*100)/100:0,rh:a["rh-surface"][i]?Math.round(a["rh-surface"][i]*100)/100:0,gh:a["gh-surface"][i]?Math.round(a["gh-surface"][i]*100)/100:0,pressure:Math.round(a["pressure-surface"][i]/100*100)/100})}const m=[];for(let i=0;i<f.ts.length;i++){const d=this.calculateDouglasScale(f["waves_height-surface"][i],f["waves_direction-surface"][i],f["waves_period-surface"][i]),E=this.calculateDouglasScale(f["wwaves_height-surface"][i],f["wwaves_direction-surface"][i],f["wwaves_period-surface"][i]),A=this.calculateDouglasScale(f["swell1_height-surface"][i],f["swell1_direction-surface"][i],f["swell1_period-surface"][i]),M=this.calculateDouglasScale(f["swell2_height-surface"][i],f["swell2_direction-surface"][i],f["swell2_period-surface"][i]);m.push({utc:o(f.ts[i]).utc().format(),wave:{sig:d,wd:E,swell:A,swell2:M}})}for(const i of l){const d=m.find(E=>E.utc===i.utc);i.wave=d==null?void 0:d.wave}}catch(n){u.warn("[%s] get-gfs-factor failed: %s",c.requestId,n)}return l}static populateUVFactor(e,s,t=!1,c={}){const r=Math.round(Math.sqrt(Math.pow(e,2)+Math.pow(s,2))*1e4)/1e4,{degree:l,direction:n}=this.calculateUVDirection(e,s,t,c),a=this.convertMs2Kts(r);return{speed:r,kts:a,degree:l,direction:n,eastward:Math.round(e*1e4)/1e4,northward:Math.round(s*1e4)/1e4}}static convertMs2Kts(e){return isNaN(e)?0:Math.round(e*3600/1852*1e3)/1e3}static calculateUVDirection(e,s,t=!1,c={}){let r=Math.atan2(e,s)+Math.PI;t&&(r=Math.atan2(e,s));const l=this.convert2Direction(r);return r=Math.round(r/(2*Math.PI)*360*1e4)/1e4,{angle:r,degree:r,direction:l}}static convert2Direction(e){let s="N/A";if(!isNaN(e)){e<0&&(e+=2*Math.PI);const t=Math.PI/16;e<t?s="N":e>=t&&e<3*t?s="NNE":e>=3*t&&e<5*t?s="NE":e>=5*t&&e<7*t?s="ENE":e>=7*t&&e<9*t?s="E":e>=9*t&&e<11*t?s="ESE":e>=11*t&&e<13*t?s="SE":e>=13*t&&e<15*t?s="SSE":e>=15*t&&e<17*t?s="S":e>=17*t&&e<19*t?s="SSW":e>=19*t&&e<21*t?s="SW":e>=21*t&&e<23*t?s="WSW":e>=23*t&&e<25*t?s="W":e>=25*t&&e<27*t?s="WNW":e>=27*t&&e<29*t?s="NW":e>=29*t&&e<31*t?s="NNW":e>=31*t&&e<32*t&&(s="N")}return s}static calculateBeaufortWindForceScale(e){let s=0;return isNaN(e)||(e=Math.round(e*10)/10,e<=.2?s=0:e<=1.5?s=1:e<=3.3?s=2:e<=5.4?s=3:e<=7.9?s=4:e<=10.7?s=5:e<=13.8?s=6:e<=17.1?s=7:e<=20.7?s=8:e<=22.4?s=9:e<=28.4?s=10:e<=32.6?s=11:e>32.6&&(s=12)),s}static calculateDouglasScale(e,s,t){let c="Calm";const r=this.convert2Direction(s/360*2*Math.PI);return isNaN(e)||e<=.1?c="Calm":e<=.5?c="Smooth":e<=1.25?c="Slight":e<=2.5?c="Moderate":e<=4?c="Rough":e<=6?c="VeryRough":e<=9?c="High":e<=14?c="VeryHigh":c="Precipitous",{degree:Math.round(s*100)/100,scale:c,direction:r,height:Math.round(e*1e3)/1e3,period:Math.round(t*100)/100}}}let I;try{I=p.getLogger("open-meteo")}catch{}finally{}class U{constructor(e,s){b(this,"apikey");b(this,"debug");b(this,"FORECAST",{OM_URL:"https://customer-api.open-meteo.com/v1/forecast",ORM_URL:"https://meteo2.idmwx.com/v1/forecast",OM_HISTORY_URL:"https://customer-historical-forecast-api.open-meteo.com/v1/forecast",OM_MARINE_URL:"https://customer-marine-api.open-meteo.com/v1/marine",ORM_MARINE_URL:"https://meteo2.idmwx.com/v1/marine",WEATHER_VARIABLES:{NORMAL:{DAILY:"weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,sunrise,sunset,precipitation_sum,precipitation_hours,precipitation_probability_max,wind_speed_10m_max,wind_gusts_10m_max,wind_direction_10m_dominant",HOURLY:"temperature_2m,relative_humidity_2m,apparent_temperature,precipitation_probability,precipitation,weather_code,visibility,wind_speed_10m,wind_direction_10m,wind_gusts_10m,is_day"},SIMPLE:{DAILY:"weather_code",HOURLY:"wind_speed_10m,wind_direction_10m,wind_gusts_10m"}},MARINE_VARIABLES:{DAILY:"wave_height_max,wave_direction_dominant,wave_period_max,wind_wave_height_max,wind_wave_direction_dominant,wind_wave_period_max,wind_wave_peak_period_max,swell_wave_height_max,swell_wave_direction_dominant,swell_wave_period_max,swell_wave_peak_period_max",HOURLY:"wave_height,wave_direction,wave_period,wind_wave_height,wind_wave_direction,wind_wave_period,wind_wave_peak_period,swell_wave_height,swell_wave_direction,swell_wave_period,swell_wave_peak_period,ocean_current_velocity,ocean_current_direction,sea_level_height_msl,sea_surface_temperature"}});b(this,"HISTORICAL",{OM_URL:"https://customer-archive-api.open-meteo.com/v1/archive",WEATHER_VARIABLES:{HOURLY:"temperature_2m,apparent_temperature,precipitation,weather_code,pressure_msl,surface_pressure,wind_speed_10m,wind_direction_10m,wind_gusts_10m",DAILY:"weather_code,temperature_2m_max,temperature_2m_min,temperature_2m_mean,precipitation_sum,precipitation_hours,wind_speed_10m_max,wind_gusts_10m_max,wind_direction_10m_dominant"}});this.apikey=e||"smE3JnDLHy3TizVv",this.debug=s}range(e,s,t){return Array.from({length:(s-e)/t},(c,r)=>e+r*t)}async weatherForecast(e,s={}){const t=o(),c=await F.fetchWeatherApi(e.url,e);delete e.apikey;const r=o();return this.debug&&I.info("[%s] fetch weather api (%s) cost: %d ms",s.requestId,e.url,r.diff(t,"ms")),this.parseWeatherData(c,e,s)}async marineForecast(e,s={}){const t=o(),c=await F.fetchWeatherApi(e.url,e);delete e.apikey;const r=o();return this.debug&&I.info("[%s] fetch marine api (%s) cost: %d ms",s.requestId,e.url,r.diff(t,"ms")),this.parseWeatherData(c,e,s)}async parseWeatherData(e,s,t={}){var l,n,a,h,f,m;const c=[],r=Math.pow(10,t.precision||6);for(const i of e){const d=i.utcOffsetSeconds(),E=i.timezone(),A=i.current(),M=i.hourly(),y=i.daily(),S={timezone:E};if(A){const N=o();S.current={time:o.unix(Number(A.time())+d).utc().format()};for(let v=0;v<A.variablesLength();v++){const R=A.variables(v).value();S.current[s.current[v]]=Number.isNaN(R)?R:Math.round(R*r)/r}const L=o();this.debug&&I.info("[%s] fetch current variables cost: %d ms",t.requestId,L.diff(N,"ms"))}if(M){const N=o(),L=o.unix(Number(M.time())+d);S.hourly={date:L.utc().format(),time:this.range(Number(M.time()),Number(M.timeEnd()),M.interval()).map(R=>o.unix(R+d).diff(L,"h"))};for(let R=0;R<M.variablesLength();R++){const O=(a=(n=(l=M.variables(R).valuesArray())==null?void 0:l.toString())==null?void 0:n.split(","))==null?void 0:a.map(T=>Number.isNaN(T)?T:Math.round(Number(T)*r)/r);S.hourly[s.hourly[R]]=O}const v=o();this.debug&&I.info("[%s] fetch hourly variables cost: %d ms",t.requestId,v.diff(N,"ms"))}if(y){const N=o();S.daily={time:this.range(Number(y.time()),Number(y.timeEnd()),y.interval()).map(v=>o.unix(v+d).utc().format())};for(let v=0;v<y.variablesLength();v++){const R=(m=(f=(h=y.variables(v).valuesArray())==null?void 0:h.toString())==null?void 0:f.split(","))==null?void 0:m.map(O=>Number.isNaN(O)?O:Math.round(Number(O)*r)/r);S.daily[s.daily[v]]=R}const L=o();this.debug&&I.info("[%s] fetch daily variables cost: %d ms",t.requestId,L.diff(N,"ms"))}c.push(S)}return c}prepare(e,s,t,c={}){e?(t.start_date=e.utc().set({minute:0,second:0,millisecond:0}).format("YYYY-MM-DD"),t.end_date=e.clone().add(c.forecastDays??1,"d").utc().format("YYYY-MM-DD")):t.forecast_days=c.forecastDays;const r=o().subtract(1,"d");return s?(t.url=c.selfHosted?this.FORECAST.ORM_MARINE_URL:this.FORECAST.OM_MARINE_URL,e!=null&&e.isBefore(r)&&(t.url=this.FORECAST.OM_MARINE_URL)):(t.url=c.selfHosted?this.FORECAST.ORM_URL:this.FORECAST.OM_URL,e!=null&&e.isBefore(r)&&(t.url=this.FORECAST.OM_HISTORY_URL)),t}async spotForecast(e,s,t,c=!0,r=!0,l=!1,n={forecastDays:1,precision:6,selfHosted:!0}){var i,d,E,A,M,y;const a={apikey:this.apikey,latitude:e,longitude:s,cell_selection:"sea",wind_speed_unit:"kn",models:((i=n.weatherModels)==null?void 0:i.split(","))||["best_match"],timezone:"auto"};r&&(a.daily=c?((d=this.FORECAST.WEATHER_VARIABLES.SIMPLE.DAILY)==null?void 0:d.split(","))||[]:((E=this.FORECAST.WEATHER_VARIABLES.NORMAL.DAILY)==null?void 0:E.split(","))||[]),t||(n.forecastDays=n.forecastDays||1,l=!0),l&&(a.hourly=c?((A=this.FORECAST.WEATHER_VARIABLES.SIMPLE.HOURLY)==null?void 0:A.split(","))||[]:((M=this.FORECAST.WEATHER_VARIABLES.NORMAL.HOURLY)==null?void 0:M.split(","))||[]),this.prepare(t,!1,a,n);const h=await this.weatherForecast(a,n),f={apikey:this.apikey,latitude:e,longitude:s,cell_selection:"sea",timezone:"auto",wind_speed_unit:"kn",models:((y=n.marineModels)==null?void 0:y.split(","))||["best_match"]};r&&(f.daily=this.FORECAST.MARINE_VARIABLES.DAILY.split(",")),t||(n.forecastDays=n.forecastDays||1,l=!0),l&&(f.hourly=this.FORECAST.MARINE_VARIABLES.HOURLY.split(",")),this.prepare(t,!0,f,n);const m=await this.marineForecast(f,n);return{weather:h,marine:m}}async spotHistorical(){}}_.MeteoHelper=x,_.MeteoHelper2=U,_.WindyModel=H,Object.defineProperty(_,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(d,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("@log4js-node/log4js-api"),require("moment"),require("got"),require("openmeteo")):typeof define=="function"&&define.amd?define(["exports","@log4js-node/log4js-api","moment","got","openmeteo"],w):(d=typeof globalThis<"u"?globalThis:d||self,w(d["idm-plugin-rabbitmq"]={},d["@log4js-node/log4js-api"],d.moment,d.got,d.openmeteo))})(this,function(d,w,c,b,D){"use strict";var U=Object.defineProperty;var Y=(d,w,c)=>w in d?U(d,w,{enumerable:!0,configurable:!0,writable:!0,value:c}):d[w]=c;var N=(d,w,c)=>(Y(d,typeof w!="symbol"?w+"":w,c),c);let f;try{f=w.getLogger("meteo")}catch{}finally{}var H=(m=>(m.Arome="arome",m.IconEU="iconEu",m.GFS="gfs",m.GFSWave="gfsWave",m.NamConus="namConus",m.NamHawaii="namHawaii",m.NamAlaska="namAlaska",m.Geos5="geos5",m))(H||{});class F{static async queryPointMeteo(e,s,t,o=!1,r="",l={}){typeof t=="number"&&(t=t<1e12?t*1e3:t);const n=c(t),a={searchParams:{lng:e,lat:s,ts:n.valueOf(),params:o?"watertemp":void 0,source:r==null?void 0:r.toLowerCase()},timeout:3e4},_=c(),u=_.valueOf();n.isBefore(_.subtract(1,"month"))&&(f==null||f.warn("[%s] get history meteo on %s: %j",l.requestId,n.format(),a));const p="https://aod4idm.idmwx.com/api/ocean/point",i=await b.get(p,a).json(),h=c().valueOf();if(f==null||f.info("[%s] get meteo(cost: %d ms) from %s with options: %j",l.requestId,h-u,p,a),(i==null?void 0:i.code)===0)return{...i.data,source:r};f==null||f.warn("[%s] get meteo failed: %j",l.requestId,i)}static async queryPointFactor(e,s,t,o="wind,wave,current,watertemp,visibility",r="",l={}){typeof t=="number"&&(t=t<1e12?t*1e3:t);const n=c(t),a={searchParams:{lng:e,lat:s,ts:n.valueOf(),params:o,source:r==null?void 0:r.toLowerCase()},timeout:3e4},_=c(),u=_.valueOf();n.isBefore(_.subtract(1,"month"))&&(f==null||f.warn("[%s] get history factors on %s: %j",l.requestId,n.format(),a));const p="https://aod4idm.idmwx.com/api/ocean/factor",i=await b.get(p,a).json(),h=c().valueOf();if(f==null||f.info("[%s] get factors(cost: %d ms) from %s with options: %j",l.requestId,h-u,p,a),(i==null?void 0:i.code)===0)return{...i.data,source:r};f==null||f.warn("[%s] get factors failed: %j",l.requestId,i)}static async queryWindyPointForecast(e,s,t,o={}){const r="https://api.windy.com/api/point-forecast/v2",l=[];try{let n=c().valueOf();const a=await b.post(r,{headers:{"Content-Type":"application/json"},json:{lat:e,lon:s,key:t,model:"gfs",parameters:["temp","dewpoint","precip","convPrecip","snowPrecip","wind","windGust","cape","ptype","lclouds","mclouds","hclouds","rh","gh","pressure"],levels:["surface"]}}).json();let _=c().valueOf();f==null||f.info("[%s] get gfs-factors(cost: %d ms) from %s",o.requestId,_-n,r),n=_;const u=await b.post(r,{headers:{"Content-Type":"application/json"},json:{lat:e,lon:s,key:t,model:"gfsWave",parameters:["waves","windWaves","swell1","swell2"],levels:["surface"]}}).json();_=c().valueOf(),f==null||f.info("[%s] get gfs-wave-factors(cost: %d ms) from %s",o.requestId,_-n,r);for(let i=0;i<a.ts.length;i++){const h=this.populateUVFactor(a["wind_u-surface"][i],a["wind_v-surface"][i],!1,o);h.scale=this.calculateBeaufortWindForceScale(h.speed),l.push({utc:c(a.ts[i]).utc().format(),temp:a["temp-surface"][i]?Math.round((a["temp-surface"][i]-273.15)*100)/100:void 0,dp_temp:a["dewpoint-surface"][i]?Math.round((a["dewpoint-surface"][i]-273.15)*100)/100:void 0,precip:{inter3h:a["past3hprecip-surface"][i]?Math.round(a["past3hprecip-surface"][i]*1e3*1e3)/1e3:0,inter3hSnow:a["past3hsnowprecip-surface"][i]?Math.round(a["past3hsnowprecip-surface"][i]*1e3*1e3)/1e3:0,inter3hConv:a["past3hconvprecip-surface"][i]?Math.round(a["past3hconvprecip-surface"][i]*1e3*1e3)/1e3:0},wind:h,gusts:{speed:Math.round((a["gust-surface"][i]||0)*100)/100,kts:this.convertMs2Kts(a["gust-surface"][i])},lclouds:a["lclouds-surface"][i]?Math.round(a["lclouds-surface"][i]*100)/100:0,mclouds:a["mclouds-surface"][i]?Math.round(a["mclouds-surface"][i]*100)/100:0,hclouds:a["hclouds-surface"][i]?Math.round(a["hclouds-surface"][i]*100)/100:0,rh:a["rh-surface"][i]?Math.round(a["rh-surface"][i]*100)/100:0,gh:a["gh-surface"][i]?Math.round(a["gh-surface"][i]*100)/100:0,pressure:Math.round(a["pressure-surface"][i]/100*100)/100})}const p=[];for(let i=0;i<u.ts.length;i++){const h=this.calculateDouglasScale(u["waves_height-surface"][i],u["waves_direction-surface"][i],u["waves_period-surface"][i]),M=this.calculateDouglasScale(u["wwaves_height-surface"][i],u["wwaves_direction-surface"][i],u["wwaves_period-surface"][i]),R=this.calculateDouglasScale(u["swell1_height-surface"][i],u["swell1_direction-surface"][i],u["swell1_period-surface"][i]),E=this.calculateDouglasScale(u["swell2_height-surface"][i],u["swell2_direction-surface"][i],u["swell2_period-surface"][i]);p.push({utc:c(u.ts[i]).utc().format(),wave:{sig:h,wd:M,swell:R,swell2:E}})}for(const i of l){const h=p.find(M=>M.utc===i.utc);i.wave=h==null?void 0:h.wave}}catch(n){f.warn("[%s] get-gfs-factor failed: %s",o.requestId,n)}return l}static populateUVFactor(e,s,t=!1,o={}){const r=Math.round(Math.sqrt(Math.pow(e,2)+Math.pow(s,2))*1e4)/1e4,{degree:l,direction:n}=this.calculateUVDirection(e,s,t,o),a=this.convertMs2Kts(r);return{speed:r,kts:a,degree:l,direction:n,eastward:Math.round(e*1e4)/1e4,northward:Math.round(s*1e4)/1e4}}static convertMs2Kts(e){return isNaN(e)?0:Math.round(e*3600/1852*1e3)/1e3}static calculateUVDirection(e,s,t=!1,o={}){let r=Math.atan2(e,s)+Math.PI;t&&(r=Math.atan2(e,s));const l=this.convert2Direction(r);return r=Math.round(r/(2*Math.PI)*360*1e4)/1e4,{angle:r,degree:r,direction:l}}static convert2Direction(e){let s="N/A";if(!isNaN(e)){e<0&&(e+=2*Math.PI);const t=Math.PI/16;e<t?s="N":e>=t&&e<3*t?s="NNE":e>=3*t&&e<5*t?s="NE":e>=5*t&&e<7*t?s="ENE":e>=7*t&&e<9*t?s="E":e>=9*t&&e<11*t?s="ESE":e>=11*t&&e<13*t?s="SE":e>=13*t&&e<15*t?s="SSE":e>=15*t&&e<17*t?s="S":e>=17*t&&e<19*t?s="SSW":e>=19*t&&e<21*t?s="SW":e>=21*t&&e<23*t?s="WSW":e>=23*t&&e<25*t?s="W":e>=25*t&&e<27*t?s="WNW":e>=27*t&&e<29*t?s="NW":e>=29*t&&e<31*t?s="NNW":e>=31*t&&e<32*t&&(s="N")}return s}static calculateBeaufortWindForceScale(e){let s=0;return isNaN(e)||(e=Math.round(e*10)/10,e<=.2?s=0:e<=1.5?s=1:e<=3.3?s=2:e<=5.4?s=3:e<=7.9?s=4:e<=10.7?s=5:e<=13.8?s=6:e<=17.1?s=7:e<=20.7?s=8:e<=22.4?s=9:e<=28.4?s=10:e<=32.6?s=11:e>32.6&&(s=12)),s}static calculateDouglasScale(e,s,t){let o="Calm";const r=this.convert2Direction(s/360*2*Math.PI);return isNaN(e)||e<=.1?o="Calm":e<=.5?o="Smooth":e<=1.25?o="Slight":e<=2.5?o="Moderate":e<=4?o="Rough":e<=6?o="VeryRough":e<=9?o="High":e<=14?o="VeryHigh":o="Precipitous",{degree:Math.round(s*100)/100,scale:o,direction:r,height:Math.round(e*1e3)/1e3,period:Math.round(t*100)/100}}}let I;try{I=w.getLogger("open-meteo")}catch{}finally{}class C{constructor(e,s){N(this,"apikey");N(this,"debug");N(this,"FORECAST",{OM_URL:"https://customer-api.open-meteo.com/v1/forecast",ORM_URL:"https://meteo2.idmwx.com/v1/forecast",OM_HISTORY_URL:"https://customer-historical-forecast-api.open-meteo.com/v1/forecast",OM_MARINE_URL:"https://customer-marine-api.open-meteo.com/v1/marine",ORM_MARINE_URL:"https://meteo2.idmwx.com/v1/marine",WEATHER_VARIABLES:{NORMAL:{DAILY:"weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,sunrise,sunset,precipitation_sum,precipitation_hours,precipitation_probability_max,wind_speed_10m_max,wind_gusts_10m_max,wind_direction_10m_dominant",HOURLY:"temperature_2m,relative_humidity_2m,apparent_temperature,precipitation_probability,precipitation,weather_code,visibility,wind_speed_10m,wind_direction_10m,wind_gusts_10m,is_day"},SIMPLE:{DAILY:"weather_code",HOURLY:"wind_speed_10m,wind_direction_10m,wind_gusts_10m"}},MARINE_VARIABLES:{DAILY:"wave_height_max,wave_direction_dominant,wave_period_max,wind_wave_height_max,wind_wave_direction_dominant,wind_wave_period_max,wind_wave_peak_period_max,swell_wave_height_max,swell_wave_direction_dominant,swell_wave_period_max,swell_wave_peak_period_max",HOURLY:"wave_height,wave_direction,wave_period,wind_wave_height,wind_wave_direction,wind_wave_period,wind_wave_peak_period,swell_wave_height,swell_wave_direction,swell_wave_period,swell_wave_peak_period,ocean_current_velocity,ocean_current_direction,sea_level_height_msl,sea_surface_temperature"}});N(this,"HISTORICAL",{OM_URL:"https://customer-archive-api.open-meteo.com/v1/archive",WEATHER_VARIABLES:{HOURLY:"temperature_2m,apparent_temperature,precipitation,weather_code,pressure_msl,surface_pressure,wind_speed_10m,wind_direction_10m,wind_gusts_10m",DAILY:"weather_code,temperature_2m_max,temperature_2m_min,temperature_2m_mean,precipitation_sum,precipitation_hours,wind_speed_10m_max,wind_gusts_10m_max,wind_direction_10m_dominant"}});this.apikey=e||"smE3JnDLHy3TizVv",this.debug=s}range(e,s,t){return Array.from({length:(s-e)/t},(o,r)=>e+r*t)}async weatherForecast(e,s={}){const t=c(),o=await D.fetchWeatherApi(e.url,e);delete e.apikey;const r=c();return this.debug&&I.info("[%s] fetch weather api (%s) cost: %d ms",s.requestId,e.url,r.diff(t,"ms")),this.parseWeatherData(o,e,s)}async marineForecast(e,s={}){const t=c(),o=await D.fetchWeatherApi(e.url,e);delete e.apikey;const r=c();return this.debug&&I.info("[%s] fetch marine api (%s) cost: %d ms",s.requestId,e.url,r.diff(t,"ms")),this.parseWeatherData(o,e,s)}async parseWeatherData(e,s,t={}){var l,n,a,_,u,p;const o=[],r=Math.pow(10,t.precision||6);for(const i of e){const h=i.timezone(),M=i.current(),R=i.hourly(),E=i.daily(),y={timezone:h};if(M){const S=c();y.current={time:c.unix(Number(M.time())).utc().format()};for(let v=0;v<M.variablesLength();v++){const A=M.variables(v).value();y.current[s.current[v]]=Number.isNaN(A)?A:Math.round(A*r)/r}const L=c();this.debug&&I.info("[%s] fetch current variables cost: %d ms",t.requestId,L.diff(S,"ms"))}if(R){const S=c(),L=c.unix(Number(R.time()));y.hourly={date:L.utc().format(),time:this.range(Number(R.time()),Number(R.timeEnd()),R.interval()).map(A=>c.unix(A).diff(L,"h"))};for(let A=0;A<R.variablesLength();A++){const O=(a=(n=(l=R.variables(A).valuesArray())==null?void 0:l.toString())==null?void 0:n.split(","))==null?void 0:a.map(T=>Number.isNaN(T)?T:Math.round(Number(T)*r)/r);y.hourly[s.hourly[A]]=O}const v=c();this.debug&&I.info("[%s] fetch hourly variables cost: %d ms",t.requestId,v.diff(S,"ms"))}if(E){const S=c();y.daily={time:this.range(Number(E.time()),Number(E.timeEnd()),E.interval()).map(v=>c.unix(v).utc().format())};for(let v=0;v<E.variablesLength();v++){const A=(p=(u=(_=E.variables(v).valuesArray())==null?void 0:_.toString())==null?void 0:u.split(","))==null?void 0:p.map(O=>Number.isNaN(O)?O:Math.round(Number(O)*r)/r);y.daily[s.daily[v]]=A}const L=c();this.debug&&I.info("[%s] fetch daily variables cost: %d ms",t.requestId,L.diff(S,"ms"))}o.push(y)}return o}prepare(e,s,t,o={}){e?(t.start_date=e.utc().set({minute:0,second:0,millisecond:0}).format("YYYY-MM-DD"),t.end_date=e.clone().add(o.forecastDays??1,"d").utc().format("YYYY-MM-DD")):t.forecast_days=o.forecastDays;const r=c().subtract(1,"d");return s?(t.url=o.selfHosted?this.FORECAST.ORM_MARINE_URL:this.FORECAST.OM_MARINE_URL,e!=null&&e.isBefore(r)&&(t.url=this.FORECAST.OM_MARINE_URL)):(t.url=o.selfHosted?this.FORECAST.ORM_URL:this.FORECAST.OM_URL,e!=null&&e.isBefore(r)&&(t.url=this.FORECAST.OM_HISTORY_URL)),t}async spotForecast(e,s,t,o=!0,r=!0,l=!1,n={forecastDays:1,precision:6,selfHosted:!0}){var i,h,M,R,E,y;const a={apikey:this.apikey,latitude:e,longitude:s,cell_selection:"sea",wind_speed_unit:"kn",models:((i=n.weatherModels)==null?void 0:i.split(","))||["best_match"],timezone:"auto"};r&&(a.daily=o?((h=this.FORECAST.WEATHER_VARIABLES.SIMPLE.DAILY)==null?void 0:h.split(","))||[]:((M=this.FORECAST.WEATHER_VARIABLES.NORMAL.DAILY)==null?void 0:M.split(","))||[]),t||(n.forecastDays=n.forecastDays||1,l=!0),l&&(a.hourly=o?((R=this.FORECAST.WEATHER_VARIABLES.SIMPLE.HOURLY)==null?void 0:R.split(","))||[]:((E=this.FORECAST.WEATHER_VARIABLES.NORMAL.HOURLY)==null?void 0:E.split(","))||[]),this.prepare(t,!1,a,n);const _=await this.weatherForecast(a,n),u={apikey:this.apikey,latitude:e,longitude:s,cell_selection:"sea",timezone:"auto",wind_speed_unit:"kn",models:((y=n.marineModels)==null?void 0:y.split(","))||["best_match"]};r&&(u.daily=this.FORECAST.MARINE_VARIABLES.DAILY.split(",")),t||(n.forecastDays=n.forecastDays||1,l=!0),l&&(u.hourly=this.FORECAST.MARINE_VARIABLES.HOURLY.split(",")),this.prepare(t,!0,u,n);const p=await this.marineForecast(u,n);return{weather:_,marine:p}}async spotHistorical(e,s,t,o,r=!1,l={precision:6}){var u,p;const n={apikey:this.apikey,latitude:e,longitude:s,cell_selection:"sea",wind_speed_unit:"kn",models:((u=l.weatherModels)==null?void 0:u.split(","))||["best_match"],timezone:"auto",hourly:this.HISTORICAL.WEATHER_VARIABLES.HOURLY.split(","),daily:this.HISTORICAL.WEATHER_VARIABLES.DAILY.split(","),url:this.HISTORICAL.OM_URL},a=await this.weatherForecast(n,l);let _;if(r){const i={apikey:this.apikey,latitude:e,longitude:s,cell_selection:"sea",timezone:"auto",wind_speed_unit:"kn",models:((p=l.marineModels)==null?void 0:p.split(","))||["best_match"],daily:this.FORECAST.MARINE_VARIABLES.DAILY.split(","),hourly:this.FORECAST.MARINE_VARIABLES.HOURLY.split(","),url:this.FORECAST.OM_MARINE_URL};_=await this.marineForecast(i,l)}return{weather:a,marine:_}}}d.MeteoHelper=F,d.MeteoHelper2=C,d.WindyModel=H,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -62,5 +62,8 @@ export declare class MeteoHelper2 {
|
|
|
62
62
|
weather: any[];
|
|
63
63
|
marine: any[];
|
|
64
64
|
}>;
|
|
65
|
-
spotHistorical(): Promise<
|
|
65
|
+
spotHistorical(lat: number, lng: number, startDate: moment.Moment | string, endDate: moment.Moment | string, withMarine?: boolean, options?: OMOptions): Promise<{
|
|
66
|
+
weather: any[];
|
|
67
|
+
marine: any[] | undefined;
|
|
68
|
+
}>;
|
|
66
69
|
}
|