v1.4.5 — Page WiFi: oublier réseau + badge hotspot sidebar + refonte UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,28 @@
|
|||||||
{
|
{
|
||||||
"versions": [
|
"versions": [
|
||||||
|
{
|
||||||
|
"version": "1.4.5",
|
||||||
|
"date": "2026-03-17",
|
||||||
|
"changes": {
|
||||||
|
"features": [
|
||||||
|
"Page WiFi: bouton Oublier le reseau pour passer en mode hotspot sans reboot",
|
||||||
|
"Sidebar: badge Mode Hotspot visible sur toutes les pages quand le capteur est en hotspot (lien vers page WiFi)"
|
||||||
|
],
|
||||||
|
"improvements": [
|
||||||
|
"Page WiFi: refonte UI avec cards contextuelles (infos connexion si connecte, scan si hotspot)",
|
||||||
|
"Page WiFi: affichage detaille de la connexion WiFi (SSID, signal, IP, passerelle, hostname, frequence, securite)",
|
||||||
|
"Page WiFi: chargement automatique des infos au chargement (plus de bouton Get Data)",
|
||||||
|
"Page WiFi: scan WiFi masque quand deja connecte (inutile)",
|
||||||
|
"Page WiFi: migration de config.json vers get_config_sqlite (coherent avec les autres pages)",
|
||||||
|
"topbar-logo.js: gestion centralisee du nom capteur sidebar et badge hotspot pour toutes les pages"
|
||||||
|
],
|
||||||
|
"fixes": [
|
||||||
|
"Correction VERSION 1.4.3 -> 1.4.4 (fichier VERSION non mis a jour lors du commit precedent)"
|
||||||
|
],
|
||||||
|
"compatibility": []
|
||||||
|
},
|
||||||
|
"notes": "Le bouton Oublier le reseau supprime la connexion WiFi sauvegardee et demarre le hotspot immediatement (pas de reboot necessaire). Le badge hotspot dans la sidebar permet de voir rapidement le mode reseau depuis n'importe quelle page."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"date": "2026-03-16",
|
"date": "2026-03-16",
|
||||||
|
|||||||
42
forget_wifi.sh
Normal file
42
forget_wifi.sh
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo "-------"
|
||||||
|
echo "Start forget WiFi shell script at $(date)"
|
||||||
|
|
||||||
|
# Get deviceName from database for hotspot SSID
|
||||||
|
DEVICE_NAME=$(sqlite3 /var/www/nebuleair_pro_4g/sqlite/sensors.db "SELECT value FROM config_table WHERE key='deviceName'")
|
||||||
|
echo "Device Name: $DEVICE_NAME"
|
||||||
|
|
||||||
|
# Get current active WiFi connection name
|
||||||
|
ACTIVE_WIFI=$(nmcli -t -f NAME,TYPE,DEVICE connection show --active | grep ':802-11-wireless:wlan0' | cut -d: -f1)
|
||||||
|
|
||||||
|
if [ -z "$ACTIVE_WIFI" ]; then
|
||||||
|
echo "No active WiFi connection found on wlan0"
|
||||||
|
echo "End forget WiFi shell script"
|
||||||
|
echo "-------"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Forgetting WiFi connection: $ACTIVE_WIFI"
|
||||||
|
|
||||||
|
# Delete (forget) the saved connection
|
||||||
|
sudo nmcli connection delete "$ACTIVE_WIFI"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Connection '$ACTIVE_WIFI' deleted successfully"
|
||||||
|
else
|
||||||
|
echo "Failed to delete connection '$ACTIVE_WIFI'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Start hotspot
|
||||||
|
echo "Starting hotspot with SSID: $DEVICE_NAME"
|
||||||
|
sudo nmcli device wifi hotspot ifname wlan0 ssid "$DEVICE_NAME" password nebuleaircfg
|
||||||
|
|
||||||
|
# Update SQLite to reflect hotspot mode
|
||||||
|
sqlite3 /var/www/nebuleair_pro_4g/sqlite/sensors.db "UPDATE config_table SET value='hotspot' WHERE key='WIFI_status'"
|
||||||
|
echo "Updated database: WIFI_status = hotspot"
|
||||||
|
echo "Hotspot started with SSID: $DEVICE_NAME"
|
||||||
|
|
||||||
|
echo "End forget WiFi shell script"
|
||||||
|
echo "-------"
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
* Global configuration handler for UI elements
|
* Global configuration handler for UI elements
|
||||||
* - Updates Topbar Logo based on device type
|
* - Updates Topbar Logo based on device type
|
||||||
* - Shows/Hides "Screen" sidebar tab based on device type
|
* - Shows/Hides "Screen" sidebar tab based on device type
|
||||||
|
* - Updates sidebar device name
|
||||||
|
* - Shows hotspot badge in sidebar when in hotspot mode
|
||||||
*/
|
*/
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
let config = null;
|
let config = null;
|
||||||
@@ -42,17 +44,28 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (navScreenElements.length > 0) {
|
if (navScreenElements.length > 0) {
|
||||||
navScreenElements.forEach(navScreen => {
|
navScreenElements.forEach(navScreen => {
|
||||||
if (isModuleAirPro) {
|
if (isModuleAirPro) {
|
||||||
// Ensure it's visible (bootstrap nav-link usually block or flex)
|
|
||||||
if (navScreen.style.display === 'none') {
|
if (navScreen.style.display === 'none') {
|
||||||
navScreen.style.display = 'flex';
|
navScreen.style.display = 'flex';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Hide if not pro
|
|
||||||
if (navScreen.style.display !== 'none') {
|
if (navScreen.style.display !== 'none') {
|
||||||
navScreen.style.display = 'none';
|
navScreen.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Sidebar device name
|
||||||
|
if (config.deviceName) {
|
||||||
|
document.querySelectorAll('.sideBar_sensorName').forEach(el => {
|
||||||
|
el.textContent = config.deviceName;
|
||||||
|
});
|
||||||
|
document.title = config.deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Hotspot badge in sidebar
|
||||||
|
document.querySelectorAll('.sidebar-hotspot-badge').forEach(badge => {
|
||||||
|
badge.style.display = (config.WIFI_status === 'hotspot') ? '' : 'none';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1042,35 +1042,64 @@ if ($type == "sara_sendMessage") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($type == "internet") {
|
if ($type == "internet") {
|
||||||
//eth0
|
// eth0
|
||||||
$command = 'nmcli -g GENERAL.STATE device show eth0';
|
$eth0_connStatus = str_replace("\n", "", shell_exec('nmcli -g GENERAL.STATE device show eth0 2>/dev/null'));
|
||||||
$eth0_connStatus = shell_exec($command);
|
$eth0_IPAddr = str_replace("\n", "", shell_exec('nmcli -g IP4.ADDRESS device show eth0 2>/dev/null'));
|
||||||
$eth0_connStatus = str_replace("\n", "", $eth0_connStatus);
|
|
||||||
$command = 'nmcli -g IP4.ADDRESS device show eth0';
|
|
||||||
$eth0_IPAddr = shell_exec($command);
|
|
||||||
$eth0_IPAddr = str_replace("\n", "", $eth0_IPAddr);
|
|
||||||
|
|
||||||
//wlan0
|
// wlan0 basic
|
||||||
$command = 'nmcli -g GENERAL.STATE device show wlan0';
|
$wlan0_connStatus = str_replace("\n", "", shell_exec('nmcli -g GENERAL.STATE device show wlan0 2>/dev/null'));
|
||||||
$wlan0_connStatus = shell_exec($command);
|
$wlan0_IPAddr = str_replace("\n", "", shell_exec('nmcli -g IP4.ADDRESS device show wlan0 2>/dev/null'));
|
||||||
$wlan0_connStatus = str_replace("\n", "", $wlan0_connStatus);
|
|
||||||
$command = 'nmcli -g IP4.ADDRESS device show wlan0';
|
|
||||||
$wlan0_IPAddr = shell_exec($command);
|
|
||||||
$wlan0_IPAddr = str_replace("\n", "", $wlan0_IPAddr);
|
|
||||||
|
|
||||||
$data= array(
|
// wlan0 detailed info (connection name, signal, frequency, security, gateway, etc.)
|
||||||
|
$wlan0_connection = str_replace("\n", "", shell_exec("nmcli -t -f GENERAL.CONNECTION device show wlan0 2>/dev/null | cut -d: -f2"));
|
||||||
|
$wlan0_gateway = str_replace("\n", "", shell_exec('nmcli -g IP4.GATEWAY device show wlan0 2>/dev/null'));
|
||||||
|
|
||||||
|
// Get active WiFi details (signal, frequency, security) from nmcli
|
||||||
|
$wifi_signal = '';
|
||||||
|
$wifi_freq = '';
|
||||||
|
$wifi_security = '';
|
||||||
|
$wifi_ssid = '';
|
||||||
|
$wifi_output = shell_exec('nmcli -t -f ACTIVE,SSID,SIGNAL,FREQ,SECURITY device wifi list ifname wlan0 2>/dev/null');
|
||||||
|
if ($wifi_output) {
|
||||||
|
$lines = explode("\n", trim($wifi_output));
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
// Active connection line starts with "yes:" (nmcli -t uses : separator)
|
||||||
|
if (strpos($line, 'yes:') === 0) {
|
||||||
|
// Format: yes:SSID:SIGNAL:FREQ:SECURITY
|
||||||
|
// Use explode with limit to handle SSIDs containing ':'
|
||||||
|
$parts = explode(':', $line);
|
||||||
|
if (count($parts) >= 5) {
|
||||||
|
$wifi_ssid = $parts[1];
|
||||||
|
$wifi_signal = $parts[2];
|
||||||
|
$wifi_freq = $parts[3];
|
||||||
|
$wifi_security = $parts[4];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hostname
|
||||||
|
$hostname = trim(shell_exec('hostname 2>/dev/null'));
|
||||||
|
|
||||||
|
$data = array(
|
||||||
"ethernet" => array(
|
"ethernet" => array(
|
||||||
"connection" => $eth0_connStatus,
|
"connection" => $eth0_connStatus,
|
||||||
"IP" => $eth0_IPAddr
|
"IP" => $eth0_IPAddr
|
||||||
),
|
),
|
||||||
"wifi" => array(
|
"wifi" => array(
|
||||||
"connection" => $wlan0_connStatus,
|
"connection" => $wlan0_connStatus,
|
||||||
"IP" => $wlan0_IPAddr
|
"IP" => $wlan0_IPAddr,
|
||||||
|
"ssid" => $wifi_ssid ?: $wlan0_connection,
|
||||||
|
"signal" => $wifi_signal,
|
||||||
|
"frequency" => $wifi_freq,
|
||||||
|
"security" => $wifi_security,
|
||||||
|
"gateway" => $wlan0_gateway,
|
||||||
|
"hostname" => $hostname
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$json_data = json_encode($data);
|
|
||||||
|
|
||||||
echo $json_data;
|
echo json_encode($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
# IMPORTANT
|
# IMPORTANT
|
||||||
@@ -1126,6 +1155,51 @@ if ($type == "wifi_connect") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($type == "wifi_forget") {
|
||||||
|
// Get device name from database
|
||||||
|
try {
|
||||||
|
$db = new PDO("sqlite:$database_path");
|
||||||
|
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
$stmt = $db->prepare("SELECT value FROM config_table WHERE key = 'deviceName'");
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
$deviceName = $result ? $result['value'] : 'NebuleAir';
|
||||||
|
$db = null;
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$deviceName = 'NebuleAir';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Launch forget script in background
|
||||||
|
$script_path = '/var/www/nebuleair_pro_4g/forget_wifi.sh';
|
||||||
|
$log_file = '/var/www/nebuleair_pro_4g/logs/app.log';
|
||||||
|
shell_exec("$script_path >> $log_file 2>&1 &");
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'deviceName' => $deviceName,
|
||||||
|
'instructions' => [
|
||||||
|
'fr' => [
|
||||||
|
'title' => 'Réseau WiFi oublié',
|
||||||
|
'step1' => "Le capteur oublie le réseau WiFi actuel",
|
||||||
|
'step2' => "Le hotspot va démarrer automatiquement",
|
||||||
|
'step3' => "Connectez-vous au WiFi « $deviceName » (mot de passe : nebuleaircfg)",
|
||||||
|
'step4' => "Accédez au capteur via http://192.168.43.1/html/",
|
||||||
|
'warning' => "Le capteur ne se reconnectera plus automatiquement à ce réseau"
|
||||||
|
],
|
||||||
|
'en' => [
|
||||||
|
'title' => 'WiFi network forgotten',
|
||||||
|
'step1' => "The sensor is forgetting the current WiFi network",
|
||||||
|
'step2' => "The hotspot will start automatically",
|
||||||
|
'step3' => "Connect to WiFi « $deviceName » (password: nebuleaircfg)",
|
||||||
|
'step4' => "Access the sensor via http://192.168.43.1/html/",
|
||||||
|
'warning' => "The sensor will no longer auto-connect to this network"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($type == "wifi_scan") {
|
if ($type == "wifi_scan") {
|
||||||
|
|
||||||
// Perform live WiFi scan instead of reading stale CSV file
|
// Perform live WiFi scan instead of reading stale CSV file
|
||||||
|
|||||||
@@ -92,7 +92,17 @@
|
|||||||
<!-- New content at the bottom -->
|
<!-- New content at the bottom -->
|
||||||
<div class="sidebar-footer text-center text-white">
|
<div class="sidebar-footer text-center text-white">
|
||||||
<hr>
|
<hr>
|
||||||
<span class="sideBar_sensorName"> NebuleAir</span>
|
<span class="sideBar_sensorName">NebuleAir</span>
|
||||||
|
<div class="sidebar-hotspot-badge mt-2" style="display:none;">
|
||||||
|
<a href="wifi.html" class="text-decoration-none">
|
||||||
|
<span class="badge text-bg-warning w-100 py-2" style="font-size: 0.75rem;">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" class="bi bi-broadcast me-1" viewBox="0 0 16 16">
|
||||||
|
<path d="M3.05 3.05a7 7 0 0 0 0 9.9.5.5 0 0 1-.707.707 8 8 0 0 1 0-11.314.5.5 0 0 1 .707.707m2.122 2.122a4 4 0 0 0 0 5.656.5.5 0 1 1-.708.708 5 5 0 0 1 0-7.072.5.5 0 0 1 .708.708m5.656-.708a.5.5 0 0 1 .708 0 5 5 0 0 1 0 7.072.5.5 0 1 1-.708-.708 4 4 0 0 0 0-5.656.5.5 0 0 1 0-.708m2.122-2.12a.5.5 0 0 1 .707 0 8 8 0 0 1 0 11.313.5.5 0 0 1-.707-.707 7 7 0 0 0 0-9.9.5.5 0 0 1 0-.707zM10 8a2 2 0 1 1-4 0 2 2 0 0 1 4 0"/>
|
||||||
|
</svg>
|
||||||
|
Mode Hotspot
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
415
html/wifi.html
415
html/wifi.html
@@ -54,39 +54,126 @@
|
|||||||
|
|
||||||
<h3>Status
|
<h3>Status
|
||||||
<span id="wifi-status" class="badge">Loading...</span>
|
<span id="wifi-status" class="badge">Loading...</span>
|
||||||
|
<button id="btn-forget-wifi" class="btn btn-outline-danger btn-sm ms-2" style="display:none;" onclick="wifi_forget()">Oublier le réseau</button>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
|
|
||||||
<div class="col-sm-4">
|
<!-- Connection Info Card (shown when connected to WiFi) -->
|
||||||
<div class="card text-dark bg-light">
|
<div class="col-sm-6" id="card-connection-info" style="display:none;">
|
||||||
|
<div class="card border-success">
|
||||||
|
<div class="card-header bg-success text-white">
|
||||||
|
<h5 class="card-title mb-0">Connexion WiFi</h5>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">WIFI / Ethernet</h5>
|
<div id="connection-info-loading" class="text-center py-3">
|
||||||
<p class="card-text">General information.</p>
|
<div class="spinner-border spinner-border-sm text-primary" role="status"></div>
|
||||||
<button class="btn btn-primary" onclick="get_internet()">Get Data</button>
|
<span class="ms-2">Chargement...</span>
|
||||||
<table class="table table-striped-columns">
|
</div>
|
||||||
<tbody id="data-table-body_internet_general"></tbody>
|
<table class="table table-sm mb-0" id="connection-info-table" style="display:none;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted" style="width:40%">SSID</td>
|
||||||
|
<td><strong id="info-ssid">-</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted">Signal</td>
|
||||||
|
<td><span id="info-signal-bar"></span> <span id="info-signal">-</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted">Adresse IP</td>
|
||||||
|
<td><code id="info-ip">-</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted">Passerelle</td>
|
||||||
|
<td><code id="info-gateway">-</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted">Hostname</td>
|
||||||
|
<td><code id="info-hostname">-</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted">Frequence</td>
|
||||||
|
<td id="info-freq">-</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted">Securite</td>
|
||||||
|
<td id="info-security">-</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<button class="btn btn-outline-primary btn-sm mt-2" onclick="get_internet()">Rafraichir</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Ethernet Card -->
|
||||||
|
<div class="col-sm-6" id="card-ethernet">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title mb-0">Ethernet</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-sm mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted" style="width:40%">Etat</td>
|
||||||
|
<td id="info-eth-status">-</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-muted">Adresse IP</td>
|
||||||
|
<td><code id="info-eth-ip">-</code></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-8">
|
<!-- Hotspot Info Card (shown when in hotspot mode) -->
|
||||||
<div class="card text-dark bg-light">
|
<div class="col-sm-6" id="card-hotspot-info" style="display:none;">
|
||||||
|
<div class="card border-warning">
|
||||||
|
<div class="card-header bg-warning">
|
||||||
|
<h5 class="card-title mb-0">Mode Hotspot</h5>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Wifi Scan</h5>
|
<p class="mb-1">Le capteur n'est connecte a aucun reseau WiFi.</p>
|
||||||
<p class="card-text">Scan des réseaux WIFI disponibles.</p>
|
<p class="text-muted mb-0">Utilisez le scan ci-dessous pour vous connecter a un reseau.</p>
|
||||||
<button class="btn btn-primary" onclick="wifi_scan()">Scan</button>
|
</div>
|
||||||
<table class="table">
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- WiFi Scan Card (hidden when connected) -->
|
||||||
|
<div class="row mb-3" id="card-wifi-scan" style="display:none;">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="card-title mb-0">Reseaux WiFi disponibles</h5>
|
||||||
|
<button class="btn btn-primary btn-sm" onclick="wifi_scan()">Scan</button>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="wifi-scan-empty" class="text-center text-muted py-3">
|
||||||
|
Cliquez sur "Scan" pour rechercher les reseaux WiFi.
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover mb-0" id="wifi-scan-table" style="display:none;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>SSID</th>
|
||||||
|
<th>Signal</th>
|
||||||
|
<th>Securite</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
<tbody id="data-table-body_wifi_scan"></tbody>
|
<tbody id="data-table-body_wifi_scan"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</table>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal WIFI PASSWORD -->
|
<!-- Modal WIFI PASSWORD -->
|
||||||
<!-- filled with JS -->
|
|
||||||
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -147,34 +234,67 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function get_internet(){
|
function load_ethernet_info() {
|
||||||
console.log("Getting internet general infos");
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'launcher.php?type=internet',
|
url: 'launcher.php?type=internet',
|
||||||
dataType: 'json', // Specify that you expect a JSON response
|
dataType: 'json',
|
||||||
method: 'GET', // Use GET or POST depending on your needs
|
method: 'GET',
|
||||||
|
success: function(response) {
|
||||||
|
const eth = response.ethernet;
|
||||||
|
document.getElementById('info-eth-status').textContent = eth.connection || '-';
|
||||||
|
document.getElementById('info-eth-ip').textContent = eth.IP || '-';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSignalBadge(signal) {
|
||||||
|
const val = parseInt(signal, 10);
|
||||||
|
if (isNaN(val)) return '';
|
||||||
|
let color, label;
|
||||||
|
if (val >= 70) { color = 'success'; label = 'Excellent'; }
|
||||||
|
else if (val >= 50) { color = 'primary'; label = 'Bon'; }
|
||||||
|
else if (val >= 30) { color = 'warning'; label = 'Faible'; }
|
||||||
|
else { color = 'danger'; label = 'Tres faible'; }
|
||||||
|
return `<span class="badge text-bg-${color}">${val}% — ${label}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_internet(){
|
||||||
|
console.log("Getting internet general infos");
|
||||||
|
document.getElementById('connection-info-loading').style.display = '';
|
||||||
|
document.getElementById('connection-info-table').style.display = 'none';
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: 'launcher.php?type=internet',
|
||||||
|
dataType: 'json',
|
||||||
|
method: 'GET',
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
let tableBody = document.getElementById('data-table-body_internet_general');
|
const wifi = response.wifi;
|
||||||
tableBody.innerHTML = ''; // Clear existing table content
|
const eth = response.ethernet;
|
||||||
|
|
||||||
// Iterate through the data and create rows
|
// WiFi info
|
||||||
for (let key in response) {
|
document.getElementById('info-ssid').textContent = wifi.ssid || '-';
|
||||||
let row = `
|
document.getElementById('info-signal').innerHTML = wifi.signal ? getSignalBadge(wifi.signal) : '-';
|
||||||
<tr>
|
document.getElementById('info-ip').textContent = wifi.IP || '-';
|
||||||
<td>${key}</td>
|
document.getElementById('info-gateway').textContent = wifi.gateway || '-';
|
||||||
<td>${response[key].connection}</td>
|
document.getElementById('info-hostname').textContent = wifi.hostname || '-';
|
||||||
<td>${response[key].IP ? response[key].IP : "No IP"}</td>
|
document.getElementById('info-freq').textContent = wifi.frequency ? wifi.frequency + ' MHz' : '-';
|
||||||
</tr>
|
document.getElementById('info-security').textContent = wifi.security || '-';
|
||||||
`;
|
|
||||||
tableBody.innerHTML += row; // Append row to table body
|
// Ethernet info
|
||||||
}
|
const ethStatus = eth.connection || '-';
|
||||||
|
document.getElementById('info-eth-status').textContent = ethStatus;
|
||||||
|
document.getElementById('info-eth-ip').textContent = eth.IP || '-';
|
||||||
|
|
||||||
|
document.getElementById('connection-info-loading').style.display = 'none';
|
||||||
|
document.getElementById('connection-info-table').style.display = '';
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function(xhr, status, error) {
|
||||||
console.error('AJAX request failed:', status, error);
|
console.error('AJAX request failed:', status, error);
|
||||||
|
document.getElementById('connection-info-loading').innerHTML = '<span class="text-danger">Erreur de chargement</span>';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function wifi_connect(SSID, PASS){
|
function wifi_connect(SSID, PASS){
|
||||||
@@ -293,150 +413,207 @@ function get_internet(){
|
|||||||
}, 30000);
|
}, 30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wifi_forget(){
|
||||||
|
if (!confirm('Oublier le réseau WiFi actuel et passer en mode hotspot ?')) return;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: 'launcher.php?type=wifi_forget',
|
||||||
|
dataType: 'json',
|
||||||
|
method: 'GET',
|
||||||
|
success: function(response) {
|
||||||
|
console.log(response);
|
||||||
|
showForgetStatus(response);
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('AJAX request failed:', status, error);
|
||||||
|
alert('Error: Could not forget WiFi network');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showForgetStatus(response) {
|
||||||
|
const lang = localStorage.getItem('language') || 'fr';
|
||||||
|
const instructions = response.instructions[lang] || response.instructions['fr'];
|
||||||
|
|
||||||
|
const overlay = document.createElement('div');
|
||||||
|
overlay.id = 'connection-status-overlay';
|
||||||
|
overlay.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.9);
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
`;
|
||||||
|
|
||||||
|
overlay.innerHTML = `
|
||||||
|
<div style="max-width: 600px; padding: 40px; text-align: center;">
|
||||||
|
<div class="spinner-border text-warning mb-4" role="status" style="width: 4rem; height: 4rem;">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="mb-4">${instructions.title}</h2>
|
||||||
|
|
||||||
|
<div class="alert alert-info text-start" role="alert">
|
||||||
|
<ol class="mb-0" style="padding-left: 20px;">
|
||||||
|
<li class="mb-2"><strong>${instructions.step1}</strong></li>
|
||||||
|
<li class="mb-2">${instructions.step2}</li>
|
||||||
|
<li class="mb-2">${instructions.step3}</li>
|
||||||
|
<li class="mb-2">${instructions.step4}</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-warning text-start" role="alert">
|
||||||
|
<strong>Important:</strong> ${instructions.warning}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4">
|
||||||
|
<p class="text-muted">
|
||||||
|
${lang === 'fr' ? 'Hotspot' : 'Hotspot'}:
|
||||||
|
<strong class="text-white">${response.deviceName}</strong>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (document.getElementById('connection-status-overlay')) {
|
||||||
|
document.getElementById('connection-status-overlay').remove();
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
function wifi_scan(){
|
function wifi_scan(){
|
||||||
console.log("Scanning Wifi");
|
console.log("Scanning Wifi");
|
||||||
|
document.getElementById('wifi-scan-empty').innerHTML = '<div class="spinner-border spinner-border-sm text-primary" role="status"></div> Scan en cours...';
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'launcher.php?type=wifi_scan',
|
url: 'launcher.php?type=wifi_scan',
|
||||||
dataType: 'json', // Specify that you expect a JSON response
|
dataType: 'json',
|
||||||
method: 'GET', // Use GET or POST depending on your needs
|
method: 'GET',
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
const tableBody = document.getElementById("data-table-body_wifi_scan");
|
const tableBody = document.getElementById("data-table-body_wifi_scan");
|
||||||
|
|
||||||
// Clear the existing table body
|
|
||||||
tableBody.innerHTML = "";
|
tableBody.innerHTML = "";
|
||||||
|
|
||||||
// Loop through the wifiNetworks array and create rows
|
if (response.length === 0) {
|
||||||
|
document.getElementById('wifi-scan-empty').textContent = 'Aucun reseau WiFi trouve.';
|
||||||
|
document.getElementById('wifi-scan-empty').style.display = '';
|
||||||
|
document.getElementById('wifi-scan-table').style.display = 'none';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('wifi-scan-empty').style.display = 'none';
|
||||||
|
document.getElementById('wifi-scan-table').style.display = '';
|
||||||
|
|
||||||
response.forEach(network => {
|
response.forEach(network => {
|
||||||
const row = document.createElement("tr");
|
const row = document.createElement("tr");
|
||||||
|
|
||||||
// Create and append cells for SSID, BARS, and SIGNAL
|
// SSID
|
||||||
const ssidCell = document.createElement("td");
|
const ssidCell = document.createElement("td");
|
||||||
// Truncate SSID to 25 characters
|
const truncatedSSID = network.SSID.length > 25 ? network.SSID.substring(0, 25) + '...' : network.SSID;
|
||||||
const truncatedSSID = network.SSID.length > 20 ? network.SSID.substring(0, 20) + '...' : network.SSID;
|
|
||||||
ssidCell.textContent = truncatedSSID;
|
ssidCell.textContent = truncatedSSID;
|
||||||
row.appendChild(ssidCell);
|
row.appendChild(ssidCell);
|
||||||
|
|
||||||
/*
|
// Signal with badge
|
||||||
const signalCell = document.createElement("td");
|
const signalCell = document.createElement("td");
|
||||||
signalCell.textContent = network.SIGNAL;
|
signalCell.innerHTML = getSignalBadge(network.SIGNAL);
|
||||||
row.appendChild(signalCell);
|
row.appendChild(signalCell);
|
||||||
*/
|
|
||||||
|
|
||||||
// Create a button
|
// Security
|
||||||
|
const securityCell = document.createElement("td");
|
||||||
|
securityCell.textContent = network.SECURITY || '--';
|
||||||
|
securityCell.classList.add('text-muted');
|
||||||
|
row.appendChild(securityCell);
|
||||||
|
|
||||||
|
// Connect button
|
||||||
const buttonCell = document.createElement("td");
|
const buttonCell = document.createElement("td");
|
||||||
|
buttonCell.classList.add('text-end');
|
||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.textContent = "Connect"; // Button text
|
button.textContent = "Connecter";
|
||||||
button.classList.add("btn", "btn-primary"); // Bootstrap button classes
|
button.classList.add("btn", "btn-primary", "btn-sm");
|
||||||
|
|
||||||
// Determine button color based on SIGNAL value
|
|
||||||
const signalValue = parseInt(network.SIGNAL, 10); // Assuming SIGNAL is a numeric value
|
|
||||||
// Calculate color based on the signal strength
|
|
||||||
let buttonColor;
|
|
||||||
if (signalValue >= 100) {
|
|
||||||
buttonColor = "success"; // Green for strong signal
|
|
||||||
} else if (signalValue >= 50) {
|
|
||||||
buttonColor = "warning"; // Yellow for moderate signal
|
|
||||||
} else {
|
|
||||||
buttonColor = "danger"; // Red for weak signal
|
|
||||||
}
|
|
||||||
// Add Bootstrap button classes along with color
|
|
||||||
button.classList.add("btn", `btn-${buttonColor}`);
|
|
||||||
|
|
||||||
|
|
||||||
//Trigger function as soon as the button is clicked
|
|
||||||
button.addEventListener("click", () => wifi_connect(network.SSID));
|
button.addEventListener("click", () => wifi_connect(network.SSID));
|
||||||
|
|
||||||
|
|
||||||
// Append the button to the button cell
|
|
||||||
buttonCell.appendChild(button);
|
buttonCell.appendChild(button);
|
||||||
row.appendChild(buttonCell);
|
row.appendChild(buttonCell);
|
||||||
|
|
||||||
// Append the row to the table body
|
|
||||||
tableBody.appendChild(row);
|
tableBody.appendChild(row);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function(xhr, status, error) {
|
||||||
console.error('AJAX request failed:', status, error);
|
console.error('AJAX request failed:', status, error);
|
||||||
|
document.getElementById('wifi-scan-empty').innerHTML = '<span class="text-danger">Erreur lors du scan</span>';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function confirmSubmit() {
|
|
||||||
// You can display a simple confirmation message or customize the behavior
|
|
||||||
return confirm("Are you sure you want to connect to this Wi-Fi network?");
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'
|
$.ajax({
|
||||||
.then(response => response.json()) // Parse response as JSON
|
url: 'launcher.php?type=get_config_sqlite',
|
||||||
.then(data => {
|
dataType: 'json',
|
||||||
console.log("Getting config file (onload)");
|
method: 'GET',
|
||||||
//get device ID
|
success: function(data) {
|
||||||
const deviceID = data.deviceID.trim().toUpperCase();
|
console.log("Getting SQLite config table (wifi page):");
|
||||||
//document.getElementById('pageTitle_plus_ID').innerText = 'token: ' + deviceID;
|
console.log(data);
|
||||||
|
|
||||||
//get device Name
|
// WiFi connection status — toggle cards
|
||||||
const deviceName = data.deviceName;
|
|
||||||
|
|
||||||
// Function to update sidebar device name
|
|
||||||
function updateSidebarDeviceName(deviceName) {
|
|
||||||
const elements = document.querySelectorAll('.sideBar_sensorName');
|
|
||||||
if (elements.length > 0) {
|
|
||||||
elements.forEach((element) => {
|
|
||||||
element.innerText = deviceName;
|
|
||||||
});
|
|
||||||
console.log("Device name updated in sidebar:", deviceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update device name immediately and with retries to handle async sidebar loading
|
|
||||||
if (deviceName) {
|
|
||||||
updateSidebarDeviceName(deviceName);
|
|
||||||
// Retry after delays to catch async sidebar load
|
|
||||||
setTimeout(() => updateSidebarDeviceName(deviceName), 100);
|
|
||||||
setTimeout(() => updateSidebarDeviceName(deviceName), 500);
|
|
||||||
|
|
||||||
//device name html page title
|
|
||||||
document.title = deviceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//get wifi connection status
|
|
||||||
const WIFI_statusElement = document.getElementById("wifi-status");
|
const WIFI_statusElement = document.getElementById("wifi-status");
|
||||||
console.log("WIFI is: " + data.WIFI_status);
|
console.log("WIFI is: " + data.WIFI_status);
|
||||||
|
|
||||||
if (data.WIFI_status === "connected") {
|
if (data.WIFI_status === "connected") {
|
||||||
WIFI_statusElement.textContent = "Connected";
|
WIFI_statusElement.textContent = "Connected";
|
||||||
WIFI_statusElement.className = "badge text-bg-success";
|
WIFI_statusElement.className = "badge text-bg-success";
|
||||||
|
document.getElementById('btn-forget-wifi').style.display = 'inline-block';
|
||||||
|
document.getElementById('card-connection-info').style.display = '';
|
||||||
|
document.getElementById('card-hotspot-info').style.display = 'none';
|
||||||
|
document.getElementById('card-wifi-scan').style.display = 'none';
|
||||||
|
// Auto-load connection details
|
||||||
|
get_internet();
|
||||||
} else if (data.WIFI_status === "hotspot") {
|
} else if (data.WIFI_status === "hotspot") {
|
||||||
WIFI_statusElement.textContent = "Hotspot";
|
WIFI_statusElement.textContent = "Hotspot";
|
||||||
WIFI_statusElement.className = "badge text-bg-warning";
|
WIFI_statusElement.className = "badge text-bg-warning";
|
||||||
|
document.getElementById('btn-forget-wifi').style.display = 'none';
|
||||||
|
document.getElementById('card-connection-info').style.display = 'none';
|
||||||
|
document.getElementById('card-hotspot-info').style.display = '';
|
||||||
|
document.getElementById('card-wifi-scan').style.display = '';
|
||||||
} else {
|
} else {
|
||||||
WIFI_statusElement.textContent = "Unknown";
|
WIFI_statusElement.textContent = "Unknown";
|
||||||
WIFI_statusElement.className = "badge text-bg-secondary";
|
WIFI_statusElement.className = "badge text-bg-secondary";
|
||||||
|
document.getElementById('btn-forget-wifi').style.display = 'none';
|
||||||
|
document.getElementById('card-connection-info').style.display = 'none';
|
||||||
|
document.getElementById('card-hotspot-info').style.display = 'none';
|
||||||
|
document.getElementById('card-wifi-scan').style.display = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
//get local RTC
|
// Always load ethernet info
|
||||||
$.ajax({
|
load_ethernet_info();
|
||||||
url: 'launcher.php?type=RTC_time',
|
|
||||||
dataType: 'text', // Specify that you expect a JSON response
|
|
||||||
method: 'GET', // Use GET or POST depending on your needs
|
|
||||||
success: function(response) {
|
|
||||||
console.log("Local RTC: " + response);
|
|
||||||
const RTC_Element = document.getElementById("RTC_time");
|
|
||||||
RTC_Element.textContent = response;
|
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function(xhr, status, error) {
|
||||||
console.error('AJAX request failed:', status, error);
|
console.error('AJAX request failed:', status, error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load RTC time
|
||||||
})
|
$.ajax({
|
||||||
.catch(error => console.error('Error loading config.json:', error));
|
url: 'launcher.php?type=RTC_time',
|
||||||
|
dataType: 'text',
|
||||||
|
method: 'GET',
|
||||||
|
success: function(response) {
|
||||||
|
const RTC_Element = document.getElementById("RTC_time");
|
||||||
|
if (RTC_Element) RTC_Element.textContent = response;
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('AJAX request failed:', status, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user