kopia lustrzana https://github.com/cyoung/stratux
show which types of uat messages we've gotten
rodzic
f47a224c1d
commit
40239bcaf5
|
@ -4,6 +4,7 @@ import (
|
|||
"bufio"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
@ -58,6 +59,7 @@ type msg struct {
|
|||
MessageClass uint
|
||||
TimeReceived time.Time
|
||||
Data []byte
|
||||
Product uint32
|
||||
}
|
||||
|
||||
var MsgLog []msg
|
||||
|
@ -291,11 +293,13 @@ func updateStatus() {
|
|||
m := len(MsgLog)
|
||||
UAT_messages_last_minute := uint(0)
|
||||
ES_messages_last_minute := uint(0)
|
||||
products_last_minute := make(map[string]uint32)
|
||||
for i := 0; i < m; i++ {
|
||||
if time.Now().Sub(MsgLog[i].TimeReceived).Minutes() < 1 {
|
||||
t = append(t, MsgLog[i])
|
||||
if MsgLog[i].MessageClass == MSGCLASS_UAT {
|
||||
UAT_messages_last_minute++
|
||||
products_last_minute[getProductNameFromId(int(MsgLog[i].Product))]++
|
||||
} else if MsgLog[i].MessageClass == MSGCLASS_ES {
|
||||
ES_messages_last_minute++
|
||||
}
|
||||
|
@ -304,6 +308,7 @@ func updateStatus() {
|
|||
MsgLog = t
|
||||
globalStatus.UAT_messages_last_minute = UAT_messages_last_minute
|
||||
globalStatus.ES_messages_last_minute = ES_messages_last_minute
|
||||
globalStatus.UAT_products_last_minute = products_last_minute
|
||||
|
||||
// Update "max messages/min" counters.
|
||||
if globalStatus.UAT_messages_max < UAT_messages_last_minute {
|
||||
|
@ -372,15 +377,79 @@ func parseInput(buf string) ([]byte, uint16) {
|
|||
frame := make([]byte, UPLINK_FRAME_DATA_BYTES)
|
||||
hex.Decode(frame, []byte(s))
|
||||
|
||||
pos := 10
|
||||
|
||||
var thisMsg msg
|
||||
thisMsg.MessageClass = MSGCLASS_UAT
|
||||
thisMsg.TimeReceived = time.Now()
|
||||
thisMsg.Data = frame
|
||||
thisMsg.Product = ((uint32(frame[pos]) & 0x1f) << 6) | (uint32(frame[pos+1]) >> 2)
|
||||
MsgLog = append(MsgLog, thisMsg)
|
||||
|
||||
return frame, msgtype
|
||||
}
|
||||
|
||||
var product_name_map = map[int]string{
|
||||
0: "METAR", 20: "METAR", //"METAR and SPECI";
|
||||
1: "TAG", 21: "TAF", //"TAF and Amended TAF";
|
||||
2: "SIGMET", 22: "SIGMET", //"SIGMET";
|
||||
3: "Conv SIGMET", 23: "Conv SIGMET", //"Convective SIGMET";
|
||||
4: "AIRMET", 24: "AIRMET", //"AIRMET";
|
||||
5: "PIREP", 25: "PIREP", //"PIREP";
|
||||
6: "Severe Wx", 26: "Severe Wx", //"AWW";
|
||||
7: "Winds Aloft", 27: "Winds Aloft", //"Winds and Temperatures Aloft";
|
||||
8: "NOTAM", //"NOTAM (Including TFRs) and Service Status";
|
||||
9: "D-ATIS", //"Aerodrome and Airspace – D-ATIS";
|
||||
10: "Terminal Wx", //"Aerodrome and Airspace - TWIP";
|
||||
11: "AIRMET", //"Aerodrome and Airspace - AIRMET";
|
||||
12: "SIGMET", //"Aerodrome and Airspace - SIGMET/Convective SIGMET";
|
||||
13: "SUA", //"Aerodrome and Airspace - SUA Status";
|
||||
51: "NEXRAD", //"National NEXRAD, Type 0 - 4 level";
|
||||
52: "NEXRAD", //"National NEXRAD, Type 1 - 8 level (quasi 6-level VIP)";
|
||||
53: "NEXRAD", //"National NEXRAD, Type 2 - 8 level";
|
||||
54: "NEXRAD", //"National NEXRAD, Type 3 - 16 level";
|
||||
55: "NEXRAD", //"Regional NEXRAD, Type 0 - low dynamic range";
|
||||
56: "NEXRAD", //"Regional NEXRAD, Type 1 - 8 level (quasi 6-level VIP)";
|
||||
57: "NEXRAD", //"Regional NEXRAD, Type 2 - 8 level";
|
||||
58: "NEXRAD", //"Regional NEXRAD, Type 3 - 16 level";
|
||||
59: "NEXRAD", //"Individual NEXRAD, Type 0 - low dynamic range";
|
||||
60: "NEXRAD", //"Individual NEXRAD, Type 1 - 8 level (quasi 6-level VIP)";
|
||||
61: "NEXRAD", //"Individual NEXRAD, Type 2 - 8 level";
|
||||
62: "NEXRAD", //"Individual NEXRAD, Type 3 - 16 level";
|
||||
63: "NEXRAD Regional", //"Global Block Representation - Regional NEXRAD, Type 4 – 8 level";
|
||||
64: "NEXRAD CONUS", //"Global Block Representation - CONUS NEXRAD, Type 4 - 8 level";
|
||||
81: "Tops", //"Radar echo tops graphic, scheme 1: 16-level";
|
||||
82: "Tops", //"Radar echo tops graphic, scheme 2: 8-level";
|
||||
83: "Tops", //"Storm tops and velocity";
|
||||
101: "Lightning", //"Lightning strike type 1 (pixel level)";
|
||||
102: "Lightning", //"Lightning strike type 2 (grid element level)";
|
||||
151: "Lightning", //"Point phenomena, vector format";
|
||||
201: "Surface", //"Surface conditions/winter precipitation graphic";
|
||||
202: "Surface", //"Surface weather systems";
|
||||
254: "G-AIRMET", //"AIRMET, SIGMET: Bitmap encoding";
|
||||
351: "Time", //"System Time";
|
||||
352: "Status", //"Operational Status";
|
||||
353: "Status", //"Ground Station Status";
|
||||
401: "Imagery", //"Generic Raster Scan Data Product APDU Payload Format Type 1";
|
||||
402: "Text", 411: "Text", //"Generic Textual Data Product APDU Payload Format Type 1";
|
||||
403: "Vector Imagery", //"Generic Vector Data Product APDU Payload Format Type 1";
|
||||
404: "Symbols", 412: "Symbols", //"Generic Symbolic Product APDU Payload Format Type 1";
|
||||
405: "Text", 413: "Text", //"Generic Textual Data Product APDU Payload Format Type 2";
|
||||
}
|
||||
|
||||
func getProductNameFromId(product_id int) string {
|
||||
name, present := product_name_map[product_id]
|
||||
if present {
|
||||
return name
|
||||
}
|
||||
|
||||
if product_id == 600 || (product_id >= 2000 && product_id <= 2005) {
|
||||
return "Custom/Test"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Unknown (%d)", product_id)
|
||||
}
|
||||
|
||||
type settings struct {
|
||||
UAT_Enabled bool
|
||||
ES_Enabled bool
|
||||
|
@ -395,6 +464,7 @@ type status struct {
|
|||
Devices uint
|
||||
Connected_Users uint
|
||||
UAT_messages_last_minute uint
|
||||
UAT_products_last_minute map[string]uint32
|
||||
UAT_messages_max uint
|
||||
ES_messages_last_minute uint
|
||||
ES_messages_max uint
|
||||
|
|
|
@ -80,6 +80,16 @@
|
|||
<span class="col-xs-3 text-right" id="ES_messages_last_minute">--</span>
|
||||
<span class="col-xs-3 text-right" id="ES_messages_max">--</span>
|
||||
</div>
|
||||
<div id="uat_products" style="display: none;">
|
||||
<div class="row"><span class="col-xs-1"> </span></div>
|
||||
<div class="row">
|
||||
<label class="col-xs-6">UAT Products</label>
|
||||
<label class="col-xs-3 text-right">Last Minute</label>
|
||||
<label class="col-xs-3"></label>
|
||||
</div>
|
||||
<div id="product_rows">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row"><span class="col-xs-1"> </span></div>
|
||||
<div class="row">
|
||||
<label class="col-xs-6">GPS satellites:</label>
|
||||
|
@ -174,4 +184,4 @@
|
|||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -48,11 +48,26 @@ function connect() {
|
|||
$('#Devices').text(status.Devices);
|
||||
$('#Connected_Users').text(status.Connected_Users);
|
||||
$('#UAT_messages_last_minute').text(status.UAT_messages_last_minute);
|
||||
$('#UAT_products_last_minute').text(JSON.stringify(status.UAT_products_last_minute));
|
||||
$('#UAT_messages_max').text(status.UAT_messages_max);
|
||||
$('#ES_messages_last_minute').text(status.ES_messages_last_minute);
|
||||
$('#ES_messages_max').text(status.ES_messages_max);
|
||||
$('#GPS_satellites_locked').text(status.GPS_satellites_locked);
|
||||
setLEDstatus($('#RY835AI_connected'), status.RY835AI_connected);
|
||||
|
||||
//process products
|
||||
var products = status.UAT_products_last_minute;
|
||||
for (var product_name in products) {
|
||||
if (products.hasOwnProperty(product_name)) {
|
||||
var row_for_product = $('#product_rows div.row[product="' + product_name + '"]');
|
||||
if (row_for_product.length == 0) {
|
||||
$('#product_rows').append('<div class="row" product="' + product_name + '"><span class="col-xs-1"></span><label class="col-xs-5">' + product_name + '</label><span class="col-xs-3 text-right product-count"></span><span class="col-xs-3"></span></div>')
|
||||
row_for_product = $('#product_rows div.row[product="' + product_name + '"]');
|
||||
}
|
||||
$(row_for_product).find('.product-count').html(products[product_name]);
|
||||
$('#uat_products').show();
|
||||
}
|
||||
}
|
||||
|
||||
/* the formatting code could move to the other end of the socket */
|
||||
var uptime = status.Uptime;
|
||||
|
|
Ładowanie…
Reference in New Issue