diff --git a/include/Configuration.h b/include/Configuration.h index 4f4805d9..425aed54 100644 --- a/include/Configuration.h +++ b/include/Configuration.h @@ -61,6 +61,7 @@ struct CONFIG_T { byte WiFi_Dns2[4]; bool WiFi_Dhcp; char WiFi_Hostname[WIFI_MAX_HOSTNAME_STRLEN + 1]; + uint WiFi_ApTimeout; char Ntp_Server[NTP_MAX_SERVER_STRLEN + 1]; char Ntp_Timezone[NTP_MAX_TIMEZONE_STRLEN + 1]; diff --git a/include/NetworkSettings.h b/include/NetworkSettings.h index 507167b0..87c8dce9 100644 --- a/include/NetworkSettings.h +++ b/include/NetworkSettings.h @@ -64,6 +64,7 @@ private: bool adminEnabled = true; bool forceDisconnection = false; int adminTimeoutCounter = 0; + int adminTimeoutCounterMax = 0; int connectTimeoutTimer = 0; int connectRedoTimer = 0; uint32_t lastTimerCall = 0; diff --git a/include/WebApi_errors.h b/include/WebApi_errors.h index 8107840d..ac91941e 100644 --- a/include/WebApi_errors.h +++ b/include/WebApi_errors.h @@ -63,6 +63,7 @@ enum WebApiError { NetworkGatewayInvalid, NetworkDns1Invalid, NetworkDns2Invalid, + NetworkApTimeoutInvalid, NtpBase = 9000, NtpServerLength, diff --git a/include/defaults.h b/include/defaults.h index b42d776e..1df7d774 100644 --- a/include/defaults.h +++ b/include/defaults.h @@ -9,10 +9,10 @@ #define ACCESS_POINT_NAME "OpenDTU-" #define ACCESS_POINT_PASSWORD "openDTU42" +#define ACCESS_POINT_TIMEOUT 3; #define AUTH_USERNAME "admin" #define SECURITY_ALLOW_READONLY true -#define ADMIN_TIMEOUT 180 #define WIFI_RECONNECT_TIMEOUT 15 #define WIFI_RECONNECT_REDO_TIMEOUT 600 diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 94a70b89..8ebb2fab 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -39,6 +39,7 @@ bool ConfigurationClass::write() wifi["dns2"] = IPAddress(config.WiFi_Dns2).toString(); wifi["dhcp"] = config.WiFi_Dhcp; wifi["hostname"] = config.WiFi_Hostname; + wifi["aptimeout"] = config.WiFi_ApTimeout; JsonObject ntp = doc.createNestedObject("ntp"); ntp["server"] = config.Ntp_Server; @@ -184,6 +185,7 @@ bool ConfigurationClass::read() config.WiFi_Dns2[3] = wifi_dns2[3]; config.WiFi_Dhcp = wifi["dhcp"] | WIFI_DHCP; + config.WiFi_ApTimeout = wifi["aptimeout"] | ACCESS_POINT_TIMEOUT; JsonObject ntp = doc["ntp"]; strlcpy(config.Ntp_Server, ntp["server"] | NTP_SERVER, sizeof(config.Ntp_Server)); diff --git a/src/NetworkSettings.cpp b/src/NetworkSettings.cpp index 68e5751c..e0957545 100644 --- a/src/NetworkSettings.cpp +++ b/src/NetworkSettings.cpp @@ -140,6 +140,7 @@ void NetworkSettingsClass::enableAdminMode() { adminEnabled = true; adminTimeoutCounter = 0; + adminTimeoutCounterMax = Configuration.get().WiFi_ApTimeout * 60; setupMode(); } @@ -168,7 +169,12 @@ void NetworkSettingsClass::loop() } if (millis() - lastTimerCall > 1000) { - adminTimeoutCounter++; + if (adminEnabled && adminTimeoutCounterMax > 0) { + adminTimeoutCounter++; + if (adminTimeoutCounter % 10 == 0) { + MessageOutput.printf("Admin AP remaining seconds: %d / %d\r\n", adminTimeoutCounter, adminTimeoutCounterMax); + } + } connectTimeoutTimer++; connectRedoTimer++; lastTimerCall = millis(); @@ -178,9 +184,9 @@ void NetworkSettingsClass::loop() if (!isConnected()) { adminTimeoutCounter = 0; } - // If WiFi is connected to AP for more than ADMIN_TIMEOUT + // If WiFi is connected to AP for more than adminTimeoutCounterMax // seconds, disable the internal Access Point - if (adminTimeoutCounter > ADMIN_TIMEOUT) { + if (adminTimeoutCounter > adminTimeoutCounterMax) { adminEnabled = false; MessageOutput.println("Admin mode disabled"); setupMode(); diff --git a/src/WebApi_network.cpp b/src/WebApi_network.cpp index 123ee816..9c05e7cc 100644 --- a/src/WebApi_network.cpp +++ b/src/WebApi_network.cpp @@ -75,6 +75,7 @@ void WebApiNetworkClass::onNetworkAdminGet(AsyncWebServerRequest* request) root["dns2"] = IPAddress(config.WiFi_Dns2).toString(); root["ssid"] = config.WiFi_Ssid; root["password"] = config.WiFi_Password; + root["aptimeout"] = config.WiFi_ApTimeout; response->setLength(); request->send(response); @@ -127,7 +128,8 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) && root.containsKey("netmask") && root.containsKey("gateway") && root.containsKey("dns1") - && root.containsKey("dns2"))) { + && root.containsKey("dns2") + && root.containsKey("aptimeout"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; response->setLength(); @@ -196,6 +198,13 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) request->send(response); return; } + if (root["aptimeout"].as() > 99999) { + retMsg["message"] = "ApTimeout must be a number between 0 and 99999!"; + retMsg["code"] = WebApiError::NetworkApTimeoutInvalid; + response->setLength(); + request->send(response); + return; + } CONFIG_T& config = Configuration.get(); config.WiFi_Ip[0] = ipaddress[0]; @@ -226,6 +235,7 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) } else { config.WiFi_Dhcp = false; } + config.WiFi_ApTimeout = root["aptimeout"].as(); Configuration.write(); retMsg["type"] = "success"; diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index 568dd2f9..39730aa7 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -78,6 +78,7 @@ "8003": "Standardgateway ist ungültig!", "8004": "DNS-Server-IP 1 ist ungültig!", "8005": "DNS-Server-IP 2 ist ungültig!", + "8006": "Administrative AccessPoint Timeout-Wert ist ungültig!", "9001": "Zeitserver muss zwischen 1 und {max} Zeichen lang sein!", "9002": "Zeitzone muss zwischen 1 und {max} Zeichen lang sein!", "9003": "Zeitzonenbeschreibung muss zwischen 1 und {max} Zeichen lang sein!", @@ -388,6 +389,9 @@ "Netmask": "Netzmaske:", "DefaultGateway": "Standardgateway:", "Dns": "DNS-Server {num}:", + "AdminAp": "WLAN-Konfiguration (Admin AccessPoint)", + "ApTimeout": "AccessPoint Zeitlimit (Minuten)", + "ApTimeoutHint": "Wie viele Minuten der AccessPoint offen gehalten wird. Ein Wert von 0 bedeutet unendlich.", "Save": "@:dtuadmin.Save" }, "mqttadmin": { diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index b8eb2083..977733d7 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -78,6 +78,7 @@ "8003": "Gateway is invalid!", "8004": "DNS Server IP 1 is invalid!", "8005": "DNS Server IP 2 is invalid!", + "8006": "Administrative AccessPoint Timeout value is invalid", "9001": "NTP Server must between 1 and {max} characters long!", "9002": "Timezone must between 1 and {max} characters long!", "9003": "Timezone description must between 1 and {max} characters long!", @@ -388,6 +389,9 @@ "Netmask": "Netmask:", "DefaultGateway": "Default Gateway:", "Dns": "DNS Server {num}:", + "AdminAp": "WiFi Configuration (Admin AccessPoint)", + "ApTimeout": "AccessPoint Timeout (minutes)", + "ApTimeoutHint": "How many minutes the AccessPoint is kept open. A value of 0 means infinite.", "Save": "@:dtuadmin.Save" }, "mqttadmin": { diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 5aa083cc..6118780f 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -78,6 +78,7 @@ "8003": "La passerelle n'est pas valide !", "8004": "L'adresse IP du serveur DNS primaire n'est pas valide !", "8005": "L'adresse IP du serveur DNS secondaire n'est pas valide !", + "8006": "La valeur du délai d'attente du point d'accès administratif n'est pas valide !", "9001": "Le serveur NTP doit avoir une longueur comprise entre 1 et {max} caractères !", "9002": "Le fuseau horaire doit comporter entre 1 et {max} caractères !", "9003": "La description du fuseau horaire doit comporter entre 1 et {max} caractères !", @@ -388,6 +389,9 @@ "Netmask": "Masque de réseau", "DefaultGateway": "Passerelle par défaut", "Dns": "Serveur DNS {num}", + "AdminAp": "Configuration du réseau WiFi (Point d'accès)", + "ApTimeout": "Délai d'attente du point d'accès (minutes)", + "ApTimeoutHint": "Nombre de minutes pendant lesquelles le point d'accès reste ouvert. Une valeur de 0 signifie infini.", "Save": "@:dtuadmin.Save" }, "mqttadmin": { diff --git a/webapp/src/types/NetworkkConfig.ts b/webapp/src/types/NetworkkConfig.ts index 51f6a465..e9b3578b 100644 --- a/webapp/src/types/NetworkkConfig.ts +++ b/webapp/src/types/NetworkkConfig.ts @@ -8,4 +8,5 @@ export interface NetworkConfig { gateway: string; dns1: string; dns2: string; + aptimeout: number; } \ No newline at end of file diff --git a/webapp/src/views/NetworkAdminView.vue b/webapp/src/views/NetworkAdminView.vue index 277361af..ccd44ec7 100644 --- a/webapp/src/views/NetworkAdminView.vue +++ b/webapp/src/views/NetworkAdminView.vue @@ -50,6 +50,12 @@ type="text" maxlength="32"/> + + +