// First, checks if it isn't implemented yet. if (!String.prototype.format) { String.prototype.format = function() { var args = arguments; return this.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] != 'undefined' ? args[number] : match ; }); }; } var nvs_type_t = { NVS_TYPE_U8 : 0x01, /*!< Type uint8_t */ NVS_TYPE_I8 : 0x11, /*!< Type int8_t */ NVS_TYPE_U16 : 0x02, /*!< Type uint16_t */ NVS_TYPE_I16 : 0x12, /*!< Type int16_t */ NVS_TYPE_U32 : 0x04, /*!< Type uint32_t */ NVS_TYPE_I32 : 0x14, /*!< Type int32_t */ NVS_TYPE_U64 : 0x08, /*!< Type uint64_t */ NVS_TYPE_I64 : 0x18, /*!< Type int64_t */ NVS_TYPE_STR : 0x21, /*!< Type string */ NVS_TYPE_BLOB : 0x42, /*!< Type blob */ NVS_TYPE_ANY : 0xff /*!< Must be last */ } ; var task_state_t = { 0 : "eRunning", /*!< A task is querying the state of itself, so must be running. */ 1 : "eReady", /*!< The task being queried is in a read or pending ready list. */ 2 : "eBlocked", /*!< The task being queried is in the Blocked state. */ 3 : "eSuspended", /*!< The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ 4 : "eDeleted" } var releaseURL = 'https://api.github.com/repos/sle118/squeezelite-esp32/releases'; var recovery = false; var enableAPTimer = true; var enableStatusTimer = true; var commandHeader = 'squeezelite -b 500:2000 -d all=info '; var pname, ver, otapct, otadsc; var blockAjax = false; var blockFlashButton = false; var apList = null; var selectedSSID = ""; var refreshAPInterval = null; var checkStatusInterval = null; var StatusIntervalActive = false; var RefreshAPIIntervalActive = false; var LastRecoveryState=null; var output = ''; function stopCheckStatusInterval(){ if(checkStatusInterval != null){ clearTimeout(checkStatusInterval); checkStatusInterval = null; } StatusIntervalActive = false; } function stopRefreshAPInterval(){ if(refreshAPInterval != null){ clearTimeout(refreshAPInterval); refreshAPInterval = null; } RefreshAPIIntervalActive = false; } function startCheckStatusInterval(){ StatusIntervalActive = true; checkStatusInterval = setTimeout(checkStatus, 3000); } function startRefreshAPInterval(){ RefreshAPIIntervalActive = true; refreshAPInterval = setTimeout(refreshAP(false), 4500); // leave enough time for the initial scan } function RepeatCheckStatusInterval(){ if(StatusIntervalActive) startCheckStatusInterval(); } function RepeatRefreshAPInterval(){ if(RefreshAPIIntervalActive) startRefreshAPInterval(); } $(document).ready(function(){ $("#wifi-status").on("click", ".ape", function() { $( "#wifi" ).slideUp( "fast", function() {}); $( "#connect-details" ).slideDown( "fast", function() {}); }); $("#manual_add").on("click", ".ape", function() { selectedSSID = $(this).text(); $( "#ssid-pwd" ).text(selectedSSID); $( "#wifi" ).slideUp( "fast", function() {}); $( "#connect_manual" ).slideDown( "fast", function() {}); $( "#connect" ).slideUp( "fast", function() {}); //update wait screen $( "#loading" ).show(); $( "#connect-success" ).hide(); $( "#connect-fail" ).hide(); }); $("#wifi-list").on("click", ".ape", function() { selectedSSID = $(this).text(); $( "#ssid-pwd" ).text(selectedSSID); $( "#wifi" ).slideUp( "fast", function() {}); $( "#connect_manual" ).slideUp( "fast", function() {}); $( "#connect" ).slideDown( "fast", function() {}); //update wait screen $( "#loading" ).show(); $( "#connect-success" ).hide(); $( "#connect-fail" ).hide(); }); $("#cancel").on("click", function() { selectedSSID = ""; $( "#connect" ).slideUp( "fast", function() {}); $( "#connect_manual" ).slideUp( "fast", function() {}); $( "#wifi" ).slideDown( "fast", function() {}); }); $("#manual_cancel").on("click", function() { selectedSSID = ""; $( "#connect" ).slideUp( "fast", function() {}); $( "#connect_manual" ).slideUp( "fast", function() {}); $( "#wifi" ).slideDown( "fast", function() {}); }); $("#join").on("click", function() { performConnect(); }); $("#manual_join").on("click", function() { performConnect($(this).data('connect')); }); $("#ok-details").on("click", function() { $( "#connect-details" ).slideUp( "fast", function() {}); $( "#wifi" ).slideDown( "fast", function() {}); }); $("#ok-credits").on("click", function() { $( "#credits" ).slideUp( "fast", function() {}); $( "#app" ).slideDown( "fast", function() {}); }); $("#acredits").on("click", function(event) { event.preventDefault(); $( "#app" ).slideUp( "fast", function() {}); $( "#credits" ).slideDown( "fast", function() {}); }); $("#ok-connect").on("click", function() { $( "#connect-wait" ).slideUp( "fast", function() {}); $( "#wifi" ).slideDown( "fast", function() {}); }); $("#disconnect").on("click", function() { $( "#connect-details-wrap" ).addClass('blur'); $( "#diag-disconnect" ).slideDown( "fast", function() {}); }); $("#no-disconnect").on("click", function() { $( "#diag-disconnect" ).slideUp( "fast", function() {}); $( "#connect-details-wrap" ).removeClass('blur'); }); $("#yes-disconnect").on("click", function() { stopCheckStatusInterval(); selectedSSID = ""; $( "#diag-disconnect" ).slideUp( "fast", function() {}); $( "#connect-details-wrap" ).removeClass('blur'); $.ajax({ url: '/connect.json', dataType: 'text', method: 'DELETE', cache: false, contentType: 'application/json; charset=utf-8', data: JSON.stringify({ 'timestamp': Date.now()}) }); startCheckStatusInterval(); $( "#connect-details" ).slideUp( "fast", function() {}); $( "#wifi" ).slideDown( "fast", function() {}) }); $("input#show-nvs").on("click", function() { this.checked=this.checked?1:0; if(this.checked){ $('a[href^="#tab-nvs"]').show(); } else { $('a[href^="#tab-nvs"]').hide(); } }); $("input#autoexec-cb").on("click", function() { var data = { 'timestamp': Date.now() }; autoexec = (this.checked)?1:0; data['config'] = {}; data['config'] = { autoexec : { value : autoexec, type : 33 } } showMessage('please wait for the ESP32 to reboot', 'MESSAGING_WARNING'); $.ajax({ url: '/config.json', dataType: 'text', method: 'POST', cache: false, // headers: { "X-Custom-autoexec": autoexec }, contentType: 'application/json; charset=utf-8', data: JSON.stringify(data), error: function (xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); }, complete: function(response) { //var returnedResponse = JSON.parse(response.responseText); console.log(response.responseText); console.log('sent config JSON with headers:', autoexec); console.log('now triggering reboot'); $.ajax({ url: '/reboot_ota.json', dataType: 'text', method: 'POST', cache: false, contentType: 'application/json; charset=utf-8', data: JSON.stringify({ 'timestamp': Date.now()}), error: function (xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); }, complete: function(response) { console.log('reboot call completed'); } }); } }); }); $("input#save-autoexec1").on("click", function() { var data = { 'timestamp': Date.now() }; autoexec1 = $("#autoexec1").val(); data['config'] = {}; data['config'] = { autoexec1 : { value : autoexec1, type : 33 } } $.ajax({ url: '/config.json', dataType: 'text', method: 'POST', cache: false, // headers: { "X-Custom-autoexec1": autoexec1 }, contentType: 'application/json; charset=utf-8', data: JSON.stringify(data), error: function (xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); } }); console.log('sent config JSON with headers:', autoexec1); console.log('sent data:', JSON.stringify(data)); }); $("input#save-gpio").on("click", function() { var data = { 'timestamp': Date.now() }; var config = {}; var headers = {}; $("input.gpio").each(function() { var id = $(this)[0].id; var pin = $(this).val(); if (pin != '') { config[id] = {}; config[id].value = pin; config[id].type = nvs_type_t.NVS_TYPE_STR; } }); data['config'] = config; $.ajax({ url: '/config.json', dataType: 'text', method: 'POST', cache: false, headers: headers, contentType: 'application/json; charset=utf-8', data: JSON.stringify(data), error: function (xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); } }); console.log('sent config JSON with headers:', JSON.stringify(headers)); console.log('sent config JSON with data:', JSON.stringify(data)); }); $("#save-nvs").on("click", function() { var headers = {}; var data = { 'timestamp': Date.now() }; var config = {}; $("input.nvs").each(function() { var key = $(this)[0].id; var val = $(this).val(); var nvs_type = parseInt($(this)[0].attributes.nvs_type.nodeValue,10); if (key != '') { config[key] = {}; if(nvs_type == nvs_type_t.NVS_TYPE_U8 || nvs_type == nvs_type_t.NVS_TYPE_I8 || nvs_type == nvs_type_t.NVS_TYPE_U16 || nvs_type == nvs_type_t.NVS_TYPE_I16 || nvs_type == nvs_type_t.NVS_TYPE_U32 || nvs_type == nvs_type_t.NVS_TYPE_I32 || nvs_type == nvs_type_t.NVS_TYPE_U64 || nvs_type == nvs_type_t.NVS_TYPE_I64) { config[key].value = parseInt(val); } else { config[key].value = val; } config[key].type = nvs_type; } }); var key = $("#nvs-new-key").val(); var val = $("#nvs-new-value").val(); if (key != '') { // headers["X-Custom-" +key] = val; config[key] = {}; config[key].value = val; config[key].type = 33; } data['config'] = config; $.ajax({ url: '/config.json', dataType: 'text', method: 'POST', cache: false, headers: headers, contentType: 'application/json; charset=utf-8', data : JSON.stringify(data), error: function (xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); } }); console.log('sent config JSON with headers:', JSON.stringify(headers)); console.log('sent config JSON with data:', JSON.stringify(data)); }); $("#fwUpload").on("click", function() { var upload_path = "/flash.json"; var fileInput = document.getElementById("flashfilename").files; if (fileInput.length == 0) { alert("No file selected!"); } else { var file = fileInput[0]; var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (xhttp.readyState == 4) { if (xhttp.status == 200) { showMessage(xhttp.responseText, 'MESSAGING_INFO') } else if (xhttp.status == 0) { showMessage("Upload connection was closed abruptly!", 'MESSAGING_ERROR'); } else { showMessage(xhttp.status + " Error!\n" + xhttp.responseText, 'MESSAGING_ERROR'); } } }; xhttp.open("POST", upload_path, true); xhttp.send(file); } enableStatusTimer = true; }); $("#flash").on("click", function() { var data = { 'timestamp': Date.now() }; if (blockFlashButton) return; blockFlashButton = true; var url = $("#fwurl").val(); data['config'] = { fwurl : { value : url, type : 33 } }; $.ajax({ url: '/config.json', dataType: 'text', method: 'POST', cache: false, contentType: 'application/json; charset=utf-8', data: JSON.stringify(data), error: function (xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); } }); enableStatusTimer = true; }); $("#generate-command").on("click", function() { var commandLine = commandHeader + '-n "' + $("#player").val() + '"'; if (output == 'bt') { commandLine += ' -o "BT -n \'' + $("#btsink").val() + '\'" -R -Z 192000'; } else if (output == 'spdif') { commandLine += ' -o SPDIF -R -Z 192000'; } else { commandLine += ' -o I2S'; } if ($("#optional").val() != '') { commandLine += ' ' + $("#optional").val(); } $("#autoexec1").val(commandLine); }); $('[name=audio]').on("click", function(){ if (this.id == 'bt') { $("#btsinkdiv").show(200); output = 'bt'; } else if (this.id == 'spdif') { $("#btsinkdiv").hide(200); output = 'spdif'; } else { $("#btsinkdiv").hide(200); output = 'i2s'; } }); $('#fwcheck').on("click", function(){ $("#releaseTable").html(""); $.getJSON(releaseURL, function(data) { var i=0; data.forEach(function(release) { var url = ''; release.assets.forEach(function(asset) { if (asset.name.match(/\.bin$/)) { url = asset.browser_download_url; } }); var [ver, idf, cfg, branch] = release.name.split('#'); var body = release.body; body = body.replace(/\'/ig, "\""); body = body.replace(/[\s\S]+(### Revision Log[\s\S]+)### ESP-IDF Version Used[\s\S]+/, "$1"); body = body.replace(/- \(.+?\) /g, "- "); var [date, time] = release.created_at.split('T'); var trclass = (i++ > 6)?' hide':''; $("#releaseTable").append( ""+ ""+ver+""+ ""+date+""+ ""+cfg+""+ ""+idf+""+ ""+branch+""+ ""+ "" ); }); if (i > 7) { $("#releaseTable").append( ""+ ""+ ""+ ""+ "" ); $('#showallbutton').on("click", function(){ $("tr.hide").removeClass("hide"); $("tr#showall").addClass("hide"); }); } $("#searchfw").css("display", "inline"); }) .fail(function() { alert("failed to fetch release history!"); }); }); $('input#searchinput').on("input", function(){ var s = $('input#searchinput').val(); var re = new RegExp(s, "gi"); if (s.length == 0) { $("tr.release").removeClass("hide"); } else if (s.length < 3) { $("tr.release").addClass("hide"); } else { $("tr.release").addClass("hide"); $("tr.release").each(function(tr){ $(this).find('td').each (function() { if ($(this).html().match(re)) { $(this).parent().removeClass('hide'); } }); }); } }); $('#boot-button').on("click", function(){ enableStatusTimer = true; }); $('#reboot-button').on("click", function(){ enableStatusTimer = true; }); $('#updateAP').on("click", function(){ refreshAP(true); console.log("refresh AP"); }); //first time the page loads: attempt to get the connection status and start the wifi scan refreshAP(false); getConfig(); //start timers startCheckStatusInterval(); //startRefreshAPInterval(); $('[data-toggle="tooltip"]').tooltip({ html: true, placement : 'right', }); }); function setURL(button) { var url = button.dataset.url; $("#fwurl").val(url); $('[data-url^="http"]').addClass("btn-success").removeClass("btn-danger"); $('[data-url="'+url+'"]').addClass("btn-danger").removeClass("btn-success"); } function performConnect(conntype){ //stop the status refresh. This prevents a race condition where a status //request would be refreshed with wrong ip info from a previous connection //and the request would automatically shows as succesful. stopCheckStatusInterval(); //stop refreshing wifi list stopRefreshAPInterval(); var pwd; var dhcpname; if (conntype == 'manual') { //Grab the manual SSID and PWD selectedSSID=$('#manual_ssid').val(); pwd = $("#manual_pwd").val(); dhcpname= $("#dhcp-name2").val();; }else{ pwd = $("#pwd").val(); dhcpname= $("#dhcp-name1").val();; } //reset connection $( "#loading" ).show(); $( "#connect-success" ).hide(); $( "#connect-fail" ).hide(); $( "#ok-connect" ).prop("disabled",true); $( "#ssid-wait" ).text(selectedSSID); $( "#connect" ).slideUp( "fast", function() {}); $( "#connect_manual" ).slideUp( "fast", function() {}); $( "#connect-wait" ).slideDown( "fast", function() {}); $.ajax({ url: '/connect.json', dataType: 'text', method: 'POST', cache: false, // headers: { 'X-Custom-ssid': selectedSSID, 'X-Custom-pwd': pwd, 'X-Custom-host_name': dhcpname }, contentType: 'application/json; charset=utf-8', data: JSON.stringify({ 'timestamp': Date.now(), 'ssid' : selectedSSID, 'pwd' : pwd, 'host_name' : dhcpname }), error: function (xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); } }); //now we can re-set the intervals regardless of result startCheckStatusInterval(); startRefreshAPInterval(); } function rssiToIcon(rssi){ if(rssi >= -60){ return 'w0'; } else if(rssi >= -67){ return 'w1'; } else if(rssi >= -75){ return 'w2'; } else{ return 'w3'; } } function refreshAP(force){ if (!enableAPTimer && !force) return; $.getJSON( "/ap.json", function( data ) { if(data.length > 0){ //sort by signal strength data.sort(function (a, b) { var x = a["rssi"]; var y = b["rssi"]; return ((x < y) ? 1 : ((x > y) ? -1 : 0)); }); apList = data; refreshAPHTML(apList); } }); } function refreshAPHTML(data){ var h = ""; data.forEach(function(e, idx, array) { h += '
{3}
'.format(idx === array.length - 1?'':' brdb', rssiToIcon(e.rssi), e.auth==0?'':'pw',e.ssid); h += "\n"; }); $( "#wifi-list" ).html(h) } function getMessages() { $.getJSON("/messages.json?1", function(data) { data.forEach(function(msg) { var msg_age = msg["current_time"] - msg["sent_time"]; var msg_time = new Date(); msg_time.setTime( msg_time.getTime() - msg_age ); switch (msg["class"]) { case "MESSAGING_CLASS_OTA": //message: "{"ota_dsc":"Erasing flash complete","ota_pct":0}" var ota_data = JSON.parse(msg["message"]); if (ota_data.hasOwnProperty('ota_pct') && ota_data['ota_pct'] != 0){ otapct = ota_data['ota_pct']; $('.progress-bar').css('width', otapct+'%').attr('aria-valuenow', otapct); $('.progress-bar').html(otapct+'%'); } if (ota_data.hasOwnProperty('ota_dsc') && ota_data['ota_dsc'] != ''){ otadsc = ota_data['ota_dsc']; $("span#flash-status").html(otadsc); if (otadsc.match(/Error:/) || otapct > 95) { blockFlashButton = false; enableStatusTimer = true; } } break; case "MESSAGING_CLASS_STATS": // for task states, check structure : task_state_t var stats_data = JSON.parse(msg["message"]); console.log(msg_time.toLocaleString() + " - Number of tasks on the ESP32: " + stats_data["ntasks"]); var stats_tasks = stats_data["tasks"]; console.log(msg_time.toLocaleString() + '\tname' + '\tcpu' + '\tstate'+ '\tminstk'+ '\tbprio'+ '\tcprio'+ '\tnum' ); stats_tasks.forEach(function(task) { console.log(msg_time.toLocaleString() + '\t' + task["nme"] + '\t'+ task["cpu"] + '\t'+ task_state_t[task["st"]]+ '\t'+ task["minstk"]+ '\t'+ task["bprio"]+ '\t'+ task["cprio"]+ '\t'+ task["num"]); }); break; case "MESSAGING_CLASS_SYSTEM": showMessage(msg["message"], msg["type"],msg_age); $("#syslogTable").append( ""+ ""+msg_time.toLocaleString()+""+ ""+msg["message"]+""+ "" ); break; default: break; } }); }) .fail(function(xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); }); /* Minstk is minimum stack space left Bprio is base priority cprio is current priority nme is name st is task state. I provided a "typedef" that you can use to convert to text cpu is cpu percent used */ } function checkStatus(){ RepeatCheckStatusInterval(); if (!enableStatusTimer) return; if (blockAjax) return; blockAjax = true; getMessages(); $.getJSON( "/status.json", function( data ) { if (data.hasOwnProperty('ssid') && data['ssid'] != ""){ if (data["ssid"] === selectedSSID){ //that's a connection attempt if (data["urc"] === 0){ //got connection $("#connected-to span").text(data["ssid"]); $("#connect-details h1").text(data["ssid"]); $("#ip").text(data["ip"]); $("#netmask").text(data["netmask"]); $("#gw").text(data["gw"]); $("#wifi-status").slideDown( "fast", function() {}); $("span#foot-wifi").html(", SSID: "+data["ssid"]+", IP: "+data["ip"]+""); //unlock the wait screen if needed $( "#ok-connect" ).prop("disabled",false); //update wait screen $( "#loading" ).hide(); $( "#connect-success" ).text("Your IP address now is: " + data["ip"] ); $( "#connect-success" ).show(); $( "#connect-fail" ).hide(); enableAPTimer = false; if (!recovery) enableStatusTimer = false; } else if (data["urc"] === 1){ //failed attempt $("#connected-to span").text(''); $("#connect-details h1").text(''); $("#ip").text('0.0.0.0'); $("#netmask").text('0.0.0.0'); $("#gw").text('0.0.0.0'); $("span#foot-wifi").html(""); //don't show any connection $("#wifi-status").slideUp( "fast", function() {}); //unlock the wait screen $( "#ok-connect" ).prop("disabled",false); //update wait screen $( "#loading" ).hide(); $( "#connect-fail" ).show(); $( "#connect-success" ).hide(); enableAPTimer = true; enableStatusTimer = true; } } else if (data.hasOwnProperty('urc') && data['urc'] === 0){ //ESP32 is already connected to a wifi without having the user do anything if( !($("#wifi-status").is(":visible")) ){ $("#connected-to span").text(data["ssid"]); $("#connect-details h1").text(data["ssid"]); $("#ip").text(data["ip"]); $("#netmask").text(data["netmask"]); $("#gw").text(data["gw"]); $("#wifi-status").slideDown( "fast", function() {}); $("span#foot-wifi").html(", SSID: "+data["ssid"]+", IP: "+data["ip"]+""); } enableAPTimer = false; if (!recovery) enableStatusTimer = false; } } else if (data.hasOwnProperty('urc') && data['urc'] === 2){ //that's a manual disconnect if($("#wifi-status").is(":visible")){ $("#wifi-status").slideUp( "fast", function() {}); $("span#foot-wifi").html(""); } enableAPTimer = true; enableStatusTimer = true; } if (data.hasOwnProperty('recovery')) { if(LastRecoveryState != data["recovery"]){ LastRecoveryState = data["recovery"]; $("input#show-nvs")[0].checked=LastRecoveryState==1?true:false; } if($("input#show-nvs")[0].checked){ $('a[href^="#tab-nvs"]').show(); } else{ $('a[href^="#tab-nvs"]').hide(); } if (data["recovery"] === 1) { recovery = true; $("#otadiv").show(); $('a[href^="#tab-audio"]').hide(); $('a[href^="#tab-gpio"]').show(); $('#uploaddiv').show(); $("footer.footer").removeClass('sl'); $("footer.footer").addClass('recovery'); $("#boot-button").html('Reboot'); $("#boot-form").attr('action', '/reboot_ota.json'); enableStatusTimer = true; } else { recovery = false; $("#otadiv").hide(); $('a[href^="#tab-audio"]').show(); $('a[href^="#tab-gpio"]').hide(); $('#uploaddiv').hide(); $("footer.footer").removeClass('recovery'); $("footer.footer").addClass('sl'); $("#boot-button").html('Recovery'); $("#boot-form").attr('action', '/recovery.json'); enableStatusTimer = false; } } if (data.hasOwnProperty('project_name') && data['project_name'] != ''){ pname = data['project_name']; } if (data.hasOwnProperty('version') && data['version'] != ''){ ver = data['version']; $("span#foot-fw").html("fw: "+ver+", mode: "+pname+""); } else { $("span#flash-status").html(''); } if (data.hasOwnProperty('Voltage')) { var voltage = data['Voltage']; var layer; if (voltage > 0) { if (inRange(voltage, 5.8, 6.2) || inRange(voltage, 8.8, 9.2)) { layer = bat0; } else if (inRange(voltage, 6.2, 6.8) || inRange(voltage, 9.2, 10.0)) { layer = bat1; } else if (inRange(voltage, 6.8, 7.1) || inRange(voltage, 10.0, 10.5)) { layer = bat2; } else if (inRange(voltage, 7.1, 7.5) || inRange(voltage, 10.5, 11.0)) { layer = bat3; } else { layer = bat4; } layer.setAttribute("display","inline"); } } if (data.hasOwnProperty('Jack')) { var jack = data['Jack']; if (jack == '1') { o_jack.setAttribute("display","inline"); } } blockAjax = false; }) .fail(function(xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); blockAjax = false; }); } function getConfig() { $.getJSON("/config.json", function(data) { Object.keys(data).sort().forEach(function(key, i) { if (data.hasOwnProperty(key)) { if (key == 'autoexec') { if (data["autoexec"].value === "1") { $("#autoexec-cb")[0].checked=true; } else { $("#autoexec-cb")[0].checked=false; } } else if (key == 'autoexec1') { $("textarea#autoexec1").val(data[key].value); var re = / -o "?(\S+)\b/g; var m = re.exec(data[key].value); if (m[1] =='I2S') { o_i2s.setAttribute("display","inline"); } else if (m[1] =='SPDIF') { o_spdif.setAttribute("display","inline"); } else if (m[1] =='BT') { o_bt.setAttribute("display","inline"); } } else if (key == 'host_name') { $("input#dhcp-name1").val(data[key].value); $("input#dhcp-name2").val(data[key].value); } $("tbody#nvsTable").append( ""+ ""+key+""+ ""+ ""+ ""+ "" ); $("input#"+key).val(data[key].value); } }); $("tbody#nvsTable").append( ""+ ""+ ""+ ""+ ""+ ""+ // todo: provide a way to choose field type ""+ "" ); }) .fail(function(xhr, ajaxOptions, thrownError) { console.log(xhr.status); console.log(thrownError); if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR'); blockAjax = false; }); } function showMessage(message, severity, age=0) { if (severity == 'MESSAGING_INFO') { $('#message').css('background', '#6af'); } else if (severity == 'MESSAGING_WARNING') { $('#message').css('background', '#ff0'); } else if (severity == 'MESSAGING_ERROR' ) { $('#message').css('background', '#f00'); } else { $('#message').css('background', '#f00'); } $('#message').html(message); $("#content").fadeTo("slow", 0.3, function() { $("#message").show(500).delay(5000).hide(500, function() { $("#content").fadeTo("slow", 1.0); }); }); } function inRange(x, min, max) { return ((x-min)*(x-max) <= 0); }