@atmosx/event-product-parser 3.0.44 → 3.0.47
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 +77 -31
- package/SUPPORTED_EVENTS.md +369 -0
- package/dist/cjs/index.cjs +681 -403
- package/dist/esm/index.mjs +659 -382
- package/dist/index.d.mts +54 -25
- package/dist/index.d.ts +54 -25
- package/package.json +1 -1
- package/src/@building/building.attachments.ts +83 -0
- package/src/@building/building.enhance.ts +7 -3
- package/src/@building/building.office.ts +2 -2
- package/src/@building/building.properties.ts +12 -11
- package/src/@building/building.signature.ts +11 -11
- package/src/@building/building.tags.ts +2 -2
- package/src/@building/building.tracking.ts +3 -3
- package/src/@building/building.validate.ts +2 -2
- package/src/@core/core.createEvent.ts +83 -0
- package/src/@dictionaries/{dictionaries.eventActions.ts → dictionaries.actions.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventAwipAbreviations.ts → dictionaries.awips.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventCancelMessages.ts → dictionaries.cancellation.ts} +2 -1
- package/src/@dictionaries/{dictionaries.eventCauses.ts → dictionaries.causes.ts} +1 -1
- package/src/@dictionaries/{dictionaries.statusCorrelationText.ts → dictionaries.correlations.ts} +1 -1
- package/src/@dictionaries/{dictionaries.betterEventNames.ts → dictionaries.enhanced.ts} +13 -2
- package/src/@dictionaries/{dictionaries.eventTypes.ts → dictionaries.events.ts} +1 -1
- package/src/@dictionaries/{dictionaries.regExp.ts → dictionaries.expressions.ts} +2 -1
- package/src/@dictionaries/{dictionaries.hailStrings.ts → dictionaries.hail.ts} +4 -1
- package/src/@dictionaries/{dictionaries.officeICAOs.ts → dictionaries.icao.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventsMatchText.ts → dictionaries.matches.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventProducts.ts → dictionaries.products.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventRecords.ts → dictionaries.records.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventSeverity.ts → dictionaries.severity.ts} +1 -1
- package/src/@dictionaries/{dictionaries.shapefileLinks.ts → dictionaries.shapefiles.ts} +1 -1
- package/src/@dictionaries/dictionaries.states.ts +72 -0
- package/src/@dictionaries/{dictionaries.eventStatus.ts → dictionaries.status.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventTags.ts → dictionaries.tags.ts} +1 -1
- package/src/@dictionaries/{dictionaries.testSignatures.ts → dictionaries.testing.ts} +3 -2
- package/src/@events/events.api.ts +18 -15
- package/src/@events/events.text.ts +2 -2
- package/src/@events/events.ugc.ts +2 -2
- package/src/@manager/manager.mkEvent.ts +3 -3
- package/src/@manager/manager.rmEvent.ts +3 -2
- package/src/@manager/manager.updateListener.ts +163 -0
- package/src/@modules/@database/database.broadcastify.ts +67 -0
- package/src/@modules/@database/database.init.ts +14 -1
- package/src/@modules/@database/database.shapefiles.ts +3 -6
- package/src/@modules/@eas/eas.getCleanDescription.ts +2 -0
- package/src/@modules/@eas/eas.getTTS.ts +19 -8
- package/src/@modules/@eas/eas.setEasTone.ts +15 -10
- package/src/@modules/@stanza/stanza.getAwipsType.ts +2 -2
- package/src/@modules/@stanza/stanza.validate.ts +3 -3
- package/src/@modules/@utilities/utilities.createHttp.ts +56 -47
- package/src/@modules/@utilities/utilities.setCronSchedule.ts +5 -2
- package/src/@modules/@xmpp/xmpp.xReconnect.ts +1 -1
- package/src/@parsers/@hvtec/hvtec.extract.ts +8 -8
- package/src/@parsers/@pvtec/pvtec.extract.ts +12 -12
- package/src/@parsers/@text/text.getDescriptionFromProduct.ts +2 -2
- package/src/@parsers/@text/text.getEmbed.ts +58 -0
- package/src/@parsers/@ugc/ugc.header.ts +3 -3
- package/src/@types/type.event.ts +3 -3
- package/src/@types/{type.webhook.ts → type.listener.ts} +11 -7
- package/src/@types/type.properties.ts +10 -9
- package/src/@types/type.settings.ts +13 -6
- package/src/bootstrap.ts +13 -6
- package/src/index.ts +2 -1
- package/test.js +30 -22
- package/src/@building/building.outlooks.ts +0 -36
- package/src/@manager/manager.createWebhook.ts +0 -129
- package/src/@manager/manager.updateWebhooks.ts +0 -49
- package/src/@modules/@utilities/utilities.isImageReady.ts +0 -27
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
type
|
|
2
|
-
webhook: string;
|
|
3
|
-
title: string;
|
|
4
|
-
message: string;
|
|
5
|
-
upload: boolean;
|
|
6
|
-
eas: boolean;
|
|
7
|
-
rate: number;
|
|
1
|
+
type TypeListener = {
|
|
8
2
|
events: string[];
|
|
3
|
+
webhook?: {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
destination: string;
|
|
6
|
+
ratelimit: number;
|
|
7
|
+
title: string;
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
uploads?: {
|
|
11
|
+
file?: boolean;
|
|
12
|
+
eas?: boolean;
|
|
13
|
+
event?: boolean;
|
|
14
|
+
};
|
|
9
15
|
};
|
|
10
16
|
|
|
11
17
|
type TypeSettings = {
|
|
@@ -37,6 +43,11 @@ type TypeSettings = {
|
|
|
37
43
|
CallbackInterval: number;
|
|
38
44
|
EventsEndpoint: string;
|
|
39
45
|
};
|
|
46
|
+
BroadcastifySettings: {
|
|
47
|
+
BroadcastifyAttachments: boolean;
|
|
48
|
+
BroadcastifyDatabase: string;
|
|
49
|
+
BroadcastifyTags: string[];
|
|
50
|
+
};
|
|
40
51
|
GlobalSettings: {
|
|
41
52
|
EventManagement: boolean;
|
|
42
53
|
BetterEventNames: boolean;
|
|
@@ -46,7 +57,7 @@ type TypeSettings = {
|
|
|
46
57
|
ShapefileSkipPoints: number;
|
|
47
58
|
NodeTTL: number;
|
|
48
59
|
NodeMinDistance: number;
|
|
49
|
-
|
|
60
|
+
ListenerSettings?: TypeListener[];
|
|
50
61
|
EventFiltering: {
|
|
51
62
|
ListeningEvents: string[];
|
|
52
63
|
ListeningICAO: string[];
|
|
@@ -57,10 +68,12 @@ type TypeSettings = {
|
|
|
57
68
|
NodeLocationFiltering: boolean;
|
|
58
69
|
IgnoreTestProducts: boolean;
|
|
59
70
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
ArchiveSettings: {
|
|
72
|
+
TTL: number;
|
|
73
|
+
EventDirectory: string;
|
|
74
|
+
TextDirectory: string;
|
|
75
|
+
EasDirectory: string;
|
|
76
|
+
EasToneout: string;
|
|
64
77
|
};
|
|
65
78
|
};
|
|
66
79
|
};
|
|
@@ -78,8 +91,9 @@ type TypeAttributes = {
|
|
|
78
91
|
|
|
79
92
|
type TypeEventProperties = {
|
|
80
93
|
locations: string;
|
|
94
|
+
locations_array: string[];
|
|
81
95
|
description: string;
|
|
82
|
-
attributes
|
|
96
|
+
attributes?: TypeAttributes;
|
|
83
97
|
geocode: {
|
|
84
98
|
office: {
|
|
85
99
|
name: string;
|
|
@@ -90,7 +104,7 @@ type TypeEventProperties = {
|
|
|
90
104
|
polygon: string;
|
|
91
105
|
polygon_generated: boolean;
|
|
92
106
|
};
|
|
93
|
-
parameters
|
|
107
|
+
parameters?: {
|
|
94
108
|
tags: string[];
|
|
95
109
|
instructions: string;
|
|
96
110
|
source: string;
|
|
@@ -123,13 +137,13 @@ type TypeEventProperties = {
|
|
|
123
137
|
max_tops_x100feet: string;
|
|
124
138
|
pds_watch: boolean;
|
|
125
139
|
};
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
discussion_parameters?: {
|
|
141
|
+
discussion_number: string;
|
|
142
|
+
discussion_concerning: string;
|
|
143
|
+
discussion_max_tornado: string;
|
|
144
|
+
discussion_max_hail: string;
|
|
145
|
+
discussion_max_wind: string;
|
|
146
|
+
discussion_watch_issuance: string;
|
|
133
147
|
};
|
|
134
148
|
};
|
|
135
149
|
|
|
@@ -177,8 +191,8 @@ type TypeEvent = {
|
|
|
177
191
|
tracking: string;
|
|
178
192
|
hash?: string;
|
|
179
193
|
header: string;
|
|
180
|
-
vtec
|
|
181
|
-
hvtec
|
|
194
|
+
vtec?: TypePVTEC | null;
|
|
195
|
+
hvtec?: TypeHVTEC[] | null;
|
|
182
196
|
nodes?: {
|
|
183
197
|
id?: string | number;
|
|
184
198
|
coordinates: [number, number];
|
|
@@ -194,7 +208,10 @@ type TypeEvent = {
|
|
|
194
208
|
issued: string;
|
|
195
209
|
status: string;
|
|
196
210
|
}[];
|
|
197
|
-
attachments?:
|
|
211
|
+
attachments?: {
|
|
212
|
+
name: string;
|
|
213
|
+
link: string;
|
|
214
|
+
}[];
|
|
198
215
|
raw: string;
|
|
199
216
|
};
|
|
200
217
|
} & TypeEventProperties;
|
|
@@ -215,6 +232,7 @@ declare const stopService: () => Promise<void>;
|
|
|
215
232
|
interface GenerateEASOptions {
|
|
216
233
|
message: string;
|
|
217
234
|
header: string;
|
|
235
|
+
title: string;
|
|
218
236
|
}
|
|
219
237
|
declare const setEasTone: (options: GenerateEASOptions) => Promise<string>;
|
|
220
238
|
|
|
@@ -232,6 +250,17 @@ declare const getEvents: () => any;
|
|
|
232
250
|
|
|
233
251
|
declare const getNodes: () => any;
|
|
234
252
|
|
|
253
|
+
interface CreateEventOptions {
|
|
254
|
+
event: string;
|
|
255
|
+
status: string;
|
|
256
|
+
issued: Date;
|
|
257
|
+
expires: Date;
|
|
258
|
+
locations: string;
|
|
259
|
+
description: string;
|
|
260
|
+
coordinates: number[][];
|
|
261
|
+
}
|
|
262
|
+
declare const createEvent: (options: CreateEventOptions) => void;
|
|
263
|
+
|
|
235
264
|
declare const getRandomEvent: () => any;
|
|
236
265
|
|
|
237
266
|
type TypeStanza = {
|
|
@@ -267,4 +296,4 @@ declare class Manager {
|
|
|
267
296
|
trycatch(): void;
|
|
268
297
|
}
|
|
269
298
|
|
|
270
|
-
export { Manager, type TypeEvent, clearEvents, Manager as default, getCleanedEvent, getEventGeometry, getEvents, getNodes, getRandomEvent, query, setEasTone, setNode, setSettings, startService, stopService };
|
|
299
|
+
export { Manager, type TypeEvent, clearEvents, createEvent, Manager as default, getCleanedEvent, getEventGeometry, getEvents, getNodes, getRandomEvent, query, setEasTone, setNode, setSettings, startService, stopService };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
type
|
|
2
|
-
webhook: string;
|
|
3
|
-
title: string;
|
|
4
|
-
message: string;
|
|
5
|
-
upload: boolean;
|
|
6
|
-
eas: boolean;
|
|
7
|
-
rate: number;
|
|
1
|
+
type TypeListener = {
|
|
8
2
|
events: string[];
|
|
3
|
+
webhook?: {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
destination: string;
|
|
6
|
+
ratelimit: number;
|
|
7
|
+
title: string;
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
uploads?: {
|
|
11
|
+
file?: boolean;
|
|
12
|
+
eas?: boolean;
|
|
13
|
+
event?: boolean;
|
|
14
|
+
};
|
|
9
15
|
};
|
|
10
16
|
|
|
11
17
|
type TypeSettings = {
|
|
@@ -37,6 +43,11 @@ type TypeSettings = {
|
|
|
37
43
|
CallbackInterval: number;
|
|
38
44
|
EventsEndpoint: string;
|
|
39
45
|
};
|
|
46
|
+
BroadcastifySettings: {
|
|
47
|
+
BroadcastifyAttachments: boolean;
|
|
48
|
+
BroadcastifyDatabase: string;
|
|
49
|
+
BroadcastifyTags: string[];
|
|
50
|
+
};
|
|
40
51
|
GlobalSettings: {
|
|
41
52
|
EventManagement: boolean;
|
|
42
53
|
BetterEventNames: boolean;
|
|
@@ -46,7 +57,7 @@ type TypeSettings = {
|
|
|
46
57
|
ShapefileSkipPoints: number;
|
|
47
58
|
NodeTTL: number;
|
|
48
59
|
NodeMinDistance: number;
|
|
49
|
-
|
|
60
|
+
ListenerSettings?: TypeListener[];
|
|
50
61
|
EventFiltering: {
|
|
51
62
|
ListeningEvents: string[];
|
|
52
63
|
ListeningICAO: string[];
|
|
@@ -57,10 +68,12 @@ type TypeSettings = {
|
|
|
57
68
|
NodeLocationFiltering: boolean;
|
|
58
69
|
IgnoreTestProducts: boolean;
|
|
59
70
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
ArchiveSettings: {
|
|
72
|
+
TTL: number;
|
|
73
|
+
EventDirectory: string;
|
|
74
|
+
TextDirectory: string;
|
|
75
|
+
EasDirectory: string;
|
|
76
|
+
EasToneout: string;
|
|
64
77
|
};
|
|
65
78
|
};
|
|
66
79
|
};
|
|
@@ -78,8 +91,9 @@ type TypeAttributes = {
|
|
|
78
91
|
|
|
79
92
|
type TypeEventProperties = {
|
|
80
93
|
locations: string;
|
|
94
|
+
locations_array: string[];
|
|
81
95
|
description: string;
|
|
82
|
-
attributes
|
|
96
|
+
attributes?: TypeAttributes;
|
|
83
97
|
geocode: {
|
|
84
98
|
office: {
|
|
85
99
|
name: string;
|
|
@@ -90,7 +104,7 @@ type TypeEventProperties = {
|
|
|
90
104
|
polygon: string;
|
|
91
105
|
polygon_generated: boolean;
|
|
92
106
|
};
|
|
93
|
-
parameters
|
|
107
|
+
parameters?: {
|
|
94
108
|
tags: string[];
|
|
95
109
|
instructions: string;
|
|
96
110
|
source: string;
|
|
@@ -123,13 +137,13 @@ type TypeEventProperties = {
|
|
|
123
137
|
max_tops_x100feet: string;
|
|
124
138
|
pds_watch: boolean;
|
|
125
139
|
};
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
discussion_parameters?: {
|
|
141
|
+
discussion_number: string;
|
|
142
|
+
discussion_concerning: string;
|
|
143
|
+
discussion_max_tornado: string;
|
|
144
|
+
discussion_max_hail: string;
|
|
145
|
+
discussion_max_wind: string;
|
|
146
|
+
discussion_watch_issuance: string;
|
|
133
147
|
};
|
|
134
148
|
};
|
|
135
149
|
|
|
@@ -177,8 +191,8 @@ type TypeEvent = {
|
|
|
177
191
|
tracking: string;
|
|
178
192
|
hash?: string;
|
|
179
193
|
header: string;
|
|
180
|
-
vtec
|
|
181
|
-
hvtec
|
|
194
|
+
vtec?: TypePVTEC | null;
|
|
195
|
+
hvtec?: TypeHVTEC[] | null;
|
|
182
196
|
nodes?: {
|
|
183
197
|
id?: string | number;
|
|
184
198
|
coordinates: [number, number];
|
|
@@ -194,7 +208,10 @@ type TypeEvent = {
|
|
|
194
208
|
issued: string;
|
|
195
209
|
status: string;
|
|
196
210
|
}[];
|
|
197
|
-
attachments?:
|
|
211
|
+
attachments?: {
|
|
212
|
+
name: string;
|
|
213
|
+
link: string;
|
|
214
|
+
}[];
|
|
198
215
|
raw: string;
|
|
199
216
|
};
|
|
200
217
|
} & TypeEventProperties;
|
|
@@ -215,6 +232,7 @@ declare const stopService: () => Promise<void>;
|
|
|
215
232
|
interface GenerateEASOptions {
|
|
216
233
|
message: string;
|
|
217
234
|
header: string;
|
|
235
|
+
title: string;
|
|
218
236
|
}
|
|
219
237
|
declare const setEasTone: (options: GenerateEASOptions) => Promise<string>;
|
|
220
238
|
|
|
@@ -232,6 +250,17 @@ declare const getEvents: () => any;
|
|
|
232
250
|
|
|
233
251
|
declare const getNodes: () => any;
|
|
234
252
|
|
|
253
|
+
interface CreateEventOptions {
|
|
254
|
+
event: string;
|
|
255
|
+
status: string;
|
|
256
|
+
issued: Date;
|
|
257
|
+
expires: Date;
|
|
258
|
+
locations: string;
|
|
259
|
+
description: string;
|
|
260
|
+
coordinates: number[][];
|
|
261
|
+
}
|
|
262
|
+
declare const createEvent: (options: CreateEventOptions) => void;
|
|
263
|
+
|
|
235
264
|
declare const getRandomEvent: () => any;
|
|
236
265
|
|
|
237
266
|
type TypeStanza = {
|
|
@@ -267,4 +296,4 @@ declare class Manager {
|
|
|
267
296
|
trycatch(): void;
|
|
268
297
|
}
|
|
269
298
|
|
|
270
|
-
export { Manager, type TypeEvent, clearEvents, Manager as default, getCleanedEvent, getEventGeometry, getEvents, getNodes, getRandomEvent, query, setEasTone, setNode, setSettings, startService, stopService };
|
|
299
|
+
export { Manager, type TypeEvent, clearEvents, createEvent, Manager as default, getCleanedEvent, getEventGeometry, getEvents, getNodes, getRandomEvent, query, setEasTone, setNode, setSettings, startService, stopService };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atmosx/event-product-parser",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.47",
|
|
4
4
|
"description": "NOAA Weather Wire & NWS API Parser - Built for standalone and Project AtmosphericX Integration.",
|
|
5
5
|
"main": "dist/cjs/index.cjs",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ _ _ __ __
|
|
3
|
+
/\ | | | | (_) \ \ / /
|
|
4
|
+
/ \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
|
|
5
|
+
/ /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
|
|
6
|
+
/ ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
|
|
7
|
+
/_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
|
|
8
|
+
| |
|
|
9
|
+
|_|
|
|
10
|
+
|
|
11
|
+
Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
|
|
12
|
+
Discord: https://atmosphericx-discord.scriptkitty.cafe
|
|
13
|
+
Ko-Fi: https://ko-fi.com/k3yomi
|
|
14
|
+
Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
|
|
15
|
+
|
|
16
|
+
Internal Package: @atmosx/event-product-parser
|
|
17
|
+
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { bootstrap } from "../bootstrap"
|
|
21
|
+
import { TypeEvent } from "../@types/type.event"
|
|
22
|
+
import { getLatestIssuance } from "../@modules/@utilities/utilities.getLatestIssuance";
|
|
23
|
+
import { dict_states } from "../@dictionaries/dictionaries.states"
|
|
24
|
+
import { dict_expressions } from "../@dictionaries/dictionaries.expressions"
|
|
25
|
+
|
|
26
|
+
interface GetEventAttachmentsResponse {
|
|
27
|
+
name: string
|
|
28
|
+
link: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type BroadcastifyResponse = {
|
|
32
|
+
state: string
|
|
33
|
+
county: string
|
|
34
|
+
feed: string
|
|
35
|
+
type: string
|
|
36
|
+
link: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const getEventAttachments = (event: TypeEvent): GetEventAttachmentsResponse[] | null => {
|
|
40
|
+
let attachments = [];
|
|
41
|
+
const latestTime = getLatestIssuance();
|
|
42
|
+
const spcNumber = event?.properties?.discussion_parameters?.discussion_number;
|
|
43
|
+
const watchNumber = event?.properties?.watch_parameters?.watch_number;
|
|
44
|
+
const locations = event?.properties?.locations_array;
|
|
45
|
+
const events = [
|
|
46
|
+
{ target: "Day 1", attachment: `https://www.spc.noaa.gov/products/outlook/day1otlk_${latestTime}.png` },
|
|
47
|
+
{ target: "Day 2", attachment: `https://www.spc.noaa.gov/products/outlook/day2otlk.png` },
|
|
48
|
+
{ target: "Day 3", attachment: `https://www.spc.noaa.gov/products/outlook/day3otlk.png` },
|
|
49
|
+
{ target: "Mesoscale Discussion", attachment: `https://www.spc.noaa.gov/products/md/mcd${spcNumber}.png` },
|
|
50
|
+
{ target: "Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
|
|
51
|
+
{ target: "PDS Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
|
|
52
|
+
{ target: "Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
|
|
53
|
+
{ target: "PDS Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` }
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
if (events.find((e) => e.target === event.properties.event)) {
|
|
57
|
+
attachments.push({ name: `Image: Graphic`, link: events.find((e) => e.target === event.properties.event).attachment });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const location of locations) {
|
|
61
|
+
if (dict_expressions.location.test(location)) {
|
|
62
|
+
const lines = [`Northern`, `Southern`, `Eastern`, `Western`, `Inland`, `Costal`, `County`]
|
|
63
|
+
const county = location?.split(',')[0]?.trim().replace(new RegExp(`^(${lines.join('|')}) `), '')
|
|
64
|
+
const state = dict_states[location?.split(',')[1]?.trim()]
|
|
65
|
+
const feeds = bootstrap.database.prepare(`SELECT * FROM broadcastify WHERE state = ? AND county = ?`).all(state, county).sort((a, b) => {
|
|
66
|
+
const typeOrder = ['Other', 'Public Safety'];
|
|
67
|
+
const indexA = typeOrder.indexOf(a.type);
|
|
68
|
+
const indexB = typeOrder.indexOf(b.type);
|
|
69
|
+
return indexA - indexB;
|
|
70
|
+
});
|
|
71
|
+
const tags = bootstrap.settings.BroadcastifySettings.BroadcastifyTags;
|
|
72
|
+
const filtered = feeds.filter((feed: BroadcastifyResponse) => tags.includes(feed.type));
|
|
73
|
+
if (filtered.length > 0) {
|
|
74
|
+
filtered.map((filtered: BroadcastifyResponse) => {
|
|
75
|
+
if (!attachments.some((a) => a.link === filtered.link)) {
|
|
76
|
+
attachments.push({ name: `${filtered.type}: ${filtered.feed}`, link: filtered.link });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return attachments;
|
|
83
|
+
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { TypeEvent } from "../@types/type.event";
|
|
21
21
|
import { TypeSettings } from "../@types/type.settings";
|
|
22
22
|
import { bootstrap } from "../bootstrap"
|
|
23
|
-
import {
|
|
23
|
+
import { dict_enhanced } from "../@dictionaries/dictionaries.enhanced"
|
|
24
24
|
|
|
25
25
|
export const getEventEnhancedName = (event: TypeEvent): string => {
|
|
26
26
|
const configurations = bootstrap.settings as TypeSettings
|
|
@@ -31,9 +31,10 @@ export const getEventEnhancedName = (event: TypeEvent): string => {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const damage = event?.properties?.parameters?.damage_threat
|
|
34
|
-
const tornado = event?.properties?.parameters
|
|
34
|
+
const tornado = event?.properties?.parameters?.tornado_threat;
|
|
35
|
+
const pdswatch = event?.properties?.watch_parameters?.pds_watch;
|
|
35
36
|
const description = event?.properties?.description?.toLowerCase()
|
|
36
|
-
for (const [eventKey, eventConfig] of Object.entries(
|
|
37
|
+
for (const [eventKey, eventConfig] of Object.entries(dict_enhanced)) {
|
|
37
38
|
if (eventKey !== name) continue;
|
|
38
39
|
for (const [paramKey, paramValue] of Object.entries(eventConfig)) {
|
|
39
40
|
let matches = true;
|
|
@@ -46,6 +47,9 @@ export const getEventEnhancedName = (event: TypeEvent): string => {
|
|
|
46
47
|
if (paramValue?.tornado) {
|
|
47
48
|
if (paramValue.tornado !== tornado) matches = false;
|
|
48
49
|
}
|
|
50
|
+
if (paramValue?.pdswatch) {
|
|
51
|
+
if (paramValue.pdswatch !== pdswatch) matches = false;
|
|
52
|
+
}
|
|
49
53
|
if (matches) {
|
|
50
54
|
name = paramKey;
|
|
51
55
|
break;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import { TypeAttributes } from "../@types/type.attributes";
|
|
21
21
|
import { TypePVTEC } from "../@types/type.pvtec";
|
|
22
|
-
import {
|
|
22
|
+
import { dict_icao } from "../@dictionaries/dictionaries.icao";
|
|
23
23
|
|
|
24
24
|
interface GetOfficeOptions {
|
|
25
25
|
attributes: TypeAttributes
|
|
@@ -38,6 +38,6 @@ export const getEventOffice = (options: GetOfficeOptions): GetOfficeResponse =>
|
|
|
38
38
|
(options.organization != null ?
|
|
39
39
|
(Array.isArray(options.organization) ? options.organization?.[0] : options.organization)
|
|
40
40
|
: null));
|
|
41
|
-
const name =
|
|
41
|
+
const name = dict_icao?.[office] ?? null;
|
|
42
42
|
return { office, name };
|
|
43
43
|
}
|
|
@@ -22,7 +22,7 @@ import { TypeAttributes } from "../@types/type.attributes";
|
|
|
22
22
|
import { TypeUGC } from "../@types/type.ugc";
|
|
23
23
|
import { TypePVTEC } from "../@types/type.pvtec";
|
|
24
24
|
import { TypeHVTEC } from "../@types/type.hvtec";
|
|
25
|
-
import {
|
|
25
|
+
import { dict_expressions } from "../@dictionaries/dictionaries.expressions";
|
|
26
26
|
import { getDescriptionFromProduct } from "../@parsers/@text/text.getDescriptionFromProduct";
|
|
27
27
|
import { getPolygonFromProduct } from "../@parsers/@text/text.getPolygonFromProduct";
|
|
28
28
|
import { getTextFromProduct } from "../@parsers/@text/text.getTextFromProduct";
|
|
@@ -38,10 +38,11 @@ interface GetPropertiesOptions {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export const properties = (options: GetPropertiesOptions): TypeEventProperties => {
|
|
41
|
-
const organization = options.message.match(
|
|
41
|
+
const organization = options.message.match(dict_expressions.wmo)?.[0] ?? null
|
|
42
42
|
const polygons = getPolygonFromProduct(options.message)
|
|
43
43
|
const properties = {
|
|
44
44
|
locations: options?.ugc?.locations?.join(`; `) ?? null,
|
|
45
|
+
locations_array: options?.ugc?.locations ?? [],
|
|
45
46
|
description: getDescriptionFromProduct({ message: options.message, handle: options?.pVtec?.vtec ?? null }),
|
|
46
47
|
attributes: options.attributes,
|
|
47
48
|
geocode: {
|
|
@@ -65,16 +66,16 @@ export const properties = (options: GetPropertiesOptions): TypeEventProperties =
|
|
|
65
66
|
wind_threat: getTextFromProduct({ message: options.message, find: [`WIND THREAT...`]}) ?? null,
|
|
66
67
|
hail_threat: getTextFromProduct({ message: options.message, find: [`HAIL THREAT...`], removal: []}) ?? null,
|
|
67
68
|
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
discussion_parameters: {
|
|
70
|
+
discussion_number: getTextFromProduct({ message: options.message, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })?.toString()?.padStart(4, "0") ?? null,
|
|
71
|
+
discussion_concerning: getTextFromProduct({ message: options.message, find: [`Concerning...`] }) ?? null,
|
|
72
|
+
discussion_max_tornado: getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] }) ?? null,
|
|
73
|
+
discussion_max_hail: getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK HAIL SIZE...`] }) ?? null,
|
|
74
|
+
discussion_max_wind: getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK WIND GUST...`] }) ?? null,
|
|
75
|
+
discussion_watch_issuance: getTextFromProduct({ message: options.message, find: [`Probability of Watch Issuance...`], removal: [`percent`]}) ?? null,
|
|
75
76
|
},
|
|
76
77
|
watch_parameters: {
|
|
77
|
-
watch_number: getTextFromProduct({ message: options.message, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })?.replace(/(WT|WS|)/g, '')?.trim() ?? null,
|
|
78
|
+
watch_number: (options?.pVtec?.is_watch) && (getTextFromProduct({ message: options.message, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })?.replace(/(WT|WS|)/g, '')?.trim()?.toString()?.padStart(4, "0") ?? options?.pVtec?.tracking?.slice(-4)?.toString()?.padStart(4, "0") ?? null),
|
|
78
79
|
watch_type: options.message.includes(`TORNADO WATCH`) ? `Tornado` : options?.message.includes(`SEVERE`) ? `Severe` : null,
|
|
79
80
|
additional_tornadoes_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] }) ?? null,
|
|
80
81
|
strong_tornadoes_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] }) ?? null,
|
|
@@ -85,7 +86,7 @@ export const properties = (options: GetPropertiesOptions): TypeEventProperties =
|
|
|
85
86
|
max_hail_in: getTextFromProduct({ message: options.message, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] }) ?? null,
|
|
86
87
|
max_wind_surface: getTextFromProduct({ message: options.message, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] }) ?? null,
|
|
87
88
|
max_tops_x100feet: getTextFromProduct({ message: options.message, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] }) ?? null,
|
|
88
|
-
pds_watch: (getTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`)
|
|
89
|
+
pds_watch: (getTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES` ? true : null)
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
if (isNaN(Number(properties.watch_parameters.watch_number))) {
|
|
@@ -18,23 +18,23 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { TypeEvent } from "../@types/type.event";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
21
|
+
import { dict_correlations } from "../@dictionaries/dictionaries.correlations";
|
|
22
|
+
import { dict_cancellation } from "../@dictionaries/dictionaries.cancellation";
|
|
23
|
+
import { dict_testing} from "../@dictionaries/dictionaries.testing"
|
|
24
|
+
import { dict_products } from "../@dictionaries/dictionaries.products";
|
|
25
|
+
import { dict_hail } from "../@dictionaries/dictionaries.hail"
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
export const getEventSignature = (event: TypeEvent): TypeEvent => {
|
|
29
29
|
const properties = event?.properties;
|
|
30
30
|
const vtec = event?.properties?.metadata?.vtec
|
|
31
|
-
const status =
|
|
31
|
+
const status = dict_correlations
|
|
32
32
|
.find((c: { type: string }) => c.type === properties?.status);
|
|
33
|
-
const csig =
|
|
33
|
+
const csig = dict_cancellation.find(sig => properties.description.toLowerCase().includes(sig.toLowerCase()));
|
|
34
34
|
properties.status_metadata = { ...properties.status_metadata, is_issued: true, is_test: false};
|
|
35
35
|
|
|
36
|
-
if (properties
|
|
37
|
-
properties.parameters.estimated_hail_size += ` (${
|
|
36
|
+
if (properties?.parameters?.estimated_hail_size) {
|
|
37
|
+
properties.parameters.estimated_hail_size += ` (${dict_hail[properties?.parameters?.estimated_hail_size] ?? '--'})`
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
if (status) {
|
|
@@ -46,8 +46,8 @@ export const getEventSignature = (event: TypeEvent): TypeEvent => {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const getProduct = vtec?.vtec?.split(`.`)[0]?.replace(`/`, ``)
|
|
49
|
-
const isTestProduct =
|
|
50
|
-
if (isTestProduct ||
|
|
49
|
+
const isTestProduct = dict_products[getProduct] == `Test Product`
|
|
50
|
+
if (isTestProduct || dict_testing.some(sig => properties.description?.toLowerCase().includes(sig.toLowerCase()) ?? properties?.parameters?.instructions?.toLowerCase().includes(sig.toLowerCase()))) {
|
|
51
51
|
properties.status_metadata = { ...properties.status_metadata, is_test: true }
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { dict_tags } from "../@dictionaries/dictionaries.tags";
|
|
21
21
|
|
|
22
22
|
export const getEventTags = (message: string): string[] => {
|
|
23
|
-
return Object.entries(
|
|
23
|
+
return Object.entries(dict_tags).filter(([key]) => message?.toLowerCase().includes(key.toLowerCase())).map(([, value]) => value)
|
|
24
24
|
}
|
|
@@ -52,7 +52,7 @@ export const getEventTracking = (options: GetTrackingOptions): string => {
|
|
|
52
52
|
if (options.type === `API`) {
|
|
53
53
|
if (options.vtec) {
|
|
54
54
|
const vtecValue = Array.isArray(options.vtec)
|
|
55
|
-
? options.vtec[0] : options.vtec;
|
|
55
|
+
? options.vtec[0].vtec : options.vtec?.vtec;
|
|
56
56
|
const splitPVTEC = vtecValue.split('.');
|
|
57
57
|
return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
|
|
58
58
|
}
|
|
@@ -60,9 +60,9 @@ export const getEventTracking = (options: GetTrackingOptions): string => {
|
|
|
60
60
|
const station = wmoMatch?.[2] ?? 'N/A';
|
|
61
61
|
if (options.organization.featureId) {
|
|
62
62
|
const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
|
|
63
|
-
return `${station}.${idMatch?.[
|
|
63
|
+
return `${station}.${idMatch?.[0]?.replace(/\./g, '') ?? 'N/A'}`;
|
|
64
64
|
}
|
|
65
65
|
const id = wmoMatch?.[1] ?? 'N/A';
|
|
66
|
-
return `${station}.${id}`;
|
|
66
|
+
return `${station}.${id?.replace(/\./g, '') ?? 'N/A'}`;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -26,7 +26,7 @@ import { getEventSignature } from "./building.signature"
|
|
|
26
26
|
import { mkEvent } from "../@manager/manager.mkEvent";
|
|
27
27
|
import { rmEvent } from "../@manager/manager.rmEvent";
|
|
28
28
|
import { getEventGeometry } from "./building.geometry";
|
|
29
|
-
import { getEventAttachments } from "./building.
|
|
29
|
+
import { getEventAttachments } from "./building.attachments";
|
|
30
30
|
import { updateNode } from "../@manager/manager.updateNodes";
|
|
31
31
|
import { setEventEmit } from "../@modules/@utilities/utilities.setEventEmit";
|
|
32
32
|
|
|
@@ -67,7 +67,7 @@ export const validateEvents = async (events: TypeEvent[]): Promise<void> => {
|
|
|
67
67
|
return false;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if (properties.metadata?.vtec?.is_watch) {
|
|
70
|
+
if (properties.metadata?.vtec?.is_watch && properties.metadata.source != `events.api`) {
|
|
71
71
|
const isSPC = properties.metadata?.vtec?.prediction_center;
|
|
72
72
|
setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define })
|
|
73
73
|
if (bools?.SPCWatchesOnly && !isSPC) {
|