@idm-plugin/meteo2 0.0.3 → 0.0.4
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 +165 -158
- package/dist/index.umd.cjs +1 -1
- package/dist/openmeteo/src/index.d.ts +3 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { fetchWeatherApi as
|
|
1
|
+
var x = Object.defineProperty;
|
|
2
|
+
var T = (_, e, s) => e in _ ? x(_, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : _[e] = s;
|
|
3
|
+
var N = (_, e, s) => (T(_, typeof e != "symbol" ? e + "" : e, s), s);
|
|
4
|
+
import F from "@log4js-node/log4js-api";
|
|
5
|
+
import f from "moment";
|
|
6
|
+
import O from "got";
|
|
7
|
+
import { fetchWeatherApi as D } from "openmeteo";
|
|
8
8
|
let u;
|
|
9
9
|
try {
|
|
10
|
-
u =
|
|
10
|
+
u = F.getLogger("meteo");
|
|
11
11
|
} catch {
|
|
12
12
|
} finally {
|
|
13
13
|
}
|
|
14
|
-
var
|
|
15
|
-
class
|
|
14
|
+
var H = /* @__PURE__ */ ((_) => (_.Arome = "arome", _.IconEU = "iconEu", _.GFS = "gfs", _.GFSWave = "gfsWave", _.NamConus = "namConus", _.NamHawaii = "namHawaii", _.NamAlaska = "namAlaska", _.Geos5 = "geos5", _))(H || {});
|
|
15
|
+
class q {
|
|
16
16
|
/**
|
|
17
17
|
* 点查海洋气象要素(全量)
|
|
18
18
|
* @param lng
|
|
@@ -22,26 +22,26 @@ class W {
|
|
|
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, i = "", l = {}) {
|
|
26
26
|
typeof t == "number" && (t = t < 1e12 ? t * 1e3 : t);
|
|
27
|
-
const c =
|
|
27
|
+
const c = f(t), a = {
|
|
28
28
|
searchParams: {
|
|
29
29
|
lng: e,
|
|
30
30
|
lat: s,
|
|
31
31
|
ts: c.valueOf(),
|
|
32
32
|
params: o ? "watertemp" : void 0,
|
|
33
|
-
source:
|
|
33
|
+
source: i == null ? void 0 : i.toLowerCase()
|
|
34
34
|
},
|
|
35
35
|
timeout: 3e4
|
|
36
|
-
}, h =
|
|
37
|
-
c.isBefore(h.subtract(1, "month")) && (u == null || u.warn("[%s] get history meteo on %s: %j",
|
|
38
|
-
const
|
|
39
|
-
if (u == null || u.info("[%s] get meteo(cost: %d ms) from %s with options: %j",
|
|
36
|
+
}, h = f(), n = h.valueOf();
|
|
37
|
+
c.isBefore(h.subtract(1, "month")) && (u == null || u.warn("[%s] get history meteo on %s: %j", l.requestId, c.format(), a));
|
|
38
|
+
const m = "https://aod4idm.idmwx.com/api/ocean/point", r = await O.get(m, a).json(), d = f().valueOf();
|
|
39
|
+
if (u == null || u.info("[%s] get meteo(cost: %d ms) from %s with options: %j", l.requestId, d - n, m, a), (r == null ? void 0 : r.code) === 0)
|
|
40
40
|
return {
|
|
41
|
-
...
|
|
42
|
-
source:
|
|
41
|
+
...r.data,
|
|
42
|
+
source: i
|
|
43
43
|
};
|
|
44
|
-
u == null || u.warn("[%s] get meteo failed: %j",
|
|
44
|
+
u == null || u.warn("[%s] get meteo failed: %j", l.requestId, r);
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* 点查海洋气象要素(指定要素组合)
|
|
@@ -57,36 +57,36 @@ class W {
|
|
|
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", i = "", l = {}) {
|
|
61
61
|
typeof t == "number" && (t = t < 1e12 ? t * 1e3 : t);
|
|
62
|
-
const c =
|
|
62
|
+
const c = f(t), a = {
|
|
63
63
|
searchParams: {
|
|
64
64
|
lng: e,
|
|
65
65
|
lat: s,
|
|
66
66
|
ts: c.valueOf(),
|
|
67
67
|
params: o,
|
|
68
|
-
source:
|
|
68
|
+
source: i == null ? void 0 : i.toLowerCase()
|
|
69
69
|
},
|
|
70
70
|
timeout: 3e4
|
|
71
|
-
}, h =
|
|
72
|
-
c.isBefore(h.subtract(1, "month")) && (u == null || u.warn("[%s] get history factors on %s: %j",
|
|
73
|
-
const
|
|
74
|
-
if (u == null || u.info("[%s] get factors(cost: %d ms) from %s with options: %j",
|
|
71
|
+
}, h = f(), n = h.valueOf();
|
|
72
|
+
c.isBefore(h.subtract(1, "month")) && (u == null || u.warn("[%s] get history factors on %s: %j", l.requestId, c.format(), a));
|
|
73
|
+
const m = "https://aod4idm.idmwx.com/api/ocean/factor", r = await O.get(m, a).json(), d = f().valueOf();
|
|
74
|
+
if (u == null || u.info("[%s] get factors(cost: %d ms) from %s with options: %j", l.requestId, d - n, m, a), (r == null ? void 0 : r.code) === 0)
|
|
75
75
|
return {
|
|
76
|
-
...
|
|
77
|
-
source:
|
|
76
|
+
...r.data,
|
|
77
|
+
source: i
|
|
78
78
|
};
|
|
79
|
-
u == null || u.warn("[%s] get factors failed: %j",
|
|
79
|
+
u == null || u.warn("[%s] get factors failed: %j", l.requestId, r);
|
|
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 i = "https://api.windy.com/api/point-forecast/v2", l = [];
|
|
87
87
|
try {
|
|
88
|
-
let c =
|
|
89
|
-
const
|
|
88
|
+
let c = f().valueOf();
|
|
89
|
+
const a = await O.post(i, {
|
|
90
90
|
headers: {
|
|
91
91
|
"Content-Type": "application/json"
|
|
92
92
|
},
|
|
@@ -115,9 +115,9 @@ class W {
|
|
|
115
115
|
levels: ["surface"]
|
|
116
116
|
}
|
|
117
117
|
}).json();
|
|
118
|
-
let h =
|
|
119
|
-
u == null || u.info("[%s] get gfs-factors(cost: %d ms) from %s", o.requestId, h - c,
|
|
120
|
-
const n = await
|
|
118
|
+
let h = f().valueOf();
|
|
119
|
+
u == null || u.info("[%s] get gfs-factors(cost: %d ms) from %s", o.requestId, h - c, i), c = h;
|
|
120
|
+
const n = await O.post(i, {
|
|
121
121
|
headers: {
|
|
122
122
|
"Content-Type": "application/json"
|
|
123
123
|
},
|
|
@@ -130,52 +130,52 @@ class W {
|
|
|
130
130
|
levels: ["surface"]
|
|
131
131
|
}
|
|
132
132
|
}).json();
|
|
133
|
-
h =
|
|
134
|
-
for (let
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
utc:
|
|
138
|
-
temp:
|
|
139
|
-
dp_temp:
|
|
133
|
+
h = f().valueOf(), u == null || u.info("[%s] get gfs-wave-factors(cost: %d ms) from %s", o.requestId, h - c, i);
|
|
134
|
+
for (let r = 0; r < a.ts.length; r++) {
|
|
135
|
+
const d = this.populateUVFactor(a["wind_u-surface"][r], a["wind_v-surface"][r], !1, o);
|
|
136
|
+
d.scale = this.calculateBeaufortWindForceScale(d.speed), l.push({
|
|
137
|
+
utc: f(a.ts[r]).utc().format(),
|
|
138
|
+
temp: a["temp-surface"][r] ? Math.round((a["temp-surface"][r] - 273.15) * 100) / 100 : void 0,
|
|
139
|
+
dp_temp: a["dewpoint-surface"][r] ? Math.round((a["dewpoint-surface"][r] - 273.15) * 100) / 100 : void 0,
|
|
140
140
|
precip: {
|
|
141
|
-
inter3h:
|
|
142
|
-
inter3hSnow:
|
|
143
|
-
inter3hConv:
|
|
141
|
+
inter3h: a["past3hprecip-surface"][r] ? Math.round(a["past3hprecip-surface"][r] * 1e3 * 1e3) / 1e3 : 0,
|
|
142
|
+
inter3hSnow: a["past3hsnowprecip-surface"][r] ? Math.round(a["past3hsnowprecip-surface"][r] * 1e3 * 1e3) / 1e3 : 0,
|
|
143
|
+
inter3hConv: a["past3hconvprecip-surface"][r] ? Math.round(a["past3hconvprecip-surface"][r] * 1e3 * 1e3) / 1e3 : 0
|
|
144
144
|
},
|
|
145
|
-
wind:
|
|
145
|
+
wind: d,
|
|
146
146
|
gusts: {
|
|
147
|
-
speed: Math.round((
|
|
148
|
-
kts: this.convertMs2Kts(
|
|
147
|
+
speed: Math.round((a["gust-surface"][r] || 0) * 100) / 100,
|
|
148
|
+
kts: this.convertMs2Kts(a["gust-surface"][r])
|
|
149
149
|
},
|
|
150
|
-
lclouds:
|
|
151
|
-
mclouds:
|
|
152
|
-
hclouds:
|
|
153
|
-
rh:
|
|
154
|
-
gh:
|
|
155
|
-
pressure: Math.round(
|
|
150
|
+
lclouds: a["lclouds-surface"][r] ? Math.round(a["lclouds-surface"][r] * 100) / 100 : 0,
|
|
151
|
+
mclouds: a["mclouds-surface"][r] ? Math.round(a["mclouds-surface"][r] * 100) / 100 : 0,
|
|
152
|
+
hclouds: a["hclouds-surface"][r] ? Math.round(a["hclouds-surface"][r] * 100) / 100 : 0,
|
|
153
|
+
rh: a["rh-surface"][r] ? Math.round(a["rh-surface"][r] * 100) / 100 : 0,
|
|
154
|
+
gh: a["gh-surface"][r] ? Math.round(a["gh-surface"][r] * 100) / 100 : 0,
|
|
155
|
+
pressure: Math.round(a["pressure-surface"][r] / 100 * 100) / 100
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
|
-
const
|
|
159
|
-
for (let
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
utc:
|
|
158
|
+
const m = [];
|
|
159
|
+
for (let r = 0; r < n.ts.length; r++) {
|
|
160
|
+
const d = this.calculateDouglasScale(n["waves_height-surface"][r], n["waves_direction-surface"][r], n["waves_period-surface"][r]), A = this.calculateDouglasScale(n["wwaves_height-surface"][r], n["wwaves_direction-surface"][r], n["wwaves_period-surface"][r]), R = this.calculateDouglasScale(n["swell1_height-surface"][r], n["swell1_direction-surface"][r], n["swell1_period-surface"][r]), w = this.calculateDouglasScale(n["swell2_height-surface"][r], n["swell2_direction-surface"][r], n["swell2_period-surface"][r]);
|
|
161
|
+
m.push({
|
|
162
|
+
utc: f(n.ts[r]).utc().format(),
|
|
163
163
|
wave: {
|
|
164
|
-
sig:
|
|
165
|
-
wd:
|
|
166
|
-
swell:
|
|
167
|
-
swell2:
|
|
164
|
+
sig: d,
|
|
165
|
+
wd: A,
|
|
166
|
+
swell: R,
|
|
167
|
+
swell2: w
|
|
168
168
|
}
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
-
for (const
|
|
172
|
-
const
|
|
173
|
-
|
|
171
|
+
for (const r of l) {
|
|
172
|
+
const d = m.find((A) => A.utc === r.utc);
|
|
173
|
+
r.wave = d == null ? void 0 : d.wave;
|
|
174
174
|
}
|
|
175
175
|
} catch (c) {
|
|
176
176
|
u.warn("[%s] get-gfs-factor failed: %s", o.requestId, c);
|
|
177
177
|
}
|
|
178
|
-
return
|
|
178
|
+
return l;
|
|
179
179
|
}
|
|
180
180
|
/**
|
|
181
181
|
* 填充UV向量
|
|
@@ -185,11 +185,11 @@ class W {
|
|
|
185
185
|
* @param options
|
|
186
186
|
*/
|
|
187
187
|
static populateUVFactor(e, s, t = !1, o = {}) {
|
|
188
|
-
const
|
|
188
|
+
const i = Math.round(Math.sqrt(Math.pow(e, 2) + Math.pow(s, 2)) * 1e4) / 1e4, { degree: l, direction: c } = this.calculateUVDirection(e, s, t, o), a = this.convertMs2Kts(i);
|
|
189
189
|
return {
|
|
190
|
-
speed:
|
|
191
|
-
kts:
|
|
192
|
-
degree:
|
|
190
|
+
speed: i,
|
|
191
|
+
kts: a,
|
|
192
|
+
degree: l,
|
|
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 W {
|
|
|
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 i = Math.atan2(e, s) + Math.PI;
|
|
210
|
+
t && (i = Math.atan2(e, s));
|
|
211
|
+
const l = this.convert2Direction(i);
|
|
212
|
+
return i = Math.round(i / (2 * Math.PI) * 360 * 1e4) / 1e4, {
|
|
213
|
+
angle: i,
|
|
214
|
+
degree: i,
|
|
215
|
+
direction: l
|
|
216
216
|
};
|
|
217
217
|
}
|
|
218
218
|
/**
|
|
@@ -246,11 +246,11 @@ class W {
|
|
|
246
246
|
*/
|
|
247
247
|
static calculateDouglasScale(e, s, t) {
|
|
248
248
|
let o = "Calm";
|
|
249
|
-
const
|
|
249
|
+
const i = 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: i,
|
|
254
254
|
height: Math.round(e * 1e3) / 1e3,
|
|
255
255
|
period: Math.round(t * 100) / 100
|
|
256
256
|
};
|
|
@@ -258,101 +258,106 @@ class W {
|
|
|
258
258
|
}
|
|
259
259
|
let S;
|
|
260
260
|
try {
|
|
261
|
-
S =
|
|
261
|
+
S = F.getLogger("open-meteo");
|
|
262
262
|
} catch {
|
|
263
263
|
} finally {
|
|
264
264
|
}
|
|
265
265
|
class k {
|
|
266
266
|
constructor(e, s) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
267
|
+
N(this, "apikey");
|
|
268
|
+
N(this, "debug");
|
|
269
|
+
N(this, "FORECAST", {
|
|
270
|
+
OM_URL: "https://customer-api.open-meteo.com/v1/forecast",
|
|
271
|
+
ORM_URL: "https://meteo2.idmwx.com/v1/forecast",
|
|
272
|
+
OM_HISTORY_URL: "https://customer-historical-forecast-api.open-meteo.com/v1/forecast",
|
|
273
|
+
OM_MARINE_URL: "https://customer-marine-api.open-meteo.com/v1/marine",
|
|
274
|
+
ORM_MARINE_URL: "https://meteo2.idmwx.com/v1/marine",
|
|
275
|
+
WEATHER_VARIABLES: {
|
|
276
|
+
NORMAL: {
|
|
277
|
+
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",
|
|
278
|
+
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"
|
|
279
|
+
},
|
|
280
|
+
SIMPLE: {
|
|
281
|
+
DAILY: "weather_code",
|
|
282
|
+
HOURLY: "wind_speed_10m,wind_direction_10m,wind_gusts_10m"
|
|
283
|
+
}
|
|
282
284
|
},
|
|
283
|
-
|
|
284
|
-
DAILY: "
|
|
285
|
-
HOURLY: "
|
|
286
|
-
CURRENT: "wind_speed_10m,wind_direction_10m,wind_gusts_10m"
|
|
285
|
+
MARINE_VARIABLES: {
|
|
286
|
+
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",
|
|
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"
|
|
287
288
|
}
|
|
288
289
|
});
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
290
|
+
N(this, "HISTORICAL", {
|
|
291
|
+
OM_URL: "https://customer-archive-api.open-meteo.com/v1/archive",
|
|
292
|
+
WEATHER_VARIABLES: {
|
|
293
|
+
HOURLY: "temperature_2m,apparent_temperature,precipitation,weather_code,pressure_msl,surface_pressure,wind_speed_10m,wind_direction_10m,wind_gusts_10m",
|
|
294
|
+
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"
|
|
295
|
+
}
|
|
293
296
|
});
|
|
294
297
|
this.apikey = e || "smE3JnDLHy3TizVv", this.debug = s;
|
|
295
298
|
}
|
|
296
299
|
range(e, s, t) {
|
|
297
|
-
return Array.from({ length: (s - e) / t }, (o,
|
|
300
|
+
return Array.from({ length: (s - e) / t }, (o, i) => e + i * t);
|
|
298
301
|
}
|
|
299
302
|
async weatherForecast(e, s = {}) {
|
|
300
|
-
const t =
|
|
303
|
+
const t = f(), o = await D(e.url, e);
|
|
301
304
|
delete e.apikey;
|
|
302
|
-
const
|
|
303
|
-
return this.debug && S.info("[%s] fetch weather api (%s) cost: %d ms", s.requestId, e.url,
|
|
305
|
+
const i = f();
|
|
306
|
+
return this.debug && S.info("[%s] fetch weather api (%s) cost: %d ms", s.requestId, e.url, i.diff(t, "ms")), this.parseWeatherData(o, e, s);
|
|
304
307
|
}
|
|
305
308
|
async marineForecast(e, s = {}) {
|
|
306
|
-
const t =
|
|
309
|
+
const t = f(), o = await D(e.url, e);
|
|
307
310
|
delete e.apikey;
|
|
308
|
-
const
|
|
309
|
-
return this.debug && S.info("[%s] fetch marine api (%s) cost: %d ms", s.requestId, e.url,
|
|
311
|
+
const i = f();
|
|
312
|
+
return this.debug && S.info("[%s] fetch marine api (%s) cost: %d ms", s.requestId, e.url, i.diff(t, "ms")), this.parseWeatherData(o, e, s);
|
|
310
313
|
}
|
|
311
314
|
async parseWeatherData(e, s, t = {}) {
|
|
312
|
-
var
|
|
313
|
-
const o = [],
|
|
314
|
-
for (const
|
|
315
|
-
const
|
|
315
|
+
var l, c, a, h, n, m;
|
|
316
|
+
const o = [], i = Math.pow(10, t.precision || 6);
|
|
317
|
+
for (const r of e) {
|
|
318
|
+
const d = r.utcOffsetSeconds(), A = r.timezone(), R = r.current(), w = r.hourly(), M = r.daily(), y = {
|
|
319
|
+
timezone: A
|
|
320
|
+
};
|
|
316
321
|
if (R) {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
time:
|
|
322
|
+
const I = f();
|
|
323
|
+
y.current = {
|
|
324
|
+
time: f.unix(Number(R.time()) + d).utc().format()
|
|
320
325
|
};
|
|
321
|
-
for (let
|
|
322
|
-
const v = R.variables(
|
|
323
|
-
|
|
326
|
+
for (let p = 0; p < R.variablesLength(); p++) {
|
|
327
|
+
const v = R.variables(p).value();
|
|
328
|
+
y.current[s.current[p]] = Number.isNaN(v) ? v : Math.round(v * i) / i;
|
|
324
329
|
}
|
|
325
|
-
const
|
|
326
|
-
this.debug && S.info("[%s] fetch current variables cost: %d ms", t.requestId,
|
|
330
|
+
const E = f();
|
|
331
|
+
this.debug && S.info("[%s] fetch current variables cost: %d ms", t.requestId, E.diff(I, "ms"));
|
|
327
332
|
}
|
|
328
|
-
if (
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
date:
|
|
332
|
-
time: this.range(Number(
|
|
333
|
+
if (w) {
|
|
334
|
+
const I = f(), E = f.unix(Number(w.time()) + d);
|
|
335
|
+
y.hourly = {
|
|
336
|
+
date: E.utc().format(),
|
|
337
|
+
time: this.range(Number(w.time()), Number(w.timeEnd()), w.interval()).map((v) => f.unix(v + d).diff(E, "h"))
|
|
333
338
|
};
|
|
334
|
-
for (let v = 0; v <
|
|
335
|
-
const L = (
|
|
336
|
-
|
|
339
|
+
for (let v = 0; v < w.variablesLength(); v++) {
|
|
340
|
+
const L = (a = (c = (l = w.variables(v).valuesArray()) == null ? void 0 : l.toString()) == null ? void 0 : c.split(",")) == null ? void 0 : a.map((b) => Number.isNaN(b) ? b : Math.round(Number(b) * i) / i);
|
|
341
|
+
y.hourly[s.hourly[v]] = L;
|
|
337
342
|
}
|
|
338
|
-
const
|
|
339
|
-
this.debug && S.info("[%s] fetch hourly variables cost: %d ms", t.requestId,
|
|
343
|
+
const p = f();
|
|
344
|
+
this.debug && S.info("[%s] fetch hourly variables cost: %d ms", t.requestId, p.diff(I, "ms"));
|
|
340
345
|
}
|
|
341
|
-
if (
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
time: this.range(Number(
|
|
345
|
-
(
|
|
346
|
+
if (M) {
|
|
347
|
+
const I = f();
|
|
348
|
+
y.daily = {
|
|
349
|
+
time: this.range(Number(M.time()), Number(M.timeEnd()), M.interval()).map(
|
|
350
|
+
(p) => f.unix(p + d).utc().format()
|
|
346
351
|
)
|
|
347
352
|
};
|
|
348
|
-
for (let
|
|
349
|
-
const v = (
|
|
350
|
-
|
|
353
|
+
for (let p = 0; p < M.variablesLength(); p++) {
|
|
354
|
+
const v = (m = (n = (h = M.variables(p).valuesArray()) == null ? void 0 : h.toString()) == null ? void 0 : n.split(",")) == null ? void 0 : m.map((L) => Number.isNaN(L) ? L : Math.round(Number(L) * i) / i);
|
|
355
|
+
y.daily[s.daily[p]] = v;
|
|
351
356
|
}
|
|
352
|
-
const
|
|
353
|
-
this.debug && S.info("[%s] fetch daily variables cost: %d ms", t.requestId,
|
|
357
|
+
const E = f();
|
|
358
|
+
this.debug && S.info("[%s] fetch daily variables cost: %d ms", t.requestId, E.diff(I, "ms"));
|
|
354
359
|
}
|
|
355
|
-
o.push(
|
|
360
|
+
o.push(y);
|
|
356
361
|
}
|
|
357
362
|
return o;
|
|
358
363
|
}
|
|
@@ -365,26 +370,26 @@ class k {
|
|
|
365
370
|
*/
|
|
366
371
|
prepare(e, s, t, o = {}) {
|
|
367
372
|
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;
|
|
368
|
-
const
|
|
369
|
-
return s ? (t.url = o.selfHosted ? this.
|
|
373
|
+
const i = f().subtract(1, "d");
|
|
374
|
+
return s ? (t.url = o.selfHosted ? this.FORECAST.ORM_MARINE_URL : this.FORECAST.OM_MARINE_URL, e != null && e.isBefore(i) && (t.url = this.FORECAST.OM_MARINE_URL)) : (t.url = o.selfHosted ? this.FORECAST.ORM_URL : this.FORECAST.OM_URL, e != null && e.isBefore(i) && (t.url = this.FORECAST.OM_HISTORY_URL)), t;
|
|
370
375
|
}
|
|
371
|
-
async spotForecast(e, s, t, o = !0,
|
|
376
|
+
async spotForecast(e, s, t, o = !0, i = !0, l = !1, c = {
|
|
372
377
|
forecastDays: 1,
|
|
373
378
|
precision: 6,
|
|
374
379
|
selfHosted: !0
|
|
375
380
|
}) {
|
|
376
|
-
var
|
|
377
|
-
const
|
|
381
|
+
var r, d, A, R, w, M;
|
|
382
|
+
const a = {
|
|
378
383
|
apikey: this.apikey,
|
|
379
384
|
latitude: e,
|
|
380
385
|
longitude: s,
|
|
381
386
|
cell_selection: "sea",
|
|
382
387
|
wind_speed_unit: "kn",
|
|
383
|
-
models: ((
|
|
388
|
+
models: ((r = c.weatherModels) == null ? void 0 : r.split(",")) || ["best_match"],
|
|
384
389
|
timezone: "auto"
|
|
385
390
|
};
|
|
386
|
-
|
|
387
|
-
const h = await this.weatherForecast(
|
|
391
|
+
i && (a.daily = o ? ((d = this.FORECAST.WEATHER_VARIABLES.SIMPLE.DAILY) == null ? void 0 : d.split(",")) || [] : ((A = this.FORECAST.WEATHER_VARIABLES.NORMAL.DAILY) == null ? void 0 : A.split(",")) || []), t || (c.forecastDays = c.forecastDays || 1, l = !0), l && (a.hourly = o ? ((R = this.FORECAST.WEATHER_VARIABLES.SIMPLE.HOURLY) == null ? void 0 : R.split(",")) || [] : ((w = this.FORECAST.WEATHER_VARIABLES.NORMAL.HOURLY) == null ? void 0 : w.split(",")) || []), this.prepare(t, !1, a, c);
|
|
392
|
+
const h = await this.weatherForecast(a, c), n = {
|
|
388
393
|
apikey: this.apikey,
|
|
389
394
|
latitude: e,
|
|
390
395
|
longitude: s,
|
|
@@ -393,13 +398,15 @@ class k {
|
|
|
393
398
|
wind_speed_unit: "kn",
|
|
394
399
|
models: ((M = c.marineModels) == null ? void 0 : M.split(",")) || ["best_match"]
|
|
395
400
|
};
|
|
396
|
-
|
|
397
|
-
const
|
|
398
|
-
return { weather: h, marine:
|
|
401
|
+
i && (n.daily = this.FORECAST.MARINE_VARIABLES.DAILY.split(",")), t || (c.forecastDays = c.forecastDays || 1, l = !0), l && (n.hourly = this.FORECAST.MARINE_VARIABLES.HOURLY.split(",")), this.prepare(t, !0, n, c);
|
|
402
|
+
const m = await this.marineForecast(n, c);
|
|
403
|
+
return { weather: h, marine: m };
|
|
404
|
+
}
|
|
405
|
+
async spotHistorical() {
|
|
399
406
|
}
|
|
400
407
|
}
|
|
401
408
|
export {
|
|
402
|
-
|
|
409
|
+
q as MeteoHelper,
|
|
403
410
|
k as MeteoHelper2,
|
|
404
|
-
|
|
411
|
+
H as WindyModel
|
|
405
412
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(_,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):(_=typeof globalThis<"u"?globalThis:_||self,w(_["idm-plugin-rabbitmq"]={},_["@log4js-node/log4js-api"],_.moment,_.got,_.openmeteo))})(this,function(_,w,o,O,D){"use strict";var C=Object.defineProperty;var H=(_,w,o)=>w in _?C(_,w,{enumerable:!0,configurable:!0,writable:!0,value:o}):_[w]=o;var S=(_,w,o)=>(H(_,typeof w!="symbol"?w+"":w,o),o);let f;try{f=w.getLogger("meteo")}catch{}finally{}var F=(p=>(p.Arome="arome",p.IconEU="iconEu",p.GFS="gfs",p.GFSWave="gfsWave",p.NamConus="namConus",p.NamHawaii="namHawaii",p.NamAlaska="namAlaska",p.Geos5="geos5",p))(F||{});class U{static async queryPointMeteo(e,s,t,c=!1,a="",l={}){typeof t=="number"&&(t=t<1e12?t*1e3:t);const n=o(t),r={searchParams:{lng:e,lat:s,ts:n.valueOf(),params:c?"watertemp":void 0,source:a==null?void 0:a.toLowerCase()},timeout:3e4},h=o(),u=h.valueOf();n.isBefore(h.subtract(1,"month"))&&(f==null||f.warn("[%s] get history meteo on %s: %j",l.requestId,n.format(),r));const v="https://aod4idm.idmwx.com/api/ocean/point",i=await O.get(v,r).json(),d=o().valueOf();if(f==null||f.info("[%s] get meteo(cost: %d ms) from %s with options: %j",l.requestId,d-u,v,r),(i==null?void 0:i.code)===0)return{...i.data,source:a};f==null||f.warn("[%s] get meteo failed: %j",l.requestId,i)}static async queryPointFactor(e,s,t,c="wind,wave,current,watertemp,visibility",a="",l={}){typeof t=="number"&&(t=t<1e12?t*1e3:t);const n=o(t),r={searchParams:{lng:e,lat:s,ts:n.valueOf(),params:c,source:a==null?void 0:a.toLowerCase()},timeout:3e4},h=o(),u=h.valueOf();n.isBefore(h.subtract(1,"month"))&&(f==null||f.warn("[%s] get history factors on %s: %j",l.requestId,n.format(),r));const v="https://aod4idm.idmwx.com/api/ocean/factor",i=await O.get(v,r).json(),d=o().valueOf();if(f==null||f.info("[%s] get factors(cost: %d ms) from %s with options: %j",l.requestId,d-u,v,r),(i==null?void 0:i.code)===0)return{...i.data,source:a};f==null||f.warn("[%s] get factors failed: %j",l.requestId,i)}static async queryWindyPointForecast(e,s,t,c={}){const a="https://api.windy.com/api/point-forecast/v2",l=[];try{let n=o().valueOf();const r=await O.post(a,{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();f==null||f.info("[%s] get gfs-factors(cost: %d ms) from %s",c.requestId,h-n,a),n=h;const u=await O.post(a,{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(),f==null||f.info("[%s] get gfs-wave-factors(cost: %d ms) from %s",c.requestId,h-n,a);for(let i=0;i<r.ts.length;i++){const d=this.populateUVFactor(r["wind_u-surface"][i],r["wind_v-surface"][i],!1,c);d.scale=this.calculateBeaufortWindForceScale(d.speed),l.push({utc:o(r.ts[i]).utc().format(),temp:r["temp-surface"][i]?Math.round((r["temp-surface"][i]-273.15)*100)/100:void 0,dp_temp:r["dewpoint-surface"][i]?Math.round((r["dewpoint-surface"][i]-273.15)*100)/100:void 0,precip:{inter3h:r["past3hprecip-surface"][i]?Math.round(r["past3hprecip-surface"][i]*1e3*1e3)/1e3:0,inter3hSnow:r["past3hsnowprecip-surface"][i]?Math.round(r["past3hsnowprecip-surface"][i]*1e3*1e3)/1e3:0,inter3hConv:r["past3hconvprecip-surface"][i]?Math.round(r["past3hconvprecip-surface"][i]*1e3*1e3)/1e3:0},wind:d,gusts:{speed:Math.round((r["gust-surface"][i]||0)*100)/100,kts:this.convertMs2Kts(r["gust-surface"][i])},lclouds:r["lclouds-surface"][i]?Math.round(r["lclouds-surface"][i]*100)/100:0,mclouds:r["mclouds-surface"][i]?Math.round(r["mclouds-surface"][i]*100)/100:0,hclouds:r["hclouds-surface"][i]?Math.round(r["hclouds-surface"][i]*100)/100:0,rh:r["rh-surface"][i]?Math.round(r["rh-surface"][i]*100)/100:0,gh:r["gh-surface"][i]?Math.round(r["gh-surface"][i]*100)/100:0,pressure:Math.round(r["pressure-surface"][i]/100*100)/100})}const v=[];for(let i=0;i<u.ts.length;i++){const d=this.calculateDouglasScale(u["waves_height-surface"][i],u["waves_direction-surface"][i],u["waves_period-surface"][i]),A=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]),y=this.calculateDouglasScale(u["swell2_height-surface"][i],u["swell2_direction-surface"][i],u["swell2_period-surface"][i]);v.push({utc:o(u.ts[i]).utc().format(),wave:{sig:d,wd:A,swell:R,swell2:y}})}for(const i of l){const d=v.find(A=>A.utc===i.utc);i.wave=d==null?void 0:d.wave}}catch(n){f.warn("[%s] get-gfs-factor failed: %s",c.requestId,n)}return l}static populateUVFactor(e,s,t=!1,c={}){const a=Math.round(Math.sqrt(Math.pow(e,2)+Math.pow(s,2))*1e4)/1e4,{degree:l,direction:n}=this.calculateUVDirection(e,s,t,c),r=this.convertMs2Kts(a);return{speed:a,kts:r,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 a=Math.atan2(e,s)+Math.PI;t&&(a=Math.atan2(e,s));const l=this.convert2Direction(a);return a=Math.round(a/(2*Math.PI)*360*1e4)/1e4,{angle:a,degree:a,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 a=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:a,height:Math.round(e*1e3)/1e3,period:Math.round(t*100)/100}}}let I;try{I=w.getLogger("open-meteo")}catch{}finally{}class g{constructor(e,s){S(this,"apikey");S(this,"debug");S(this,"FORECAST_URL","https://customer-api.open-meteo.com/v1/forecast");S(this,"SELF_FORECAST_URL","https://meteo2.idmwx.com/v1/forecast");S(this,"HISTORY_FORECAST_URL","https://customer-historical-forecast-api.open-meteo.com/v1/forecast");S(this,"MARINE_FORECAST_URL","https://customer-marine-api.open-meteo.com/v1/marine");S(this,"SELF_MARINE_FORECAST_URL","https://meteo2.idmwx.com/v1/marine");S(this,"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,dew_point_2m,apparent_temperature,precipitation_probability,precipitation,weather_code,visibility,wind_speed_10m,wind_direction_10m,wind_gusts_10m,is_day",CURRENT:"temperature_2m,relative_humidity_2m,apparent_temperature,precipitation,weather_code,wind_speed_10m,wind_direction_10m,wind_gusts_10m"},SIMPLE:{DAILY:"weather_code",HOURLY:"wind_speed_10m,wind_direction_10m,wind_gusts_10m",CURRENT:"wind_speed_10m,wind_direction_10m,wind_gusts_10m"}});S(this,"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",CURRENT:"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"});this.apikey=e||"smE3JnDLHy3TizVv",this.debug=s}range(e,s,t){return Array.from({length:(s-e)/t},(c,a)=>e+a*t)}async weatherForecast(e,s={}){const t=o(),c=await D.fetchWeatherApi(e.url,e);delete e.apikey;const a=o();return this.debug&&I.info("[%s] fetch weather api (%s) cost: %d ms",s.requestId,e.url,a.diff(t,"ms")),this.parseWeatherData(c,e,s)}async marineForecast(e,s={}){const t=o(),c=await D.fetchWeatherApi(e.url,e);delete e.apikey;const a=o();return this.debug&&I.info("[%s] fetch marine api (%s) cost: %d ms",s.requestId,e.url,a.diff(t,"ms")),this.parseWeatherData(c,e,s)}async parseWeatherData(e,s,t={}){var l,n,r,h,u,v;const c=[],a=Math.pow(10,t.precision||6);for(const i of e){const d=i.utcOffsetSeconds(),A=i.current(),R=i.hourly(),y=i.daily(),M={};if(A){const L=o();M.current={time:o.unix(Number(A.time())+d).utc().format()};for(let m=0;m<A.variablesLength();m++){const E=A.variables(m).value();M.current[s.current[m]]=Number.isNaN(E)?E:Math.round(E*a)/a}const N=o();this.debug&&I.info("[%s] fetch current variables cost: %d ms",t.requestId,N.diff(L,"ms"))}if(R){const L=o(),N=o.unix(Number(R.time())+d);M.hourly={date:N.utc().format(),time:this.range(Number(R.time()),Number(R.timeEnd()),R.interval()).map(E=>o.unix(E+d).diff(N,"h"))};for(let E=0;E<R.variablesLength();E++){const b=(r=(n=(l=R.variables(E).valuesArray())==null?void 0:l.toString())==null?void 0:n.split(","))==null?void 0:r.map(T=>Number.isNaN(T)?T:Math.round(Number(T)*a)/a);M.hourly[s.hourly[E]]=b}const m=o();this.debug&&I.info("[%s] fetch hourly variables cost: %d ms",t.requestId,m.diff(L,"ms"))}if(y){const L=o();M.daily={time:this.range(Number(y.time()),Number(y.timeEnd()),y.interval()).map(m=>o.unix(m+d).utc().format())};for(let m=0;m<y.variablesLength();m++){const E=(v=(u=(h=y.variables(m).valuesArray())==null?void 0:h.toString())==null?void 0:u.split(","))==null?void 0:v.map(b=>Number.isNaN(b)?b:Math.round(Number(b)*a)/a);M.daily[s.daily[m]]=E}const N=o();this.debug&&I.info("[%s] fetch daily variables cost: %d ms",t.requestId,N.diff(L,"ms"))}c.push(M)}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 a=o().subtract(1,"d");return s?(t.url=c.selfHosted?this.SELF_MARINE_FORECAST_URL:this.MARINE_FORECAST_URL,e!=null&&e.isBefore(a)&&(t.url=this.MARINE_FORECAST_URL)):(t.url=c.selfHosted?this.SELF_FORECAST_URL:this.FORECAST_URL,e!=null&&e.isBefore(a)&&(t.url=this.HISTORY_FORECAST_URL)),t}async spotForecast(e,s,t,c=!0,a=!0,l=!1,n={forecastDays:1,precision:6,selfHosted:!0}){var i,d,A,R,y,M,L,N;const r={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"};a&&(r.daily=c?((d=this.WEATHER_VARIABLES.SIMPLE.DAILY)==null?void 0:d.split(","))||[]:((A=this.WEATHER_VARIABLES.NORMAL.DAILY)==null?void 0:A.split(","))||[]),t||(n.forecastDays=n.forecastDays||1,r.current=c?((R=this.WEATHER_VARIABLES.SIMPLE.CURRENT)==null?void 0:R.split(","))||[]:((y=this.WEATHER_VARIABLES.NORMAL.CURRENT)==null?void 0:y.split(","))||[]),l&&(r.hourly=c?((M=this.WEATHER_VARIABLES.SIMPLE.HOURLY)==null?void 0:M.split(","))||[]:((L=this.WEATHER_VARIABLES.NORMAL.HOURLY)==null?void 0:L.split(","))||[]),this.prepare(t,!1,r,n);const h=await this.weatherForecast(r,n),u={apikey:this.apikey,latitude:e,longitude:s,cell_selection:"sea",timezone:"auto",wind_speed_unit:"kn",models:((N=n.marineModels)==null?void 0:N.split(","))||["best_match"]};a&&(u.daily=this.MARINE_VARIABLES.DAILY.split(",")),t||(n.forecastDays=n.forecastDays||1,u.current=this.MARINE_VARIABLES.CURRENT.split(",")),l&&(u.hourly=this.MARINE_VARIABLES.HOURLY.split(",")),this.prepare(t,!0,u,n);const v=await this.marineForecast(u,n);return{weather:h,marine:v}}}_.MeteoHelper=U,_.MeteoHelper2=g,_.WindyModel=F,Object.defineProperty(_,Symbol.toStringTag,{value:"Module"})});
|
|
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"})});
|
|
@@ -43,13 +43,8 @@ export interface OMOptions {
|
|
|
43
43
|
export declare class MeteoHelper2 {
|
|
44
44
|
private readonly apikey;
|
|
45
45
|
private readonly debug;
|
|
46
|
-
private readonly
|
|
47
|
-
private readonly
|
|
48
|
-
private readonly HISTORY_FORECAST_URL;
|
|
49
|
-
private readonly MARINE_FORECAST_URL;
|
|
50
|
-
private readonly SELF_MARINE_FORECAST_URL;
|
|
51
|
-
private readonly WEATHER_VARIABLES;
|
|
52
|
-
private readonly MARINE_VARIABLES;
|
|
46
|
+
private readonly FORECAST;
|
|
47
|
+
private readonly HISTORICAL;
|
|
53
48
|
constructor(apikey: string, debug?: boolean);
|
|
54
49
|
range(start: number, stop: number, step: number): number[];
|
|
55
50
|
weatherForecast(params: any, options?: OMOptions): Promise<any[]>;
|
|
@@ -67,4 +62,5 @@ export declare class MeteoHelper2 {
|
|
|
67
62
|
weather: any[];
|
|
68
63
|
marine: any[];
|
|
69
64
|
}>;
|
|
65
|
+
spotHistorical(): Promise<void>;
|
|
70
66
|
}
|