Reworked WiFi logic

Remaining issues:
MQTT reconnects too often
WiFI AP doesn't work if searching for STA
This commit is contained in:
cschwinne 2019-10-18 23:47:11 +02:00
parent 90fa5b3b93
commit be185b46a7
6 changed files with 140 additions and 91 deletions

View File

@ -99,7 +99,7 @@
//version code in format yymmddb (b = daily build) //version code in format yymmddb (b = daily build)
#define VERSION 1910181 #define VERSION 1910182
char versionString[] = "0.8.5"; char versionString[] = "0.8.5";
@ -124,6 +124,7 @@ char apSSID[33] = ""; //AP off by default (unless setup)
byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) byte apChannel = 1; //2.4GHz WiFi AP channel (1-13)
byte apHide = 0; //hidden AP SSID byte apHide = 0; //hidden AP SSID
byte apWaitTimeSecs = 32; //time to wait for connection before opening AP byte apWaitTimeSecs = 32; //time to wait for connection before opening AP
bool apAlwaysOn = true;
bool recoveryAPDisabled = false; //never open AP (not recommended) bool recoveryAPDisabled = false; //never open AP (not recommended)
IPAddress staticIP(0, 0, 0, 0); //static IP of ESP IPAddress staticIP(0, 0, 0, 0); //static IP of ESP
IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP
@ -259,6 +260,12 @@ uint16_t userVar0 = 0, userVar1 = 0;
//internal global variable declarations //internal global variable declarations
//wifi
bool apActive = false;
bool forceReconnect = false;
uint32_t lastReconnectAttempt = 0;
bool interfacesInited = false;
//color //color
byte col[]{255, 159, 0, 0}; //target RGB(W) color byte col[]{255, 159, 0, 0}; //target RGB(W) color
byte colOld[]{0, 0, 0, 0}; //color before transition byte colOld[]{0, 0, 0, 0}; //color before transition
@ -398,7 +405,6 @@ EspalexaDevice* espalexaDevice;
//dns server //dns server
DNSServer dnsServer; DNSServer dnsServer;
bool dnsActive = false;
//network time //network time
bool ntpConnected = false; bool ntpConnected = false;
@ -433,6 +439,7 @@ E131* e131;
WS2812FX strip = WS2812FX(); WS2812FX strip = WS2812FX();
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID,"Your_Network") != 0)
//debug macros //debug macros
#ifdef WLED_DEBUG #ifdef WLED_DEBUG
@ -498,7 +505,6 @@ bool oappendi(int i)
//boot starts here //boot starts here
void setup() { void setup() {
pinMode(4, OUTPUT); digitalWrite(4, HIGH);
wledInit(); wledInit();
} }
@ -524,7 +530,7 @@ void loop() {
if (!realtimeActive) //block stuff if WARLS/Adalight is enabled if (!realtimeActive) //block stuff if WARLS/Adalight is enabled
{ {
if (dnsActive) dnsServer.processNextRequest(); if (apActive) dnsServer.processNextRequest();
#ifndef WLED_DISABLE_OTA #ifndef WLED_DISABLE_OTA
if (aOtaEnabled) ArduinoOTA.handle(); if (aOtaEnabled) ArduinoOTA.handle();
#endif #endif
@ -533,16 +539,12 @@ void loop() {
handleHue(); handleHue();
handleBlynk(); handleBlynk();
yield();
if (millis() - lastMqttReconnectAttempt > 30000)
{
initMqtt();
lastMqttReconnectAttempt = millis();
}
yield(); yield();
if (!offMode) strip.service(); if (!offMode) strip.service();
} }
yield();
if (millis() - lastMqttReconnectAttempt > 30000) initMqtt();
//DEBUG serial logging //DEBUG serial logging
#ifdef WLED_DEBUG #ifdef WLED_DEBUG

View File

@ -40,23 +40,12 @@ void wledInit()
DEBUG_PRINTLN("Load EEPROM"); DEBUG_PRINTLN("Load EEPROM");
loadSettingsFromEEPROM(true); loadSettingsFromEEPROM(true);
beginStrip(); beginStrip();
DEBUG_PRINT("CSSID: ");
DEBUG_PRINT(clientSSID);
userBeginPreConnection(); userBeginPreConnection();
if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true; if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true;
WiFi.persistent(false); WiFi.persistent(false);
initCon();
DEBUG_PRINTLN(""); if (macroBoot>0) applyMacro(macroBoot);
DEBUG_PRINT("Connected! IP address: "); Serial.println("Ada");
DEBUG_PRINTLN(WiFi.localIP());
if (hueIP[0] == 0)
{
hueIP[0] = WiFi.localIP()[0];
hueIP[1] = WiFi.localIP()[1];
hueIP[2] = WiFi.localIP()[2];
}
if (udpPort > 0 && udpPort != ntpLocalPort) if (udpPort > 0 && udpPort != ntpLocalPort)
{ {
@ -66,15 +55,10 @@ void wledInit()
if (ntpEnabled && WLED_CONNECTED) if (ntpEnabled && WLED_CONNECTED)
ntpConnected = ntpUdp.begin(ntpLocalPort); ntpConnected = ntpUdp.begin(ntpLocalPort);
//start captive portal if AP active //generate module IDs
if (!WLED_CONNECTED || strlen(apSSID) > 0) escapedMac = WiFi.macAddress();
{ escapedMac.replace(":", "");
dnsServer.setErrorReplyCode(DNSReplyCode::NoError); escapedMac.toLowerCase();
dnsServer.start(53, "*", WiFi.softAPIP());
dnsActive = true;
}
prepareIds(); //UUID from MAC (for Alexa and MQTT)
if (strcmp(cmDNS,"x") == 0) //fill in unique mdns default if (strcmp(cmDNS,"x") == 0) //fill in unique mdns default
{ {
strcpy(cmDNS, "wled-"); strcpy(cmDNS, "wled-");
@ -97,14 +81,12 @@ void wledInit()
initServer(); initServer();
strip.service(); strip.service();
//init Alexa hue emulation
if (alexaEnabled) alexaInit();
server.begin(); server.begin();
DEBUG_PRINTLN("HTTP server started"); DEBUG_PRINTLN("HTTP server started");
//init ArduinoOTA //init ArduinoOTA
if (WLED_CONNECTED) { if (true) {
#ifndef WLED_DISABLE_OTA #ifndef WLED_DISABLE_OTA
if (aOtaEnabled) if (aOtaEnabled)
{ {
@ -138,10 +120,8 @@ void wledInit()
e131Enabled = false; e131Enabled = false;
} }
initConnection();
userBegin(); userBegin();
if (macroBoot>0) applyMacro(macroBoot);
Serial.println("Ada");
} }
@ -176,17 +156,25 @@ void beginStrip()
void initAP(bool resetAP=false){ void initAP(bool resetAP=false){
DEBUG_PRINTLN("Opening AP..."); if (recoveryAPDisabled) return;
bool set = apSSID[0]; bool set = apSSID[0];
if (!set || resetAP) strcpy(apSSID, "WLED-AP"); if (!set || resetAP) strcpy(apSSID, "WLED-AP");
//if (resetAP) strcpy(apPass,"wled1234"); if (resetAP) strcpy(apPass,"wled1234");
DEBUG_PRINT("Opening access point ");
DEBUG_PRINTLN(apSSID);
WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255,255,255,0)); WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255,255,255,0));
WiFi.softAP(apSSID, apPass, apChannel, apHide); WiFi.softAP(apSSID, apPass, apChannel, apHide);
if (!set) apSSID[0] = 0; if (!set) apSSID[0] = 0;
if (!apActive) //start captive portal if AP active
{
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
dnsServer.start(53, "*", WiFi.softAPIP());
}
apActive = true;
} }
void initConnection()
void initCon()
{ {
WiFi.disconnect(); //close old connections WiFi.disconnect(); //close old connections
@ -198,23 +186,28 @@ void initCon()
WiFi.config(0U, 0U, 0U); WiFi.config(0U, 0U, 0U);
} }
if (strlen(apSSID)>0) lastReconnectAttempt = millis();
if (apAlwaysOn)
{ {
DEBUG_PRINT(" USING AP");
DEBUG_PRINTLN(strlen(apSSID));
initAP(); initAP();
} else } else if (!apActive)
{ {
DEBUG_PRINTLN(" NO AP"); DEBUG_PRINTLN("Access point disabled.");
WiFi.softAPdisconnect(true); WiFi.softAPdisconnect(true);
} }
if (strlen(clientSSID) <1 || strcmp(clientSSID,"Your_Network") == 0) if (!WLED_WIFI_CONFIGURED)
{ {
DEBUG_PRINT("No connection configured. "); DEBUG_PRINT("No connection configured. ");
initAP(); //instantly go to ap mode initAP(); //instantly go to ap mode
return; return;
} }
showWelcomePage = false;
DEBUG_PRINT("Connecting to ");
DEBUG_PRINT(clientSSID);
DEBUG_PRINTLN("...");
#ifndef ARDUINO_ARCH_ESP32 #ifndef ARDUINO_ARCH_ESP32
WiFi.hostname(serverDescription); WiFi.hostname(serverDescription);
@ -223,37 +216,97 @@ void initCon()
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
WiFi.setHostname(serverDescription); WiFi.setHostname(serverDescription);
#endif #endif
//wifiInit = true;
uint32_t fail_count = 0;
unsigned long lastTry = 0;
bool con = false;
while(!con)
{
yield();
handleTransitions();
handleButton();
handleOverlays();
if (briT) strip.service();
if (millis()-lastTry > 499) {
con = WLED_CONNECTED;
lastTry = millis();
DEBUG_PRINTLN("C_NC");
if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2)
{
WiFi.disconnect();
DEBUG_PRINT("Can't connect. ");
initAP();
return;
}
fail_count++;
}
}
} }
void initInterfaces() {
if (hueIP[0] == 0)
{
hueIP[0] = WiFi.localIP()[0];
hueIP[1] = WiFi.localIP()[1];
hueIP[2] = WiFi.localIP()[2];
}
//init Alexa hue emulation
if (alexaEnabled) alexaInit();
initMqtt();
#ifndef WLED_DISABLE_OTA
if (aOtaEnabled)
{
ArduinoOTA.onStart([]() {
#ifndef ARDUINO_ARCH_ESP32
wifi_set_sleep_type(NONE_SLEEP_T);
#endif
DEBUG_PRINTLN("Start ArduinoOTA");
});
if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS);
ArduinoOTA.begin();
}
#endif
strip.service();
// Set up mDNS responder:
if (strlen(cmDNS) > 0)
{
MDNS.begin(cmDNS);
DEBUG_PRINTLN("mDNS responder started");
// Add service to MDNS
MDNS.addService("http", "tcp", 80);
MDNS.addService("wled", "tcp", 80);
}
strip.service();
initBlynk(blynkApiKey);
initE131();
reconnectHue();
interfacesInited = true;
}
byte stacO = 0;
void handleConnection() { void handleConnection() {
byte stac = wifi_softap_get_station_num();
if (stac != stacO)
{
stacO = stac;
DEBUG_PRINT("Connected AP clients: ");
DEBUG_PRINTLN(stac);
if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected
if (stac) WiFi.disconnect(); //disable search so that AP can work
else initConnection(); //restart search
}
}
if (forceReconnect) {
DEBUG_PRINTLN("Forcing reconnect.");
initConnection();
interfacesInited = false;
forceReconnect = false;
return;
}
if (!WLED_CONNECTED) { if (!WLED_CONNECTED) {
if (interfacesInited) {
DEBUG_PRINTLN("Disconnected!");
interfacesInited = false;
initConnection();
}
if (millis() - lastReconnectAttempt > 300000 && WLED_WIFI_CONFIGURED) initConnection();
if (!apActive && millis() - lastReconnectAttempt > apWaitTimeSecs*1000) initAP();
} else if (!interfacesInited) { //newly connected
DEBUG_PRINTLN("");
DEBUG_PRINT("Connected! IP address: ");
DEBUG_PRINTLN(WiFi.localIP());
initInterfaces();
//shut down AP
if (!apAlwaysOn && apActive)
{
dnsServer.stop();
DEBUG_PRINTLN("Access point disabled.");
WiFi.softAPdisconnect(true);
apActive = false;
}
} }
} }

View File

@ -89,7 +89,7 @@ void arlsLock(uint32_t timeoutMs)
void initE131(){ void initE131(){
if (WLED_CONNECTED && e131Enabled) if (WLED_CONNECTED && e131Enabled)
{ {
e131 = new E131(); if (e131 == nullptr) e131 = new E131();
e131->begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe); e131->begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe);
} else { } else {
e131Enabled = false; e131Enabled = false;

View File

@ -5,11 +5,6 @@
* https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch
* https://github.com/probonopd/ESP8266HueEmulator * https://github.com/probonopd/ESP8266HueEmulator
*/ */
void prepareIds() {
escapedMac = WiFi.macAddress();
escapedMac.replace(":", "");
escapedMac.toLowerCase();
}
#ifndef WLED_DISABLE_ALEXA #ifndef WLED_DISABLE_ALEXA
void onAlexaChange(EspalexaDevice* dev); void onAlexaChange(EspalexaDevice* dev);

View File

@ -2,8 +2,6 @@
* MQTT communication protocol for home automation * MQTT communication protocol for home automation
*/ */
//#define WLED_MQTT_PORT 1883
void parseMQTTBriPayload(char* payload) void parseMQTTBriPayload(char* payload)
{ {
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);} if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);}
@ -47,7 +45,7 @@ void onMqttConnect(bool sessionPresent)
sendHADiscoveryMQTT(); sendHADiscoveryMQTT();
publishMqtt(); publishMqtt();
DEBUG_PRINTLN("MQ ready"); DEBUG_PRINTLN("MQTT ready");
} }
@ -74,8 +72,7 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
void publishMqtt() void publishMqtt()
{ {
if (mqtt == NULL) return; if (mqtt == nullptr || !mqtt->connected()) return;
if (!mqtt->connected()) return;
DEBUG_PRINTLN("Publish MQTT"); DEBUG_PRINTLN("Publish MQTT");
char s[10]; char s[10];
@ -206,8 +203,8 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
DEBUG_PRINTLN(buffer); DEBUG_PRINTLN(buffer);
char pubt[25 + 12 + 8]; char pubt[25 + 12 + 8];
strcpy(pubt, "homeassistant/light/WLED_"); strcpy(pubt, "homeassistant/light/");
strcat(pubt, escapedMac.c_str()); strcat(pubt, mqttClientID);
strcat(pubt, "/config"); strcat(pubt, "/config");
mqtt->publish(pubt, 0, true, buffer); mqtt->publish(pubt, 0, true, buffer);
#endif #endif
@ -215,11 +212,13 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
bool initMqtt() bool initMqtt()
{ {
lastMqttReconnectAttempt = millis();
if (mqttServer[0] == 0 || !WLED_CONNECTED) return false; if (mqttServer[0] == 0 || !WLED_CONNECTED) return false;
if (!mqtt) mqtt = new AsyncMqttClient(); if (mqtt == nullptr) mqtt = new AsyncMqttClient();
if (mqtt->connected()) return true; if (mqtt->connected()) return true;
DEBUG_PRINTLN("Reconnecting MQTT");
IPAddress mqttIP; IPAddress mqttIP;
if (mqttIP.fromString(mqttServer)) //see if server is IP or domain if (mqttIP.fromString(mqttServer)) //see if server is IP or domain
{ {
@ -228,7 +227,7 @@ bool initMqtt()
mqtt->setServer(mqttServer, mqttPort); mqtt->setServer(mqttServer, mqttPort);
} }
mqtt->setClientId(mqttClientID); mqtt->setClientId(mqttClientID);
if (mqttUser[0] && mqttPass[0] != 0) mqtt->setCredentials(mqttUser, mqttPass); if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass);
mqtt->onMessage(onMqttMessage); mqtt->onMessage(onMqttMessage);
mqtt->onConnect(onMqttConnect); mqtt->onConnect(onMqttConnect);
mqtt->connect(); mqtt->connect();

View File

@ -64,8 +64,8 @@ void initServer()
server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){ server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){
if (!(wifiLock && otaLock)) handleSettingsSet(request, 1); if (!(wifiLock && otaLock)) handleSettingsSet(request, 1);
serveMessage(request, 200,"WiFi settings saved.","Rebooting now...",255); serveMessage(request, 200,"WiFi settings saved.","Reconnecting now...",255);
doReboot = true; forceReconnect = true;
}); });
server.on("/settings/leds", HTTP_POST, [](AsyncWebServerRequest *request){ server.on("/settings/leds", HTTP_POST, [](AsyncWebServerRequest *request){