Files
quectel-rgmii-toolkit/simpleadmin/www/bandlock.html
2024-03-27 10:55:54 +08:00

330 lines
11 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AT Commands</title>
<script src="/js/alpinejs.min.js" defer></script>
<link rel="stylesheet" href="/css/bulma.css" />
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
<link rel="stylesheet" href="styles.css" />
<style>
.container {
display: flex;
justify-content: center;
}
.card-column {
margin-bottom: 20px;
}
</style>
</head>
<body>
<!-- START NAV -->
<nav class="navbar is-black" x-data="{ isOpen: false }">
<div class="container">
<div class="navbar-brand">
<a class="navbar-item brand-text" href="/"> Simple Admin </a>
<a
role="button"
class="navbar-burger burger"
@click="isOpen = !isOpen"
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div
id="navMenu"
class="navbar-menu"
:class="isOpen ? 'is-active' : ''"
>
<div class="navbar-start">
<a class="navbar-item" href="/"> Connection Info </a>
<a class="navbar-item" href="/atcommander.html"> AT Commands </a>
<a class="navbar-item" href="/bandlock.html"> Band Locking </a>
<a class="navbar-item" href="/sms.html"> SMS </a>
<a class="navbar-item" href="/ttl.html"> TTL Changer </a>
<a class="navbar-item" href="/speedtest.html"> Speedtest </a>
</div>
</div>
</div>
</nav>
<!-- END NAV -->
<div class="container" x-data="atCommands()">
<div class="columns is-multiline">
<div class="column is-8-tablet is-6-desktop card-column">
<div class="card">
<header class="card-header">
<p class="card-header-title">Band Locking</p>
</header>
<div class="card-content">
<!-- Create a drop down -->
<div class="select is-primary">
<select x-model="networkMode">
<option>Select Network Mode</option>
<option>LTE</option>
<option>NR5G-NSA</option>
<option>NR5G-SA</option>
</select>
</div>
<input
class="input is-primary"
type="text"
placeholder="Example: 1,3,41"
style="margin-top: 1rem"
x-model="bandNumbers"
/>
<div style="margin-top: 1rem; display: flex; flex-direction: row">
<button
class="button is-primary"
@click="lockBands()"
:disabled="isLocking"
>
Lock Bands
</button>
<button
class="button is-warning"
style="margin-left: 1rem"
@click="restoreBands()"
:disabled="isLocking"
>
Restore Bands
</button>
</div>
</div>
<div class="card-footer" style="padding: 0.25rem">
<p class="card-footer-item">
Please first select your desired network band from the dropdown
menu. To lock onto specific bands, please type the band numbers
separated by commas (,) and then click the lock button.
</p>
</div>
</div>
</div>
<div class="column is-8-tablet is-6-desktop card-column">
<div class="card">
<header class="card-header">
<p class="card-header-title">Cell Locking</p>
</header>
<div class="card-content">
<div style="display: flex; flex-direction: row">
<div class="select is-info">
<select id="networkModeSelect">
<option>Select Network Mode</option>
<option>LTE</option>
<option>NR5G-SA</option>
</select>
</div>
<div class="select is-info" style="margin-left: 1rem">
<select id="numFreqSelect" onchange="showInputs()">
<option>Number of Freq</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
</div>
<div id="inputsContainer" style="margin-top: 1.5rem"></div>
<div style="margin-top: 1rem; display: flex; flex-direction: row">
<button class="button is-info">Lock Cell</button>
<button class="button is-warning" style="margin-left: 1rem">
Restore Cell
</button>
</div>
</div>
<div class="card-footer" style="padding: 0.25rem">
<p class="card-footer-item">
To utilize cell locking, ensure you first select the network
mode, followed by specifying the number of frequencies you wish
to lock onto. Then, input the EARFCN and PCI values for each
frequency before clicking the lock button.
</p>
</div>
</div>
</div>
</div>
<!-- Loading Modal for Locking Band -->
<div x-show="isLocking" class="modal-overlay">
<div class="loading-modal">
<div class="spinner"></div>
<div
class="loading-text"
style="display: flex; flex-direction: column"
>
<h3>Initializing Network...</h3>
<p style="margin-top: 0.5rem">
Please wait for
<span x-text="countdown" style="font-weight: 500"></span> seconds.
</p>
</div>
</div>
</div>
<div x-show="isError" class="modal-overlay">
<div class="loading-modal">
<div class="spinner"></div>
<div
class="loading-text"
style="display: flex; flex-direction: column"
>
<h3>Request Error</h3>
<p style="margin-top: 0.5rem">
Please follow the instructions properly. Exiting in
<span x-text="countdown" style="font-weight: 500"></span> seconds.
</p>
</div>
</div>
</div>
</div>
<script>
function showInputs() {
const numFreq = document.getElementById("numFreqSelect").value;
const container = document.getElementById("inputsContainer");
container.innerHTML = ""; // Clear previous inputs
for (let i = 1; i <= numFreq; i++) {
const div = document.createElement("div");
div.style.marginTop = "0.5rem";
div.style.display = "flex";
div.style.flexDirection = "row";
const earfcnInput = document.createElement("input");
earfcnInput.className = "input is-info";
earfcnInput.type = "text";
earfcnInput.placeholder = "EARFCN";
const pciInput = document.createElement("input");
pciInput.className = "input is-info";
pciInput.type = "text";
pciInput.placeholder = "PCI";
pciInput.style.marginLeft = "0.5rem";
div.appendChild(earfcnInput);
div.appendChild(pciInput);
container.appendChild(div);
}
}
function atCommands() {
return {
isLoading: false,
isLocking: false,
isError: false,
countdown: 3, // Initial countdown value
networkMode: null,
bandNumbers: null,
atCommandResponse: "",
lockBands() {
if (!this.networkMode || !this.bandNumbers) {
this.isError = true;
this.startCountdown();
console.error("Network mode and band numbers are required.");
return;
}
// Remove commas and replace with colons
const parsedBandNumbers = this.bandNumbers.replace(/,/g, ":");
// Construct the atcmd based on the selected network mode
let atcmd;
switch (this.networkMode) {
case "LTE":
atcmd = `AT+QNWPREFCFG="lte_band",${parsedBandNumbers}`;
console.log(atcmd);
break;
case "NR5G-NSA":
atcmd = `AT+QNWPREFCFG="nsa_nr5g_band",${parsedBandNumbers}`;
console.log(atcmd);
break;
case "NR5G-SA":
atcmd = `AT+QNWPREFCFG="nr5g_band",${parsedBandNumbers}`;
console.log(atcmd);
break;
default:
console.error("Invalid network mode.");
return;
}
this.isLoading = true;
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: atcmd,
})
)
.then((res) => res.text())
.then((data) => {
this.atCommandResponse = data;
this.isLocking = true;
this.startCountdown();
})
.catch((error) => {
this.isError = true;
this.startCountdown();
console.error("Error sending AT command:", error);
})
.finally(() => {
this.isLoading = false;
});
},
restoreBands() {
const restoreCmd = 'AT+QNWPREFCFG="restore_band"';
this.sendAtCommand(restoreCmd);
},
sendAtCommand(atcmd) {
this.isLocking = true;
this.startCountdown();
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: atcmd,
})
)
.then((res) => res.text())
.then((data) => {
this.atCommandResponse = data;
this.isLocking = true;
this.startCountdown();
})
.catch((error) => {
this.isError = true;
this.startCountdown();
console.error("Error sending AT command:", error);
})
.finally(() => {
this.isLoading = false;
});
},
startCountdown() {
// Decrease countdown every second
const interval = setInterval(() => {
this.countdown--;
if (this.countdown === 0) {
clearInterval(interval);
// Reset values
this.isLocking = false;
this.isError = false;
this.countdown = 3;
// Optionally refresh the page here
}
}, 1000);
},
};
}
</script>
</body>
</html>