Fix TruthValue handling for different firmware versions
Some Accedian firmware reports SNMP TruthValue fields as '1'/'2' (INTEGER) while others use 'true'/'false' (textual). Add isTrue() helper that accepts both formats and replace all 15+ boolean checks across the viewer (present, diagCapable, active, enabled, filter enable flags, etc). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4daf26b778
commit
bcb179e7e4
@ -734,6 +734,9 @@ function formatUptime(sec) {{
|
|||||||
p.push(s+'s');
|
p.push(s+'s');
|
||||||
return p.join(' ');
|
return p.join(' ');
|
||||||
}}
|
}}
|
||||||
|
// SNMP TruthValue: some agents return '1'/'2', others 'true'/'false'
|
||||||
|
function isTrue(v) {{ return v === '1' || v === 'true' || v === true; }}
|
||||||
|
|
||||||
// Derive data ports and management port from connectors dynamically
|
// Derive data ports and management port from connectors dynamically
|
||||||
function getPortLists() {{
|
function getPortLists() {{
|
||||||
const connectors = DATA.connectors || {{}};
|
const connectors = DATA.connectors || {{}};
|
||||||
@ -990,7 +993,7 @@ function renderHeader() {{
|
|||||||
const cfgByNum = {{}};
|
const cfgByNum = {{}};
|
||||||
for (const [k,v] of Object.entries(alarmCfg)) cfgByNum[v.number] = v;
|
for (const [k,v] of Object.entries(alarmCfg)) cfgByNum[v.number] = v;
|
||||||
for (const [k,a] of Object.entries(alarmStatus)) {{
|
for (const [k,a] of Object.entries(alarmStatus)) {{
|
||||||
if (a.active === '1') {{
|
if (isTrue(a.active)) {{
|
||||||
activeCount++;
|
activeCount++;
|
||||||
const cfg = cfgByNum[a.number];
|
const cfg = cfgByNum[a.number];
|
||||||
if (cfg) sevCounts[cfg.severity] = (sevCounts[cfg.severity]||0) + 1;
|
if (cfg) sevCounts[cfg.severity] = (sevCounts[cfg.severity]||0) + 1;
|
||||||
@ -1137,7 +1140,7 @@ function renderPanel() {{
|
|||||||
const iface = ifaces[connIdx];
|
const iface = ifaces[connIdx];
|
||||||
if (connType(connIdx) === 'sfp') {{
|
if (connType(connIdx) === 'sfp') {{
|
||||||
const sfp = sfpInfo[connIdx];
|
const sfp = sfpInfo[connIdx];
|
||||||
const present = sfp && sfp.present === '1';
|
const present = sfp && isTrue(sfp.present);
|
||||||
if (!present) return 'empty';
|
if (!present) return 'empty';
|
||||||
if (iface && isUp(iface.ifOperStatus)) return 'present-link';
|
if (iface && isUp(iface.ifOperStatus)) return 'present-link';
|
||||||
return 'present-nolink';
|
return 'present-nolink';
|
||||||
@ -1152,7 +1155,7 @@ function renderPanel() {{
|
|||||||
function sfpLabel(connIdx) {{
|
function sfpLabel(connIdx) {{
|
||||||
const sfp = sfpInfo[connIdx];
|
const sfp = sfpInfo[connIdx];
|
||||||
if (!sfp) return '';
|
if (!sfp) return '';
|
||||||
if (sfp.present !== '1') return 'EMPTY';
|
if (!isTrue(sfp.present)) return 'EMPTY';
|
||||||
const pn = sfp.vendorPn || '';
|
const pn = sfp.vendorPn || '';
|
||||||
if (pn.length > 8) return pn.substring(0,8);
|
if (pn.length > 8) return pn.substring(0,8);
|
||||||
return pn || sfp.vendor || '';
|
return pn || sfp.vendor || '';
|
||||||
@ -1214,7 +1217,7 @@ function renderPanel() {{
|
|||||||
// Power feeds
|
// Power feeds
|
||||||
let pwrHtml = '<div class="pwr-block">';
|
let pwrHtml = '<div class="pwr-block">';
|
||||||
for (const [k,p] of Object.entries(pwr)) {{
|
for (const [k,p] of Object.entries(pwr)) {{
|
||||||
const ok = p.present === '1';
|
const ok = isTrue(p.present);
|
||||||
pwrHtml += `<div><span class="pwr-led ${{ok?'ok':'fail'}}"></span>${{esc(p.name)}} ${{ok?'OK':'ABSENT'}}</div>`;
|
pwrHtml += `<div><span class="pwr-led ${{ok?'ok':'fail'}}"></span>${{esc(p.name)}} ${{ok?'OK':'ABSENT'}}</div>`;
|
||||||
}}
|
}}
|
||||||
pwrHtml += '</div>';
|
pwrHtml += '</div>';
|
||||||
@ -1336,7 +1339,7 @@ function renderSfp() {{
|
|||||||
const thresh = sfpThresh[si] || {{}};
|
const thresh = sfpThresh[si] || {{}};
|
||||||
const conn = connectors[si] || {{}};
|
const conn = connectors[si] || {{}};
|
||||||
|
|
||||||
if (!info || info.present !== '1') {{
|
if (!info || !isTrue(info.present)) {{
|
||||||
cards += `<div class="sfp-detail" id="sfp-detail-${{si}}">
|
cards += `<div class="sfp-detail" id="sfp-detail-${{si}}">
|
||||||
<div class="card-dark" style="border-left:3px solid #555">
|
<div class="card-dark" style="border-left:3px solid #555">
|
||||||
<div class="card-body" style="text-align:center;color:#555;padding:2rem">
|
<div class="card-body" style="text-align:center;color:#555;padding:2rem">
|
||||||
@ -1348,7 +1351,7 @@ function renderSfp() {{
|
|||||||
continue;
|
continue;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
const ddm = info.diagCapable === '1';
|
const ddm = isTrue(info.diagCapable);
|
||||||
const ddmBadge = ddm
|
const ddmBadge = ddm
|
||||||
? '<span class="badge bg-success">DDM Supported</span>'
|
? '<span class="badge bg-success">DDM Supported</span>'
|
||||||
: '<span class="badge bg-secondary">DDM Not Supported</span>';
|
: '<span class="badge bg-secondary">DDM Not Supported</span>';
|
||||||
@ -1405,8 +1408,8 @@ function renderSfp() {{
|
|||||||
<h6 style="font-size:0.8rem;color:var(--text-muted)">CAPABILITIES</h6>
|
<h6 style="font-size:0.8rem;color:var(--text-muted)">CAPABILITIES</h6>
|
||||||
<div style="font-size:0.82rem">
|
<div style="font-size:0.82rem">
|
||||||
<div>DDM Capable: <strong>${{ddm ? 'Yes' : 'No'}}</strong></div>
|
<div>DDM Capable: <strong>${{ddm ? 'Yes' : 'No'}}</strong></div>
|
||||||
<div>Internal Cal: <strong>${{info.internalCal==='1' ? 'Yes' : 'No'}}</strong></div>
|
<div>Internal Cal: <strong>${{isTrue(info.internalCal) ? 'Yes' : 'No'}}</strong></div>
|
||||||
<div>Alarm Capable: <strong>${{info.alarmCapable==='1' ? 'Yes' : 'No'}}</strong></div>
|
<div>Alarm Capable: <strong>${{isTrue(info.alarmCapable) ? 'Yes' : 'No'}}</strong></div>
|
||||||
<div>SFF-8472 Rev: <strong>${{esc(info.rev8472)}}</strong></div>
|
<div>SFF-8472 Rev: <strong>${{esc(info.rev8472)}}</strong></div>
|
||||||
<div>ID Type: <strong>${{esc(info.idType)}}</strong></div>
|
<div>ID Type: <strong>${{esc(info.idType)}}</strong></div>
|
||||||
<div>Ext ID: <strong>${{esc(info.extIdType)}}</strong></div>
|
<div>Ext ID: <strong>${{esc(info.extIdType)}}</strong></div>
|
||||||
@ -1447,7 +1450,7 @@ function renderAlarms() {{
|
|||||||
// Collect active alarms (when status table available)
|
// Collect active alarms (when status table available)
|
||||||
const active = [];
|
const active = [];
|
||||||
for (const [k,a] of Object.entries(alarmStatus)) {{
|
for (const [k,a] of Object.entries(alarmStatus)) {{
|
||||||
if (a.active === '1') {{
|
if (isTrue(a.active)) {{
|
||||||
const cfg = cfgByNum[a.number] || {{}};
|
const cfg = cfgByNum[a.number] || {{}};
|
||||||
active.push({{ ...a, ...cfg, _statusId: k }});
|
active.push({{ ...a, ...cfg, _statusId: k }});
|
||||||
}}
|
}}
|
||||||
@ -1489,7 +1492,7 @@ function renderAlarms() {{
|
|||||||
<td>${{esc(c.description)}}</td>`;
|
<td>${{esc(c.description)}}</td>`;
|
||||||
if (hasSeverity) rows += `
|
if (hasSeverity) rows += `
|
||||||
<td><span class="badge ${{sevClass(c.severity)}}">${{sevLabel(c.severity)}}</span></td>
|
<td><span class="badge ${{sevClass(c.severity)}}">${{sevLabel(c.severity)}}</span></td>
|
||||||
<td>${{c.enabled === '1' ? '<span style="color:var(--green)">Yes</span>' : '<span style="color:var(--text-muted)">No</span>'}}</td>`;
|
<td>${{isTrue(c.enabled) ? '<span style="color:var(--green)">Yes</span>' : '<span style="color:var(--text-muted)">No</span>'}}</td>`;
|
||||||
if (hasCondition) rows += `
|
if (hasCondition) rows += `
|
||||||
<td class="mono">${{esc(c.conditionType)}}</td>
|
<td class="mono">${{esc(c.conditionType)}}</td>
|
||||||
<td class="mono">${{esc(c.amoType)}}</td>`;
|
<td class="mono">${{esc(c.amoType)}}</td>`;
|
||||||
@ -1636,12 +1639,12 @@ function renderFilters() {{
|
|||||||
let rows = '';
|
let rows = '';
|
||||||
for (const [id, f] of Object.entries(filters)) {{
|
for (const [id, f] of Object.entries(filters)) {{
|
||||||
const conditions = [];
|
const conditions = [];
|
||||||
if (f.macDstEn === '1') conditions.push('MAC Dst: ' + esc(f.macDst));
|
if (isTrue(f.macDstEn)) conditions.push('MAC Dst: ' + esc(f.macDst));
|
||||||
if (f.macSrcEn === '1') conditions.push('MAC Src: ' + esc(f.macSrc));
|
if (isTrue(f.macSrcEn)) conditions.push('MAC Src: ' + esc(f.macSrc));
|
||||||
if (f.etypeEn === '1') conditions.push('EType: ' + esc(f.etype));
|
if (isTrue(f.etypeEn)) conditions.push('EType: ' + esc(f.etype));
|
||||||
if (f.vlan1IdEn === '1') conditions.push('VLAN1: ' + esc(f.vlan1Id));
|
if (isTrue(f.vlan1IdEn)) conditions.push('VLAN1: ' + esc(f.vlan1Id));
|
||||||
if (f.vlan2IdEn === '1') conditions.push('VLAN2: ' + esc(f.vlan2Id));
|
if (isTrue(f.vlan2IdEn)) conditions.push('VLAN2: ' + esc(f.vlan2Id));
|
||||||
if (f.vlan1PriorEn === '1') conditions.push('PCP1: ' + esc(f.vlan1Prior));
|
if (isTrue(f.vlan1PriorEn)) conditions.push('PCP1: ' + esc(f.vlan1Prior));
|
||||||
const condStr = conditions.length ? conditions.join(', ') : '<span class="status-na">any (catchall)</span>';
|
const condStr = conditions.length ? conditions.join(', ') : '<span class="status-na">any (catchall)</span>';
|
||||||
|
|
||||||
rows += `<tr>
|
rows += `<tr>
|
||||||
@ -1802,7 +1805,7 @@ function renderLldp() {{
|
|||||||
const iface = ifaces[portIdx];
|
const iface = ifaces[portIdx];
|
||||||
if (isSfp) {{
|
if (isSfp) {{
|
||||||
const sfp = sfpInfo[portIdx];
|
const sfp = sfpInfo[portIdx];
|
||||||
const present = sfp && sfp.present === '1';
|
const present = sfp && isTrue(sfp.present);
|
||||||
if (!present) return 'empty';
|
if (!present) return 'empty';
|
||||||
if (iface && isUp(iface.ifOperStatus)) return 'present-link';
|
if (iface && isUp(iface.ifOperStatus)) return 'present-link';
|
||||||
return 'present-nolink';
|
return 'present-nolink';
|
||||||
@ -2005,7 +2008,7 @@ function renderCoverage() {{
|
|||||||
// Check SFP DDM
|
// Check SFP DDM
|
||||||
const sfpInfo = DATA.sfp_info || {{}};
|
const sfpInfo = DATA.sfp_info || {{}};
|
||||||
for (const [k,s] of Object.entries(sfpInfo)) {{
|
for (const [k,s] of Object.entries(sfpInfo)) {{
|
||||||
if (s.present === '1' && s.diagCapable !== '1') {{
|
if (isTrue(s.present) && !isTrue(s.diagCapable)) {{
|
||||||
gaps.push({{
|
gaps.push({{
|
||||||
type: 'red',
|
type: 'red',
|
||||||
text: `SFP-${{k}} DDM: Not available via SNMP (diagCapable=false). NID web UI reads SFP I2C bus directly.`
|
text: `SFP-${{k}} DDM: Not available via SNMP (diagCapable=false). NID web UI reads SFP I2C bus directly.`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user