Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Petit prog pour esp32
#18
(29-05-2025, 07:49 PM)grostoto a écrit : bon
doit y avoir un cheveux dans le potage..

ligne 534 je met ceci:

Code :
<!-- <span class="frame-label" id="label1">Interface 1</span> -->


certes cela me supprime l'étiquette.. mais cela me supprime aussi l'affichage du 2d routeur.. (écran splitté de droite noir)

dès que je décommente, cela réapparait.
je test

oui un oubli ....il faut aussi commenter cette ligne

// label.textContent = config[`name${i}`] || `Interface ${i}`;

Code :
// ESP32 Dashboard avec mode AP pour configuration initiale
#include <WiFi.h>
#include <WebServer.h>
#include <EEPROM.h>
#include <ArduinoJson.h>

// Structure pour stocker la config en EEPROM
struct Config {
  char magic[4];  // "RMS" pour vérifier si config valide
  char ssid[32];
  char password[64];
  char dashUser[32];     // Nom d'utilisateur pour le dashboard
  char dashPass[32];     // Mot de passe pour le dashboard
  char ip1[16];
  char ip2[16];
  char ip3[16];
  char ip4[16];
  char name1[32];
  char name2[32];
  char name3[32];
  char name4[32];
};

Config config;
WebServer server(80);
bool isAPMode = false;

// Page de configuration en mode AP
const char config_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Configuration Dashboard RMS</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background: #1a1a2e;
            color: white;
        }
        .container {
            max-width: 600px;
            margin: 0 auto;
            background: rgba(255,255,255,0.1);
            padding: 30px;
            border-radius: 10px;
        }
        h1 {
            text-align: center;
            color: #4CAF50;
        }
        .section {
            background: rgba(0,0,0,0.3);
            padding: 20px;
            margin: 20px 0;
            border-radius: 5px;
        }
        h2 {
            color: #2196F3;
            margin-top: 0;
        }
        label {
            display: block;
            margin: 10px 0 5px;
        }
        input, select {
            width: 100%;
            padding: 10px;
            border: 1px solid #555;
            border-radius: 3px;
            background: #333;
            color: white;
            box-sizing: border-box;
        }
        .ip-group {
            display: grid;
            grid-template-columns: 2fr 1fr;
            gap: 10px;
            margin: 10px 0;
        }
        button {
            background: #4CAF50;
            color: white;
            padding: 12px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            width: 100%;
            margin-top: 20px;
        }
        button:hover {
            background: #45a049;
        }
        .scan-btn {
            background: #2196F3;
            margin: 10px 0;
        }
        #scanResults {
            max-height: 200px;
            overflow-y: auto;
            background: rgba(0,0,0,0.5);
            padding: 10px;
            border-radius: 3px;
            margin: 10px 0;
        }
        .network-item {
            padding: 5px;
            cursor: pointer;
            border-bottom: 1px solid #444;
        }
        .network-item:hover {
            background: rgba(255,255,255,0.1);
        }
        .loading {
            text-align: center;
            color: #4CAF50;
        }
        .info {
            background: #ff9800;
            color: black;
            padding: 10px;
            border-radius: 5px;
            margin: 10px 0;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Configuration Dashboard RMS</h1>
       
        <div class="info" id="networkInfo">
            <!-- L'info sera remplie dynamiquement -->
        </div>
       
        <div class="section">
            <h2>1. Configuration WiFi</h2>
            <div id="currentWifi" style="background: #4CAF50; color: white; padding: 10px; border-radius: 3px; margin-bottom: 10px; display: none;">
                ? Connecté à : <strong id="wifiName">---</strong>
            </div>
            <button class="scan-btn" onclick="scanNetworks()">? Scanner les réseaux</button>
            <div id="scanResults"></div>
           
            <label>SSID:</label>
            <input type="text" id="ssid" placeholder="Nom du réseau WiFi">
           
            <label>Mot de passe:</label>
            <input type="password" id="password" placeholder="Mot de passe WiFi">
        </div>
       
        <div class="section">
            <h2>2. Sécurité du Dashboard</h2>
            <label>Nom d'utilisateur:</label>
            <input type="text" id="dashUser" placeholder="admin">
           
            <label>Mot de passe:</label>
            <input type="password" id="dashPass" placeholder="Mot de passe dashboard">
            <p style="color: #aaa; font-size: 12px;">Laissez vide pour désactiver l'authentification</p>
        </div>
       
        <div class="section">
            <h2>3. Configuration des interfaces RMS</h2>
            <p style="color: #aaa;">Configurez entre 2 et 4 interfaces</p>
           
            <div class="ip-group">
                <input type="text" id="ip1" placeholder="IP Interface 1 (ex: 192.168.1.100)">
                <input type="text" id="name1" placeholder="Nom 1">
            </div>
           
            <div class="ip-group">
                <input type="text" id="ip2" placeholder="IP Interface 2 (ex: 192.168.1.101)">
                <input type="text" id="name2" placeholder="Nom 2">
            </div>
           
            <div class="ip-group">
                <input type="text" id="ip3" placeholder="IP Interface 3 (optionnel)">
                <input type="text" id="name3" placeholder="Nom 3">
            </div>
           
            <div class="ip-group">
                <input type="text" id="ip4" placeholder="IP Interface 4 (optionnel)">
                <input type="text" id="name4" placeholder="Nom 4">
            </div>
        </div>
       
        <button onclick="saveConfig()">? Sauvegarder et redémarrer</button>

        <button style="background: #666; margin-top: 10px;" onclick="window.location.href='/'">
            ↩️ Retour au Dashboard
        </button>
       
        <div id="message"></div>
    </div>
   
    <script>
        // Charger la config existante au démarrage
        window.onload = function() {
    // Afficher l'info réseau
    fetch('/networkinfo')
        .then(response => response.json())
        .then(info => {
            const networkInfo = document.getElementById('networkInfo');
            if (info.isAP) {
                networkInfo.innerHTML = 'Mode Configuration - Connectez-vous au WiFi pour continuer';
                networkInfo.style.background = '#ff9800';
            } else {
                networkInfo.innerHTML = `IP réseau : ${info.ip}`;
                networkInfo.style.background = '#4CAF50';
            }
        });
   
    fetch('/getconfig')
        .then(response => response.json())
        .then(data => {
            // Pré-remplir les IPs et noms
            if (data.ip1) document.getElementById('ip1').value = data.ip1;
            if (data.ip2) document.getElementById('ip2').value = data.ip2;
            if (data.ip3) document.getElementById('ip3').value = data.ip3;
            if (data.ip4) document.getElementById('ip4').value = data.ip4;
            if (data.name1) document.getElementById('name1').value = data.name1;
            if (data.name2) document.getElementById('name2').value = data.name2;
            if (data.name3) document.getElementById('name3').value = data.name3;
            if (data.name4) document.getElementById('name4').value = data.name4;
           
            // AJOUT : Afficher le WiFi actuel si connecté
            if (data.ssid && window.location.hostname !== '192.168.4.1') {
                document.getElementById('currentWifi').style.display = 'block';
                document.getElementById('wifiName').textContent = data.ssid;
            }
        })
        .catch(err => {
            console.log('Pas de config existante');
        });
};
       
        function scanNetworks() {
            document.getElementById('scanResults').innerHTML = '<div class="loading">Scan en cours...</div>';
           
            fetch('/scan')
                .then(response => response.json())
                .then(data => {
                    let html = '';
                    data.networks.forEach(network => {
                        html += `<div class="network-item" onclick="selectNetwork('${network.ssid}')">
                                   ? ${network.ssid} (${network.rssi} dBm)
                                 </div>`;
                    });
                    document.getElementById('scanResults').innerHTML = html || 'Aucun réseau trouvé';
                });
        }
       
        function selectNetwork(ssid) {
            document.getElementById('ssid').value = ssid;
        }
       
        function saveConfig() {
            const config = {
                ssid: document.getElementById('ssid').value,
                password: document.getElementById('password').value,
                dashUser: document.getElementById('dashUser').value,
                dashPass: document.getElementById('dashPass').value,
                ip1: document.getElementById('ip1').value,
                ip2: document.getElementById('ip2').value,
                ip3: document.getElementById('ip3').value,
                ip4: document.getElementById('ip4').value,
                name1: document.getElementById('name1').value || 'Interface 1',
                name2: document.getElementById('name2').value || 'Interface 2',
                name3: document.getElementById('name3').value || 'Interface 3',
                name4: document.getElementById('name4').value || 'Interface 4'
            };
           
            // Validation
            if (!config.ssid || !config.password) {
                alert('Veuillez remplir les informations WiFi');
                return;
            }
           
            if (!config.ip1 || !config.ip2) {
                alert('Veuillez configurer au moins 2 interfaces');
                return;
            }
           
            document.getElementById('message').innerHTML = '<div class="loading">Sauvegarde en cours...</div>';
           
            fetch('/save', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(config)
            })
            .then(response => response.text())
            .then(data => {
                document.getElementById('message').innerHTML =
                    '<div class="info">Configuration sauvegardée! Redémarrage dans 5 secondes...</div>';
                setTimeout(() => {
                    document.getElementById('message').innerHTML +=
                        '<div class="info">Connectez-vous au WiFi configuré pour accéder au dashboard</div>';
                }, 2000);
            });
        }
    </script>
</body>
</html>
)rawliteral";

// Page de login
const char login_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Dashboard RMS</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background: #1a1a2e;
            color: white;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }
        .login-box {
            background: rgba(255,255,255,0.1);
            padding: 40px;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0,0,0,0.5);
            width: 300px;
        }
        h2 {
            text-align: center;
            color: #4CAF50;
            margin-bottom: 30px;
        }
        input {
            width: 100%;
            padding: 12px;
            margin: 10px 0;
            border: 1px solid #555;
            border-radius: 5px;
            background: #333;
            color: white;
            box-sizing: border-box;
        }
        button {
            width: 100%;
            padding: 12px;
            margin-top: 20px;
            background: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background: #45a049;
        }
        .error {
            color: #ff4444;
            text-align: center;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <div class="login-box">
        <h2>? Dashboard RMS</h2>
        <form action="/login" method="POST">
            <input type="text" name="user" placeholder="Nom d'utilisateur" required>
            <input type="password" name="pass" placeholder="Mot de passe" required>
            <button type="submit">Se connecter</button>
        </form>
        <div id="error" class="error"></div>
    </div>
    <script>
        if (window.location.search.includes('error=1')) {
            document.getElementById('error').textContent = 'Identifiants incorrects';
        }
    </script>
</body>
</html>
)rawliteral";

// Page dashboard modifiée avec bouton plein écran
const char dashboard_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard RMS</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background: #222;
            font-family: Arial, sans-serif;
            height: 100vh;
            overflow: hidden;
        }
       
        #dashboard {
            display: grid;
            height: 100vh;
            gap: 2px;
            transition: all 0.3s ease;
        }
       
        #dashboard.fullscreen {
            display: block !important;
        }
       
        .layout-2 {
            grid-template-columns: 1fr 1fr;
            grid-template-rows: 1fr;
        }
       
        .layout-3 {
            grid-template-columns: 1fr 1fr;
            grid-template-rows: 1fr 1fr;
        }
        .layout-3 .frame-container:first-child {
            grid-row: span 2;
        }
       
        .layout-4 {
            grid-template-columns: 1fr 1fr;
            grid-template-rows: 1fr 1fr;
        }
       
        .frame-container {
            position: relative;
            overflow: hidden;
            background: white;
            display: none;
        }
       
        .frame-container.active {
            display: block;
        }
       
        .frame-container.fullscreen-active {
            display: block !important;
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 50;
        }
       
        .frame-wrapper {
            width: 100%;
            height: 100%;
            transform-origin: top left;
            transition: transform 0.3s ease;
        }
       
        iframe {
            width: 100%;
            height: 100%;
            border: none;
            background: white;
        }
       
        .frame-header {
            position: absolute;
            top: 5px;
            left: 5px;
            display: flex;
            align-items: center;
            gap: 10px;
            z-index: 10;
        }
       
        .frame-label {
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 5px 10px;
            font-size: 12px;
            border-radius: 3px;
            pointer-events: none;
        }
       
        .fullscreen-btn {
            background: rgba(0,0,0,0.8);
            color: white;
            border: none;
            padding: 5px 8px;
            font-size: 12px;
            border-radius: 3px;
            cursor: pointer;
            transition: background 0.2s;
        }
       
        .fullscreen-btn:hover {
            background: rgba(0,0,0,0.9);
        }
       
        .fullscreen-btn.exit {
            background: rgba(220,53,69,0.9);
        }
       
        .fullscreen-btn.exit:hover {
            background: rgba(220,53,69,1);
        }
       
        /* Contrôles de zoom */
        .zoom-controls {
            position: absolute;
            top: 5px;
            right: 5px;
            background: rgba(0,0,0,0.8);
            padding: 5px;
            border-radius: 3px;
            z-index: 10;
            display: flex;
            gap: 5px;
        }
       
        .zoom-btn {
            width: 25px;
            height: 25px;
            border: none;
            background: #444;
            color: white;
            cursor: pointer;
            border-radius: 3px;
            font-size: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
       
        .zoom-btn:hover {
            background: #666;
        }
       
        .zoom-value {
            color: white;
            font-size: 12px;
            min-width: 45px;
            text-align: center;
            display: flex;
            align-items: center;
        }
       
        .btn-config {
            position: fixed;
            bottom: 10px;
            right: 10px;
            background: #2196F3;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            z-index: 100;
        }
       
        .btn-config:hover {
            background: #1976D2;
        }
       
        .hidden {
            display: none !important;
        }
    </style>
</head>
<body>
    <div id="dashboard">
        <div class="frame-container" id="frame1-container">
            <div class="frame-header">
                <span class="frame-label" id="label1">Interface 1</span>
                <button class="fullscreen-btn" onclick="toggleFullscreen(1)" id="fullscreen-btn-1">⛶</button>
            </div>
            <div class="zoom-controls">
                <button class="zoom-btn" onclick="zoom(1, -0.1)">−</button>
                <span class="zoom-value" id="zoom1">100%</span>
                <button class="zoom-btn" onclick="zoom(1, 0.1)">+</button>
            </div>
            <div class="frame-wrapper" id="wrapper1">
                <iframe id="frame1"></iframe>
            </div>
        </div>
       
        <div class="frame-container" id="frame2-container">
            <div class="frame-header">
                <span class="frame-label" id="label2">Interface 2</span>
                <button class="fullscreen-btn" onclick="toggleFullscreen(2)" id="fullscreen-btn-2">⛶</button>
            </div>
            <div class="zoom-controls">
                <button class="zoom-btn" onclick="zoom(2, -0.1)">−</button>
                <span class="zoom-value" id="zoom2">100%</span>
                <button class="zoom-btn" onclick="zoom(2, 0.1)">+</button>
            </div>
            <div class="frame-wrapper" id="wrapper2">
                <iframe id="frame2"></iframe>
            </div>
        </div>
       
        <div class="frame-container" id="frame3-container">
            <div class="frame-header">
                <span class="frame-label" id="label3">Interface 3</span>
                <button class="fullscreen-btn" onclick="toggleFullscreen(3)" id="fullscreen-btn-3">⛶</button>
            </div>
            <div class="zoom-controls">
                <button class="zoom-btn" onclick="zoom(3, -0.1)">−</button>
                <span class="zoom-value" id="zoom3">100%</span>
                <button class="zoom-btn" onclick="zoom(3, 0.1)">+</button>
            </div>
            <div class="frame-wrapper" id="wrapper3">
                <iframe id="frame3"></iframe>
            </div>
        </div>
       
        <div class="frame-container" id="frame4-container">
            <div class="frame-header">
                <span class="frame-label" id="label4">Interface 4</span>
                <button class="fullscreen-btn" onclick="toggleFullscreen(4)" id="fullscreen-btn-4">⛶</button>
            </div>
            <div class="zoom-controls">
                <button class="zoom-btn" onclick="zoom(4, -0.1)">−</button>
                <span class="zoom-value" id="zoom4">100%</span>
                <button class="zoom-btn" onclick="zoom(4, 0.1)">+</button>
            </div>
            <div class="frame-wrapper" id="wrapper4">
                <iframe id="frame4"></iframe>
            </div>
        </div>
    </div>
   
    <button class="btn-config" onclick="window.location.href='/config'">
        ⚙️ Configuration
    </button>
   
    <script>
        // Stocker les niveaux de zoom et l'état plein écran
        const zoomLevels = {1: 1, 2: 1, 3: 1, 4: 1};
        let currentFullscreen = null;
       
        // Fonction de basculement plein écran
        function toggleFullscreen(frameNum) {
            const container = document.getElementById(`frame${frameNum}-container`);
            const dashboard = document.getElementById('dashboard');
            const btn = document.getElementById(`fullscreen-btn-${frameNum}`);
            const configBtn = document.querySelector('.btn-config');
           
            if (currentFullscreen === frameNum) {
                // Sortir du plein écran
                container.classList.remove('fullscreen-active');
                dashboard.classList.remove('fullscreen');
                btn.classList.remove('exit');
                btn.textContent = '⛶';
                configBtn.classList.remove('hidden');
                currentFullscreen = null;
               
                // Réafficher toutes les autres vues actives
                for (let i = 1; i <= 4; i++) {
                    const otherContainer = document.getElementById(`frame${i}-container`);
                    if (otherContainer.classList.contains('active') && i !== frameNum) {
                        otherContainer.style.display = '';
                    }
                }
            } else {
                // Entrer en plein écran
               
                // D'abord sortir du plein écran si une autre vue l'est
                if (currentFullscreen !== null) {
                    toggleFullscreen(currentFullscreen);
                }
               
                container.classList.add('fullscreen-active');
                dashboard.classList.add('fullscreen');
                btn.classList.add('exit');
                btn.textContent = '✕';
                configBtn.classList.add('hidden');
                currentFullscreen = frameNum;
               
                // Masquer toutes les autres vues
                for (let i = 1; i <= 4; i++) {
                    if (i !== frameNum) {
                        const otherContainer = document.getElementById(`frame${i}-container`);
                        otherContainer.style.display = 'none';
                    }
                }
            }
        }
       
        // Fonction de zoom individuel
        function zoom(frameNum, delta) {
            zoomLevels[frameNum] = Math.max(0.5, Math.min(2, zoomLevels[frameNum] + delta));
            updateZoom(frameNum);
        }
       
        // Mettre à jour l'affichage du zoom
        function updateZoom(frameNum) {
            const wrapper = document.getElementById(`wrapper${frameNum}`);
            const zoomDisplay = document.getElementById(`zoom${frameNum}`);
            const scale = zoomLevels[frameNum];
           
            wrapper.style.transform = `scale(${scale})`;
            wrapper.style.width = `${100 / scale}%`;
            wrapper.style.height = `${100 / scale}%`;
            zoomDisplay.textContent = `${Math.round(scale * 100)}%`;
        }
       
        // Gestion de la touche Escape pour sortir du plein écran
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape' && currentFullscreen !== null) {
                toggleFullscreen(currentFullscreen);
            }
        });
       
        // Charger la config depuis l'ESP32
        fetch('/getconfig')
            .then(response => response.json())
            .then(config => {
                applyConfig(config);
            });
       
        function applyConfig(config) {
            const dashboard = document.getElementById('dashboard');
            let count = 0;
           
            // Compter les interfaces configurées
            for (let i = 1; i <= 4; i++) {
                if (config[`ip${i}`]) count++;
            }
           
            // Appliquer le layout
            dashboard.className = '';
            dashboard.classList.add(`layout-${count}`);
           
            // Configurer les frames
            let frameIndex = 1;
            for (let i = 1; i <= 4; i++) {
                if (config[`ip${i}`]) {
                    const container = document.getElementById(`frame${frameIndex}-container`);
                    const frame = document.getElementById(`frame${frameIndex}`);
                    const label = document.getElementById(`label${frameIndex}`);
                   
                    container.classList.add('active');
                    frame.src = `http://${config[`ip${i}`]}`;
                    label.textContent = config[`name${i}`] || `Interface ${i}`;
                   
                    frameIndex++;
                }
            }
        }
    </script>
</body>
</html>
)rawliteral";

void loadConfig() {
  EEPROM.begin(sizeof(Config));
  EEPROM.get(0, config);
 
  // Vérifier si config valide
  if (String(config.magic) != "RMS") {
    // Config invalide, mode AP
    isAPMode = true;
  }
}

void saveConfig() {
  strcpy(config.magic, "RMS");
  EEPROM.put(0, config);
  EEPROM.commit();
}

void clearConfig() {
  strcpy(config.magic, "");
  EEPROM.put(0, config);
  EEPROM.commit();
}

void startAPMode() {
  Serial.println("Démarrage en mode AP...");
  WiFi.mode(WIFI_AP);
  WiFi.softAP("RMS_Dashboard_Config", "rms12345");
 
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP: ");
  Serial.println(IP);
}

void handleConfigPage() {
  server.send(200, "text/html", config_html);
}

// Variables globales pour l'authentification
bool isAuthenticated = false;
String sessionID = "";

// Générer un ID de session aléatoire
String generateSessionID() {
  String id = "";
  for (int i = 0; i < 16; i++) {
    id += String(random(0, 16), HEX);
  }
  return id;
}

// Vérifier l'authentification
bool checkAuth() {
  // En mode AP, pas d'authentification
  if (isAPMode) {
    return true;
  }
 
  // Si pas de mot de passe configuré, accès libre
  if (strlen(config.dashUser) == 0 && strlen(config.dashPass) == 0) {
    return true;
  }
 
  // Si seulement un des deux est vide, accès libre aussi (config incomplète)
  if (strlen(config.dashUser) == 0 || strlen(config.dashPass) == 0) {
    return true;
  }
 
  // Vérifier le cookie de session
  if (server.hasHeader("Cookie")) {
    String cookie = server.header("Cookie");
    if (cookie.indexOf("session=" + sessionID) != -1 && sessionID != "") {
      return true;
    }
  }
  return false;
}

void handleNetworkInfo() {
  String json = "{";
  if (isAPMode) {
    json += "\"isAP\":true,";
    json += "\"ip\":\"192.168.4.1\"";
  } else {
    json += "\"isAP\":false,";
    json += "\"ip\":\"" + WiFi.localIP().toString() + "\"";
  }
  json += "}";
 
  server.send(200, "application/json", json);
}

void handleLogin() {
  if (server.method() == HTTP_POST) {
    String user = server.arg("user");
    String pass = server.arg("pass");
   
    if (user == config.dashUser && pass == config.dashPass) {
      // Login réussi
      sessionID = generateSessionID();
      server.sendHeader("Set-Cookie", "session=" + sessionID + "; Path=/");
      server.sendHeader("Location", "/");
      server.send(302);
    } else {
      // Login échoué
      server.sendHeader("Location", "/?error=1");
      server.send(302);
    }
  } else {
    server.send(200, "text/html", login_html);
  }
}

void handleRoot() {
  if (isAPMode) {
    server.send(200, "text/html", config_html);
  } else {
    if (!checkAuth()) {
      server.send(200, "text/html", login_html);
    } else {
      server.send(200, "text/html", dashboard_html);
    }
  }
}

void handleScan() {
  int n = WiFi.scanNetworks();
  String json = "{\"networks\":[";
 
  for (int i = 0; i < n; i++) {
    if (i > 0) json += ",";
    String ssid = WiFi.SSID(i);
    // Échapper les caractères spéciaux dans le SSID
    ssid.replace("\"", "\\\"");
    ssid.replace("\\", "\\\\");
    json += "{\"ssid\":\"" + ssid + "\",\"rssi\":" + String(WiFi.RSSI(i)) + "}";
  }
  json += "]}";
 
  server.send(200, "application/json", json);
}

void handleSave() {
  if (server.hasArg("plain")) {
    DynamicJsonDocument doc(1024);
    deserializeJson(doc, server.arg("plain"));
   
    // Sauvegarder la config
    strcpy(config.ssid, doc["ssid"]);
    strcpy(config.password, doc["password"]);
    strcpy(config.dashUser, doc["dashUser"] | "");
    strcpy(config.dashPass, doc["dashPass"] | "");
    strcpy(config.ip1, doc["ip1"]);
    strcpy(config.ip2, doc["ip2"]);
    strcpy(config.ip3, doc["ip3"] | "");
    strcpy(config.ip4, doc["ip4"] | "");
    strcpy(config.name1, doc["name1"] | "Interface 1");
    strcpy(config.name2, doc["name2"] | "Interface 2");
    strcpy(config.name3, doc["name3"] | "Interface 3");
    strcpy(config.name4, doc["name4"] | "Interface 4");
   
    saveConfig();
    server.send(200, "text/plain", "OK");
   
    delay(5000);
    ESP.restart();
  }
}

void handleConfig() {
  String json = "{";
  json += "\"ssid\":\"" + String(config.ssid) + "\","; 
  json += "\"ip1\":\"" + String(config.ip1) + "\",";
  json += "\"ip2\":\"" + String(config.ip2) + "\",";
  json += "\"ip3\":\"" + String(config.ip3) + "\",";
  json += "\"ip4\":\"" + String(config.ip4) + "\",";
  json += "\"name1\":\"" + String(config.name1) + "\",";
  json += "\"name2\":\"" + String(config.name2) + "\",";
  json += "\"name3\":\"" + String(config.name3) + "\",";
  json += "\"name4\":\"" + String(config.name4) + "\"";
  json += "}";
 
  server.send(200, "application/json", json);
}

void handleReset() {
  clearConfig();
  server.send(200, "text/plain", "Config cleared");
}

void setup() {
  Serial.begin(115200);
 
  // Charger la config
  loadConfig();
 
  if (isAPMode) {
    // Mode AP pour configuration
    startAPMode();
  } else {
    // Mode normal - connexion WiFi
    WiFi.begin(config.ssid, config.password);
   
    int attempts = 0;
    while (WiFi.status() != WL_CONNECTED && attempts < 20) {
      delay(500);
      Serial.print(".");
      attempts++;
    }
   
    if (WiFi.status() != WL_CONNECTED) {
      // Échec connexion, retour en mode AP
      isAPMode = true;
      startAPMode();
    } else {
      Serial.println("\nConnecté!");
      Serial.print("IP: ");
      Serial.println(WiFi.localIP());
    }
  }
 
  // Routes
  server.on("/", handleRoot);
  server.on("/login", handleLogin);
  server.on("/config", handleConfigPage);  // Page de configuration
  server.on("/scan", handleScan);
  server.on("/save", HTTP_POST, handleSave);
  server.on("/getconfig", handleConfig);  // API pour récupérer la config
  server.on("/reset", handleReset);

  server.on("/networkinfo", handleNetworkInfo);
 
  server.begin();
  Serial.println("Serveur démarré");
}

void loop() {
  server.handleClient();
}


j ai fait des modifs dans config (bouton retor et rappel des enregistrements d ip et autre)
pour intergrer creez un dossier" webif_multi " et dedans un fichier "webif_multi.ino" avec le contenu du code si dessus

Cdlt
ESP32Wroom, Triac 40A "BTA40", Source UxIx2, Cumulus 300L 3000W.
Sonde temperature sur radiateur triac mise en route ventilateur a 25°
réactivité 30 seuil -50
2 esp32 pour gestion charge batteries
14 panneaux de 410wcc en autoconso micro-onduleur APS DS3
Suivi sur Domoticz
Répondre


Messages dans ce sujet
Petit prog pour esp32 - par lucky - 27-05-2025, 09:04 PM
RE: Petit prog pour esp32 - par Sgb31 - 28-05-2025, 07:51 AM
RE: Petit prog pour esp32 - par lucky - 28-05-2025, 08:03 AM
RE: Petit prog pour esp32 - par Sgb31 - 28-05-2025, 09:52 AM
RE: Petit prog pour esp32 - par Serge111 - 28-05-2025, 03:09 PM
RE: Petit prog pour esp32 - par grostoto - 28-05-2025, 07:57 PM
RE: Petit prog pour esp32 - par lucky - 28-05-2025, 08:07 PM
RE: Petit prog pour esp32 - par grostoto - 28-05-2025, 09:48 PM
RE: Petit prog pour esp32 - par lucky - 28-05-2025, 10:03 PM
RE: Petit prog pour esp32 - par grostoto - 28-05-2025, 10:07 PM
RE: Petit prog pour esp32 - par lucky - 29-05-2025, 08:21 AM
RE: Petit prog pour esp32 - par Philmaz - 29-05-2025, 05:32 PM
RE: Petit prog pour esp32 - par lucky - 29-05-2025, 06:03 PM
RE: Petit prog pour esp32 - par Philmaz - 29-05-2025, 07:45 PM
RE: Petit prog pour esp32 - par grostoto - 29-05-2025, 06:08 PM
RE: Petit prog pour esp32 - par lucky - 29-05-2025, 06:17 PM
RE: Petit prog pour esp32 - par grostoto - 29-05-2025, 07:49 PM
RE: Petit prog pour esp32 - par lucky - 29-05-2025, 08:14 PM
RE: Petit prog pour esp32 - par grostoto - 29-05-2025, 09:01 PM
RE: Petit prog pour esp32 - par lucky - 29-05-2025, 09:51 PM
RE: Petit prog pour esp32 - par Philmaz - 29-05-2025, 10:32 PM
RE: Petit prog pour esp32 - par grostoto - 29-05-2025, 11:21 PM
RE: Petit prog pour esp32 - par Philmaz - 30-05-2025, 07:26 AM
RE: Petit prog pour esp32 - par lucky - 30-05-2025, 07:41 AM
RE: Petit prog pour esp32 - par grostoto - 30-05-2025, 08:02 AM
RE: Petit prog pour esp32 - par Philmaz - 30-05-2025, 08:19 AM
RE: Petit prog pour esp32 - par lucky - 30-05-2025, 08:26 AM
RE: Petit prog pour esp32 - par Philmaz - 30-05-2025, 08:29 AM
RE: Petit prog pour esp32 - par Philmaz - 30-05-2025, 09:01 AM
RE: Petit prog pour esp32 - par lucky - 30-05-2025, 09:02 AM
RE: Petit prog pour esp32 - par lucky - 30-05-2025, 09:00 AM
RE: Petit prog pour esp32 - par grostoto - 30-05-2025, 09:11 AM
RE: Petit prog pour esp32 - par lucky - 30-05-2025, 03:26 PM
RE: Petit prog pour esp32 - par PhDV61 - 30-05-2025, 09:12 AM
RE: Petit prog pour esp32 - par lucky - 30-05-2025, 09:26 AM
RE: Petit prog pour esp32 - par bernard62 - 30-05-2025, 12:12 PM
RE: Petit prog pour esp32 - par glu3 - 30-05-2025, 02:21 PM
RE: Petit prog pour esp32 - par pdunet - 30-05-2025, 02:29 PM
RE: Petit prog pour esp32 - par lucky - 30-05-2025, 05:33 PM
RE: Petit prog pour esp32 - par grostoto - 30-05-2025, 07:50 PM
RE: Petit prog pour esp32 - par 59jag - 30-05-2025, 10:03 PM
RE: Petit prog pour esp32 - par lucky - 31-05-2025, 08:03 AM
RE: Petit prog pour esp32 - par lucky - 31-05-2025, 08:04 AM
RE: Petit prog pour esp32 - par 59jag - 31-05-2025, 09:22 AM
RE: Petit prog pour esp32 - par Sgb31 - 31-05-2025, 09:35 AM
RE: Petit prog pour esp32 - par lucky - 31-05-2025, 12:01 PM
RE: Petit prog pour esp32 - par pdunet - Il y a 22 minutes

Atteindre :


Utilisateur(s) parcourant ce sujet : GPL, 1 visiteur(s)