kopia lustrzana https://github.com/projecthorus/radiosonde_auto_rx
1689 wiersze
84 KiB
HTML
1689 wiersze
84 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="{{ url_for('static', filename='css/autorx.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') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/utils.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/autorxapi.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";
|
|
|
|
// Function to change CSS options when changing dark mode.
|
|
function changeTheme(dark) {
|
|
if (dark == false) {
|
|
document.body.style.background = 'white';
|
|
if (document.getElementById("log-tray").style.color == "rgb(255, 0, 0)") {
|
|
$('#main span').css('color', 'black')
|
|
$('#log-tray').css('color', 'red');
|
|
} else {
|
|
$('#main span').css('color', 'black')
|
|
}
|
|
$('#main p').css('color', 'black')
|
|
$('.modal-content p').css('color', 'black')
|
|
$('.modal-content h2').css('color', 'black')
|
|
$('.modal-content span').css('color', 'black')
|
|
$('.modal-content').css('background-color', 'white')
|
|
$('.close').css('color', 'black')
|
|
$('#myBtn1').css('color', 'black')
|
|
$('#myBtn2').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';
|
|
if (document.getElementById("log-tray").style.color == "rgb(255, 0, 0)") {
|
|
$('#main span').css('color', 'white')
|
|
$('#log-tray').css('color', 'red');
|
|
} else {
|
|
$('#main span').css('color', 'white')
|
|
}
|
|
$('#main p').css('color', 'white')
|
|
$('.modal-content p').css('color', 'white')
|
|
$('.modal-content h2').css('color', 'white')
|
|
$('.modal-content span').css('color', 'white')
|
|
$('.modal-content').css('background-color', 'black')
|
|
$('.close').css('color', 'white')
|
|
$('#myBtn1').css('color', 'white')
|
|
$('#myBtn2').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") }}');
|
|
}
|
|
}
|
|
|
|
$( document ).ready(function() {
|
|
|
|
namespace = '/update_status';
|
|
var socket_path = "{{ url_for("static", filename="") }}".replace('static/', 'socket.io')
|
|
var socket = io.connect(location.origin+namespace, {'path': socket_path});
|
|
|
|
$.ajax({
|
|
// Get station.cfg file.
|
|
url: "get_config",
|
|
dataType: 'json',
|
|
async: false,
|
|
success: function(data) {
|
|
autorx_config = data;
|
|
// Update station callsign area
|
|
_station_call = autorx_config['habitat_uploader_callsign'];
|
|
if (autorx_config['aprs_user'] !== "N0CALL"){
|
|
_station_call += " / " + autorx_config['aprs_user'];
|
|
}
|
|
$('#station_callsign').text(_station_call);
|
|
|
|
// Update webpage title
|
|
// document.title = _station_call + " Auto-RX Status";
|
|
document.title = autorx_config['habitat_uploader_callsign'] + " - Radiosonde Auto-RX Status";
|
|
if(autorx_config["web_control"] == false){
|
|
$("#password-header").html("<h2>Web Control Disabled</h2>");
|
|
disable_web_controls();
|
|
}
|
|
}
|
|
});
|
|
|
|
$.ajax({
|
|
// Get local version number.
|
|
url: "get_version",
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
// Update the current version field.
|
|
if (getCookie('version') == 'false') {}
|
|
else if (getCookie('version') == 'true') {
|
|
$('#currentversion').text(data.current);
|
|
} else if ((window.innerWidth/window.innerHeight) > 1) {
|
|
$('#currentversion').text(data.current);
|
|
}
|
|
|
|
// Update the latest version area.
|
|
if(data.latest == 'Latest'){
|
|
//pass
|
|
} else if (data.latest == "Unknown"){
|
|
//pass
|
|
} else {
|
|
if (data.latest.includes("-beta")) {
|
|
$("#footertext").html("Update Available: <a href='https://github.com/projecthorus/radiosonde_auto_rx/commits/testing' target='_blank'>" + data.latest + "</a>");
|
|
} else {
|
|
$("#footertext").html("Update Available: <a href='https://github.com/projecthorus/radiosonde_auto_rx/releases' target='_blank'>" + data.latest + "</a>");
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
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.
|
|
var log_time_converted = log_time.toLocaleString(window.navigator.language,{hourCycle:'h23', year:"numeric", month:"2-digit", day:'2-digit', hour:'2-digit',minute:'2-digit', second:'2-digit'});
|
|
if (msg.level == "INFO" || msg.level == "DEBUG") {
|
|
var log_entry = "<tr><td>" + log_time_converted + " – " + msg.level + "<br><em style='font-size: 15px;'>" + msg.msg + "</em></td></tr>";
|
|
} else {
|
|
// If entry is important colour text red.
|
|
var log_entry = "<tr><td>" + log_time_converted + " – " + msg.level + "<br><em style='font-size: 15px; color:red;'>" + msg.msg + "</em></td></tr>"
|
|
if (msg.level == "ERROR" || msg.level == "CRITICAL") {
|
|
if (document.getElementById("mySidenav").offsetWidth == 0) {
|
|
$('#log-tray').css('color', 'red');
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (msg.level == "INFO" || msg.level == "DEBUG") {
|
|
var log_entry = "<tr><td>" + new Date(msg.timestamp).toISOString().replace("T", " ").replace("Z", "").slice(0, -4) + " UTC – " + msg.level + "<br><em style='font-size: 15px;'>" + msg.msg + "</em></td></tr>";
|
|
} else {
|
|
// If entry is important colour text red.
|
|
var log_entry = "<tr><td>" + new Date(msg.timestamp).toISOString().replace("T", " ").replace("Z", "").slice(0, -4) + " UTC – " + msg.level + "<br><em style='font-size: 15px; color:red;'>" + msg.msg + "</em></td></tr>";
|
|
if (msg.level == "ERROR" || msg.level == "CRITICAL") {
|
|
if (document.getElementById("mySidenav").offsetWidth == 0) {
|
|
$('#log-tray').css('color', 'red');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 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){
|
|
// Load the data into our data stores.
|
|
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[0] = ['x_thresh'].concat([data.freq[0],data.freq[data.freq.length-1]]);
|
|
scan_chart_threshold.columns[1] = ['Threshold'].concat([data.threshold+autorx_config.snr_threshold,data.threshold+autorx_config.snr_threshold]);
|
|
scan_chart_latest_timestamp = data.timestamp;
|
|
|
|
// Do not update the scan plot if the tab is hidden, or we have the scan plot hidden.
|
|
if( (document.visibilityState == "hidden") || (document.getElementById("showscanbutton").checked == false) ){
|
|
return;
|
|
} else {
|
|
redraw_scan_chart(data);
|
|
}
|
|
|
|
}
|
|
);
|
|
});
|
|
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (document.visibilityState === "visible" && document.getElementById("showscanbutton").checked) {
|
|
redraw_scan_chart();
|
|
}
|
|
});
|
|
|
|
socket.on('task_event', function(msg){
|
|
update_task_list();
|
|
});
|
|
|
|
// Update task list now.
|
|
update_task_list();
|
|
|
|
// 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 UTC time selection.
|
|
if (getCookie('imperial') == 'true') {
|
|
document.getElementById("showimperialbutton").checked = true;
|
|
} else {
|
|
document.getElementById("showimperialbutton").checked = false;
|
|
}
|
|
|
|
// Check if user has version shown selection.
|
|
if (getCookie('version') == 'false') {
|
|
document.getElementById("showversionbutton").checked = false;
|
|
} else if (getCookie('version') == 'true') {
|
|
document.getElementById("showversionbutton").checked = true;
|
|
} else if ((window.innerWidth/window.innerHeight) > 1) {
|
|
document.getElementById("showversionbutton").checked = true;
|
|
} else {
|
|
document.getElementById("showversionbutton").checked = false;
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
|
|
// 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 imperial units button has been ticked.
|
|
$('#showimperialbutton').change(function() {
|
|
if ($(this).is(":checked")) {
|
|
setCookie("imperial", 'true', 365);
|
|
location.reload();
|
|
} else {
|
|
setCookie("imperial", 'false', 365);
|
|
location.reload();
|
|
}
|
|
});
|
|
|
|
// Check if show version button has been ticked.
|
|
$('#showversionbutton').change(function() {
|
|
if ($(this).is(":checked")) {
|
|
setCookie("version", 'true', 365);
|
|
location.reload();
|
|
} else {
|
|
setCookie("version", 'false', 365);
|
|
location.reload();
|
|
}
|
|
});
|
|
|
|
// Check if UTC button has been ticked.
|
|
$('#showUTCbutton').change(function() {
|
|
if ($(this).is(":checked")) {
|
|
setCookie("UTC", 'true', 365);
|
|
for (var i = 0; i < Object.keys(sonde_positions).length; i++) {
|
|
table.getRow(Object.keys(sonde_positions)[i]).reformat();
|
|
}
|
|
} else {
|
|
setCookie("UTC", 'false', 365);
|
|
for (var i = 0; i < Object.keys(sonde_positions).length; i++) {
|
|
table.getRow(Object.keys(sonde_positions)[i]).reformat();
|
|
}
|
|
}
|
|
});
|
|
|
|
// Check if settings div has been scrolled.
|
|
$('#scrollsettingsid').scroll(function() {
|
|
if ((document.getElementById("scrollsettingsid").scrollHeight - document.getElementById("scrollsettingsid").scrollTop - document.getElementById("scrollsettingsid").clientHeight) < 1 ) {
|
|
document.getElementById("downdiv").style.display = "none";
|
|
} else {
|
|
document.getElementById("downdiv").style.display = "block";
|
|
}
|
|
});
|
|
|
|
// Check if pagination selector 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", Does not work when some columns are hidden
|
|
// 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", width:125, headerSort:true, formatter:function(cell, formatterParams, onRendered){
|
|
_cell_data = cell.getData();
|
|
_id = _cell_data.id.replace(/^(DFM|M10|M20|IMET|IMET5|IMET54|MRZ|IMS100|RS11G|MTS01|WXR)-/,"");
|
|
_sondehub_id = _cell_data.id.replace(/^(DFM|M10|M20|IMET|IMET5|IMET54|MRZ|IMS100|RS11G|MTS01|WXR)-/,"");
|
|
|
|
// Add Sondehub Link
|
|
_id += " <a href='http://sondehub.org/" + _sondehub_id + "' title='View on Sondehub' target='_blank'>" + "<img src='{{ url_for('static', filename='img/sondehub.png')}}'/>" + "</a>";
|
|
|
|
// Add Radiosondy Link
|
|
if(_cell_data.aprsid != null){
|
|
_aprs_id = _cell_data.aprsid.trim();
|
|
_id += "<a href='https://radiosondy.info/sonde_archive.php?sondenumber=" + _aprs_id + "' title='View on Radiosondy.info' target='_blank'>" + "<img src='{{ url_for('static', filename='img/radiosondy.png')}}'/>" + "</a>";
|
|
|
|
} else {
|
|
_aprs_id = null;
|
|
}
|
|
|
|
return _id;
|
|
}},
|
|
{title:"Time", field:"datetime", width:180, headerSort:true, formatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('UTC') == 'false') {
|
|
var temp_time = new Date(cell.getValue());
|
|
var temp_converted = temp_time.toLocaleString(window.navigator.language,{hourCycle:'h23', year:"numeric", month:"2-digit", day:'2-digit', hour:'2-digit',minute:'2-digit', second:'2-digit'});
|
|
if (temp_converted == "Invalid Date") {
|
|
return;
|
|
} else {
|
|
return temp_converted;
|
|
}
|
|
} 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", field:"alt", headerSort:true, formatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return (Math.round((cell.getValue()*3.28084) * 10) / 10);
|
|
} else {
|
|
return cell.getValue();
|
|
}
|
|
}, titleFormatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return cell.getValue() + " (ft)";
|
|
} else {
|
|
return cell.getValue() + " (m)";
|
|
}
|
|
}
|
|
},
|
|
{title:"Vel", field:"vel_h", headerSort:false, formatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return (Math.round((cell.getValue()*0.62137) * 10) / 10);
|
|
} else {
|
|
return cell.getValue();
|
|
}
|
|
}, titleFormatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return cell.getValue() + " (mph)";
|
|
} else {
|
|
return cell.getValue() + " (kph)";
|
|
}
|
|
}
|
|
},
|
|
{title:"Asc", field:"vel_v", headerSort:false, formatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return (Math.round((cell.getValue()*196.85) * 10) / 10);
|
|
} else {
|
|
return cell.getValue();
|
|
}
|
|
}, titleFormatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return cell.getValue() + " (ft/min)";
|
|
} else {
|
|
return cell.getValue() + " (m/s)";
|
|
}
|
|
}
|
|
},
|
|
{title:"Temp", field:"temp", headerSort:false, formatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return (Math.round(((cell.getValue()*9/5) + 32) * 10) / 10);
|
|
} else {
|
|
return cell.getValue();
|
|
}
|
|
}, titleFormatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return cell.getValue() + " (°F)";
|
|
} else {
|
|
return cell.getValue() + " (°C)";
|
|
}
|
|
}
|
|
},
|
|
{title:"RH (%)", field:"humidity", headerSort:false},
|
|
{title:"Az (°)", field:"azimuth", headerSort:false},
|
|
{title:"El (°)", field:"elevation", headerSort:false},
|
|
{title:"Range", field:"range", headerSort:true, formatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return (Math.round((cell.getValue()*0.621371) * 10) / 10);
|
|
} else {
|
|
return cell.getValue();
|
|
}
|
|
}, titleFormatter:function(cell, formatterParams, onRendered){
|
|
if (getCookie('imperial') == 'true') {
|
|
return cell.getValue() + " (mi)";
|
|
} else {
|
|
return cell.getValue() + " (km)";
|
|
}
|
|
}
|
|
},
|
|
{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";
|
|
// Remove the LOS line
|
|
if(sonde_positions[sonde_id].hasOwnProperty("los_path")){
|
|
sonde_positions[sonde_id].los_path.remove();
|
|
delete sonde_positions[sonde_id].los_path;
|
|
}
|
|
|
|
}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);
|
|
if (_look_angles.elevation >= 10){
|
|
sonde_id_data.elevation = _look_angles.elevation.toFixed(1);
|
|
}else{
|
|
sonde_id_data.elevation = _look_angles.elevation.toFixed(2);
|
|
}
|
|
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.sondehub_enabled == true) {
|
|
// sonde_id_data.id = "<a href='http://sondehub.org/" + sonde_id.replace(/^(DFM|M10|M20|IMET|IMET54|MRZ)-/,"") + "' target='_blank'>" + sonde_id + "</a>";
|
|
// // These links are only going to work for Vaisala radiosondes since the APRS callsign is never passed through to the web interface,
|
|
// // and the APRS callsigns for everything other than RS41s and RS92s is different to the 'full' serials
|
|
// } 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);
|
|
|
|
if (getCookie('imperial') == 'true'){
|
|
_alt = (telem.alt*3.28084).toFixed(0) + 'ft ';
|
|
_vel_v = (telem.vel_v*3.28084).toFixed(0) + 'ft/s ';
|
|
_vel_h = (telem.vel_h*2.23694).toFixed(0) + 'mph ';
|
|
} else {
|
|
_alt = telem.alt.toFixed(0) + 'm ';
|
|
_vel_v = telem.vel_v.toFixed(1) + 'm/s ';
|
|
_vel_h = (telem.vel_h*3.6).toFixed(0) + 'km/h ';
|
|
}
|
|
|
|
sonde_positions[sonde_id].marker = L.marker([telem.lat, telem.lon, telem.alt],{icon: sondeAscentIcons[sonde_positions[sonde_id].colour]})
|
|
.bindTooltip('<div class="tooltip-container">' + sonde_id + '<div class="tooltip-container" style="color: #005ec1;">' + _alt + _vel_v + _vel_h + '</div></div>',{permanent:false, direction:'right', className: 'sondeTooltip', offset: [10,0], interactive: false, opacity: 0.7 })
|
|
.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);
|
|
if (getCookie('imperial') == 'true'){
|
|
_alt = (msg.alt*3.28084).toFixed(0) + 'ft ';
|
|
_vel_v = (msg.vel_v*3.28084).toFixed(0) + 'ft/s ';
|
|
_vel_h = (msg.vel_h*2.23694).toFixed(0) + 'mph ';
|
|
} else {
|
|
_alt = msg.alt.toFixed(0) + 'm ';
|
|
_vel_v = msg.vel_v.toFixed(1) + 'm/s ';
|
|
_vel_h = (msg.vel_h*3.6).toFixed(0) + 'km/h ';
|
|
}
|
|
sonde_positions[msg.id].marker = L.marker([msg.lat, msg.lon, msg.alt],{title:msg.id, icon: sondeAscentIcons[sonde_positions[msg.id].colour]})
|
|
.bindTooltip('<div class="tooltip-container">' + msg.id + '<div class="tooltip-container" style="color: #005ec1;">' + _alt + _vel_v + _vel_h + '</div></div>',{permanent:false, direction:'right', className: 'sondeTooltip', offset: [10,0], interactive: false, opacity: 0.7})
|
|
.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 (getCookie('imperial') == 'true'){
|
|
_alt = (msg.alt*3.28084).toFixed(0) + 'ft ';
|
|
_vel_v = (msg.vel_v*3.28084).toFixed(0) + 'ft/s ';
|
|
_vel_h = (msg.vel_h*2.23694).toFixed(0) + 'mph ';
|
|
} else {
|
|
_alt = msg.alt.toFixed(0) + 'm ';
|
|
_vel_v = msg.vel_v.toFixed(1) + 'm/s ';
|
|
_vel_h = (msg.vel_h*3.6).toFixed(0) + 'km/h ';
|
|
}
|
|
sonde_positions[msg.id].marker.setTooltipContent('<div class="tooltip-container">' + msg.id + '<div class="tooltip-container" style="color: #005ec1;">' + _alt + _vel_v + _vel_h +'</div></div>');
|
|
|
|
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){
|
|
if(sonde_positions[msg.id].hasOwnProperty("los_path")){
|
|
sonde_positions[msg.id].los_path.setLatLngs([[autorx_config.station_lat, autorx_config.station_lon],[msg.lat, msg.lon]]);
|
|
} else {
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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], { duration: 2.5, easeLinearity: 0.9 });
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
// 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';
|
|
}
|
|
|
|
var index = $(this).attr("class");
|
|
|
|
// Set cookie for columns to show in future.
|
|
setCookie("col" + index, cookiesend, 365);
|
|
|
|
// 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() > 1200) {
|
|
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() {
|
|
if (getCookie('dark') == 'false') {
|
|
$('#log-tray').css('color', 'black');
|
|
} else if (getCookie('dark') == 'true') {
|
|
$('#log-tray').css('color', 'white');
|
|
} else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
$('#log-tray').css('color', 'white');
|
|
} else {
|
|
$('#log-tray').css('color', 'black');
|
|
}
|
|
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);
|
|
setTimeout(showDown,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);
|
|
setTimeout(showDown,500);
|
|
}
|
|
}
|
|
|
|
function showDown () {
|
|
if ((document.getElementById("scrollsettingsid").scrollHeight - document.getElementById("scrollsettingsid").scrollTop - document.getElementById("scrollsettingsid").clientHeight) < 1 ) {
|
|
document.getElementById("downdiv").style.display = "none";
|
|
} else {
|
|
document.getElementById("downdiv").style.display = "block";
|
|
}
|
|
}
|
|
|
|
// 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();
|
|
redraw_scan_chart();
|
|
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) {
|
|
localStorage.setItem(name, value);
|
|
}
|
|
|
|
// Return cookie value given name.
|
|
function getCookie(name) {
|
|
return localStorage.getItem(name);
|
|
}
|
|
|
|
// Reset specific cookie.
|
|
function eraseCookie(name) {
|
|
localStorage.removeItem(name);
|
|
}
|
|
|
|
// Reset all cookies.
|
|
function deleteAllCookies() {
|
|
localStorage.clear();
|
|
location.reload();
|
|
}
|
|
|
|
// When the user clicks on the button, open the modal
|
|
function openModal() {
|
|
document.getElementById("myModal").style.display = "block";
|
|
changeSettings()
|
|
if (getCookie("password") === null) {} else {
|
|
verify_password();
|
|
}
|
|
}
|
|
|
|
// When the user clicks on close button, close the modal
|
|
function closeModal() {
|
|
document.getElementById("myModal").style.display = "none";
|
|
$('#password-input').val('');
|
|
}
|
|
|
|
// When the user clicks anywhere outside of the modal, close it
|
|
$(window).click(function(e) {
|
|
if (e.target == document.getElementById("myModal")) {
|
|
document.getElementById("myModal").style.display = "none";
|
|
$('#password-input').val('');
|
|
}
|
|
});
|
|
|
|
let vh = window.innerHeight * 0.01;
|
|
|
|
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
|
</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>
|
|
|
|
<!-- Wrapper for settings sidebar -->
|
|
<div id="mySettings" class="settings">
|
|
<a href="javascript:void(0)" class="closebtn2" id="closebtn2" onclick="changeSettings()">✖</a>
|
|
<h1 style="color: white; text-align: center; margin: -0.25em;">Settings</h1>
|
|
<div class="scrollsettings" id="scrollsettingsid" style="margin-top: 20px;">
|
|
<h2 style="display:inline; vertical-align:middle; margin-left: 35px; margin-bottom: 0.3em;">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> Ascent Rate</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:40px;">
|
|
<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" style="font-size: 1.2rem;">
|
|
<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;">Show Imperial Units</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" id="showimperialbutton">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Show Software Version</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<label class="switch">
|
|
<input type="checkbox" id="showversionbutton">
|
|
<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>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Controls</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button id="open-controls" onclick="openModal()">OPEN</button>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<h2 style="display:inline;vertical-align:middle;">Historical View</h2>
|
|
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button onclick="window.location.href='historical.html'">OPEN</button>
|
|
</div>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
</div>
|
|
</div>
|
|
<div id="downdiv">
|
|
<i class="icon-angle-down" style="font-size:60px;opacity:1;"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Wrapper for main screen -->
|
|
<div id="main" onload="loadMap();">
|
|
<div>
|
|
<span style="font-size:3vh;font-size:calc(var(--vh, 1vh) * 3);cursor:pointer;" onclick="changeNav()"><span id="log-tray">☰</span> Radiosonde Auto-RX <span id="currentversion" style="white-space:nowrap"></span></span>
|
|
</div>
|
|
<span style="font-size:2vh;font-size:calc(var(--vh, 1vh) * 2);" id="footertext"></span>
|
|
<p style="font-size:2vh;font-size:calc(var(--vh, 1vh) * 2);">Station: <span id="station_callsign">???</span></p>
|
|
<p style="font-size:2vh;font-size:calc(var(--vh, 1vh) * 2);">Tasking: <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="myBtn1" onclick="changeSettings()" class="icon-cog" style="font-size:4vh;font-size:calc(var(--vh, 1vh) * 4);"></i>
|
|
<a href="historical.html" id="myBtn2"><i class="icon-history" style="font-size:4vh;font-size:calc(var(--vh, 1vh) * 4);"></i></a>
|
|
</div>
|
|
|
|
<!-- Wrapper for advanced control modal -->
|
|
<div id="myModal" class="modal">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<span class="close" onclick="closeModal()">×</span>
|
|
<h2>Advanced Controls</h2>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div id="password-field">
|
|
<span id="password-header"><h2>No Password Entered</h2></span>
|
|
<input style="display:inline;vertical-align:middle;" type="text" id="password-input" placeholder="Password" >
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button id="verify-password" onclick="verify_password();$('#password-input').val('');">Submit</button>
|
|
</div>
|
|
</div>
|
|
<div id="controls" style="visibility:hidden;display:none;">
|
|
<h2>Decoder Control</h2>
|
|
<p>Start Decoder</p>
|
|
<input style="display:inline;vertical-align:middle;" type="text" id="frequency-input" placeholder="Frequency (MHz)">
|
|
<select style="display:inline;vertical-align:middle;" class="control" id="sonde-type-select">
|
|
<option value="RS41" selected>RS41</option>
|
|
<option value="RS92">RS92</option>
|
|
<option value="DFM">DFM</option>
|
|
<option value="M10">M10</option>
|
|
<option value="M20">M20</option>
|
|
<option value="LMS6">LMS6 (400 MHz)</option>
|
|
<option value="MK2LMS">LMS6 (1680 MHz)</option>
|
|
<option value="IMET">iMet-4</option>
|
|
<option value="IMET5">iMet-50/54</option>
|
|
<option value="MEISEI">iMS-100</option>
|
|
<option value="MRZ">MRZ-H1</option>
|
|
<option value="MTS01">MTS01</option>
|
|
<option value="WXR301">WXR301</option>
|
|
</select>
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button id="start-decoder" onclick="start_decoder();">Start</button>
|
|
</div>
|
|
<br>
|
|
<p>Stop Decoder</p>
|
|
<select style="display:inline;vertical-align:middle;" class="control" id="stop-frequency-select">
|
|
<option value="0" disabled selected>No Decoders</option>
|
|
</select>
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button id="stop-decoder" onclick="stop_decoder();">Stop</button>
|
|
</div>
|
|
<h2>Scanner Control</h2>
|
|
<p>Scanner</p>
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button id="enable-scanner" onclick="enable_scanner();">Enable</button>
|
|
</div>
|
|
<div style="display:inline;vertical-align:middle;">
|
|
<button id="disable-scanner" onclick="disable_scanner();">Disable</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|