@aeroswarm/weather 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/dist/aftn.d.ts +4 -4
- package/dist/aftn.d.ts.map +1 -1
- package/dist/conditions.d.ts +2 -1
- package/dist/conditions.d.ts.map +1 -1
- package/dist/geo.d.ts +54 -0
- package/dist/geo.d.ts.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +844 -19
- package/dist/metar.d.ts.map +1 -1
- package/dist/nil.d.ts +16 -0
- package/dist/nil.d.ts.map +1 -0
- package/dist/sigmet.d.ts +91 -0
- package/dist/sigmet.d.ts.map +1 -0
- package/dist/snowtam.d.ts +43 -0
- package/dist/snowtam.d.ts.map +1 -0
- package/dist/store.d.ts +4 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/taf.d.ts.map +1 -1
- package/dist/types.d.ts +34 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vaa.d.ts +75 -0
- package/dist/vaa.d.ts.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,3 +46,50 @@ temperature) for any model source. `parseWeatherGridSeries`, `serializeWeatherGr
|
|
|
46
46
|
`seriesFieldsAt`, and the Open-Meteo adapter (`latticePoints`, `weatherGridFromOpenMeteo`) are in the
|
|
47
47
|
package; the network call stays in the app.
|
|
48
48
|
|
|
49
|
+
## Tokens that are understood
|
|
50
|
+
|
|
51
|
+
Checked against 2,400 real METAR/SPECI and 212 real TAF from 100+ airports (see `test/fixtures/README.md`).
|
|
52
|
+
Every token of that corpus is either read or recognised as a group the model does not use; the one
|
|
53
|
+
exception is a typo in the source (`VEB03KT`), which stays visible in `unparsed`.
|
|
54
|
+
|
|
55
|
+
| Group | Read into the model | Recognised, not modelled |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| Wind | `dddffKT`, `dddffGggKT`, `dddffMPS`, `VRB`, variable range `dddVddd` (also glued to the wind group) | |
|
|
58
|
+
| Visibility | metres (`9999`, `0750`), statute miles (`10SM`, `1/2SM`, `1 1/2SM`, `P6SM`), `CAVOK` | directional lowest visibility (`0500NE`) |
|
|
59
|
+
| RVR | `R06R/0600N`, `R28/P2000`, `R35L/1200V1400FT` (metres or feet, trend, variable) in `conditions.rvr` | runway state (`R06C/CLRD62`, `R88/090065`) |
|
|
60
|
+
| Weather | intensity, descriptor and phenomena (`+TSRA`, `VCTS`, `FZFG`, `BCFG`...), `NSW` | recent weather (`RERA`, `RETS`) |
|
|
61
|
+
| Cloud | `FEW/SCT/BKN/OVC` with `CB/TCU`, `VV`, `SKC/CLR/NSC/NCD` | |
|
|
62
|
+
| Temperature, pressure | `tt/dd` (also `M`), `Qpppp`, `Appp` (inHg to hPa) | |
|
|
63
|
+
| Flags, trend | `AUTO`, `COR`, `NOSIG`, `BECMG`, `TEMPO`; everything after `RMK` is ignored | `//` (missing group), wind shear (`WS020/14030KT`, `WS R10`, `WS ALL RWY`) |
|
|
64
|
+
| TAF | `AMD`, `COR`, `CNL`, `FMddhhmm`, `BECMG`, `TEMPO`, `PROBnn [TEMPO]`, `TX/TN` | remarks |
|
|
65
|
+
|
|
66
|
+
A token that is none of these ends up in `Metar.unparsed` / `TafPeriod.unparsed` instead of silently
|
|
67
|
+
disappearing. A report with an impossible date (for example `0000/0000`) is rejected (`null`), not
|
|
68
|
+
guessed. A fuzz test mutates real reports (truncated, tokens removed, inserted, swapped) and requires
|
|
69
|
+
that the parser never throws and never returns invalid numbers or dates.
|
|
70
|
+
|
|
71
|
+
Not supported: the US domestic SIGMET formats (convective SIGMET, `AREA EMBD TS ...` with VOR-radial
|
|
72
|
+
points), graphical G-AIRMET, and ICAO Annex 3 trend groups with `FM`/`TL`/`AT` times inside a METAR
|
|
73
|
+
trend.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## Warnings and special messages
|
|
78
|
+
|
|
79
|
+
`decodeWeatherMessage` and `extractReports` also recognise these, and tell them apart by `kind`:
|
|
80
|
+
|
|
81
|
+
| Kind | Reader | What is read | Verified against |
|
|
82
|
+
|---|---|---|---|
|
|
83
|
+
| `NIL` | `parseNil` | `METAR/SPECI/TAF [COR/AMD] ICAO [ddhhmmZ] NIL` | ICAO template only (no real NIL in the corpus) |
|
|
84
|
+
| `SIGMET`, `AIRMET` | `parseSigmet` | FIR, series, validity, MWO, hazard (thunderstorm, turbulence, icing, mountain wave, volcanic ash, tropical cyclone, dust/sand storm, radioactive cloud, surface wind/visibility/cloud, cancellation), observed or forecast time, area (polygon, line with side, circle, latitude/longitude line, corridor, entire FIR, several areas), levels, movement, trend, volcano and cyclone names with positions, forecast position | 124 real SIGMET (aviationweather.gov); AIRMET only against the Annex 3 template |
|
|
85
|
+
| `VAA` | `parseVaa` | VAAC, issue time, volcano and number, position, summit elevation, advisory number, colour code, eruption details, observed/estimated ash cloud, +6/+12/+18 h forecasts (layers with boundary points, movement, wind at the vent level), remarks, next advisory | 60 real advisories (Tokyo VAAC, JMA) |
|
|
86
|
+
| `SNOWTAM` | `parseSnowtam` | lettered format A) to T): aerodrome, assessment time, every runway (cleared length and width, deposits and depth per third, friction), next observation, remarks. The global reporting format: head only (aerodrome, time), the rest in `unparsed` | Annex 15 items only (no real message) |
|
|
87
|
+
|
|
88
|
+
Anything in these messages that is not understood is returned in `unparsed`, not dropped.
|
|
89
|
+
A message whose header cannot be read returns `null`. The store counts these messages as `other`
|
|
90
|
+
and does not keep them (they are not weather conditions at a station).
|
|
91
|
+
|
|
92
|
+
Honest limits: AIRMET, NIL and SNOWTAM were written from the ICAO specification because no real
|
|
93
|
+
messages could be collected (aviationweather.gov does not publish them; the Bureau of Meteorology
|
|
94
|
+
blocks automated access, so Darwin VAAC advisories were not collected). Treat those three as
|
|
95
|
+
specification-checked, not field-proven, until real samples are added to `test/fixtures`.
|
package/dist/aftn.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { ReportKind } from "./types.js";
|
|
2
2
|
export interface RawReport {
|
|
3
3
|
kind: ReportKind;
|
|
4
|
-
/** Teks laporan dari kata kunci
|
|
4
|
+
/** Teks laporan dari kata kunci sampai sebelum laporan berikutnya, spasi dirapikan. */
|
|
5
5
|
text: string;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Ambil laporan
|
|
9
|
-
* (`SAID31 WARR 021030`), atau pesan AFTN lengkap (`ZCZC ... NNNN` dengan baris alamat).
|
|
10
|
-
*
|
|
8
|
+
* Ambil laporan dari teks mentah: boleh berupa laporan polos, buletin dengan header
|
|
9
|
+
* (`SAID31 WARR 021030`), atau pesan AFTN lengkap (`ZCZC ... NNNN` dengan baris alamat). Banyak laporan
|
|
10
|
+
* dalam satu pesan dipisah per kata kunci, dengan atau tanpa tanda `=`.
|
|
11
11
|
*/
|
|
12
12
|
export declare function extractReports(message: string): RawReport[];
|
|
13
13
|
//# sourceMappingURL=aftn.d.ts.map
|
package/dist/aftn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aftn.d.ts","sourceRoot":"","sources":["../src/aftn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,
|
|
1
|
+
{"version":3,"file":"aftn.d.ts","sourceRoot":"","sources":["../src/aftn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;CACd;AAYD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAwB3D"}
|
package/dist/conditions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CloudLayer, Conditions, PresentWeather, Wind } from "./types.js";
|
|
1
|
+
import type { CloudLayer, Conditions, PresentWeather, Rvr, Wind } from "./types.js";
|
|
2
2
|
export declare function emptyConditions(): Conditions;
|
|
3
3
|
export interface ConditionTokens {
|
|
4
4
|
wind?: Wind;
|
|
@@ -6,6 +6,7 @@ export interface ConditionTokens {
|
|
|
6
6
|
cavok?: boolean;
|
|
7
7
|
clouds?: CloudLayer[];
|
|
8
8
|
weather?: PresentWeather[];
|
|
9
|
+
rvr?: Rvr[];
|
|
9
10
|
noSignificantWeather?: boolean;
|
|
10
11
|
/** Token yang tidak dikenali (diteruskan ke pemanggil, mis. suhu atau QNH). */
|
|
11
12
|
rest: string[];
|
package/dist/conditions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditions.d.ts","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,UAAU,EACV,UAAU,EACV,cAAc,EACd,IAAI,EAEL,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"conditions.d.ts","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,UAAU,EACV,UAAU,EACV,cAAc,EACd,GAAG,EACH,IAAI,EAEL,MAAM,YAAY,CAAC;AAgCpB,wBAAgB,eAAe,IAAI,UAAU,CAa5C;AAgCD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IACZ,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,+EAA+E;IAC/E,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CA+JtE;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7D,UAAU,CAsBZ"}
|
package/dist/geo.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Posisi dan ketinggian pada pesan peringatan (SIGMET, AIRMET, VAA): murni, tanpa jaringan. */
|
|
2
|
+
export interface GeoPosition {
|
|
3
|
+
lat: number;
|
|
4
|
+
lon: number;
|
|
5
|
+
}
|
|
6
|
+
export type Compass = "N" | "NNE" | "NE" | "ENE" | "E" | "ESE" | "SE" | "SSE" | "S" | "SSW" | "SW" | "WSW" | "W" | "WNW" | "NW" | "NNW";
|
|
7
|
+
export declare const isCompass: (value: string) => value is Compass;
|
|
8
|
+
/** Derajat dari utara untuk arah mata angin 16 titik. */
|
|
9
|
+
export declare const compassDegrees: (direction: Compass) => number;
|
|
10
|
+
/**
|
|
11
|
+
* Satu titik seperti `N1034 W07726` atau `S0200W07820`. Lintang `ddmm` (atau `dd`), bujur `dddmm` (atau
|
|
12
|
+
* `ddd`). Bujur empat angka (`W5815`, salah ketik yang ada pada laporan nyata) dibaca `ddmm`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const POINT: string;
|
|
15
|
+
export declare function parsePosition(text: string): GeoPosition | null;
|
|
16
|
+
/** Semua titik dalam teks, berurutan. */
|
|
17
|
+
export declare function parsePositions(text: string): GeoPosition[];
|
|
18
|
+
/** Rentang ketinggian dalam kaki; `null` = tidak disebut, `0` = permukaan (SFC). */
|
|
19
|
+
export interface AltitudeRange {
|
|
20
|
+
baseFt: number | null;
|
|
21
|
+
topFt: number | null;
|
|
22
|
+
/** `TOP ABV FL450`: puncaknya di atas nilai itu. */
|
|
23
|
+
topAbove?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare const ALTITUDE_PATTERNS: {
|
|
26
|
+
/** `TOP FL490`, `TOP ABV FL450`, `TOP FL250/390`. */
|
|
27
|
+
readonly top: RegExp;
|
|
28
|
+
/** `FL240/300`, `SFC/FL100`, `SFC/6000FT`, `2000/4000FT`. */
|
|
29
|
+
readonly range: RegExp;
|
|
30
|
+
/** `ABV FL250` sendirian. */
|
|
31
|
+
readonly above: RegExp;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Cari satu petunjuk ketinggian dalam `text`. Mengembalikan rentangnya dan bagian teks yang dipakai,
|
|
35
|
+
* atau null.
|
|
36
|
+
*/
|
|
37
|
+
export declare function findAltitude(text: string): {
|
|
38
|
+
range: AltitudeRange;
|
|
39
|
+
matched: string;
|
|
40
|
+
} | null;
|
|
41
|
+
export interface Movement {
|
|
42
|
+
stationary: boolean;
|
|
43
|
+
direction?: Compass;
|
|
44
|
+
/** Kecepatan (kt); untuk rentang (`10-15KT`) nilai terbesar. */
|
|
45
|
+
speedKt?: number;
|
|
46
|
+
/** Batas bawah bila kecepatan dilaporkan sebagai rentang. */
|
|
47
|
+
speedMinKt?: number;
|
|
48
|
+
}
|
|
49
|
+
/** `MOV NW 10KT`, `MOV ENE`, `MOV E 25KMH`, `STNR`. */
|
|
50
|
+
export declare function findMovement(text: string): {
|
|
51
|
+
movement: Movement;
|
|
52
|
+
matched: string;
|
|
53
|
+
} | null;
|
|
54
|
+
//# sourceMappingURL=geo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geo.d.ts","sourceRoot":"","sources":["../src/geo.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,OAAO,GACf,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,GACL,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,GACL,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,GACL,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,CAAC;AAqBV,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,KAAK,IAAI,OAAmC,CAAC;AAEvF,yDAAyD;AACzD,eAAO,MAAM,cAAc,GAAI,WAAW,OAAO,KAAG,MAAoC,CAAC;AAEzF;;;GAGG;AACH,eAAO,MAAM,KAAK,QAAwC,CAAC;AAW3D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAU9D;AAED,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAO1D;AAED,oFAAoF;AACpF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAeD,eAAO,MAAM,iBAAiB;IAC5B,qDAAqD;;IAErD,6DAA6D;;IAE7D,6BAA6B;;CAErB,CAAC;AAEX;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsC3F;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmBzF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,16 +2,22 @@ import type { Report } from "./types.js";
|
|
|
2
2
|
export * from "./aftn.js";
|
|
3
3
|
export * from "./animation.js";
|
|
4
4
|
export * from "./conditions.js";
|
|
5
|
+
export * from "./geo.js";
|
|
5
6
|
export * from "./grid.js";
|
|
6
7
|
export * from "./gridSeries.js";
|
|
7
8
|
export * from "./openMeteo.js";
|
|
8
9
|
export * from "./metar.js";
|
|
10
|
+
export * from "./nil.js";
|
|
11
|
+
export * from "./sigmet.js";
|
|
12
|
+
export * from "./snowtam.js";
|
|
9
13
|
export * from "./taf.js";
|
|
10
14
|
export * from "./store.js";
|
|
11
15
|
export * from "./time.js";
|
|
12
16
|
export * from "./types.js";
|
|
17
|
+
export * from "./vaa.js";
|
|
13
18
|
/**
|
|
14
|
-
* Baca semua laporan cuaca
|
|
19
|
+
* Baca semua laporan cuaca dari satu pesan mentah, termasuk bungkus AFTN: METAR, SPECI, TAF, NIL,
|
|
20
|
+
* SIGMET, AIRMET, pemberitahuan abu vulkanik (VAA), dan SNOWTAM.
|
|
15
21
|
* Laporan yang tidak terbaca dilewati. `reference` = waktu pesan diterima (menentukan bulan/tahun).
|
|
16
22
|
*/
|
|
17
23
|
export declare function decodeWeatherMessage(message: string, reference?: Date): Report[];
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AAEzB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,IAAiB,GAC3B,MAAM,EAAE,CA0BV"}
|