新增:概览仪表盘及统一频谱页面
This commit is contained in:
+145
-61
@@ -4,6 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title id="webtitle"></title>
|
||||
<script src="js/theme.js"></script>
|
||||
<link href="css/styles.css" rel="stylesheet" media="screen">
|
||||
<script src="js/auth.js"></script>
|
||||
<script src="js/jquery.js"></script>
|
||||
@@ -41,7 +42,19 @@ function get_remote_local_ctrl() {
|
||||
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];
|
||||
/* P-4 ROOT CAUSE + the better fix (2026-08-06).
|
||||
What was here: document.title = table[0].split("#")[11]; — copied from the
|
||||
1.0 BY VALUE, index and all (the same copy-by-value class as C1's
|
||||
INPUT_SOURCES). The 1.0's sys_cfg carries five NTP fields after ctl so its
|
||||
title sits at index 11; smod's sys_cfg has no NTP fields there, so index 11
|
||||
is ab_mode — the FSSI Refresh switch. The tab was displaying the FSSI switch
|
||||
state: "0" or "1", flipping as FSSI was toggled (owner, 2026-08-06).
|
||||
Why the line is DELETED rather than re-indexed: this page already has a
|
||||
correct, authoritative title source — the dedicated web_title section polled
|
||||
in SetFormDefaults below (table[7]). Two writers for one value is the defect,
|
||||
not the index; re-indexing would have left a second writer racing the first
|
||||
(and is exactly what C1 removed on the input-source axis). One source of
|
||||
truth: the web_title section. This function now only does what its name says. */
|
||||
});
|
||||
}
|
||||
|
||||
@@ -51,6 +64,11 @@ function get_remote_local_ctrl() {
|
||||
}
|
||||
|
||||
function SetFormDefaults() {
|
||||
// R-2 (2026-08-05): NaN guards — in-tree pattern from sys_spectrum.html. Readbacks
|
||||
// show "--" for absent data; finite values format as before.
|
||||
function fmtScaled(v, scale, dp){ var n = Number(v); return isFinite(n) ? (n*scale).toFixed(dp) : "--"; }
|
||||
function fmtRaw(v){ var n = Number(v); return isFinite(n) ? n : "--"; }
|
||||
|
||||
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;
|
||||
@@ -63,10 +81,23 @@ function SetFormDefaults() {
|
||||
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 Source — C1 (2026-08-05): the page-private ternary is DELETED; this and the
|
||||
// dashboard cards read the ONE map via DashboardHelpers.getInputSource (the two lists
|
||||
// disagreed at index 5 — SMPTE vs None — which is your "None for a selected input").
|
||||
cf.asi_input.value = window.DashboardHelpers.getInputSource(form[1]);
|
||||
|
||||
/* REG-2 / ST.F11 port (2026-08-05, from the 1.0): auto-expand Tuner Status on
|
||||
ENTERING tuner/translator mode — smod IS a translator, so this is its primary
|
||||
mode. Same "changed" semantics as the 1.0's adaptation of 3.0's publishMode:
|
||||
expand only on the transition INTO Tuner input (form[1]===3, same index here,
|
||||
proven by this page's own map), tracked by _stTunerMode — NEVER on every poll,
|
||||
so an operator's manual collapse is not fought. Box-headers exist by now
|
||||
(initCollapsibleTables runs at DOMContentLoaded, before this callback). */
|
||||
(function(){
|
||||
var inTuner = (Number(form[1]) === 3);
|
||||
if (inTuner && window._stTunerMode !== true) { autoExpandTunerStatus(); }
|
||||
window._stTunerMode = inTuner;
|
||||
})();
|
||||
|
||||
// Input Status
|
||||
cf.asi_status.value = (Number(form[2])==0) ? "OK" : "Err";
|
||||
@@ -76,12 +107,15 @@ function SetFormDefaults() {
|
||||
|
||||
cf.ts_rate.value = form[4]; // TS Rate
|
||||
|
||||
// Temperature
|
||||
if(temp_unit==0){
|
||||
// Temperature — R-2: absent data -> "--", never NaN cascades
|
||||
var t_raw = Number(form[5]);
|
||||
if(!isFinite(t_raw)){
|
||||
cf.temp1.value = "--"; cf.temp1_c.value = "--";
|
||||
} else if(temp_unit==0){
|
||||
cf.temp1.value = form[5];
|
||||
cf.temp1_c.value = ((cf.temp1.value - 32)/1.8).toFixed(2);
|
||||
cf.temp1_c.value = ((t_raw - 32)/1.8).toFixed(2);
|
||||
} else {
|
||||
cf.temp1.value = (form[5]*1.8+32).toFixed(2);
|
||||
cf.temp1.value = (t_raw*1.8+32).toFixed(2);
|
||||
cf.temp1_c.value = form[5];
|
||||
}
|
||||
|
||||
@@ -102,27 +136,27 @@ function SetFormDefaults() {
|
||||
|
||||
// Offset
|
||||
i = Number(form[8]);
|
||||
s_str = (i==0) ? "+" : "-";
|
||||
var s_str = (i==0) ? "+" : "-"; // scratch var — its declaration moved here when C1 deleted the input-source ternary that used to declare it
|
||||
cf.hz1.value = s_str + form[9];
|
||||
|
||||
// FWD Power & SNR
|
||||
var rawFwd = Number(form[10]);
|
||||
cf.fwd.value = (ab_modenum==1) ? "N/A" : (rawFwd + " %");
|
||||
cf.fwd.value = (ab_modenum==1) ? "N/A-FSSI" : (rawFwd + " %");
|
||||
|
||||
// SNR. Half-dB from the app, shown as-is (PR12 removed the old fixed
|
||||
// +10 dB display offset; this is the true measured MER).
|
||||
var tmpdata = Number(form[11]);
|
||||
var snrStr = (tmpdata/2).toFixed(1);
|
||||
cf.tsnr.value = (ab_modenum==1) ? "N/A" : snrStr;
|
||||
cf.tsnr.value = (ab_modenum==1) ? "N/A-FSSI" : 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);
|
||||
cf.l_imd.value = (ab_modenum==1) ? "N/A-FSSI" : (tmpdata/2 + 11).toFixed(1);
|
||||
|
||||
tmpdata = Number(form[13]);
|
||||
cf.u_imd.value = (ab_modenum==1) ? "N/A" : (tmpdata/2 + 11).toFixed(1);
|
||||
cf.u_imd.value = (ab_modenum==1) ? "N/A-FSSI" : (tmpdata/2 + 11).toFixed(1);
|
||||
|
||||
// Control & Amp
|
||||
cf.f1ctrl.value = (Number(form[14])==0) ? "Remote" : "Local";
|
||||
@@ -143,6 +177,13 @@ function SetFormDefaults() {
|
||||
cf.b_fssi.value = (ab_modenum==1) ? (Number(form[17]) + " %") : "N/A";
|
||||
|
||||
// AGC State
|
||||
/* FSSI active alternates the RFinA feedback path AGC realizes on,
|
||||
so AGC state (and its error codes) are not meaningful — show the
|
||||
reason instead of a misleading adjustment value. Takes priority.
|
||||
(Ported from the 1.0, status_info.html:239-243 — FSSI parity round.) */
|
||||
if(ab_modenum==1){
|
||||
s_str = "N/A-FSSI";
|
||||
} else {
|
||||
agc_err_code = Number(form[27]);
|
||||
var agc_adj = Number(form[28]);
|
||||
if(agc_err_code==1) s_str="Down Limit!";
|
||||
@@ -154,6 +195,7 @@ function SetFormDefaults() {
|
||||
s_str="OK";
|
||||
}
|
||||
}
|
||||
}
|
||||
cf.agc_state.value = s_str;
|
||||
|
||||
// --- 2. PARSE SYS_RF FOR DASHBOARD ---
|
||||
@@ -191,37 +233,40 @@ function SetFormDefaults() {
|
||||
// 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.rx_freq.value = fmtRaw(form1[1]);
|
||||
cf1.rssi.value = fmtRaw(form1[2]);
|
||||
cf1.rsnr.value = fmtRaw(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);
|
||||
cf2.v9v.value = fmtScaled(form2[1], 0.1, 2);
|
||||
cf2.v12v.value = fmtScaled(form2[2], 0.1, 2);
|
||||
cf2.v50v.value = fmtScaled(form2[3], 0.1, 2);
|
||||
cf2.pac_fwd.value = fmtScaled(form2[4], 0.1, 2);
|
||||
cf2.ref.value = fmtScaled(form2[5], 0.1, 2);
|
||||
cf2.vswr.value = fmtScaled(form2[6], 0.1, 2);
|
||||
|
||||
// PAC Temp
|
||||
if(temp_unit==0){
|
||||
cf2.temp.value = (Number(form2[7])*0.1).toFixed(2);
|
||||
// PAC Temp — R-2 guarded
|
||||
var pac_t = Number(form2[7]);
|
||||
if(!isFinite(pac_t)){
|
||||
cf2.temp.value = "--"; cf2.temp_c.value = "--";
|
||||
} else if(temp_unit==0){
|
||||
cf2.temp.value = (pac_t*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.temp.value = (pac_t*0.1*1.8+32).toFixed(2);
|
||||
cf2.temp_c.value = (pac_t*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.c50v1.value = fmtScaled(form2[9], 0.1, 2);
|
||||
cf2.c50v2.value = fmtScaled(form2[10], 0.1, 2);
|
||||
cf2.c50v3.value = fmtScaled(form2[11], 0.1, 2);
|
||||
cf2.c50v4.value = fmtScaled(form2[12], 0.1, 2);
|
||||
cf2.gv.value = fmtScaled(form2[13], 0.1, 2);
|
||||
cf2.lvl.selectedIndex = Number(form2[14]);
|
||||
|
||||
// Form 3: GPS
|
||||
@@ -252,8 +297,11 @@ function SetFormDefaults() {
|
||||
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;
|
||||
/* P-4 guard: never paint a short/absent read over a good title (R-2 class). */
|
||||
if (titleStr !== "") {
|
||||
document.getElementById('webtitle').textContent = titleStr;
|
||||
document.getElementById('webtitle_header').textContent = titleStr;
|
||||
}
|
||||
}
|
||||
|
||||
// Update Status Colors and UI helpers
|
||||
@@ -330,14 +378,15 @@ function highlightProblemTableRows() {
|
||||
}
|
||||
// SNR, LIMD, UIMD: same error thresholds as summary cards / updateStatusColors
|
||||
var id = inp.id || '';
|
||||
if (id === 'tsnr' && v !== '' && v !== 'N/A') {
|
||||
/* v.indexOf('N/A') !== 0 excludes both "N/A" and "N/A-FSSI" (FSSI-active) — 1.0 :413 pattern */
|
||||
if (id === 'tsnr' && v !== '' && v.indexOf('N/A') !== 0) {
|
||||
var snrNum = parseFloat(v); // true measured dB (PR12: no display offset)
|
||||
if (snrNum < 15) { tr.classList.add('row-has-error'); break; }
|
||||
}
|
||||
if (id === 'l_imd' && v !== '' && v !== 'N/A') {
|
||||
if (id === 'l_imd' && v !== '' && v.indexOf('N/A') !== 0) {
|
||||
if (parseFloat(v) < 47) { tr.classList.add('row-has-error'); break; }
|
||||
}
|
||||
if (id === 'u_imd' && v !== '' && v !== 'N/A') {
|
||||
if (id === 'u_imd' && v !== '' && v.indexOf('N/A') !== 0) {
|
||||
if (parseFloat(v) < 47) { tr.classList.add('row-has-error'); break; }
|
||||
}
|
||||
// License fields: INACTIVE is an error
|
||||
@@ -381,7 +430,7 @@ function updateStatusColors() {
|
||||
|
||||
// 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") {
|
||||
if(tsnrEl && tsnrEl.value !== "" && tsnrEl.value.indexOf("N/A") !== 0) {
|
||||
var snrVal = parseFloat(tsnrEl.value); // true measured dB (PR12: no display offset)
|
||||
if(snrVal >= 27) tsnrEl.style.color = color_ok;
|
||||
else if(snrVal >= 20) tsnrEl.style.color = color_warn;
|
||||
@@ -389,12 +438,12 @@ function updateStatusColors() {
|
||||
} else if(tsnrEl) tsnrEl.style.color = "";
|
||||
|
||||
var limdEl = document.getElementById("l_imd");
|
||||
if(limdEl && limdEl.value !== "" && limdEl.value !== "N/A") {
|
||||
if(limdEl && limdEl.value !== "" && limdEl.value.indexOf("N/A") !== 0) {
|
||||
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") {
|
||||
if(uimdEl && uimdEl.value !== "" && uimdEl.value.indexOf("N/A") !== 0) {
|
||||
uimdEl.style.color = parseFloat(uimdEl.value) >= 47 ? color_ok : color_err;
|
||||
} else if(uimdEl) uimdEl.style.color = "";
|
||||
|
||||
@@ -599,7 +648,28 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
});
|
||||
|
||||
// Collapsible Tables - MAIN STATUS, PAC STATUS, GPS STATUS
|
||||
/* ST.F11 support (2026-08-05): expand the Tuner Status box if collapsed. Called only on
|
||||
the transition into tuner/translator mode by the data callback — see the port note there. */
|
||||
function autoExpandTunerStatus() {
|
||||
var headers = document.querySelectorAll('.box-header');
|
||||
for (var i = 0; i < headers.length; i++) {
|
||||
var titleSpan = headers[i].querySelector('span');
|
||||
if (titleSpan && titleSpan.innerText.indexOf('Tuner Status') !== -1) {
|
||||
if (headers[i].classList.contains('collapsed')) {
|
||||
headers[i].classList.remove('collapsed');
|
||||
var content = headers[i].nextElementSibling;
|
||||
if (content && content.className.indexOf('box-content') !== -1) {
|
||||
content.style.display = 'block';
|
||||
}
|
||||
var badge = headers[i].querySelector('.toggle-text');
|
||||
if (badge) badge.innerText = 'Hide Details';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collapsible Tables - MAIN STATUS, TUNER STATUS, PAC STATUS, GPS STATUS
|
||||
function initCollapsibleTables() {
|
||||
var headers = document.querySelectorAll('.app-main h2');
|
||||
for (var i = 0; i < headers.length; i++) {
|
||||
@@ -621,20 +691,26 @@ function initCollapsibleTables() {
|
||||
}
|
||||
|
||||
if (box) {
|
||||
/* REG-1 (2026-08-05, 1.0 C.2 port — "3.0 parity"): the primary status block
|
||||
is OPEN on load so the operator sees it without a click; every other
|
||||
section starts collapsed. Tuner Status is additionally auto-expanded on
|
||||
entering translator mode by the data callback (ST.F11) — it cannot be
|
||||
decided here because the mode is not yet read at init. */
|
||||
var startOpen = (headerText === "Main Status");
|
||||
var boxHeader = document.createElement('div');
|
||||
boxHeader.className = "box-header collapsed";
|
||||
boxHeader.className = startOpen ? "box-header" : "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";
|
||||
toggleSpan.innerText = startOpen ? "Hide Details" : "View Details";
|
||||
|
||||
boxHeader.appendChild(titleSpan);
|
||||
boxHeader.appendChild(toggleSpan);
|
||||
|
||||
var contentDiv = document.createElement('div');
|
||||
contentDiv.className = "box-content";
|
||||
contentDiv.style.display = "none";
|
||||
contentDiv.style.display = startOpen ? "block" : "none";
|
||||
|
||||
while (box.firstChild) {
|
||||
contentDiv.appendChild(box.firstChild);
|
||||
@@ -683,17 +759,17 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="refresh_show()">
|
||||
<body onload="refresh_show()">
|
||||
<div class="app-layout">
|
||||
<aside class="app-sidebar">
|
||||
<ul class="items">
|
||||
<li><a href="overview.html" title="Overview">Overview</a></li>
|
||||
<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="sys_spectrum.html" title="RF Performance">RF Performance</a></li>
|
||||
<li><a href="log_output.html" title="Log">Log</a></li>
|
||||
</ul>
|
||||
<div class="sidebar-footer">
|
||||
@@ -713,8 +789,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
</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">
|
||||
<h3 class="has-toggle">
|
||||
<div class="utility-cluster">
|
||||
<button class="theme-toggle" onclick="toggleTheme()" aria-label="Switch color theme" title="Switch color theme">
|
||||
<span class="tt-sun" aria-hidden="true"><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="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg></span>
|
||||
<span class="tt-moon" aria-hidden="true"><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="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg></span>
|
||||
<span class="tt-label"><span class="tt-to-light">Light Mode</span><span class="tt-to-dark">Dark Mode</span></span>
|
||||
</button>
|
||||
<span class="utility-divider" aria-hidden="true"></span>
|
||||
<div class="dropdown">
|
||||
<button class="dropbtn-modern">Admin ▾</button>
|
||||
<div class="dropdown-content">
|
||||
<a href="#" onclick="openAccountModal(); return false;">
|
||||
@@ -734,7 +817,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</h3>
|
||||
</div>
|
||||
</h3>
|
||||
</header>
|
||||
|
||||
<!-- Fixed Dashboard Summary - Top of page, under header -->
|
||||
@@ -760,16 +844,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
<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>
|
||||
@@ -780,6 +854,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
<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_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-off" id="dot_rf" aria-hidden="true"></span>
|
||||
|
||||
Reference in New Issue
Block a user