feat: add wifi configuration

This commit is contained in:
2025-08-21 07:31:18 +02:00
parent 81fedb1260
commit 1d2a817b61

View File

@@ -34,6 +34,19 @@ int powerButtonState = 0;
#define MAX_NAME_LENGTH 50
#define STATIONS_START_ADDR 100
// WiFi credentials EEPROM addresses
#define WIFI_CREDS_ADDR 0
#define MAX_SSID_LENGTH 32
#define MAX_PASSWORD_LENGTH 64
#define MAX_HOSTNAME_LENGTH 32
struct WiFiCredentials {
char ssid[MAX_SSID_LENGTH];
char password[MAX_PASSWORD_LENGTH];
char hostname[MAX_HOSTNAME_LENGTH];
bool isConfigured;
};
struct RadioStation {
char name[MAX_NAME_LENGTH];
char url[MAX_URL_LENGTH];
@@ -44,11 +57,18 @@ RadioStation radioStations[MAX_STATIONS];
int numStations = 0;
int currentStation = 0;
// WiFi configuration variables
WiFiCredentials wifiCreds;
bool configMode = false;
const char* AP_SSID = "ESP32_Radio_Config";
const char* AP_PASSWORD = "radio12345";
// Button timing
unsigned long buttonPressTime = 0;
bool buttonPressed = false;
bool selectionMode = false;
const unsigned long LONG_PRESS_TIME = 2000; // 2 seconds for long press
const unsigned long VERY_LONG_PRESS_TIME = 5000; // 5 seconds for config mode
// Selection mode timeout
unsigned long lastPotentiometerChange = 0;
@@ -63,6 +83,7 @@ void setup() {
// Initialize EEPROM
EEPROM.begin(EEPROM_SIZE);
loadWiFiCredentials();
loadStationsFromEEPROM();
esp_sleep_wakeup_cause_t source_reveil;
@@ -90,6 +111,9 @@ void setup() {
server.on("/delete", HTTP_POST, handleDelete);
server.on("/play", HTTP_POST, handlePlay);
server.on("/stop", HTTP_POST, handleStop);
server.on("/wifi-config", handleWiFiConfig);
server.on("/save-wifi", HTTP_POST, handleSaveWiFi);
server.on("/reset-wifi", HTTP_POST, handleResetWiFi);
server.begin();
Serial.println("Serveur web demarré sur port 80");
@@ -113,9 +137,26 @@ void loop()
server.handleClient();
volumeAdjust();
powerButton();
// Indicateur LED pour mode configuration
if (configMode) {
configModeLEDIndicator();
}
}
void configModeLEDIndicator() {
static unsigned long lastBlink = 0;
static bool ledState = false;
// Clignotement rapide en mode configuration
if (millis() - lastBlink > 500) {
ledState = !ledState;
digitalWrite(STATUSLED, ledState ? HIGH : LOW);
lastBlink = millis();
}
}
void volumeAdjust() {
volumeresistor = analogRead(VOLUMERES);
@@ -177,7 +218,13 @@ void powerButton() {
if (currentButtonState == 0 && powerButtonState == 1) {
unsigned long pressDuration = millis() - buttonPressTime;
if (pressDuration >= LONG_PRESS_TIME) {
if (pressDuration >= VERY_LONG_PRESS_TIME) {
// Very long press: force config mode
Serial.println("Forçage du mode configuration");
resetWiFiCredentials();
delay(1000);
ESP.restart();
} else if (pressDuration >= LONG_PRESS_TIME) {
// Long press: enter selection mode
if (!selectionMode) {
selectionMode = true;
@@ -218,12 +265,20 @@ void wifi_init() {
Serial.begin(115200);
digitalWrite(STATUSLED, HIGH);
WiFi.disconnect();
// Check if we have valid WiFi credentials
if (!wifiCreds.isConfigured || strlen(wifiCreds.ssid) == 0) {
startConfigMode();
return;
}
// Try to connect to WiFi
WiFi.mode(WIFI_STA);
WiFi.setHostname(hostname.c_str());
WiFi.begin(ssid.c_str(), password.c_str());
WiFi.setHostname(wifiCreds.hostname);
WiFi.begin(wifiCreds.ssid, wifiCreds.password);
Serial.print("Connexion au reseau ");
Serial.println(ssid);
Serial.println(wifiCreds.ssid);
int timeout_counter = 0;
@@ -235,11 +290,37 @@ void wifi_init() {
delay(500);
timeout_counter++;
if (timeout_counter > CONNECTION_TIMEOUT){
ESP.restart();
Serial.println("\nConnexion WiFi échouée, passage en mode configuration");
startConfigMode();
return;
}
}
configMode = false;
WiFi.config(WiFi.localIP(), WiFi.gatewayIP(), WiFi.subnetMask(), IPAddress(192,168,2,1));
Serial.println("\nConnexion WiFi réussie");
}
void startConfigMode() {
configMode = true;
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID, AP_PASSWORD);
Serial.println("Mode configuration activé");
Serial.print("Nom du réseau: ");
Serial.println(AP_SSID);
Serial.print("Mot de passe: ");
Serial.println(AP_PASSWORD);
Serial.print("Adresse IP: ");
Serial.println(WiFi.softAPIP());
// Clignotement spécial LED pour indiquer le mode configuration
for (int i = 0; i < 5; i++) {
digitalWrite(STATUSLED, LOW);
delay(200);
digitalWrite(STATUSLED, HIGH);
delay(200);
}
}
void audio_info(const char *info) {
@@ -276,6 +357,40 @@ void audio_eof_speech(const char *info) {
Serial.print("eof_speech "); Serial.println(info);
}
// WiFi credentials EEPROM functions
void saveWiFiCredentials() {
int addr = WIFI_CREDS_ADDR;
EEPROM.put(addr, wifiCreds);
EEPROM.commit();
Serial.println("WiFi credentials saved to EEPROM");
}
void loadWiFiCredentials() {
int addr = WIFI_CREDS_ADDR;
EEPROM.get(addr, wifiCreds);
// If not configured, use defaults from wifiinfo.h
if (!wifiCreds.isConfigured) {
strcpy(wifiCreds.ssid, WIFI_SSID);
strcpy(wifiCreds.password, WIFI_PASSWD);
strcpy(wifiCreds.hostname, HOSTNAME);
wifiCreds.isConfigured = true;
saveWiFiCredentials();
}
Serial.print("Loaded WiFi credentials - SSID: ");
Serial.println(wifiCreds.ssid);
}
void resetWiFiCredentials() {
strcpy(wifiCreds.ssid, "");
strcpy(wifiCreds.password, "");
strcpy(wifiCreds.hostname, HOSTNAME);
wifiCreds.isConfigured = false;
saveWiFiCredentials();
Serial.println("WiFi credentials reset");
}
// EEPROM functions
void saveStationsToEEPROM() {
int addr = STATIONS_START_ADDR;
@@ -333,7 +448,18 @@ void handleRoot() {
html += "th,td{border:1px solid #ddd;padding:8px;text-align:left}th{background-color:#f2f2f2}";
html += "input[type=text]{width:90%;padding:5px}button{padding:10px;margin:5px}</style></head><body>";
html += "<h1>Configuration Radio ESP32</h1>";
html += "<p>IP: " + WiFi.localIP().toString() + "</p>";
if (configMode) {
html += "<p><strong>🔧 Mode Configuration</strong></p>";
html += "<p>IP: " + WiFi.softAPIP().toString() + "</p>";
html += "<p>Réseau: " + String(AP_SSID) + "</p>";
html += "<p><a href='/wifi-config'>🌐 Configurer WiFi</a></p>";
} else {
html += "<p><strong>📡 Mode Normal</strong></p>";
html += "<p>IP: " + WiFi.localIP().toString() + "</p>";
html += "<p>Réseau: " + String(wifiCreds.ssid) + "</p>";
html += "<p><a href='/wifi-config'>🌐 Modifier WiFi</a></p>";
}
if (numStations > 0) {
html += "<h2>Station actuelle</h2>";
@@ -452,3 +578,70 @@ void handleStop() {
delay(1000); // Laisser le temps de recevoir la réponse
esp_deep_sleep_start();
}
void handleWiFiConfig() {
String html = "<!DOCTYPE html><html><head><title>Configuration WiFi</title>";
html += "<style>body{font-family:Arial;margin:20px}input[type=text],input[type=password]{width:300px;padding:10px;margin:5px 0}";
html += "button{padding:10px 20px;margin:10px 5px;font-size:16px}";
html += ".back-btn{background-color:#6c757d;color:white;text-decoration:none;padding:10px 20px;display:inline-block;margin:10px 0}</style></head><body>";
html += "<h1>Configuration WiFi</h1>";
if (configMode) {
html += "<p><strong>🔧 Mode Configuration Actif</strong></p>";
html += "<p>Connectez-vous au réseau <strong>" + String(AP_SSID) + "</strong> pour accéder à cette page.</p>";
}
html += "<form method='POST' action='/save-wifi'>";
html += "<p>Nom du réseau (SSID):</p>";
html += "<input type='text' name='ssid' value='" + String(wifiCreds.ssid) + "' maxlength='" + String(MAX_SSID_LENGTH-1) + "' required><br>";
html += "<p>Mot de passe:</p>";
html += "<input type='password' name='password' value='" + String(wifiCreds.password) + "' maxlength='" + String(MAX_PASSWORD_LENGTH-1) + "'><br>";
html += "<p>Nom de l'appareil:</p>";
html += "<input type='text' name='hostname' value='" + String(wifiCreds.hostname) + "' maxlength='" + String(MAX_HOSTNAME_LENGTH-1) + "' required><br><br>";
html += "<button type='submit'>💾 Sauvegarder et Redémarrer</button>";
html += "</form>";
html += "<form method='POST' action='/reset-wifi'>";
html += "<button type='submit' onclick=\"return confirm('Êtes-vous sûr de vouloir effacer la configuration WiFi ?')\">🔄 Reset Configuration</button>";
html += "</form>";
html += "<a href='/' class='back-btn'>⬅️ Retour</a>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleSaveWiFi() {
String newSSID = server.arg("ssid");
String newPassword = server.arg("password");
String newHostname = server.arg("hostname");
if (newSSID.length() == 0 || newHostname.length() == 0) {
server.send(400, "text/plain", "SSID et nom d'appareil requis");
return;
}
// Sauvegarder les nouvelles credentials
newSSID.toCharArray(wifiCreds.ssid, MAX_SSID_LENGTH);
newPassword.toCharArray(wifiCreds.password, MAX_PASSWORD_LENGTH);
newHostname.toCharArray(wifiCreds.hostname, MAX_HOSTNAME_LENGTH);
wifiCreds.isConfigured = true;
saveWiFiCredentials();
String response = "Configuration WiFi sauvegardée. Redémarrage en cours...<br>";
response += "SSID: " + newSSID + "<br>";
response += "Appareil: " + newHostname;
server.send(200, "text/html", response);
Serial.println("Nouvelles credentials WiFi sauvegardées, redémarrage...");
delay(2000);
ESP.restart();
}
void handleResetWiFi() {
resetWiFiCredentials();
server.send(200, "text/html", "Configuration WiFi effacée. Redémarrage en mode configuration...");
delay(2000);
ESP.restart();
}