Fixed map module references to be uppercase
[WebPacketRadio.git] / src / www / js / packet / APRSMessages / APRS_Parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/**
 * @author      Michael Marques <dryerzinia@gmail.com>
 */
 
/**
 * @module Packet
 */
 
/**
 * @class APRS_Parser
 * @static
 */
 
define(
        [
                'map/LatLong',
                'util/misc/math',
                'util/misc/string'
        ],
        function(
                LatLong,
                math,
                string
        ){
                
                var APRS_Parser = {};
 
                APRS_Parser.update_extensions = function(info, status){
 
                        if(info.status_official){
                                status.status = info.status;
                                status.status_official = info.status_official;
                        }
 
                        if(!status.status_official && info.status)
                                status.status = info.status;
 
                        if(info.altitude !== undefined){
                                status.altitude = info.altitude;
                                status.altitude_unit = 'feet';
                        }
 
                        if(info.power !== undefined)
                                status.power = info.power;
 
                        if(info.haat !== undefined)
                                status.haat = info.haat;
 
                        if(info.gain !== undefined)
                                status.gain = info.gain;
 
                        if(info.directivity !== undefined)
                                status.directivity = info.directivity;
 
                        if(info.heading !== undefined)
                                status.heading = info.heading;
 
                        if(info.speed !== undefined){
                                status.speed = info.speed;
                                status.speed_unit = info.speed_unit;
                        }
 
                };
 
                APRS_Parser.update_WX = function(info, status){
 
                        if(info.wind_direction !== undefined){
                                status.wind_direction = info.wind_direction;
                        }
                        if(info.wind_speed !== undefined){
                                status.wind_speed = info.wind_speed;
                                status.wind_speed_unit = 'MPH';
                        }
                        if(info.gust_speed !== undefined){
                                status.gust_speed = info.gust_speed;
                                status.gust_speed_unit = 'MPH';
                        }
                        if(info.temperature !== undefined){
                                status.temperature = info.temperature;
                                status.temperature_unit = 'fahrenheit';
                        }
                        if(info.rain_hour !== undefined){
                                status.rain_hour = info.rain_hour / 100;
                                status.rain_hour_unit = 'inch';
                        }
                        if(info.rain_24hour !== undefined){
                                status.rain_24hour = info.rain_24hour / 100;
                                status.rain_24hour_unit = 'inch';
                        }
                        if(info.rain_midnight !== undefined){
                                status.rain_midnight = info.rain_midnight / 100;
                                status.rain_midnight_unit = 'inch';
                        }
                        if(info.humidity !== undefined){
                                status.humidity = info.humidity;
                        }
                        if(info.barometric_pressure !== undefined){
                                status.barometric_pressure = info.barometric_pressure;
                                status.barometric_pressure_unit = 'mBars/tenths_hPascal';
                        }
 
                };
 
                APRS_Parser.parse_extensions = function(info, packet, i){
 
                        info.status = '';
                        for(; i < packet.message_data.length; i++){
                                info.status += String.fromCharCode(packet.message_data[i]);
                        }
 
                        APRS_Parser.parse_course_speed(info, info.status);
                        APRS_Parser.parse_PHG(info, info.status);
                        APRS_Parser.parse_alt_in_stat(info, info.status);
 
                };
 
                APRS_Parser.parse_course_speed = function(info, status_in){
 
                        var m = status_in.match(/[0-9][0-9][0-9]\/[0-9][0-9][0-9]/);
 
                        if(m !== null){
 
                                var idx = status_in.indexOf(m[0]);
 
                                info.heading = parseFloat(status_in.substring(idx, idx + 3));
                                info.speed = parseFloat(status_in.substring(idx + 4, idx + 7));
                                info.speed_unit = 'MPH'; // TODO this needs confirmation
 
                                info.status = status_in.substring(0, idx) + status_in.substring(idx + 7, status_in.length);
 
                        }
 
                };
 
                APRS_Parser.parse_PHG = function(info, status_in){
 
                        var phg = status_in.indexOf('PHG');
                        if(phg != -1){
 
                                info.power = Math.pow(status_in.charCodeAt(phg + 3) - 0x30, 2);
                                info.haat = Math.pow(2, status_in.charCodeAt(phg + 4) - 0x30) * 10;
                                info.gain = status_in.charCodeAt(phg + 5) - 0x30;
                                info.directivity = (status_in.charCodeAt(phg + 6) - 0x30) * 45;
 
                                info.status = info.status.substring(phg + 7, info.status.length);
 
                        };
 
                };
 
                APRS_Parser.parse_alt_in_stat = function(info, status_in){
 
                        var altitude = undefined,
                                status = status_in;
 
                        var alt = status_in.indexOf('/A=');
                        if(alt != -1){
 
                                altitude = parseFloat(status.substring(alt + 3, alt + 9));
 
                                status = status_in.substring(0, alt);
                                if(status_in.length > alt + 9)
                                        status += status_in.substring(alt + 9, status_in.length);
 
                        }
 
                        info.status = status;
                        info.altitude = altitude;
 
                };
 
                APRS_Parser.parse_wind = function(info, packet, i){
 
                        info.wind_direction = math.parse_int(packet.message_data, i, 3);
                        i += 4;
                        info.wind_speed = math.parse_int(packet.message_data, i, 3);
                        i += 3;
 
                        return i;
 
                };
 
                APRS_Parser.parse_WX = function(info, packet, i){
 
                        var finished = false;
 
                        while(!finished && i < packet.message_data.length){
 
                                var type = String.fromCharCode(packet.message_data[i]);
 
                                i++;
 
                                switch(type){
                                        case 'c':
                                                if(packet.message_data[i] != 0x2E)
                                                        info.wind_direction = math.parse_int(packet.message_data, i, 3);
                                                i += 3;
                                                break;
                                        case 's':
                                                if(packet.message_data[i] != 0x2E)
                                                        info.wind_speed = math.parse_int(packet.message_data, i, 3);
                                                i += 3;
                                                break;
                                        case 'g':
                                                if(packet.message_data[i] != 0x2E)
                                                        info.gust_speed = math.parse_int(packet.message_data, i, 3);
                                                i += 3;
                                                break;
                                        case 't':
                                                if(packet.message_data[i] != 0x2E){
                                                        if(packet.message_data[i] == 0x2D){
                                                                info.temperature = -math.parse_int(packet.message_data, i + 1, 2);
                                                        }
                                                        else
                                                                info.temperature = math.parse_int(packet.message_data, i, 3);
                                                }
                                                i += 3;
                                                break;
                                        case 'r':
                                                if(packet.message_data[i] != 0x2E)
                                                        info.rain_hour = math.parse_int(packet.message_data, i, 3);
                                                i += 3;
                                                break;
                                        case 'p':
                                                if(packet.message_data[i] != 0x2E)
                                                        info.rain_24hour = math.parse_int(packet.message_data, i, 3);
                                                i += 3;
                                                break;
                                        case 'P':
                                                if(packet.message_data[i] != 0x2E)
                                                        info.rain_midnight = math.parse_int(packet.message_data, i, 3);
                                                i += 3;
                                                break;
                                        case 'h':
                                                if(packet.message_data[i] != 0x2E){
                                                        info.humidity = math.parse_int(packet.message_data, i, 2);
                                                        if(info.humidity == 0)
                                                                info.humidity = 100; 
                                                }
                                                i += 2;
                                                break;
                                        case 'b':
                                                if(packet.message_data[i+1] != 0x2E)
                                                        info.barometric_pressure = math.parse_int(packet.message_data, i, 5);
                                                i += 5;
                                                break;
                                        default:
 
                                                info.software_type = String.fromCharCode(packet.message_data[i++]);
 
                                                info.WX_unit = '';
                                                var start = i;
                                                while(i < packet.message_data.length && i < start + 4 && string.is_printable(packet.message_data[i])){
 
                                                        info.WX_unit += String.fromCharCode(packet.message_data[i]);
                                                        i++;
 
                                                }
 
                                                break;
                                }
        
                        }
 
                        return i;
 
                };
 
                APRS_Parser.parse_lat_lon = function(info, packet, i){
 
                        var latDeg = "";
                        var latMin = "";
 
                        for(var j = i+2; i < j; i++)
                                latDeg += String.fromCharCode(packet.message_data[i]);
 
                        for(var j = i+4; i < j; i++)
                                latMin += String.fromCharCode(packet.message_data[i]);
 
                        i++;
                        var latCardinal = String.fromCharCode(packet.message_data[i]);
 
                        i++;
                        info.symbol_table = String.fromCharCode(packet.message_data[i]);
 
                        i++;
                        var longDeg = "";
                        var longMin = "";
 
                        for(var j = i+3; i < j; i++)
                                longDeg += String.fromCharCode(packet.message_data[i]);
 
                        for(var j = i+4; i < j; i++)
                                longMin += String.fromCharCode(packet.message_data[i]);
 
                        i++;
                        var longCardinal = String.fromCharCode(packet.message_data[i]);
 
                        i++;
                        info.symbol_code = String.fromCharCode(packet.message_data[i]);
 
                        var lat = parseFloat(latDeg) + parseFloat(latMin)/60;
                        var long =  parseFloat(longDeg) + parseFloat(longMin)/60;
 
                        if(latCardinal == 'S')
                                lat *= -1;
 
                        if(longCardinal == 'W')
                                long *= -1;
 
                        info.coordinates = new LatLong(lat, long);
 
                        return i;
 
                };
 
                APRS_Parser.parse_time_stamp = function(info, packet, i){
 
                        info.time_stamp = new Date();
 
                        var timeStampType = String.fromCharCode(packet.message_data[i+6]);
 
                        var month = "";
                        var day = "";
                        var hour = "";
                        var minute = "";
                        var second = "";
 
                        switch(timeStampType){
                        case 'z':       // Day/Hours/Minutes Zulu (UTC)
                                {
                                        for(var j = i+2; i < j; i++)
                                                day += String.fromCharCode(packet.message_data[i]);
                                        for(var j = i+2; i < j; i++)
                                                hour += String.fromCharCode(packet.message_data[i]);
                                        for(var j = i+2; i < j; i++)
                                                minute += String.fromCharCode(packet.message_data[i]);
 
                                        info.time_stamp.setUTCDate(parseFloat(day));
                                        info.time_stamp.setUTCHours(parseFloat(hour));
                                        info.time_stamp.setUTCMinutes(parseFloat(minute));
 
                                }
                                break;
                        case '/':       // Day/Hours/Minutes Local
                                {
                                        for(var j = i+2; i < j; i++)
                                                day += String.fromCharCode(packet.message_data[i]);
                                        for(var j = i+2; i < j; i++)
                                                hour += String.fromCharCode(packet.message_data[i]);
                                        for(var j = i+2; i < j; i++)
                                                minute += String.fromCharCode(packet.message_data[i]);
 
                                        info.time_stamp.setDate(parseFloat(day));
                                        info.time_stamp.setHours(parseFloat(hour));
                                        info.time_stamp.setMinutes(parseFloat(minute));
 
                                }
                                break;
                        case 'h':       // Hours/Minutes/Seconds
                        {
                                for(var j = i+2; i < j; i++)
                                        hour += String.fromCharCode(packet.message_data[i]);
                                for(var j = i+2; i < j; i++)
                                        minute += String.fromCharCode(packet.message_data[i]);
                                for(var j = i+2; i < j; i++)
                                        second += String.fromCharCode(packet.message_data[i]);
 
                                info.time_stamp.setUTCHours(parseFloat(hour));
                                info.time_stamp.setUTCMinutes(parseFloat(minute));
                                info.time_stamp.setUTCSeconds(parseFloat(second));
 
                        }
                                break;
                        default:        // Month/Day/Hours/Minutes
                        {
                                for(var j = i+2; i < j; i++)
                                        month += String.fromCharCode(packet.message_data[i]);
                                for(var j = i+2; i < j; i++)
                                        day += String.fromCharCode(packet.message_data[i]);
                                for(var j = i+2; i < j; i++)
                                        hour += String.fromCharCode(packet.message_data[i]);
                                for(var j = i+2; i < j; i++)
                                        minute += String.fromCharCode(packet.message_data[i]);
 
                                info.time_stamp.setUTCMonth(parseFloat(month));
                                info.time_stamp.setUTCDate(parseFloat(day));
                                info.time_stamp.setUTCHours(parseFloat(hour));
                                info.time_stamp.setUTCMinutes(parseFloat(minute));
 
                        }
                                break;
                        };
 
                        return i;
 
                };
 
                return APRS_Parser;
 
        }
);