Merge pull request #159 from diijkstra/web_sfp_state

Web: Add SFP state/pin status
This commit is contained in:
logicog
2026-03-19 05:22:24 +01:00
committed by GitHub
3 changed files with 37 additions and 13 deletions
+22 -6
View File
@@ -93,32 +93,48 @@ function update(callback) {
iHTML += "<tr><td align=\"left\">Link speed</td><td>:</td><td>" + linkS[p.link + 1] + "</td></tr>"; iHTML += "<tr><td align=\"left\">Link speed</td><td>:</td><td>" + linkS[p.link + 1] + "</td></tr>";
if (p.isSFP) { if (p.isSFP) {
pAdvertised[n] = 0; pAdvertised[n] = 0;
const hasExtendedStatus = p.sfp_options & 0x40;
iHTML += "<tr><td>Vendor</td><td>:</td><td>" + p.sfp_vendor + "</td></tr>"; iHTML += "<tr><td>Vendor</td><td>:</td><td>" + p.sfp_vendor + "</td></tr>";
iHTML += "<tr><td>Model</td><td>:</td><td>" + p.sfp_model + "</td></tr>"; iHTML += "<tr><td>Model</td><td>:</td><td>" + p.sfp_model + "</td></tr>";
iHTML += "<tr><td>Serial</td><td>:</td><td>" + p.sfp_serial + "</td></tr>"; iHTML += "<tr><td>Serial</td><td>:</td><td>" + p.sfp_serial + "</td></tr>";
if (p.sfp_options & 0x40) { if (hasExtendedStatus) {
iHTML += "<tr><td>Temp</td><td>:</td><td>" + (Number(p.sfp_temp) >> 8) + "." + ((Number(p.sfp_temp) & 0xff)/256.0 * 100).toFixed(0) + "&#8239;&#8451;</td></tr>"; iHTML += "<tr><td>Temp</td><td>:</td><td>" + (Number(p.sfp_temp) >> 8) + "." + ((Number(p.sfp_temp) & 0xff)/256.0 * 100).toFixed(0) + "&#8239;&#8451;</td></tr>";
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + (Number(p.sfp_vcc) / 10000.0).toFixed(2) + "&#8239;V</td></tr>"; iHTML += "<tr><td>Vcc</td><td>:</td><td>" + (Number(p.sfp_vcc) / 10000.0).toFixed(2) + "&#8239;V</td></tr>";
iHTML += "<tr><td>TX-Fault</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x4)) + "</td></tr>";
iHTML += "<tr><td>TX-Disabled</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x80)) + "</td></tr>";
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + (Number(p.sfp_txbias) / 500.0).toFixed(1) + "&#8239;mA</td></tr>"; iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + (Number(p.sfp_txbias) / 500.0).toFixed(1) + "&#8239;mA</td></tr>";
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + (Number(p.sfp_txpower) / 10.0).toFixed(0) + "&#8239;mW</td></tr>"; iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + (Number(p.sfp_txpower) / 10.0).toFixed(0) + "&#8239;mW</td></tr>";
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + (Number(p.sfp_rxpower) / 10.0).toFixed(0) + "&#8239;mW</td></tr>"; iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + (Number(p.sfp_rxpower) / 10.0).toFixed(0) + "&#8239;mW</td></tr>";
} }
// Not all devices & modules have LOS pin...
const rx_los_pin = p.sfp_los !== null ? Boolean(Number(p.sfp_los)) : null;
const rx_los_module = hasExtendedStatus ? Boolean(Number(p.sfp_state) & 0x2) : null;
if (rx_los_module !== null || rx_los_pin !== null) {
iHTML += `<tr><td>RX-LOS</td><td>:</td><td>${rxLosHTML(rx_los_pin, rx_los_module)}</td></tr>`;
}
} else { } else {
pAdvertised[n] = parseInt(p.adv, 2); pAdvertised[n] = parseInt(p.adv, 2);
} };
iHTML += "</table>"; iHTML += "</table>";
tt.innerHTML = iHTML; tt.innerHTML = iHTML;
} }}
}
if (callback) if (callback)
callback(); callback();
} }};
};
xhttp.open("GET", "/status.json", true); xhttp.open("GET", "/status.json", true);
xhttp.timeout = 5000; xhttp.timeout = 5000;
sendXHTTP(xhttp); sendXHTTP(xhttp);
} }
function rxLosHTML(pinStatus, moduleStatus) {
if (moduleStatus !== null && pinStatus !== null && moduleStatus !== pinStatus) {
return `pin=${pinStatus}<br/>mod=${moduleStatus}<br/>❗❗❗❗`;
}
// Returns first non null value
return moduleStatus ?? pinStatus;
}
function callbackXHTTP() function callbackXHTTP()
{ {
x = currentRequests.shift(); x = currentRequests.shift();
+6 -1
View File
@@ -655,7 +655,12 @@ void send_status(void)
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\""); slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
for (register uint8_t s = 0; s < 16; s++) for (register uint8_t s = 0; s < 16; s++)
outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s]; outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s];
char_to_html('"'); slen += strtox(outbuf + slen,"\",\"sfp_los\":");
if (machine.sfp_port[machine.is_sfp[i]-1].pin_los == GPIO_NA) {
slen += strtox(outbuf + slen,"null");
} else {
bool_to_html(sfp_pins_last & (0x2 << (((machine.is_sfp[i]-1) << 2))));
}
} else { } else {
bool_to_html(0); bool_to_html(0);
} }
+3
View File
@@ -124,6 +124,9 @@ __code uint16_t bit_mask[16] = {
__xdata uint8_t linkbits_last[4]; __xdata uint8_t linkbits_last[4];
__xdata uint8_t linkbits_last_p89; __xdata uint8_t linkbits_last_p89;
// Last known state of the SFP detection/Loss of Signal pins
// SFP1 b0 = 1 => module missing, b1 = 1 => LOS;
// SFP2 b4 = 1 => module missing, b5 = 1 => LOS;
__xdata uint8_t sfp_pins_last; __xdata uint8_t sfp_pins_last;
__xdata char sfp_module_vendor[2][17]; __xdata char sfp_module_vendor[2][17];
__xdata char sfp_module_model[2][17]; __xdata char sfp_module_model[2][17];