Files
repo-smod-atsc/out/rootfs/aw/anywave/web/www/status_info.html
T

1126 lines
40 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title id="webtitle"></title>
<link href="css/styles.css" rel="stylesheet" media="screen">
<script src="js/auth.js"></script>
<script src="js/jquery.js"></script>
<script src="js/dashboard.js"></script>
<script>
var lastTime = new Date().getTime();
var currentTime = new Date().getTime();
var timeOut = 20 * 60 * 1000; // 20 min timeout
// Arrays for mapping RF Power indices to values (matching sys_rf.html)
var arry_p = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95"];
$(function(){
// Listen to multiple types of user activity to prevent timeout
$(document).on('mousemove keydown click scroll touchstart', function(){
lastTime = new Date().getTime();
});
});
function testTime(){
currentTime = new Date().getTime();
if(currentTime - lastTime > timeOut){
window.location.href="login.cgi?logout=1"
}
}
// Timer check (1s)
window.setInterval(testTime, 1000);
// Refresh data (2s)
setInterval(SetFormDefaults, 2000);
function get_remote_local_ctrl() {
var queryData = "sys_cfg=&";
$.get("atsc_status_cfg.cgi?"+queryData, function(data, status) {
var table = data.split("|");
// Logic for remote/local control if needed
// g_remot_local_ctrl = Number(table[0].split("#")[5]);
document.title = table[0].split("#")[11];
});
}
function refresh_show(){
get_remote_local_ctrl();
SetFormDefaults();
}
function SetFormDefaults() {
var queryData = "State_SysState=&tuner_status=&pac_status=&gps_status=&State_SysVer=&mac_sn_status=&sys_rf=&web_title=&"
$.get("atsc_status_cfg.cgi?"+queryData, function(data, status) {
var temp_unit=1;
var agc_err_code=0;
var table = data.split("|");
// --- 1. SYSTEM STATUS (Form 0) ---
var form = table[0].split("#");
var cf = document.getElementById("iostatus"); // iostatus
var ab_modenum = Number(form[25]);
temp_unit = Number(form[26]);
// Input Source Map
var i = Number(form[1]);
var s_str = (i==0)?"ASI1":(i==1)?"ASI2":(i==2)?"EAS":(i==3)?"Tuner":(i==4)?"TSoIP":(i==5)?"SMPTE":"None";
cf.asi_input.value = s_str;
// Input Status
cf.asi_status.value = (Number(form[2])==0) ? "OK" : "Err";
// AGC
cf.agc0.value = (Number(form[3])==0) ? "Off" : "On";
cf.ts_rate.value = form[4]; // TS Rate
// Temperature
if(temp_unit==0){
cf.temp1.value = form[5];
cf.temp1_c.value = ((cf.temp1.value - 32)/1.8).toFixed(2);
} else {
cf.temp1.value = (form[5]*1.8+32).toFixed(2);
cf.temp1_c.value = form[5];
}
// System Error
cf.syserr.value = (Number(form[6])==0) ? "OK" : "Err";
// Frequency Logic
i = Number(form[7]);
var freqVal = 0;
if((i>=2)&&(i<=6)){
freqVal = (i-2)*6+57; if(freqVal>69) freqVal+=4;
} else if((i>=7)&&(i<=13)){
freqVal = 177+6*(i-7);
} else if((i>=14)&&(i<=83)){
freqVal = 473+(i-14)*6;
}
cf.cha.value = freqVal; // Just the number for display
// Offset
i = Number(form[8]);
s_str = (i==0) ? "+" : "-";
cf.hz1.value = s_str + form[9];
// FWD Power & SNR
var rawFwd = Number(form[10]);
cf.fwd.value = (ab_modenum==1) ? "N/A" : (rawFwd + " %");
// SNR. Half-dB from the app, plus the fixed +10 dB display offset.
var tmpdata = Number(form[11]);
var snrStr = (tmpdata/2 + 10).toFixed(1);
cf.tsnr.value = (ab_modenum==1) ? "N/A" : snrStr;
// IMD. Half-dB from the app, plus the fixed +11 dB display offset.
// (Do not Math.round() the sum and then paste on the half: for an odd
// half-dB value that rounds x.5 up and reports 1 dB too much.)
tmpdata = Number(form[12]);
cf.l_imd.value = (ab_modenum==1) ? "N/A" : (tmpdata/2 + 11).toFixed(1);
tmpdata = Number(form[13]);
cf.u_imd.value = (ab_modenum==1) ? "N/A" : (tmpdata/2 + 11).toFixed(1);
// Control & Amp
cf.f1ctrl.value = (Number(form[14])==0) ? "Remote" : "Local";
i = Number(form[15]);
if(i>1){
// Hide if invalid
document.getElementById("amp").style.visibility="hidden";
document.getElementById("amp+").style.visibility="hidden";
} else {
document.getElementById("amp").style.visibility="visible";
document.getElementById("amp+").style.visibility="visible";
cf.amp.value = (i==0) ? "OK" : "FLT";
}
// FSSI
cf.a_fssi.value = Number(form[16]) + " %";
cf.b_fssi.value = (ab_modenum==1) ? (Number(form[17]) + " %") : "N/A";
// AGC State
agc_err_code = Number(form[27]);
var agc_adj = Number(form[28]);
if(agc_err_code==1) s_str="Down Limit!";
else if(agc_err_code==2) s_str="Up Limit!";
else {
if(Number(form[3])==1) { // AGC ON
s_str = (agc_adj>0) ? ("+"+(agc_adj/100)) : (agc_adj/100).toString();
} else {
s_str="OK";
}
}
cf.agc_state.value = s_str;
// --- 2. PARSE SYS_RF FOR DASHBOARD ---
var rfStat = 0;
var finalPower = '--';
if(table[6]) {
var rf_form = table[6].split("#");
rfStat = Number(rf_form[4]); // RFY index
var p_sign = (Number(rf_form[1]) == 0) ? "+" : "-";
var p_int = Number(rf_form[2]);
var p_dec = arry_p[Number(rf_form[3])];
finalPower = p_sign + p_int + "." + p_dec;
}
// --- 3. UPDATE DASHBOARD USING SHARED MODULE ---
if (typeof updateDashboardCards === 'function') {
updateDashboardCards({
freqVal: freqVal,
snr: cf.tsnr.value,
limd: cf.l_imd.value,
uimd: cf.u_imd.value,
inputSrc: cf.asi_input.value,
inputStatus: cf.asi_status.value,
bitrate: cf.ts_rate.value,
temp: cf.temp1.value,
agc: cf.agc0.value,
ctrl: cf.f1ctrl.value,
rfStat: rfStat,
finalPower: finalPower
});
}
// --- 4. PARSE OTHER FORMS ---
// Form 1: Tuner
var form1 = table[1].split("#");
var cf1 = document.getElementById("tuner");
cf1.rx_freq.value = Number(form1[1]);
cf1.rssi.value = Number(form1[2]);
cf1.rsnr.value = Number(form1[3]);
cf1.lock.selectedIndex = Number(form1[4]);
// Form 2: PAC Status
var form2 = table[2].split("#");
var cf2 = document.getElementById("pac_status");
cf2.v9v.value = (Number(form2[1])*0.1).toFixed(2);
cf2.v12v.value = (Number(form2[2])*0.1).toFixed(2);
cf2.v50v.value = (Number(form2[3])*0.1).toFixed(2);
cf2.pac_fwd.value = (Number(form2[4])*0.1).toFixed(2);
cf2.ref.value = (Number(form2[5])*0.1).toFixed(2);
cf2.vswr.value = (Number(form2[6])*0.1).toFixed(2);
// PAC Temp
if(temp_unit==0){
cf2.temp.value = (Number(form2[7])*0.1).toFixed(2);
cf2.temp_c.value = (cf2.temp.value < 32) ? 0 : ((cf2.temp.value - 32)/1.8).toFixed(2);
} else {
cf2.temp.value = (Number(form2[7])*0.1*1.8+32).toFixed(2);
cf2.temp_c.value = (Number(form2[7])*0.1).toFixed(2);
}
cf2.pain.value = Number(form2[8]); // This is PA_IN
cf2.c50v1.value = (Number(form2[9])*0.1).toFixed(2);
cf2.c50v2.value = (Number(form2[10])*0.1).toFixed(2);
cf2.c50v3.value = (Number(form2[11])*0.1).toFixed(2);
cf2.c50v4.value = (Number(form2[12])*0.1).toFixed(2);
cf2.gv.value = (Number(form2[13])*0.1).toFixed(2);
cf2.lvl.selectedIndex = Number(form2[14]);
// Form 3: GPS
var form3 = table[3].split("#");
var cf3 = document.getElementById("gps_form");
cf3.gps.value = (Number(form3[1])==0)?"NoGPS":(Number(form3[1])==1)?"Unlock":"Lock";
cf3.gps_in.value = (Number(form3[2])==0)?"External":"Internal";
cf3.gps_date.value = form3[3];
cf3.gps_time.value = form3[4];
cf3.gps_sv.value = form3[5];
cf3.gps_status.value = form3[6];
cf3.gps_freq.value = form3[7];
// Form 5: Version
var form5 = table[4].split("#");
var cf5 = document.getElementById("version");
cf5.atsc_ver.value = form5[1];
cf5.fpga_ver.value = form5[2];
cf5.mcu_ver.value = form5[3];
cf5.plc_ver.value = form5[4];
// Form 6: MAC/SN
var form6 = table[5].split("#");
var cf6 = document.getElementById("macsn");
cf6.mac.value = form6[1];
cf6.sn.value = form6[2];
if (table[7]) {
var title = table[7].split("#");
var titleStr = (title[1] != null) ? title[1] : "";
document.getElementById('webtitle').textContent = titleStr;
document.getElementById('webtitle_header').textContent = titleStr;
}
// Update Status Colors and UI helpers
updateStatusColors();
updateStatusAlertStrip();
highlightProblemTableRows();
updateBoxHeaderErrorState();
get_license();
});
}
function updateStatusAlertStrip() {
var strip = document.getElementById('status-alert-strip');
var textEl = strip ? strip.querySelector('.status-alert-text') : null;
var detailEl = document.getElementById('status-alert-detail');
if (!strip || !textEl) return;
var cards = document.querySelectorAll('.summary-card');
var errLabels = [], warnLabels = [];
cards.forEach(function(card) {
var val = card.querySelector('.summary-value');
var label = card.querySelector('.summary-label');
var name = label ? label.textContent.trim() : '';
if (val && val.classList.contains('value-err')) errLabels.push(name);
else if (val && val.classList.contains('value-warn')) warnLabels.push(name);
});
strip.classList.remove('status-alert-ok', 'status-alert-warn', 'status-alert-err');
if (errLabels.length > 0) {
strip.classList.add('status-alert-err');
textEl.textContent = errLabels.length + ' issue(s) detected';
if (detailEl) detailEl.textContent = ' - e.g. ' + errLabels.slice(0, 2).join(', ');
} else if (warnLabels.length > 0) {
strip.classList.add('status-alert-warn');
textEl.textContent = warnLabels.length + ' warning(s)';
if (detailEl) detailEl.textContent = ' - e.g. ' + warnLabels.slice(0, 2).join(', ');
} else {
strip.classList.add('status-alert-ok');
textEl.textContent = 'System OK';
if (detailEl) detailEl.textContent = '';
}
updateSummaryCardTooltips();
}
function updateSummaryCardTooltips() {
document.querySelectorAll('.summary-card').forEach(function(card) {
var label = card.querySelector('.summary-label');
var value = card.querySelector('.summary-value');
var status = value && value.classList.contains('value-err') ? 'Error' : (value && value.classList.contains('value-warn') ? 'Warning' : (value && value.classList.contains('value-ok') ? 'OK' : ''));
var name = label ? label.textContent.trim() : '';
var val = value ? value.textContent.trim() : '--';
card.title = name + ': ' + val + (status ? ' (' + status + ')' : '');
});
}
function highlightProblemTableRows() {
var tables = document.querySelectorAll('.app-main .box table');
tables.forEach(function(table) {
var rows = table.querySelectorAll('tr');
rows.forEach(function(tr) {
tr.classList.remove('row-has-error');
var inputs = tr.querySelectorAll('input[readonly], select');
for (var i = 0; i < inputs.length; i++) {
var inp = inputs[i];
var v = '';
if (inp.tagName === 'SELECT') {
var opt = inp.options[inp.selectedIndex];
v = opt ? opt.text.trim() : '';
} else {
v = inp.value || '';
}
// Literal error values (case-insensitive: values may be "Err", "Unlock", etc.)
if ((v && v.toUpperCase() === 'ERR') || v === 'FLT' || (v && v.toUpperCase() === 'UNLOCK')) {
tr.classList.add('row-has-error');
break;
}
// SNR, LIMD, UIMD: same error thresholds as summary cards / updateStatusColors
var id = inp.id || '';
if (id === 'tsnr' && v !== '' && v !== 'N/A') {
var snrNum = parseFloat(v); // carries the +10 dB display offset
if (snrNum < 25) { tr.classList.add('row-has-error'); break; }
}
if (id === 'l_imd' && v !== '' && v !== 'N/A') {
if (parseFloat(v) < 47) { tr.classList.add('row-has-error'); break; }
}
if (id === 'u_imd' && v !== '' && v !== 'N/A') {
if (parseFloat(v) < 47) { tr.classList.add('row-has-error'); break; }
}
// License fields: INACTIVE is an error
if (id === 'pisp_editing_lc' || id === 'eas_lc') {
if (v === 'INACTIVE') {
tr.classList.add('row-has-error');
break;
}
}
}
});
});
}
function updateBoxHeaderErrorState() {
document.querySelectorAll('.box-header').forEach(function(boxHeader) {
var box = boxHeader.parentElement;
if (!box || !box.classList.contains('box')) return;
var content = box.querySelector('.box-content');
var hasError = content && content.querySelector('tr.row-has-error');
if (hasError) boxHeader.classList.add('has-error');
else boxHeader.classList.remove('has-error');
});
}
// Color Logic: Main Status details (OK/ERR, LIMD/UIMD/SNR ranges) + Tuner Lock/Unlock
function updateStatusColors() {
var color_ok = getComputedStyle(document.documentElement).getPropertyValue('--accent-green').trim();
var color_err = getComputedStyle(document.documentElement).getPropertyValue('--status-err').trim();
var color_warn = getComputedStyle(document.documentElement).getPropertyValue('--status-warn').trim();
var inputs = document.getElementsByTagName("input");
for(var i=0; i<inputs.length; i++) {
// Skip inputs inside the account modal to prevent flicker
var inModal = inputs[i].closest('#accountModal');
if(inModal) continue;
if(inputs[i].value.toUpperCase() === "OK" || inputs[i].value.toUpperCase() === "LOCK") inputs[i].style.color = color_ok;
else if(inputs[i].value.toUpperCase() === "ERR" || inputs[i].value.toUpperCase() === "UNLOCK") inputs[i].style.color = color_err;
else inputs[i].style.color = "";
}
// Main Status details: LIMD, UIMD, SNR – same rules as summary cards (green/red/warn by range)
var tsnrEl = document.getElementById("tsnr");
if(tsnrEl && tsnrEl.value !== "" && tsnrEl.value !== "N/A") {
var snrVal = parseFloat(tsnrEl.value); // already carries the +10 dB display offset
if(snrVal >= 37) tsnrEl.style.color = color_ok;
else if(snrVal >= 30) tsnrEl.style.color = color_warn;
else tsnrEl.style.color = color_err;
} else if(tsnrEl) tsnrEl.style.color = "";
var limdEl = document.getElementById("l_imd");
if(limdEl && limdEl.value !== "" && limdEl.value !== "N/A") {
limdEl.style.color = parseFloat(limdEl.value) >= 47 ? color_ok : color_err;
} else if(limdEl) limdEl.style.color = "";
var uimdEl = document.getElementById("u_imd");
if(uimdEl && uimdEl.value !== "" && uimdEl.value !== "N/A") {
uimdEl.style.color = parseFloat(uimdEl.value) >= 47 ? color_ok : color_err;
} else if(uimdEl) uimdEl.style.color = "";
// Tuner section only: Lock (green) / Unlock (red). PAC section PA Level (#lvl) is power level 0/160/310/610 W – never color it.
var selects = document.getElementsByTagName("select");
for(var j=0; j<selects.length; j++) {
var sel = selects[j];
// Skip selects inside the account modal to prevent flicker
var inModal = sel.closest('#accountModal');
if(inModal) continue;
if(sel.id !== "lock" && sel.name !== "lock") {
sel.style.color = "";
continue;
}
var opt = sel.options[sel.selectedIndex];
var text = opt ? opt.text.trim() : "";
var val = opt ? opt.value : "";
sel.classList.remove("state-error", "state-ok");
if(text === "Lock" || val === "1") {
sel.style.color = color_ok;
sel.style.fontWeight = "bold";
sel.classList.add("state-ok");
}
else if(text === "Unlock" || val === "0") {
sel.style.color = color_err;
sel.style.fontWeight = "bold";
sel.classList.add("state-error");
}
else {
sel.style.color = "";
sel.style.fontWeight = "normal";
}
}
// License fields
var licenseFields = ["pisp_editing_lc", "eas_lc"];
for (var k = 0; k < licenseFields.length; k++) {
var field = document.getElementById(licenseFields[k]);
if (field) {
if (field.value.toUpperCase() === "ACTIVE") {
field.style.color = color_ok;
} else if (field.value.toUpperCase() === "INACTIVE") {
field.style.color = color_err;
} else {
field.style.color = "";
}
}
}
}
// Modal Logic - Open and close account modal
function openAccountModal() {
// Fetch current username from server
$.get("login.cgi?action=get_user", function(data) {
var trimmedData = (data || "").trim();
if (trimmedData && trimmedData !== "UNAUTHORIZED") {
document.getElementById('current_user').value = trimmedData;
}
document.getElementById('accountModal').style.display = 'block';
setTimeout(function() { document.getElementById('current_pwd').focus(); }, 100);
}).fail(function() {
// On error, modal still opens but current_user remains empty
document.getElementById('accountModal').style.display = 'block';
setTimeout(function() { document.getElementById('current_pwd').focus(); }, 100);
});
}
function closeAccountModal() {
document.getElementById('accountModal').style.display = 'none';
// Clear sensitive fields
document.getElementById('current_pwd').value = '';
document.getElementById('new_pwd').value = '';
document.getElementById('confirm_pwd').value = '';
}
// Validates that a string contains only printable characters (excluding space)
function isValidPrintableString(str) {
// Regular expression to check for printable characters (ASCII 33-126), excluding space
// Space is ASCII 32, and we want to exclude it
var printableCharRegex = /^[!-~]+$/; // ! is ASCII 33, ~ is ASCII 126
return printableCharRegex.test(str);
}
// Validate Account Form - All required fields must be filled
function validateAccountForm() {
var currentUser = document.getElementById('current_user').value;
var currentPwd = document.getElementById('current_pwd').value;
var newUsername = document.getElementById('new_user').value;
var newPwd = document.getElementById('new_pwd').value;
var confirmPwd = document.getElementById('confirm_pwd').value;
// Current password is required (cannot be empty)
if (!currentPwd || currentPwd.trim() === "") {
alert("Current password is required");
return false;
}
// Validate current password contains only printable characters
if (!isValidPrintableString(currentPwd)) {
alert("Current password contains invalid characters. Only printable characters (excluding space) are allowed.");
return false;
}
// New password is required (cannot be empty)
if (!newPwd || newPwd.trim() === "") {
alert("New password is required");
return false;
}
// Validate new password contains only printable characters
if (!isValidPrintableString(newPwd)) {
alert("New password contains invalid characters. Only printable characters (excluding space) are allowed.");
return false;
}
// Validate new password length (max 16 chars)
if (newPwd.length > 16) {
alert("New password must be no more than 16 characters");
return false;
}
// Validate new password length
if (newPwd.length < 6) {
alert("New password must be at least 6 characters");
return false;
}
// Confirm password must match new password
if (newPwd !== confirmPwd) {
alert("New passwords do not match");
return false;
}
// Validate confirm password contains only printable characters
if (!isValidPrintableString(confirmPwd)) {
alert("Confirm password contains invalid characters. Only printable characters (excluding space) are allowed.");
return false;
}
// Validate confirm password length (max 16 chars)
if (confirmPwd.length > 16) {
alert("Confirm password must be no more than 16 characters");
return false;
}
// Validate new username if provided
if (newUsername && newUsername.trim() !== "") {
// Validate new username contains only printable characters
if (!isValidPrintableString(newUsername)) {
alert("New username contains invalid characters. Only printable characters (excluding space) are allowed.");
return false;
}
// Validate new username length (max 16 chars)
if (newUsername.length > 16) {
alert("New username must be no more than 16 characters");
return false;
}
}
return true; // Allows the form to submit
}
// Form submission handler using fetch API
document.addEventListener('DOMContentLoaded', function() {
var accountForm = document.getElementById('accountForm');
if (accountForm) {
accountForm.addEventListener('submit', function(e) {
e.preventDefault();
if (!validateAccountForm()) return;
var formData = new URLSearchParams({
Username: document.getElementById('current_user').value,
OldPassword: document.getElementById('current_pwd').value,
NewUsername: document.getElementById('new_user').value,
NewPassword: document.getElementById('new_pwd').value,
ConfirmPassword: document.getElementById('confirm_pwd').value
});
fetch('login.cgi?action=change_account', {
method: 'POST',
body: formData
})
.then(r => r.json())
.then(data => {
if (data.success) {
alert("Update successful! Please login again.");
closeAccountModal();
// Redirect to login page after 1.5 seconds
setTimeout(function() {
window.location.href = 'login.cgi?logout=1';
}, 1500);
} else {
alert(data.error || "Update failed");
}
})
.catch(function(err) {
alert("Network error: " + err);
});
});
}
});
// Collapsible Tables - MAIN STATUS, PAC STATUS, GPS STATUS
function initCollapsibleTables() {
var headers = document.querySelectorAll('.app-main h2');
for (var i = 0; i < headers.length; i++) {
var header = headers[i];
var headerText = header.innerText.trim();
if (headerText === "Main Status" || headerText === "Tuner Status" || headerText === "PAC Status" || headerText === "GPS Status") {
// Smart Search for the box
var nextEl = header.nextElementSibling;
var box = null;
while (nextEl) {
if (nextEl.className && nextEl.className.indexOf("box") !== -1) {
box = nextEl;
break;
}
if (nextEl.tagName === "H2") break;
nextEl = nextEl.nextElementSibling;
}
if (box) {
var boxHeader = document.createElement('div');
boxHeader.className = "box-header collapsed";
var titleSpan = document.createElement('span');
titleSpan.innerText = headerText + " Details";
var toggleSpan = document.createElement('span');
toggleSpan.className = "toggle-text";
toggleSpan.innerText = "View Details";
boxHeader.appendChild(titleSpan);
boxHeader.appendChild(toggleSpan);
var contentDiv = document.createElement('div');
contentDiv.className = "box-content";
contentDiv.style.display = "none";
while (box.firstChild) {
contentDiv.appendChild(box.firstChild);
}
box.appendChild(boxHeader);
box.appendChild(contentDiv);
boxHeader.onclick = function() {
this.classList.toggle("collapsed");
var content = this.nextElementSibling;
var badge = this.querySelector('.toggle-text');
if (content.style.display === "none") {
content.style.display = "block";
badge.innerText = "Hide Details";
} else {
content.style.display = "none";
badge.innerText = "View Details";
}
};
}
}
}
}
function get_license() {
var queryData = "sn_license=&";
$.get("atsc_status_cfg.cgi?" + queryData, function(data, status) {
var table = data.split("|");
var licence_para = table[0].split("#");
var cf = document.getElementById("license");
if (cf) {
cf.pisp_editing_lc.value = (licence_para[2] == "1") ? "ACTIVE" : "INACTIVE";
cf.eas_lc.value = (licence_para[4] == "1") ? "ACTIVE" : "INACTIVE";
updateStatusColors();
highlightProblemTableRows();
updateBoxHeaderErrorState();
updateStatusAlertStrip();
}
});
}
document.addEventListener('DOMContentLoaded', function() {
initCollapsibleTables();
});
</script>
</head>
<body onload="refresh_show()">
<body onload="refresh_show()">
<div class="app-layout">
<aside class="app-sidebar">
<ul class="items">
<li class="active"><a href="status_info.html" title="Status">Status</a></li>
<li><a href="sys_set.html" title="Settings">Settings</a></li>
<li><a href="sys_rf.html" title="RF Control">RF Control</a></li>
<li><a href="sys_psip.html" title="TSID&PSIP">TSID&PSIP</a></li>
<li><a href="sys_ts.html" title="TSoIP">TSoIP</a></li>
<li><a href="sys_spectrum.html" title="Spectrum">Spectrum</a></li>
<li><a href="log_output.html" title="Log">Log</a></li>
</ul>
<div class="sidebar-footer">
<h4>Anywave Broadcast Inc.</h4>
<p>Copyright 2026<br><br><span class="redbox-label">Technical Support</span><br>+1 847 415 2258<br><a href="mailto:support@anywaveus.com">support@anywaveus.com</a></p>
</div>
</aside>
<div class="sidebar-overlay" onclick="toggleSidebar()"></div>
<header class="app-header">
<button class="menu-toggle" onclick="toggleSidebar()" aria-label="Toggle menu">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</button>
<h1><a href="https://anywavecom.net/" class="logo-bg" title="Anywave Broadcast Inc."></a></h1>
<h2 id="webtitle_header"><span></span></h2>
<h3>
<div class="dropdown">
<button class="dropbtn-modern">Admin &#9662;</button>
<div class="dropdown-content">
<a href="#" onclick="openAccountModal(); return false;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg>
Account Settings
</a>
<a href="login.cgi?logout=1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
<polyline points="16 17 21 12 16 7"></polyline>
<line x1="21" y1="12" x2="9" y2="12"></line>
</svg>
Logout
</a>
</div>
</div>
</h3>
</header>
<!-- Fixed Dashboard Summary - Top of page, under header -->
<div class="dashboard-fixed">
<div class="summary-dashboard">
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-neutral" id="dot_freq" aria-hidden="true"></span>
<span class="summary-label">Frequency</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-neutral" id="sum_freq">--</span>
<span class="summary-unit">MHz</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-ok" id="dot_snr" aria-hidden="true"></span>
<span class="summary-label">SNR</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-ok" id="sum_snr">--</span>
<span class="summary-unit">dB</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-ok" id="dot_uimd" aria-hidden="true"></span>
<span class="summary-label">UIMD</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-ok" id="sum_uimd">--</span>
<span class="summary-unit">dBc</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-ok" id="dot_limd" aria-hidden="true"></span>
<span class="summary-label">LIMD</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-ok" id="sum_limd">--</span>
<span class="summary-unit">dBc</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-off" id="dot_rf" aria-hidden="true"></span>
<span class="summary-label">RF Switch</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-muted" id="sum_rf">--</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-ok" id="dot_outpow" aria-hidden="true"></span>
<span class="summary-label">Output Power</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-ok" id="sum_outpow">--</span>
<span class="summary-unit">dBm</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-neutral" id="dot_input" aria-hidden="true"></span>
<span class="summary-label">Input Source</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-neutral" id="sum_input">--</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-neutral" id="dot_input_status" aria-hidden="true"></span>
<span class="summary-label">Input Status</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-neutral" id="sum_input_status">--</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-neutral" id="dot_bitrate" aria-hidden="true"></span>
<span class="summary-label">Bitrate</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-neutral" id="sum_bitrate">--</span>
<span class="summary-unit">Mbps</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-ok" id="dot_temp" aria-hidden="true"></span>
<span class="summary-label">Temperature</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-ok" id="sum_temp">--</span>
<span class="summary-unit">&#176;F</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-off" id="dot_agc" aria-hidden="true"></span>
<span class="summary-label">AGC</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-muted" id="sum_agc">--</span>
</div>
</div>
<div class="summary-card">
<div class="summary-label-row">
<span class="status-dot status-neutral" id="dot_control" aria-hidden="true"></span>
<span class="summary-label">Control</span>
</div>
<div class="summary-value-wrapper">
<span class="summary-value value-neutral" id="sum_control">--</span>
</div>
</div>
</div>
</div>
<main class="app-main">
<div id="status-alert-strip" class="status-alert status-alert-ok" role="status" aria-live="polite">
<span class="status-alert-icon" aria-hidden="true"></span>
<span class="status-alert-text">System OK</span>
<span class="status-alert-detail" id="status-alert-detail"></span>
</div>
<h2>Main Status</h2>
<div class="box">
<form name="iostatus" id="iostatus">
<table>
<tr>
<td>Input</td>
<td><input type="text" readonly name="asi_input" id="asi_input" value=""></td>
<td>Status</td>
<td><input type="text" readonly name="asi_status" id="asi_status" value=""></td>
</tr>
<tr>
<td>AGC</td>
<td>
<input type="text" readonly name="agc0" id="agc0" value="">
<input type="text" readonly name="agc_state" id="agc_state" style="margin-top: 4px;" value="">
</td>
<td>TS Bitrate</td>
<td><input type="text" readonly name="ts_rate" id="ts_rate" value=""> Mbps</td>
</tr>
<tr>
<td>Temperature</td>
<td>
<fieldset>
<input type="text" readonly name="temp1" id="temp1" value="">&#176;F
<input type="text" readonly name="temp1_c" id="temp1_c" value="">&#176;C
</fieldset>
</td>
<td>SYSERR</td>
<td><input type="text" readonly name="syserr" id="syserr" value=""></td>
</tr>
<tr>
<td>TX Frequency</td>
<td><input type="text" readonly name="cha" id="cha" value=""> MHz</td>
<td>Hz(+/-50000Hz)</td>
<td><fieldset>
<input type="text" readonly name="hz1" id="hz1" value="">
</fieldset></td>
</tr>
<tr>
<td>FWD</td>
<td><input type="text" readonly name="fwd" id="fwd" value=""></td>
<td>SNR</td>
<td><input type="text" readonly name="tsnr" id="tsnr" value=""> dB</td>
</tr>
<tr>
<td>LIMD</td>
<td><input type="text" readonly name="l_imd" id="l_imd" value=""> dBc</td>
<td>UIMD</td>
<td><input type="text" readonly name="u_imd" id="u_imd" value=""> dBc</td>
</tr>
<tr>
<td>Control</td>
<td><input type="text" readonly name="f1ctrl" id="f1ctrl" value=""></td>
<td id="amp+">AMP</td>
<td id="amp">
<input type="text" readonly name="amp" value="">
</td>
</tr>
<tr>
<td>A FSSI</td>
<td><input type="text" readonly name="a_fssi" id="a_fssi" value=""></td>
<td>B FSSI</td>
<td><input type="text" readonly name="b_fssi" id="b_fssi" value=""></td>
</tr>
</table>
</form>
</div>
<h2>Tuner Status</h2>
<div class="box">
<form name="tuner" id="tuner">
<table>
<tr>
<td>Rx Frequency</td>
<td><input type="text" readonly name="rx_freq" id="rx_freq" value="">MHz</td>
<td>RSSI</td>
<td><input type="text" readonly name="rssi" id="rssi" value="">dBm</td>
</tr>
<tr>
<td>RSNR</td>
<td><input type="text" readonly name="rsnr" id="rsnr" value="">dB</td>
<td>Lock</td>
<td>
<select class="display-only-select" disabled name="lock" id="lock">
<option value="0">Unlock</option>
<option value="1">Lock</option>
</select>
</td>
</tr>
</table>
</form>
</div>
<h2>PAC Status</h2>
<div class="box">
<form name="pac" id="pac_status">
<table>
<tr>
<td>Vol 9V</td><td><input type="text" readonly name="v9v" id="v9v" value="">V</td>
<td>Vol 12V</td><td><input type="text" readonly name="v12v" id="v12v" value="">V</td>
</tr>
<tr>
<td>Vol 50V</td><td><input type="text" readonly name="v50v" id="v50v" value="">V</td>
<td>PA FWD</td><td><input type="text" readonly name="pac_fwd" id="pac_fwd" value="">W</td>
</tr>
<tr>
<td>PA REF</td><td><input type="text" readonly name="ref" id="ref" value="">W</td>
<td>VSWR</td><td><input type="text" readonly name="vswr" id="vswr" value=""></td>
</tr>
<tr>
<td>Temperature</td>
<td>
<fieldset>
<input type="text" readonly name="temp" id="temp" value="">&#176;F
<input type="text" readonly name="temp_c" id="temp_c" value="">&#176;C
</fieldset>
</td>
<td>PA IN</td><td><input type="text" readonly name="pain" id="pain" value="">dBm</td>
</tr>
<tr>
<td>GV</td><td><input type="text" readonly name="gv" id="gv" value="">mV</td>
<td>PA Level</td>
<td>
<select class="display-only-select" disabled name="lvl" id="lvl">
<option value="0">0</option>
<option value="1">160</option>
<option value="2">310</option>
<option value="3">610</option>
</select>W
</td>
</tr>
<tr>
<td>50V Cur1</td><td><input type="text" readonly name="c50v1" id="c50v1" value="">A</td>
<td>50V Cur2</td><td><input type="text" readonly name="c50v2" id="c50v2" value="">A</td>
</tr>
<tr>
<td>50V Cur3</td><td><input type="text" readonly name="c50v3" id="c50v3" value="">A</td>
<td>50V Cur4</td><td><input type="text" readonly name="c50v4" id="c50v4" value="">A</td>
</tr>
</table>
</form>
</div>
<h2>GPS Status</h2>
<div class="box">
<form name="gps_form" id="gps_form">
<table>
<tr>
<td>GPS Lock</td><td><input type="text" readonly name="gps" id="gps" value=""></td>
<td>GPS</td><td><input type="text" readonly name="gps_in" id="gps_in" value=""></td>
</tr>
<tr>
<td>Date</td><td><input type="text" readonly name="gps_date" id="gps_date" value=""></td>
<td>Time</td><td><input type="text" readonly name="gps_time" id="gps_time" value=""></td>
</tr>
<tr>
<td>Satellite</td><td><input type="text" readonly name="gps_sv" id="gps_sv" value=""></td>
<td>Status</td><td><input type="text" readonly name="gps_status" id="gps_status" value=""></td>
</tr>
<tr>
<td>Frequency</td><td><input type="text" readonly name="gps_freq" id="gps_freq" value=""></td>
</tr>
</table>
</form>
</div>
<h2>Version</h2>
<div class="box">
<form name="ver" id="version">
<table>
<tr>
<td>ATSC</td><td><input type="text" style="max-width: 150px;" readonly name="atsc_ver" id="atsc_ver" value=""></td>
<td>FPGA</td><td><input type="text" style="max-width: 150px;" readonly name="fpga_ver" id="fpga_ver" value=""></td>
</tr>
<tr>
<td>MCU</td><td><input type="text" style="max-width: 150px;" readonly name="mcu_ver" id="mcu_ver" value=""></td>
<td>DryLoop</td><td><input type="text" style="max-width: 150px;" readonly name="plc_ver" id="plc_ver" value=""></td>
</tr>
</table>
</form>
</div>
<h2>MAC&SN</h2>
<div class="box">
<form name="macsn" id="macsn">
<table>
<tr>
<td>MAC</td><td><input type="text" style="max-width: 150px;" readonly name="mac" id="mac" value=""></td>
<td>SN</td><td><input type="text" style="max-width: 150px;" readonly name="sn" id="sn" value=""></td>
</tr>
</table>
</form>
</div>
<h2>License</h2>
<div class="box">
<form name="license" id="license">
<table>
<tr>
<td>PSIP Editing</td>
<td><input type="text" style="max-width: 150px;" readonly name="pisp_editing_lc" id="pisp_editing_lc" value=""></td>
<td>EAS</td>
<td><input type="text" style="max-width: 150px;" readonly name="eas_lc" id="eas_lc" value=""></td>
</tr>
</table>
</form>
</div>
<br><br><br>
</main>
</div>
<div id="accountModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Account Settings</h3>
<span class="close" onclick="closeAccountModal()">&times;</span>
</div>
<div class="modal-body">
<form id="accountForm" method="post" action="login.cgi?action=change_account" onsubmit="return validateAccountForm()">
<table class="modal-table">
<tr>
<td>Current Username</td>
<td><input type="text" id="current_user" name="current_user" readonly></td>
</tr>
<tr>
<td>Current Password</td>
<td><input type="password" id="current_pwd" name="current_pwd" required></td>
</tr>
<tr>
<td>New Username</td>
<td><input type="text" id="new_user" name="new_user"></td>
</tr>
<tr>
<td>New Password</td>
<td><input type="password" id="new_pwd" name="new_pwd"></td>
</tr>
<tr>
<td>Confirm Password</td>
<td><input type="password" id="confirm_pwd" name="confirm_pwd"></td>
</tr>
</table>
<div class="modal-footer">
<input type="button" class="btn-modern" style="background-color: #64748b;" value="Cancel" onclick="closeAccountModal()">
<input type="submit" class="btn-modern" value="Save Changes">
</div>
</form>
</div>
</div>
</div>
<script>
function toggleSidebar(){
document.querySelector('.app-sidebar').classList.toggle('sidebar-open');
document.querySelector('.sidebar-overlay').classList.toggle('active');
}
</script>
</body>
</html>