kopia lustrzana https://github.com/projecthorus/radiosonde_auto_rx
1333 wiersze
66 KiB
HTML
1333 wiersze
66 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Radiosonde Auto-RX Status</title>
|
|
|
|
<!-- Configure to work on mobile -->
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<!-- Import style sheets (font and icons are remote, should fix) -->
|
|
<link href="{{ url_for('static', filename='css/main.css') }}" rel="stylesheet">
|
|
<link href="{{ url_for('static', filename='css/roboto.css') }}" rel="stylesheet">
|
|
<link href="{{ url_for('static', filename='css/c3.min.css') }}" rel="stylesheet">
|
|
<link href="{{ url_for('static', filename='css/leaflet.css') }}" rel="stylesheet">
|
|
<link href="{{ url_for('static', filename='css/leaflet.fullscreen.css') }}" rel="stylesheet">
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" >
|
|
<link id='tabulatorsheet' href='{{ url_for('static', filename='css/tabulator_midnight.min.css') }}' rel='stylesheet'>
|
|
|
|
<!-- Import local libraries -->
|
|
<script src="{{ url_for('static', filename='js/jquery-3.6.0.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/jquery-ui.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/leaflet.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/leaflet-providers.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/Leaflet.fullscreen.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/leaflet.edgebuffer.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/socket.io.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/scan_chart.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/c3.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/d3.min.js') }}" charset="utf-8"></script>
|
|
<script src="{{ url_for('static', filename='js/utils.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/tabulator.min.js') }}"></script>
|
|
|
|
<script>
|
|
var autorx_config = {
|
|
lat: 0.0,
|
|
lon: 0.0
|
|
};
|
|
|
|
var sonde_positions = {};
|
|
|
|
var sonde_currently_following = "none";
|
|
|
|
$( document ).ready(function() {
|
|
|
|
namespace = '/update_status';
|
|
|
|
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
|
|
|
|
$.ajax({
|
|
// Get station.cfg file.
|
|
url: "/get_config",
|
|
dataType: 'json',
|
|
async: false,
|
|
success: function(data) {
|
|
autorx_config = data;
|
|
}
|
|
});
|
|
|
|
$.ajax({
|
|
// Get local version number.
|
|
url: "/get_version",
|
|
dataType: 'text',
|
|
async: true,
|
|
success: function(data) {
|
|
$('#currentversion').text(data);
|
|
}
|
|
});
|
|
|
|
socket.on('log_event', function(msg) {
|
|
// New log entry received.
|
|
var log_time = new Date(msg.timestamp);
|
|
// Check if time is UTC mode.
|
|
if (getCookie('UTC') == 'false') {
|
|
// Check if entry is important.
|
|
if (msg.level == "INFO") {
|
|
var log_entry = "<tr><td><em>" + msg.level + "</em><br><b>" + msg.msg + "</b><br>" + log_time.toLocaleString("en-AU") + "</td></tr>";
|
|
} else {
|
|
// If entry is important colour text red.
|
|
var log_entry = "<tr><td><em>" + msg.level + "</em><br><b style='color:red'>" + msg.msg + "</b><br>" + log_time.toLocaleString("en-AU") + "</td></tr>";
|
|
}
|
|
} else {
|
|
if (msg.level == "INFO") {
|
|
var log_entry = "<tr><td><em>" + msg.level + "</em><br><b>" + msg.msg + "</b><br>" + msg.timestamp + "</td></tr>";
|
|
} else {
|
|
// If entry is important colour text red.
|
|
var log_entry = "<tr><td><em>" + msg.level + "</em><br><b style='color:red'>" + msg.msg + "</b><br>" + msg.timestamp + "</td></tr>";
|
|
}
|
|
}
|
|
// Append entry to log table.
|
|
$('#log_data > tbody').prepend(log_entry);
|
|
});
|
|
|
|
setup_scan_chart();
|
|
|
|
socket.on('scan_event', function(msg) {
|
|
// There is Scan data ready for us!
|
|
// Grab the latest set of data.
|
|
$.getJSON("/get_scan_data", function(data){
|
|
scan_chart_spectra.columns[0] = ['x_spectra'].concat(data.freq);
|
|
scan_chart_spectra.columns[1] = ['Spectra'].concat(data.power);
|
|
scan_chart_peaks.columns[0] = ['x_peaks'].concat(data.peak_freq);
|
|
scan_chart_peaks.columns[1] = ['Peaks'].concat(data.peak_lvl);
|
|
|
|
scan_chart_threshold.columns[1] = ['Threshold'].concat([data.threshold+autorx_config.snr_threshold,data.threshold+autorx_config.snr_threshold]);
|
|
// Plot the updated data.
|
|
scan_chart_obj.load(scan_chart_spectra);
|
|
scan_chart_obj.load(scan_chart_peaks);
|
|
scan_chart_obj.load(scan_chart_threshold);
|
|
|
|
// Run dark mode check again to solve render issues.
|
|
var z = getCookie('dark');
|
|
if (z == 'true') {
|
|
changeTheme(true);
|
|
} else if (z == 'false') {
|
|
changeTheme(false);
|
|
} else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
changeTheme(true);
|
|
} else {
|
|
changeTheme(false);
|
|
}
|
|
|
|
// Show the latest scan time.
|
|
if (getCookie('UTC') == 'false') {
|
|
temp_date = data.timestamp;
|
|
temp_date = temp_date.slice(0, -3);
|
|
temp_date += "Z";
|
|
var date = new Date(temp_date);
|
|
$('#scan_results').html('<b>Latest Scan:</b> ' + date.toLocaleString("en-AU"));
|
|
} else {
|
|
$('#scan_results').html('<b>Latest Scan:</b> ' + data.timestamp.slice(0, -3) + 'Z');
|
|
}
|
|
|
|
}
|
|
);
|
|
});
|
|
|
|
socket.on('task_event', function(msg){
|
|
// Grab the latest task list.
|
|
$.getJSON("/get_task_list", function(data){
|
|
var task_info = "";
|
|
for (_task in data){
|
|
task_info += "SDR #" + _task + ": " + data[_task] + " ";
|
|
}
|
|
|
|
// Update page with latest task.
|
|
$('#task_status').text(task_info);
|
|
});
|
|
});
|
|
|
|
// List of available map layers.
|
|
var Mapnik = L.tileLayer.provider("OpenStreetMap.Mapnik", {edgeBufferTiles: 2});
|
|
var DarkMatter = L.tileLayer.provider("CartoDB.DarkMatter", {edgeBufferTiles: 2});
|
|
var Terrain = L.tileLayer.provider("Stamen.Terrain", {edgeBufferTiles: 2});
|
|
var WorldImagery = L.tileLayer.provider("Esri.WorldImagery", {edgeBufferTiles: 2});
|
|
var Voyager = L.tileLayer.provider("CartoDB.Voyager", {edgeBufferTiles: 2});
|
|
var OpenTopoMap = L.tileLayer.provider("OpenTopoMap", {edgeBufferTiles: 2});
|
|
|
|
// Add maps to baseMaps.
|
|
var baseMaps = {
|
|
"Mapnik": Mapnik,
|
|
"DarkMatter": DarkMatter,
|
|
"WorldImagery": WorldImagery,
|
|
"Terrain": Terrain,
|
|
"Voyager": Voyager,
|
|
"OpenTopoMap": OpenTopoMap
|
|
};
|
|
|
|
// Check if user has preffered map theme.
|
|
var x = getCookie('theme');
|
|
if (x) {
|
|
mapTheme = x;
|
|
} else {
|
|
if (getCookie('dark') == "false") {
|
|
mapTheme = "Mapnik"
|
|
} else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
mapTheme = "DarkMatter"
|
|
} else {
|
|
mapTheme = "Mapnik"
|
|
}
|
|
}
|
|
|
|
// Home Icon.
|
|
homeIcon = L.icon({
|
|
iconUrl: '{{ url_for('static', filename='img/antenna-green.png') }}',
|
|
iconSize: [26, 34],
|
|
iconAnchor: [13, 34]
|
|
});
|
|
|
|
// Home Icon for dark mode.
|
|
homeIconDark = L.icon({
|
|
iconUrl: '{{ url_for('static', filename='img/antenna-green-dark.png') }}',
|
|
iconSize: [26, 34],
|
|
iconAnchor: [13, 34]
|
|
});
|
|
|
|
// Create map object.
|
|
mymap = L.map('mapid').setView([autorx_config.station_lat, autorx_config.station_lon], 8);
|
|
mymap.addControl(new L.Control.Fullscreen());
|
|
if (mapTheme != 'DarkMatter' && mapTheme != 'WorldImagery') {
|
|
home_marker = L.marker([autorx_config.station_lat, autorx_config.station_lon, autorx_config.alt],
|
|
{title: 'Receiver Location', icon: homeIcon}
|
|
).addTo(mymap);
|
|
} else {
|
|
home_marker = L.marker([autorx_config.station_lat, autorx_config.station_lon, autorx_config.alt],
|
|
{title: 'Receiver Location', icon: homeIconDark}
|
|
).addTo(mymap);
|
|
}
|
|
|
|
|
|
L.control.layers(baseMaps).addTo(mymap);
|
|
|
|
baseMaps[mapTheme].addTo(mymap);
|
|
|
|
// Update preffered them cookie on layer change.
|
|
mymap.on('baselayerchange', function(e) {
|
|
setCookie("theme", e['name'], 365);
|
|
if(e['name'] == "DarkMatter" || e['name'] == "WorldImagery"){
|
|
home_marker.setIcon(homeIconDark);
|
|
}else{
|
|
home_marker.setIcon(homeIcon);
|
|
}
|
|
});
|
|
|
|
// Check if user has preffered map visiblity.
|
|
if (getCookie('map') == 'false') {
|
|
document.getElementById("showmapbutton").checked = false;
|
|
document.getElementById("mapid").style.display = "none";
|
|
} else {
|
|
document.getElementById("showmapbutton").checked = true;
|
|
}
|
|
|
|
// Check if user has preffered table visiblity.
|
|
if (getCookie('table') == 'false') {
|
|
document.getElementById("showtablebutton").checked = false;
|
|
document.getElementById("tableid").style.display = "none";
|
|
} else {
|
|
document.getElementById("showtablebutton").checked = true;
|
|
}
|
|
|
|
// Check if user has preffered follow latest sonde selection.
|
|
if (getCookie('follow') == 'false') {
|
|
document.getElementById("sondeAutoFollow").checked = false;
|
|
} else {
|
|
document.getElementById("sondeAutoFollow").checked = true;
|
|
}
|
|
|
|
// Check if user has UTC time selection.
|
|
if (getCookie('UTC') == 'false') {
|
|
document.getElementById("showUTCbutton").checked = false;
|
|
} else {
|
|
document.getElementById("showUTCbutton").checked = true;
|
|
}
|
|
|
|
// Check if user has preffered scan chart visiblity.
|
|
if (getCookie('scan') == 'true') {
|
|
document.getElementById("showscanbutton").checked = true;
|
|
document.getElementById("scanid").style.display = "block";
|
|
} else {
|
|
document.getElementById("showscanbutton").checked = false;
|
|
document.getElementById("scanid").style.display = "none";
|
|
}
|
|
|
|
// Check if user has dark mode set.
|
|
if (getCookie('dark') == 'true') {
|
|
document.getElementById("showdarkbutton").checked = true;
|
|
changeTheme(true);
|
|
} else if (getCookie('dark') == 'false') {
|
|
document.getElementById("showdarkbutton").checked = false;
|
|
changeTheme(false);
|
|
} else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
document.getElementById("showdarkbutton").checked = true;
|
|
changeTheme(true);
|
|
} else {
|
|
document.getElementById("showdarkbutton").checked = false;
|
|
changeTheme(false);
|
|
}
|
|
|
|
// Function to change CSS options when changing dark mode.
|
|
function changeTheme(dark) {
|
|
if (dark == false) {
|
|
document.body.style.background = 'white';
|
|
$('#main span').css('color', 'black')
|
|
$('#main p').css('color', 'black')
|
|
$('#myBtn').css('color', 'black')
|
|
$('#scanid').css('color', 'black')
|
|
$('.c3-axis-y').css('fill', 'black')
|
|
$('.c3-axis-x').css('fill', 'black')
|
|
$('.c3-legend-item text').css('fill', 'black')
|
|
$('.domain').css('stroke', 'black')
|
|
$('.tick line').css('stroke', 'black')
|
|
$('#mapid span').css('color', 'black')
|
|
$('.sidenav').css('background-color', '#111')
|
|
$('.settings').css('background-color', '#111')
|
|
$('#tabulatorsheet').attr('href', '{{ url_for("static", filename="css/tabulator_simple.min.css") }}');
|
|
} else {
|
|
document.body.style.background = '#121212';
|
|
$('#main span').css('color', 'white')
|
|
$('#main p').css('color', 'white')
|
|
$('#myBtn').css('color', 'white')
|
|
$('#scanid').css('color', 'white')
|
|
$('.c3-axis-y').css('fill', 'white')
|
|
$('.c3-axis-x').css('fill', 'white')
|
|
$('.c3-legend-item text').css('fill', 'white')
|
|
$('.domain').css('stroke', 'white')
|
|
$('.tick line').css('stroke', 'white')
|
|
$('#mapid span').css('color', 'black')
|
|
$('.sidenav').css('background-color', '#414141')
|
|
$('.settings').css('background-color', '#414141')
|
|
$('#tabulatorsheet').attr('href', '{{ url_for("static", filename="css/tabulator_midnight.min.css") }}');
|
|
}
|
|
}
|
|
|
|
// Check if dark mode button has been ticked.
|
|
$('#showdarkbutton').change(function() {
|
|
if ($(this).is(":checked")) {
|
|
setCookie("dark", 'true', 365);
|
|
changeTheme(true);
|
|
} else {
|
|
setCookie("dark", 'false', 365);
|
|
changeTheme(false);
|
|
}
|
|
});
|
|
|
|
// Check if UTC button has been ticked.
|
|
$('#showUTCbutton').change(function() {
|
|
if ($(this).is(":checked")) {
|
|
setCookie("UTC", 'true', 365);
|
|
updateTelemetryTable();
|
|
} else {
|
|
setCookie("UTC", 'false', 365);
|
|
updateTelemetryTable();
|
|
}
|
|
});
|
|
|
|
// Check if UTC button has been ticked.
|
|
$('#paginationSelector').change(function() {
|
|
setCookie("pagination", this.value, 365);
|
|
table.setPageSize(this.value);
|
|
});
|
|
|
|
|
|
// Check if cookie exists for entries to display per page in table
|
|
if (getCookie('pagination') != null) {
|
|
pagination_size = parseInt(getCookie('pagination'));
|
|
$('#paginationSelector option[value="'+ getCookie('pagination') +'"]').attr("selected",true);
|
|
} else {
|
|
if (($( window ).width()/$( window ).height()) > 1) {
|
|
pagination_size = 6;
|
|
$('#paginationSelector option[value="6"]').attr("selected",true);
|
|
} else {
|
|
pagination_size = 3;
|
|
$('#paginationSelector option[value="3"]').attr("selected",true);
|
|
}
|
|
}
|
|
|
|
// Create Tabulator table.
|
|
table = new Tabulator("#telem_table", {
|
|
index:"realid",
|
|
placeholder:"No Sonde Data Available",
|
|
// Split into pages for over 6 entries.
|
|
pagination:"local",
|
|
paginationSize:pagination_size,
|
|
layout:"fitDataFill",
|
|
resizableColumns:"header",
|
|
layoutColumnsOnNewData:true,
|
|
columns:[ //Define Table Columns
|
|
{title:"SDR", field:"sdr_device_idx", headerSort:true},
|
|
{title:"Age", field:"age", headerSort:true},
|
|
{title:"Type", field:"type", headerSort:true},
|
|
{title:'Freq (MHz)', field:"freq", headerSort:true},
|
|
{title:"ID", field:"id", formatter:'html', width:80, headerSort:true},
|
|
{title:"Time", field:"datetime", width:180, headerSort:true, formatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('UTC') == 'false') {
|
|
var temp_time = new Date(cell.getValue());
|
|
if (temp_time.toLocaleString("en-AU") == "Invalid Date") {
|
|
return;
|
|
} else {
|
|
return temp_time.toLocaleString("en-AU");
|
|
}
|
|
} else {
|
|
return cell.getValue();
|
|
}
|
|
}
|
|
},
|
|
{title:"Frame", field:"frame", headerSort:true},
|
|
{title:"Latitude", field:"lat", width:80, formatter:'html', headerSort:false},
|
|
{title:"Longitude", field:"lon", width:80, formatter:'html', headerSort:false},
|
|
{title:"Alt (m)", field:"alt", headerSort:true},
|
|
{title:"Vel (kph)", field:"vel_h", headerSort:false},
|
|
{title:"Asc (m/s)", field:"vel_v", headerSort:false},
|
|
{title:"Temp (°C)", field:"temp", headerSort:false},
|
|
{title:"RH (%)", field:"humidity", headerSort:false},
|
|
{title:"Az (°)", field:"azimuth", headerSort:false},
|
|
{title:"El (°)", field:"elevation", headerSort:false},
|
|
{title:"Range (km)", field:"range", headerSort:true},
|
|
{title:"SNR (dB)", field:"snr", headerSort:true},
|
|
{title:"Other", field:"other", width:140, headerSort:false},
|
|
{title:"Real ID", field:"realid", visible:false}
|
|
],
|
|
rowContext:function(e, row){
|
|
e.preventDefault();
|
|
//Highlight Sonde on map when row selected
|
|
for (var i = 0; i < Object.keys(sonde_positions).length; i++) {
|
|
console.log(Object.keys(sonde_positions)[i]);
|
|
if (Object.keys(sonde_positions)[i] != row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")) {
|
|
sonde_positions[Object.keys(sonde_positions)[i]]['path'].setStyle({
|
|
color: sonde_positions[Object.keys(sonde_positions)[i]]['colour']
|
|
});
|
|
if (sonde_positions[Object.keys(sonde_positions)[i]]['latest_data']['vel_v'] < 0){
|
|
sonde_positions[Object.keys(sonde_positions)[i]].marker.setIcon(sondeDescentIcons[sonde_positions[Object.keys(sonde_positions)[i]]['colour']]);
|
|
}else{
|
|
sonde_positions[Object.keys(sonde_positions)[i]].marker.setIcon(sondeAscentIcons[sonde_positions[Object.keys(sonde_positions)[i]]['colour']]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['path']['options']['color'] != 'white') {
|
|
selected_sonde = row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "");
|
|
sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['path'].setStyle({
|
|
color: 'white'
|
|
});
|
|
if (sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['latest_data']['vel_v'] < 0){
|
|
sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")].marker.setIcon(sondeDescentIcons['white']);
|
|
}else{
|
|
sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")].marker.setIcon(sondeAscentIcons['white']);
|
|
}
|
|
} else {
|
|
selected_sonde = "";
|
|
sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['path'].setStyle({
|
|
color: sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['colour']
|
|
});
|
|
if (sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['latest_data']['vel_v'] < 0){
|
|
sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")].marker.setIcon(sondeDescentIcons[sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['colour']]);
|
|
}else{
|
|
sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")].marker.setIcon(sondeAscentIcons[sonde_positions[row['_row']['data']['id'].replace(/(<([^>]+)>)/gi, "")]['colour']]);
|
|
}
|
|
}
|
|
|
|
}
|
|
});
|
|
|
|
// Update Tabulator table.
|
|
function updateTelemetryTable(){
|
|
var telem_data = [];
|
|
|
|
if (jQuery.isEmptyObject(sonde_positions)){
|
|
telem_data = [];
|
|
}else{
|
|
var sonde_id_list = Object.getOwnPropertyNames(sonde_positions).reverse();
|
|
|
|
//for (sonde_id in sonde_id_list){
|
|
sonde_id_list.forEach( function(sonde_id){
|
|
var sonde_id_data = Object.assign({},sonde_positions[sonde_id].latest_data);
|
|
var sonde_id_age = Date.now() - sonde_positions[sonde_id].age;
|
|
if (sonde_id_age>(1000*autorx_config.rx_timeout)){
|
|
sonde_id_data.sdr_device_idx = "";
|
|
sonde_id_data.age = "old";
|
|
}else{
|
|
sonde_id_data.age = (sonde_id_age/1000.0).toFixed(0) + " s";
|
|
}
|
|
|
|
// If we have a station lat/lon/alt set, calculate az/el/range.
|
|
if (autorx_config.station_lat != 0.0){
|
|
// There is a station lat/lon set.
|
|
var _bal = {lat:sonde_id_data.lat, lon:sonde_id_data.lon, alt:sonde_id_data.alt};
|
|
var _station = {lat:autorx_config.station_lat, lon:autorx_config.station_lon, alt:autorx_config.station_alt};
|
|
|
|
var _look_angles = calculate_lookangles(_station, _bal);
|
|
|
|
sonde_id_data.azimuth = _look_angles.azimuth.toFixed(1);
|
|
sonde_id_data.elevation = _look_angles.elevation.toFixed(1);
|
|
sonde_id_data.range = (_look_angles.range/1000).toFixed(1);
|
|
} else{
|
|
// Insert blank data.
|
|
sonde_id_data.azimuth = "";
|
|
sonde_id_data.elevation = "";
|
|
sonde_id_data.range = "";
|
|
}
|
|
|
|
// Modify some of the fields to fixed point values.
|
|
|
|
// Add Geo ref links to lat/lon fields.
|
|
temp_lat = "<a href='geo:" + sonde_id_data.lat.toFixed(5) + "," + sonde_id_data.lon.toFixed(5) + "'>" + sonde_id_data.lat.toFixed(5) + "</a>";
|
|
temp_lon = "<a href='geo:" + sonde_id_data.lat.toFixed(5) + "," + sonde_id_data.lon.toFixed(5) + "'>" + sonde_id_data.lon.toFixed(5) + "</a>";
|
|
sonde_id_data.lat = temp_lat;
|
|
sonde_id_data.lon = temp_lon;
|
|
|
|
sonde_id_data.alt = sonde_id_data.alt.toFixed(1);
|
|
sonde_id_data.vel_v = sonde_id_data.vel_v.toFixed(1);
|
|
sonde_id_data.vel_h = (sonde_id_data.vel_h*3.6).toFixed(1);
|
|
// Add a link to HabHub if we have habitat enabled.
|
|
if (autorx_config.habitat_enabled == true) {
|
|
// Add a link to HabHub card if sonde is old.
|
|
if (sonde_id_data.age != "old") {
|
|
sonde_id_data.id = "<a href='http://sondehub.org/" + sonde_id + "' target='_blank'>" + sonde_id + "</a>";
|
|
} else {
|
|
sonde_id_data.id = "<a href='http://sondehub.org/card/" + sonde_id + "' target='_blank'>" + sonde_id + "</a>";
|
|
}
|
|
} else if (autorx_config.aprs_enabled == true && autorx_config.aprs_server == "radiosondy.info") {
|
|
sonde_id_data.id = "<a href='https://radiosondy.info/sonde_archive.php?sondenumber=" + sonde_id + "' target='_blank'>" + sonde_id + "</a>";
|
|
} else if (autorx_config.aprs_enabled == true) {
|
|
sonde_id_data.id = "<a href='https://aprs.fi/#!call=" + sonde_id + "&timerange=3600&tail=3600' target='_blank'>" + sonde_id + "</a>";
|
|
}
|
|
|
|
sonde_id_data.realid = sonde_id;
|
|
|
|
// Add SNR data, if it exists.
|
|
if (sonde_id_data.hasOwnProperty('snr')){
|
|
sonde_id_data.snr = sonde_id_data.snr.toFixed(1);
|
|
}
|
|
|
|
// Add data into the 'other' field.
|
|
sonde_id_data.other = "";
|
|
// Burst timer for RS41s
|
|
if (sonde_id_data.hasOwnProperty('bt')){
|
|
if ((sonde_id_data.bt >= 0) && (sonde_id_data.bt < 65535)) {
|
|
sonde_id_data.other += "BT " + new Date(sonde_id_data.bt*1000).toISOString().substr(11, 8) + " ";
|
|
}
|
|
}
|
|
if (sonde_id_data.hasOwnProperty('batt')){
|
|
sonde_id_data.other += sonde_id_data.batt.toFixed(1) + " V";
|
|
}
|
|
|
|
telem_data.push(sonde_id_data);
|
|
});
|
|
}
|
|
table.updateOrAddData(telem_data);
|
|
// Hide table page navigation if only one page.
|
|
if(table.getPageMax() == 1){
|
|
$(".tabulator-footer").hide();
|
|
}else{
|
|
$(".tabulator-footer").show();
|
|
}
|
|
}
|
|
// Invalidate map size to fix problems with elements resizing.
|
|
mymap.invalidateSize();
|
|
|
|
var initial_load_complete = false;
|
|
selected_sonde = "";
|
|
$.ajax({ // Get archived data.
|
|
url: "/get_telemetry_archive",
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
for (sonde_id in data){
|
|
var telem = data[sonde_id].latest_telem;
|
|
sonde_positions[sonde_id] = {
|
|
latest_data: telem,
|
|
age: 0,
|
|
colour: colour_values[colour_idx]
|
|
};
|
|
// Create markers
|
|
sonde_positions[sonde_id].path = L.polyline(data[sonde_id].path,{title:telem.id + " Path", color:sonde_positions[sonde_id].colour}).addTo(mymap);
|
|
|
|
sonde_positions[sonde_id].marker = L.marker([telem.lat, telem.lon, telem.alt],{title:telem.id, icon: sondeAscentIcons[sonde_positions[sonde_id].colour]}).bindTooltip(sonde_id,{permanent:false,direction:'right'}).addTo(mymap);
|
|
|
|
if(autorx_config.station_lat != 0.0){
|
|
sonde_positions[sonde_id].los_path = L.polyline([],
|
|
{
|
|
color:los_color,
|
|
opacity:los_opacity
|
|
}
|
|
).addTo(mymap);
|
|
}
|
|
|
|
if (telem.vel_v < 0){
|
|
sonde_positions[sonde_id].marker.setIcon(sondeDescentIcons[sonde_positions[sonde_id].colour]);
|
|
}
|
|
|
|
colour_idx = (colour_idx+1)%colour_values.length;
|
|
}
|
|
updateTelemetryTable();
|
|
initial_load_complete = true;
|
|
}
|
|
});
|
|
|
|
socket.on('station_update', function(msg) {
|
|
// Station update messages indicate a move of the station location, as updated
|
|
// by a GPS receiver.
|
|
|
|
if(initial_load_complete == false){
|
|
// If we have not completed our initial load of telemetry data, discard this data.
|
|
return
|
|
}
|
|
|
|
// Update the marker position.
|
|
home_marker.setLatLng([msg.lat, msg.lon, msg.alt]).update();
|
|
|
|
// Update the autorx_config object, which is used to calculate relative look angles for the telemetry table.
|
|
autorx_config.station_lat = msg.lat;
|
|
autorx_config.station_lon = msg.lon;
|
|
autorx_config.station_alt = msg.alt;
|
|
|
|
});
|
|
|
|
socket.on('telemetry_event', function(msg) {
|
|
// Telemetry Event messages contain the entire telemetry dictionary, as produced by the SondeDecoder class.
|
|
// This includes the fields: ['frame', 'id', 'datetime', 'lat', 'lon', 'alt', 'temp', 'type', 'freq', 'freq_float']
|
|
|
|
if(initial_load_complete == false){
|
|
// If we have not completed our initial load of telemetry data, discard this data.
|
|
return
|
|
}
|
|
|
|
// Have we seen this sonde before?
|
|
if (sonde_positions.hasOwnProperty(msg.id) == false){
|
|
// Nope, add a property to the sonde_positions object, and setup markers for the sonde.
|
|
sonde_positions[msg.id] = {
|
|
latest_data : msg,
|
|
age : Date.now(),
|
|
colour : colour_values[colour_idx]
|
|
};
|
|
// Create markers
|
|
sonde_positions[msg.id].path = L.polyline([[msg.lat, msg.lon, msg.alt]],{title:msg.id + " Path", color:sonde_positions[msg.id].colour}).addTo(mymap);
|
|
|
|
sonde_positions[msg.id].marker = L.marker([msg.lat, msg.lon, msg.alt],{title:msg.id, icon: sondeAscentIcons[sonde_positions[msg.id].colour]})
|
|
.bindTooltip(msg.id,{permanent:false,direction:'right'})
|
|
.addTo(mymap);
|
|
|
|
// If there is a station location defined, show the path from the station to the sonde.
|
|
if(autorx_config.station_lat != 0.0){
|
|
sonde_positions[msg.id].los_path = L.polyline([[autorx_config.station_lat, autorx_config.station_lon],[msg.lat, msg.lon]],
|
|
{
|
|
color:los_color,
|
|
opacity:los_opacity
|
|
}
|
|
).addTo(mymap);
|
|
}
|
|
|
|
colour_idx = (colour_idx+1)%colour_values.length;
|
|
// If this is our first sonde since the browser has been opened, follow it.
|
|
if (Object.keys(sonde_positions).length == 1){
|
|
sonde_positions[msg.id].following = true;
|
|
}
|
|
} else {
|
|
// Yep - update the sonde_positions entry.
|
|
sonde_positions[msg.id].latest_data = msg;
|
|
sonde_positions[msg.id].age = Date.now();
|
|
sonde_positions[msg.id].path.addLatLng([msg.lat, msg.lon, msg.alt]);
|
|
sonde_positions[msg.id].marker.setLatLng([msg.lat, msg.lon, msg.alt]).update();
|
|
|
|
if (msg.vel_v < 0){
|
|
if (selected_sonde == msg.id) {
|
|
sonde_positions[msg.id].marker.setIcon(sondeDescentIcons['white']);
|
|
} else {
|
|
sonde_positions[msg.id].marker.setIcon(sondeDescentIcons[sonde_positions[msg.id].colour]);
|
|
}
|
|
}else{
|
|
if (selected_sonde == msg.id) {
|
|
sonde_positions[msg.id].marker.setIcon(sondeAscentIcons['white']);
|
|
} else {
|
|
sonde_positions[msg.id].marker.setIcon(sondeAscentIcons[sonde_positions[msg.id].colour]);
|
|
}
|
|
}
|
|
|
|
if(autorx_config.station_lat != 0.0){
|
|
sonde_positions[msg.id].los_path.setLatLngs([[autorx_config.station_lat, autorx_config.station_lon],[msg.lat, msg.lon]]);
|
|
}
|
|
}
|
|
|
|
// Update the telemetry table display
|
|
//updateTelemetryText();
|
|
updateTelemetryTable();
|
|
|
|
// Are we currently following any other sondes?
|
|
if (sonde_currently_following == "none"){
|
|
// If not, follow this one!
|
|
sonde_currently_following = msg.id;
|
|
}
|
|
|
|
// Is sonde following enabled?
|
|
if (document.getElementById("sondeAutoFollow").checked == true){
|
|
// If we are currently following this sonde, snap the map to it.
|
|
if (msg.id == sonde_currently_following){
|
|
mymap.panTo([msg.lat,msg.lon]);
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
// Sonde-Following Logic. May need to adjust timeouts.
|
|
var sonde_follow_timeout = 30000; // 30 Seconds - reasonable timeout.
|
|
// Every X seconds, check if the currently followed sonde is still getting regular data.
|
|
// If not, clear the currently_following flag to allow another sonde to be auto tracked.
|
|
window.setInterval(function () {
|
|
if (sonde_currently_following == "none"){
|
|
return;
|
|
}
|
|
var now_time = Date.now();
|
|
if ( (now_time-sonde_positions[sonde_currently_following].age) > sonde_follow_timeout){
|
|
sonde_currently_following = "none";
|
|
}
|
|
}, sonde_follow_timeout);
|
|
|
|
// Automatically gets the latest version number and GitHub URL
|
|
$.ajax({
|
|
url:"https://api.github.com/repos/projecthorus/radiosonde_auto_rx/releases",
|
|
dataType: "jsonp",
|
|
success : function( returndata )
|
|
{
|
|
$("#footertext").html("<a href='" + returndata['data'][0].html_url + "' target='_blank' style='text-decoration:none;color:white;'>" + returndata['data'][0].tag_name.substring(1) + "</a>");
|
|
}
|
|
});
|
|
|
|
// Update telemetry table every second (this is mainly to update the age field)
|
|
window.setInterval(function(){
|
|
updateTelemetryTable();
|
|
}, 1000);
|
|
|
|
// Tell program we are connected and ready for data.
|
|
socket.on('connect', function() {
|
|
socket.emit('client_connected', {data: 'I\'m connected!'});
|
|
});
|
|
|
|
// Function to change table columns visible.
|
|
$(document).on('change', 'form input', function() {
|
|
var checked = $(this).is(":checked");
|
|
|
|
if (checked == false) {
|
|
var cookiesend = 'false';
|
|
} else {
|
|
var cookiesend = 'true';
|
|
}
|
|
|
|
// Set cookie for columns to show in future.
|
|
setCookie("col" + index, cookiesend, 365);
|
|
|
|
var index = $(this).attr("class");
|
|
|
|
// Update Tabulator table with selected columns visible.
|
|
if(checked) {
|
|
switch(index) {
|
|
case "0":
|
|
table.showColumn("sdr_device_idx");
|
|
break;
|
|
case "1":
|
|
table.showColumn("age");
|
|
break;
|
|
case "2":
|
|
table.showColumn("type");
|
|
break;
|
|
case "3":
|
|
table.showColumn("freq");
|
|
break;
|
|
case "4":
|
|
table.showColumn("id");
|
|
break;
|
|
case "5":
|
|
table.showColumn("datetime");
|
|
break;
|
|
case "6":
|
|
table.showColumn("frame");
|
|
break;
|
|
case "7":
|
|
table.showColumn("lat");
|
|
break;
|
|
case "8":
|
|
table.showColumn("lon");
|
|
break;
|
|
case "9":
|
|
table.showColumn("alt");
|
|
break;
|
|
case "10":
|
|
table.showColumn("vel_h");
|
|
break;
|
|
case "11":
|
|
table.showColumn("vel_v");
|
|
break;
|
|
case "12":
|
|
table.showColumn("temp");
|
|
break;
|
|
case "13":
|
|
table.showColumn("humidity");
|
|
break;
|
|
case "14":
|
|
table.showColumn("azimuth");
|
|
break;
|
|
case "15":
|
|
table.showColumn("elevation");
|
|
break;
|
|
case "16":
|
|
table.showColumn("range");
|
|
break;
|
|
case "17":
|
|
table.showColumn("snr");
|
|
break;
|
|
case "18":
|
|
table.showColumn("other");
|
|
break;
|
|
}
|
|
table.redraw();
|
|
} else {
|
|
switch(index) {
|
|
case "0":
|
|
table.hideColumn("sdr_device_idx");
|
|
break;
|
|
case "1":
|
|
table.hideColumn("age");
|
|
break;
|
|
case "2":
|
|
table.hideColumn("type");
|
|
break;
|
|
case "3":
|
|
table.hideColumn("freq");
|
|
break;
|
|
case "4":
|
|
table.hideColumn("id");
|
|
break;
|
|
case "5":
|
|
table.hideColumn("datetime");
|
|
break;
|
|
case "6":
|
|
table.hideColumn("frame");
|
|
break;
|
|
case "7":
|
|
table.hideColumn("lat");
|
|
break;
|
|
case "8":
|
|
table.hideColumn("lon");
|
|
break;
|
|
case "9":
|
|
table.hideColumn("alt");
|
|
break;
|
|
case "10":
|
|
table.hideColumn("vel_h");
|
|
break;
|
|
case "11":
|
|
table.hideColumn("vel_v");
|
|
break;
|
|
case "12":
|
|
table.hideColumn("temp");
|
|
break;
|
|
case "13":
|
|
table.hideColumn("humidity");
|
|
break;
|
|
case "14":
|
|
table.hideColumn("azimuth");
|
|
break;
|
|
case "15":
|
|
table.hideColumn("elevation");
|
|
break;
|
|
case "16":
|
|
table.hideColumn("range");
|
|
break;
|
|
case "17":
|
|
table.hideColumn("snr");
|
|
break;
|
|
case "18":
|
|
table.hideColumn("other");
|
|
break;
|
|
}
|
|
table.redraw();
|
|
}
|
|
});
|
|
|
|
// Runs once at page load to set which Tabulator columns to show/hide per set cookies
|
|
for (i = 0; i < 19; i++) {
|
|
var show = getCookie("col"+i);
|
|
if (show == 'false') {
|
|
document.getElementById("checkbox" + i).checked = false;
|
|
switch(i) {
|
|
case 0:
|
|
table.hideColumn("sdr_device_idx");
|
|
break;
|
|
case 1:
|
|
table.hideColumn("age");
|
|
break;
|
|
case 2:
|
|
table.hideColumn("type");
|
|
break;
|
|
case 3:
|
|
table.hideColumn("freq");
|
|
break;
|
|
case 4:
|
|
table.hideColumn("id");
|
|
break;
|
|
case 5:
|
|
table.hideColumn("datetime");
|
|
break;
|
|
case 6:
|
|
table.hideColumn("frame");
|
|
break;
|
|
case 7:
|
|
table.hideColumn("lat");
|
|
break;
|
|
case 8:
|
|
table.hideColumn("lon");
|
|
break;
|
|
case 9:
|
|
table.hideColumn("alt");
|
|
break;
|
|
case 10:
|
|
table.hideColumn("vel_h");
|
|
break;
|
|
case 11:
|
|
table.hideColumn("vel_v");
|
|
break;
|
|
case 12:
|
|
table.hideColumn("temp");
|
|
break;
|
|
case 13:
|
|
table.hideColumn("humidity");
|
|
break;
|
|
case 14:
|
|
table.hideColumn("azimuth");
|
|
break;
|
|
case 15:
|
|
table.hideColumn("elevation");
|
|
break;
|
|
case 16:
|
|
table.hideColumn("range");
|
|
break;
|
|
case 17:
|
|
table.hideColumn("snr");
|
|
break;
|
|
case 18:
|
|
table.hideColumn("other");
|
|
break;
|
|
}
|
|
} else if (show == 'true') {
|
|
document.getElementById("checkbox" + i).checked = true;
|
|
} else {
|
|
if (($( window ).width()/$( window ).height()) > 1) {
|
|
document.getElementById("checkbox" + i).checked = true;
|
|
} else { // If no cookies are set on mobile device show limited number for better experience.
|
|
if ([1,4,9,16].includes(i)) {
|
|
setCookie("col" + i, 'true', 365);
|
|
document.getElementById("checkbox" + i).checked = true;
|
|
}
|
|
if ([0,2,3,5,6,7,8,10,11,12,13,14,15,17,18].includes(i)) {
|
|
setCookie("col" + i, 'false', 365);
|
|
document.getElementById("checkbox" + i).checked = false;
|
|
switch(i) {
|
|
case 0:
|
|
table.hideColumn("sdr_device_idx");
|
|
break;
|
|
case 1:
|
|
table.hideColumn("age");
|
|
break;
|
|
case 2:
|
|
table.hideColumn("type");
|
|
break;
|
|
case 3:
|
|
table.hideColumn("freq");
|
|
break;
|
|
case 4:
|
|
table.hideColumn("id");
|
|
break;
|
|
case 5:
|
|
table.hideColumn("datetime");
|
|
break;
|
|
case 6:
|
|
table.hideColumn("frame");
|
|
break;
|
|
case 7:
|
|
table.hideColumn("lat");
|
|
break;
|
|
case 8:
|
|
table.hideColumn("lon");
|
|
break;
|
|
case 9:
|
|
table.hideColumn("alt");
|
|
break;
|
|
case 10:
|
|
table.hideColumn("vel_h");
|
|
break;
|
|
case 11:
|
|
table.hideColumn("vel_v");
|
|
break;
|
|
case 12:
|
|
table.hideColumn("temp");
|
|
break;
|
|
case 13:
|
|
table.hideColumn("humidity");
|
|
break;
|
|
case 14:
|
|
table.hideColumn("azimuth");
|
|
break;
|
|
case 15:
|
|
table.hideColumn("elevation");
|
|
break;
|
|
case 16:
|
|
table.hideColumn("range");
|
|
break;
|
|
case 17:
|
|
table.hideColumn("snr");
|
|
break;
|
|
case 18:
|
|
table.hideColumn("other");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
table.redraw();
|
|
});
|
|
|
|
// Function to open/close left log menu along with adjusting other elements so they render correctly.
|
|
function changeNav() {
|
|
var x = document.getElementById("closebtn");
|
|
var y = document.getElementById('mapid');
|
|
if (document.getElementById("mySidenav").style.width == "0px" || document.getElementById("mySidenav").style.width == 0) {
|
|
var myDiv = document.getElementById('sidenavtable');
|
|
myDiv.scrollTop = 0;
|
|
if ((window.innerWidth/window.innerHeight) > 1) { // 350px wide on desktop.
|
|
x.style.display = "none";
|
|
if (getCookie('map') == true || document.getElementById("showmapbutton").checked == true) {
|
|
y.style.display = "block";
|
|
}
|
|
document.getElementById("mySidenav").style.width = "350px";
|
|
document.getElementById("main").style.marginLeft = "350px";
|
|
document.getElementById("mySidenav").style.borderRadius = "0px 25px 25px 0px";
|
|
mymap.invalidateSize();
|
|
setTimeout(scan_chart_obj.resize,500);
|
|
} else { // Fullsize on mobile.
|
|
x.style.display = "block";
|
|
y.style.display = "none";
|
|
document.getElementById("mySidenav").style.width = "100%";
|
|
document.getElementById("main").style.marginLeft = "0";
|
|
document.getElementById("mySidenav").style.borderRadius = "0px";
|
|
}
|
|
} else {
|
|
x.style.display = "none";
|
|
if (getCookie('map') == true || document.getElementById("showmapbutton").checked == true) {
|
|
y.style.display = "block";
|
|
}
|
|
document.getElementById("mySidenav").style.width = 0;
|
|
document.getElementById("main").style.marginLeft = 0;
|
|
mymap.invalidateSize();
|
|
setTimeout(scan_chart_obj.resize,500);
|
|
}
|
|
}
|
|
|
|
// Function to open/close right settings menu along with adjusting other elements so they render correctly.
|
|
function changeSettings() {
|
|
var y = document.getElementById('mapid');
|
|
if (document.getElementById("mySettings").style.width == "0px" || document.getElementById("mySettings").style.width == 0) {
|
|
if ((window.innerWidth/window.innerHeight) > 1) { // 350px wide on desktop.
|
|
if (getCookie('map') == true || document.getElementById("showmapbutton").checked == true) {
|
|
y.style.display = "block";
|
|
}
|
|
document.getElementById("mySettings").style.width = "350px";
|
|
document.getElementById("main").style.marginRight = "350px";
|
|
document.getElementById("mySettings").style.borderRadius = "25px 0px 0px 25px";
|
|
mymap.invalidateSize();
|
|
setTimeout(scan_chart_obj.resize,500);
|
|
} else { // Fullsize on mobile.
|
|
y.style.display = "none";
|
|
document.getElementById("mySettings").style.width = "100%";
|
|
document.getElementById("main").style.marginRight = "0";
|
|
document.getElementById("mySettings").style.borderRadius = "0px";
|
|
}
|
|
} else {
|
|
if (getCookie('map') == true || document.getElementById("showmapbutton").checked == true) {
|
|
y.style.display = "block";
|
|
}
|
|
document.getElementById("mySettings").style.width = 0;
|
|
document.getElementById("main").style.marginRight = 0;
|
|
mymap.invalidateSize();
|
|
setTimeout(scan_chart_obj.resize,500);
|
|
}
|
|
}
|
|
|
|
// Show/hide map on button press and update cookies.
|
|
function showMap(element) {
|
|
if (element.checked == false) {
|
|
document.getElementById("mapid").style.display = "none";
|
|
setCookie("map", 'false', 365);
|
|
} else {
|
|
document.getElementById("mapid").style.display = "block";
|
|
setCookie("map", 'true', 365);
|
|
mymap.invalidateSize();
|
|
}
|
|
}
|
|
|
|
// Show/hide scan chart on button press and update cookies.
|
|
function showScan(element) {
|
|
if (element.checked == false) {
|
|
document.getElementById("scanid").style.display = "none";
|
|
setCookie("scan", 'false', 365);
|
|
mymap.invalidateSize();
|
|
} else {
|
|
document.getElementById("scanid").style.display = "block";
|
|
setCookie("scan", 'true', 365);
|
|
mymap.invalidateSize();
|
|
setTimeout(scan_chart_obj.resize,500);
|
|
}
|
|
}
|
|
|
|
// Enable/disable auto follow on button press and update cookies.
|
|
function autoFollow(element) {
|
|
if (element.checked == false) {
|
|
setCookie("follow", 'false', 365);
|
|
} else {
|
|
setCookie("follow", 'true', 365);
|
|
}
|
|
}
|
|
|
|
// Show/hide table on button press and update cookies.
|
|
function showTable(element) {
|
|
if (element.checked == false) {
|
|
document.getElementById("tableid").style.display = "none";
|
|
setCookie("table", 'false', 365);
|
|
} else {
|
|
document.getElementById("tableid").style.display = "block";
|
|
setCookie("table", 'true', 365);
|
|
}
|
|
}
|
|
|
|
// Set given cookie name and value.
|
|
function setCookie(name,value,days) {
|
|
var expires = "";
|
|
if (days) {
|
|
var date = new Date();
|
|
date.setTime(date.getTime() + (days*24*60*60*1000));
|
|
expires = "; expires=" + date.toUTCString();
|
|
}
|
|
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
|
}
|
|
|
|
// Return cookie value given name.
|
|
function getCookie(name) {
|
|
var nameEQ = name + "=";
|
|
var ca = document.cookie.split(';');
|
|
for(var i=0;i < ca.length;i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Reset specific cookie.
|
|
function eraseCookie(name) {
|
|
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
|
}
|
|
|
|
// Reset all cookies.
|
|
function deleteAllCookies() {
|
|
var cookies = document.cookie.split(";");
|
|
|
|
for (var i = 0; i < cookies.length; i++) {
|
|
var cookie = cookies[i];
|
|
var eqPos = cookie.indexOf("=");
|
|
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
|
|
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
|
|
}
|
|
location.reload();
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<!-- Wrapper for entire body to ensure flex works -->
|
|
<div class="wrapper">
|
|
<!-- Wrapper for log sidebar -->
|
|
<div id="mySidenav" class="sidenav">
|
|
<div class="headerdiv">
|
|
<a href="javascript:void(0)" class="closebtn" id="closebtn" onclick="changeNav()">✖</a>
|
|
<img src="{{ url_for('static', filename='img/autorx_logo.png') }}" alt="Radiosonde Auto-RX Button">
|
|
<h2>Log</h2>
|
|
</div>
|
|
<div class="sidenavtable" id="sidenavtable">
|
|
<table style="width:100%" id="log_data">
|
|
<tbody>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="footerdiv">
|
|
<p class="footer">Version: <span id="currentversion">???</span> (latest: <span id="footertext">???</span>)</p>
|
|
<br>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Wrapper for settings sidebar -->
|
|
<div id="mySettings" class="settings">
|
|
<a href="javascript:void(0)" class="closebtn2" id="closebtn2" onclick="changeSettings()">✖</a>
|
|
<br><h2>Settings</h2>
|
|
<div class="scrollsettings">
|
|
<h2>Table Options</h2>
|
|
<form>
|
|
<input type="checkbox" class="0" id="checkbox0" checked>
|
|
<label> SDR</label><br>
|
|
<input type="checkbox" class="1" id="checkbox1" checked>
|
|
<label> Age</label><br>
|
|
<input type="checkbox" class="2" id="checkbox2" checked>
|
|
<label> Type</label><br>
|
|
<input type="checkbox" class="3" id="checkbox3" checked>
|
|
<label> Frequency</label><br>
|
|
<input type="checkbox" class="4" id="checkbox4" checked>
|
|
<label> ID</label><br>
|
|
<input type="checkbox" class="5" id="checkbox5" checked>
|
|
<label> Time</label><br>
|
|
<input type="checkbox" class="6" id="checkbox6" checked>
|
|
<label> Frame</label><br>
|
|
<input type="checkbox" class="7" id="checkbox7" checked>
|
|
<label> Latitude</label><br>
|
|
<input type="checkbox" class="8" id="checkbox8" checked>
|
|
<label> Longitude</label><br>
|
|
<input type="checkbox" class="9" id="checkbox9" checked>
|
|
<label> Altitude</label><br>
|
|
<input type="checkbox" class="10" id="checkbox10" checked>
|
|
<label> Velocity</label><br>
|
|
<input type="checkbox" class="11" id="checkbox11" checked>
|
|
<label> Ascension</label><br>
|
|
<input type="checkbox" class="12" id="checkbox12" checked>
|
|
<label> Temperature</label><br>
|
|
<input type="checkbox" class="13" id="checkbox13" checked>
|
|
<label> Humidity</label><br>
|
|
<input type="checkbox" class="14" id="checkbox14" checked>
|
|
<label> Azimuth</label><br>
|
|
<input type="checkbox" class="15" id="checkbox15" checked>
|
|
<label> EI</label><br>
|
|
<input type="checkbox" class="16" id="checkbox16" checked>
|
|
<label> Range</label><br>
|
|
<input type="checkbox" class="17" id="checkbox17" checked>
|
|
<label> SNR</label><br>
|
|
<input type="checkbox" class="18" id="checkbox18" checked>
|
|
<label> Other</label><br><br>
|
|
</form>
|
|
<div style="margin-left:60px;">
|
|
<h2 style="display:inline;vertical-align:middle;">Show Table</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" onchange="showTable(this)" id="showtablebutton">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Show Scan Plot</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" onchange="showScan(this)" id="showscanbutton">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Show Map</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" onchange="showMap(this)" id="showmapbutton">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Dark Mode</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" id="showdarkbutton">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Show UTC Time</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" id="showUTCbutton">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Set Pagination Size</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<select id="paginationSelector">
|
|
<option value="1">One</option>
|
|
<option value="2">Two</option>
|
|
<option value="3">Three</option>
|
|
<option value="4">Four</option>
|
|
<option value="5">Five</option>
|
|
<option value="6">Six</option>
|
|
<option value="7">Seven</option>
|
|
<option value="8">Eight</option>
|
|
<option value="9">Nine</option>
|
|
<option value="10">Ten</option>
|
|
</select>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Follow Sonde</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" onchange="autoFollow(this)" id="sondeAutoFollow">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Live KML</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button onclick="window.location.href='/rs.kml'">SHOW</button>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Reset Page</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button onclick="deleteAllCookies()">RESET</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Wrapper for main screen -->
|
|
<div id="main" onload="loadMap();">
|
|
<span style="font-size:3vh;cursor:pointer;" onclick="changeNav()">☰ Radiosonde Auto-RX</span>
|
|
<p style="font-size:2vh;">Current Task: <span id="task_status">???</span></p>
|
|
<div id="tableid">
|
|
<div id="telem_table"></div>
|
|
</div>
|
|
<div id="scanid">
|
|
<h2>Scan Results:</h2>
|
|
<div id='scan_results'>No scan data yet...</div>
|
|
<div id="scan_chart" style="width:100%;"></div>
|
|
</div>
|
|
<br>
|
|
<div id="mapid"></div>
|
|
<i id="myBtn" onclick="changeSettings()" class="fa fa-gear" style="font-size:4vh;"></i>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |