The system has 3 ways to communicate with the end user.
Sample web page to control the unit from a button:
Basically, this webpage holds div containers that can ba loaded from json data provided by websocket transactions from javascript called from a button action.
<!DOCTYPE html>
<html lang="en" class="js csstransforms3d">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content=""VSCode editor">
<meta name="description" content="Kialex T-Sim esp32 module">
<meta name="author" content="JP Coenen">
<title>Kialex T-Sim esp32 module</title>
</head>
<body>
<header>
<h1>T-Sim esp32 module</h1>
</header>
<main>
<div id='status'>
<button id='gpsreading'>GPS Reading</button>
</div>
<BR>
<div id='boutons'>
<button id='location'>Location (gps)</button>
<button id='state'>Get State</button>
<button id='upload'>Upload to SD</button>
<button id='files'>SD DIr</button>
<button id='gps-ws'>WS gps</button>
<button id='gpsquery'>is GPS Valid ?</button>
<button id='Rconnect'>Reconnect modem</button>
<button id='OTA'>OTA</button>
<button id='home'>Home</button><br>
</div>
<H2>Called HTML pages</H2>
<div id='box' style="border: thin solid black"></div>
<H3>Websocket message</H3>
<div id='ws-data' style="border: thin solid black"></div>
<script>
const socket = new WebSocket('ws://kialex.local/ws');
socket.onopen = function(event) {
// Handle connection open
};
socket.onmessage = function(event) {
document.getElementById('ws-data').innerHTML = "<pre>"+JSON.stringify(JSON.parse(event.data),null,2)+"</pre>";
const wsmsg = JSON.parse(event.data);
if (Object.hasOwn(wsmsg, 'gpsreading') ) {
document.getElementById('gpsreading').innerHTML = wsmsg.gpsreading;
if (wsmsg.gpsreading == 'valid') {
document.getElementById('gpsreading').style.backgroundColor = 'lightgreen';
document.getElementById('gpsreading').removeAttribute("disabled");
} else {
document.getElementById('gpsreading').style.backgroundColor = 'red';
document.getElementById('gpsreading').setAttribute("disabled", "disabled");
}
}
};
socket.onclose = function(event) {
// Handle connection close
};
function sendMessage(message) {
console.log('Sending message: ' + message);
socket.send(message);
}
async function getData(url) {
console.log('getData '+url)
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
const result = await response.text();
console.log(result);
document.getElementById('box').innerHTML = result;
} catch (error) {
console.error(error.message);
}
}
document.getElementById('location').onclick = function() { console.log('calling getdata'); getData('gps'); };
document.getElementById('state').onclick = function() { console.log('calling getdata'); getData('status'); };
document.getElementById('upload').onclick = function() {console.log('calling getdata'); getData('upload')};
document.getElementById('files').onclick = function() {console.log('calling getdata'); getData('files')};
document.getElementById('gps-ws').onclick = function() {console.log('Sending gps to ws'); sendMessage("gps");};
document.getElementById('gpsquery').onclick = function() {console.log('Sending gps to ws'); sendMessage("valid");};
document.getElementById('gpsreading').onclick = function() { console.log('Sending GPS to ws'); sendMessage("GPS");};
document.getElementById('Rconnect').onclick = function() { console.log('Reconnecting modem'); sendMessage("connect");};
document.getElementById('OTA').onclick = function() {location.replace('/update');};
document.getElementById('home').onclick = function() {location.replace('');};
function delfile(fichier) {alert("del:/"+fichier.name); sendMessage("del:/"+fichier.name);};
</script>
</main>
<footer>
<p>© 2025 JP Coenen</p>
</footer>
</body>
</html>