feat(ui): add signal and network tests to self-test

Add two more tests to the modem self-test:
- Test 3: Signal Strength (AT+CSQ) with quality thresholds
- Test 4: Network Connection (AT+COPS?) with operator name lookup
Respects 1 second delay between each AT command.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
PaulVua
2026-02-10 10:33:51 +01:00
parent 49a4623d85
commit 3c8558ea1d

View File

@@ -392,6 +392,24 @@
</div> </div>
<span id="test_sim_status" class="badge bg-secondary">Pending</span> <span id="test_sim_status" class="badge bg-secondary">Pending</span>
</div> </div>
<!-- Test 3: Signal Strength -->
<div class="list-group-item d-flex justify-content-between align-items-center" id="test_signal">
<div>
<strong>Signal Strength</strong>
<div class="small text-muted" id="test_signal_detail">Waiting...</div>
</div>
<span id="test_signal_status" class="badge bg-secondary">Pending</span>
</div>
<!-- Test 4: Network Connection -->
<div class="list-group-item d-flex justify-content-between align-items-center" id="test_network">
<div>
<strong>Network Connection</strong>
<div class="small text-muted" id="test_network_detail">Waiting...</div>
</div>
<span id="test_network_status" class="badge bg-secondary">Pending</span>
</div>
</div> </div>
<!-- Logs section --> <!-- Logs section -->
@@ -1501,6 +1519,14 @@ function resetSelfTestUI() {
document.getElementById('test_sim_status').textContent = 'Pending'; document.getElementById('test_sim_status').textContent = 'Pending';
document.getElementById('test_sim_detail').textContent = 'Waiting...'; document.getElementById('test_sim_detail').textContent = 'Waiting...';
document.getElementById('test_signal_status').className = 'badge bg-secondary';
document.getElementById('test_signal_status').textContent = 'Pending';
document.getElementById('test_signal_detail').textContent = 'Waiting...';
document.getElementById('test_network_status').className = 'badge bg-secondary';
document.getElementById('test_network_status').textContent = 'Pending';
document.getElementById('test_network_detail').textContent = 'Waiting...';
// Reset logs // Reset logs
document.getElementById('selftest_logs').innerHTML = ''; document.getElementById('selftest_logs').innerHTML = '';
@@ -1656,6 +1682,117 @@ async function selfTestSequence() {
testsFailed++; testsFailed++;
} }
// Delay between AT commands
await delay(1000);
// Step 4: Test Signal Strength (AT+CSQ)
document.getElementById('selftest_status').innerHTML = `
<div class="d-flex align-items-center text-primary">
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
<span>Testing signal strength...</span>
</div>`;
updateTestStatus('signal', 'Testing...', 'Sending AT+CSQ command...', 'bg-info');
try {
const signalResponse = await sendATCommand('AT+CSQ', 5);
const csqMatch = signalResponse.match(/\+CSQ:\s*(\d+),(\d+)/);
if (signalResponse.includes('OK') && csqMatch) {
const signalPower = parseInt(csqMatch[1]);
const qual = parseInt(csqMatch[2]);
if (signalPower === 99) {
updateTestStatus('signal', 'Failed', 'No signal detected', 'bg-danger');
testsFailed++;
} else if (signalPower === 0) {
updateTestStatus('signal', 'Warning', 'Very poor signal (0/31)', 'bg-warning');
testsFailed++;
} else if (signalPower <= 24) {
updateTestStatus('signal', 'Passed', `Poor signal (${signalPower}/31)`, 'bg-success');
testsPassed++;
} else if (signalPower <= 26) {
updateTestStatus('signal', 'Passed', `Good signal (${signalPower}/31)`, 'bg-success');
testsPassed++;
} else if (signalPower <= 28) {
updateTestStatus('signal', 'Passed', `Very good signal (${signalPower}/31)`, 'bg-success');
testsPassed++;
} else {
updateTestStatus('signal', 'Passed', `Excellent signal (${signalPower}/31)`, 'bg-success');
testsPassed++;
}
} else if (signalResponse.includes('ERROR')) {
updateTestStatus('signal', 'Failed', 'Unable to read signal', 'bg-danger');
testsFailed++;
} else {
updateTestStatus('signal', 'Warning', 'Unexpected response', 'bg-warning');
testsFailed++;
}
} catch (error) {
updateTestStatus('signal', 'Failed', error.message, 'bg-danger');
testsFailed++;
}
// Delay between AT commands
await delay(1000);
// Step 5: Test Network Connection (AT+COPS?)
document.getElementById('selftest_status').innerHTML = `
<div class="d-flex align-items-center text-primary">
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
<span>Testing network connection...</span>
</div>`;
updateTestStatus('network', 'Testing...', 'Sending AT+COPS? command...', 'bg-info');
try {
// Load operators data for network name lookup
let opData = null;
try {
opData = await loadOperatorsData();
} catch (e) {
addSelfTestLog('Warning: Could not load operators data');
}
const networkResponse = await sendATCommand('AT+COPS?', 5);
const copsMatch = networkResponse.match(/\+COPS:\s*(\d+)(?:,(\d+),"?([^",]+)"?,(\d+))?/);
if (networkResponse.includes('OK') && copsMatch) {
const mode = copsMatch[1];
const oper = copsMatch[3];
const act = copsMatch[4];
if (oper) {
// Get operator name from lookup table
let operatorName = oper;
if (opData && opData.operators && opData.operators[oper]) {
operatorName = opData.operators[oper].name;
}
// Get access technology
let actDesc = 'Unknown';
if (opData && opData.accessTechnology && opData.accessTechnology[act]) {
actDesc = opData.accessTechnology[act];
}
updateTestStatus('network', 'Passed', `${operatorName} (${actDesc})`, 'bg-success');
testsPassed++;
} else {
updateTestStatus('network', 'Warning', 'Not registered to network', 'bg-warning');
testsFailed++;
}
} else if (networkResponse.includes('ERROR')) {
updateTestStatus('network', 'Failed', 'Unable to get network info', 'bg-danger');
testsFailed++;
} else {
updateTestStatus('network', 'Warning', 'Unexpected response', 'bg-warning');
testsFailed++;
}
} catch (error) {
updateTestStatus('network', 'Failed', error.message, 'bg-danger');
testsFailed++;
}
} catch (error) { } catch (error) {
addSelfTestLog(`Test sequence error: ${error.message}`); addSelfTestLog(`Test sequence error: ${error.message}`);
} finally { } finally {