Add dispatchDim

This commit is contained in:
fvanroie 2020-02-10 21:50:57 +01:00
parent e4e3fdfc2c
commit fc8d618361
6 changed files with 179 additions and 82 deletions

View File

@ -1,4 +1,6 @@
#include "hasp_dispatch.h" #include "hasp_dispatch.h"
#include "hasp_config.h"
#include "hasp_debug.h"
#include "hasp_mqtt.h" #include "hasp_mqtt.h"
#include "hasp_http.h" #include "hasp_http.h"
#include "hasp_mdns.h" #include "hasp_mdns.h"
@ -32,13 +34,15 @@ void IRAM_ATTR dispatchAttribute(String & strTopic, String & strPayload)
} // valid page } // valid page
} }
} else if(strTopic == "page") { } else if(strTopic == "page") {
dispatchPage(strPayload);
} else if(strTopic == "dim") { } else if(strTopic == "dim") {
dispatchDim(strPayload);
} }
} }
void IRAM_ATTR dispatchPage(String & strPageid) void IRAM_ATTR dispatchPage(String & strPageid)
{ {
debugPrintln("PAGE:" + strPageid); debugPrintln("PAGE: " + strPageid);
if(strPageid.length() == 0) { if(strPageid.length() == 0) {
String strPayload = String(haspGetPage()); String strPayload = String(haspGetPage());
@ -48,10 +52,28 @@ void IRAM_ATTR dispatchPage(String & strPageid)
} }
} }
void dispatchDim(String & strDimLevel)
{
debugPrintln("DIM: " + strDimLevel);
if(strDimLevel.length() == 0) {
String strPayload = String(guiGetDim());
mqttSendState("dim", strPayload.c_str());
} else {
guiSetDim(strDimLevel.toInt());
}
}
void IRAM_ATTR dispatchCommand(String cmnd) void IRAM_ATTR dispatchCommand(String cmnd)
{ {
debugPrintln("CMND: " + cmnd); debugPrintln("CMND: " + cmnd);
if(cmnd.startsWith(F("page ")) || cmnd.startsWith(F("page="))) {
cmnd = cmnd.substring(5, cmnd.length());
dispatchPage(cmnd);
return;
}
if(cmnd == F("calibrate")) { if(cmnd == F("calibrate")) {
guiCalibrate(); guiCalibrate();
return; return;
@ -63,7 +85,7 @@ void IRAM_ATTR dispatchCommand(String cmnd)
} }
if(cmnd == F("reboot") || cmnd == F("restart")) { if(cmnd == F("reboot") || cmnd == F("restart")) {
haspReboot(true); dispatchReboot(true);
return; return;
} }
@ -81,7 +103,7 @@ void IRAM_ATTR dispatchCommand(String cmnd)
} }
} }
void IRAM_ATTR dispatchJson(String & strPayload) void dispatchJson(String & strPayload)
{ // Parse an incoming JSON array into individual commands { // Parse an incoming JSON array into individual commands
if(strPayload.endsWith(",]")) { if(strPayload.endsWith(",]")) {
// Trailing null array elements are an artifact of older Home Assistant automations // Trailing null array elements are an artifact of older Home Assistant automations
@ -97,14 +119,7 @@ void IRAM_ATTR dispatchJson(String & strPayload)
return; return;
} }
// Slow
// for(uint8_t i = 0; i < haspCommands.size(); i++) {
// dispatchCommand(haspCommands[i]);
//}
// Get a reference to the root array
JsonArray arr = haspCommands.as<JsonArray>(); JsonArray arr = haspCommands.as<JsonArray>();
// Fast
for(JsonVariant command : arr) { for(JsonVariant command : arr) {
dispatchCommand(command.as<String>()); dispatchCommand(command.as<String>());
} }
@ -113,4 +128,17 @@ void IRAM_ATTR dispatchJson(String & strPayload)
void IRAM_ATTR dispatchIdle(const __FlashStringHelper * state) void IRAM_ATTR dispatchIdle(const __FlashStringHelper * state)
{ {
mqttSendState(String(F("idle")).c_str(), String(state).c_str()); mqttSendState(String(F("idle")).c_str(), String(state).c_str());
}
void dispatchReboot(bool saveConfig)
{
mqttStop(); // Stop the MQTT Client first
if(saveConfig) configWriteConfig();
debugStop();
delay(250);
wifiStop();
debugPrintln(F("CMND: Properly Rebooting the MCU now!"));
debugPrintln(F("-------------------------------------"));
ESP.restart();
delay(5000);
} }

View File

@ -9,7 +9,11 @@ void dispatchLoop(void);
void dispatchAttribute(String & strTopic, String & strPayload); void dispatchAttribute(String & strTopic, String & strPayload);
void dispatchCommand(String cmnd); void dispatchCommand(String cmnd);
void dispatchJson(String & strPayload); void dispatchJson(String & strPayload);
void dispatchPage(String & strPageid); void dispatchPage(String & strPageid);
void dispatchDim(String & strDimLevel);
void dispatchIdle(const __FlashStringHelper * state); void dispatchIdle(const __FlashStringHelper * state);
void dispatchReboot(bool saveConfig);
#endif #endif

View File

@ -6,9 +6,6 @@
#include "TFT_eSPI.h" #include "TFT_eSPI.h"
#if defined(ARDUINO_ARCH_ESP32)
//#include "png_decoder.h"
#endif
#include "lv_zifont.h" #include "lv_zifont.h"
#include "hasp_log.h" #include "hasp_log.h"
@ -18,24 +15,43 @@
#include "hasp_gui.h" #include "hasp_gui.h"
#include "hasp.h" #include "hasp.h"
#if LV_USE_HASP_SPIFFS #if HASP_USE_PNGDECODE != 0
#include "png_decoder.h"
#endif
#if HASP_USE_SPIFFS
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h" #include "SPIFFS.h"
#endif #endif
#include <FS.h> // Include the SPIFFS library #include <FS.h> // Include the SPIFFS library
#endif #endif
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
static ESP8266WebServer * webClient; // for snatshot
#endif
#if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h>
static WebServer * webClient; // for snatshot
#endif // ESP32
#define LVGL_TICK_PERIOD 30 // 30 #define LVGL_TICK_PERIOD 30 // 30
bool guiAutoCalibrate = true; #ifndef TFT_BCKL
uint16_t guiSleepTime = 150; // 0.1 second resolution #define TFT_BCKL -1 // No Backlight Control
bool guiSleeping = false; #endif
uint8_t guiTickPeriod = 50;
int8_t guiDimLevel = -1;
int8_t guiBacklightPin = TFT_BCKL;
bool guiAutoCalibrate = true;
uint16_t guiSleepTime = 150; // 0.1 second resolution
bool guiSleeping = false;
uint8_t guiTickPeriod = 50;
static Ticker tick; /* timer for interrupt handler */ static Ticker tick; /* timer for interrupt handler */
static TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ static TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static uint16_t calData[5] = {0, 65535, 0, 65535, 0}; static uint16_t calData[5] = {0, 65535, 0, 65535, 0};
static WiFiClient webClient; // for snatshot
static File pFileOut; static File pFileOut;
static uint8_t guiSnapshot = 0; static uint8_t guiSnapshot = 0;
@ -92,7 +108,7 @@ void tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * c
break; break;
case 2: case 2:
// Send to remote client // Send to remote client
if(webClient.write(pixel, i) != i) { if(webClient->client().write(pixel, i) != i) {
errorPrintln(F("GUI: %sPixelbuffer not completely sent")); errorPrintln(F("GUI: %sPixelbuffer not completely sent"));
} }
} }
@ -109,7 +125,7 @@ void tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * c
break; break;
case 2: case 2:
// Send to remote client // Send to remote client
if(webClient.write(pixel, i) != i) { if(webClient->client().write(pixel, i) != i) {
errorPrintln(F("GUI: %sPixelbuffer not completely sent")); errorPrintln(F("GUI: %sPixelbuffer not completely sent"));
} }
} }
@ -231,7 +247,7 @@ void guiSetup(TFT_eSPI & screen, JsonObject settings)
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
/* allocate on iram (or psram ?) */ /* allocate on iram (or psram ?) */
buffer_size = 1024 * 8; buffer_size = 1024 * 24;
static lv_color_t * guiVdbBuffer = (lv_color_t *)malloc(sizeof(lv_color_t) * buffer_size); static lv_color_t * guiVdbBuffer = (lv_color_t *)malloc(sizeof(lv_color_t) * buffer_size);
static lv_disp_buf_t disp_buf; static lv_disp_buf_t disp_buf;
lv_disp_buf_init(&disp_buf, guiVdbBuffer, NULL, buffer_size); lv_disp_buf_init(&disp_buf, guiVdbBuffer, NULL, buffer_size);
@ -250,7 +266,9 @@ void guiSetup(TFT_eSPI & screen, JsonObject settings)
#endif #endif
/* Initialize PNG decoder */ /* Initialize PNG decoder */
// png_decoder_init(); #if HASP_USE_PNGDECODE != 0
png_decoder_init();
#endif
/* Initialize the display driver */ /* Initialize the display driver */
lv_disp_drv_t disp_drv; lv_disp_drv_t disp_drv;
@ -319,7 +337,22 @@ void guiSetup(TFT_eSPI & screen, JsonObject settings)
lv_fs_if_init(); lv_fs_if_init();
#endif #endif
// guiLoop(); /* Setup Backlight Control Pin */
if(guiBacklightPin >= 0) {
char msg[128];
sprintf(msg, PSTR("LVGL: Backlight Pin = %i"), guiBacklightPin);
debugPrintln(msg);
#if defined(ARDUINO_ARCH_ESP32)
// configure LED PWM functionalitites
ledcSetup(0, 1000, 10);
// attach the channel to the GPIO to be controlled
pinMode(guiBacklightPin, OUTPUT);
ledcAttachPin(guiBacklightPin, 0);
#else
pinMode(guiBacklightPin, OUTPUT);
#endif
}
} }
void IRAM_ATTR guiLoop() void IRAM_ATTR guiLoop()
@ -330,11 +363,33 @@ void IRAM_ATTR guiLoop()
void guiStop() void guiStop()
{} {}
void guiSetDim(uint8_t level)
{
if(guiBacklightPin >= 0) {
guiDimLevel = level >= 0 ? level : 0;
guiDimLevel = guiDimLevel <= 100 ? guiDimLevel : 100;
#if defined(ARDUINO_ARCH_ESP32)
ledcWrite(0, map(guiDimLevel, 0, 100, 0, 1023)); // ledChannel and value
#else
analogWrite(D1, map(guiDimLevel, 0, 100, 0, 1023));
#endif
} else {
guiDimLevel = -1;
}
}
int8_t guiGetDim()
{
return guiDimLevel;
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
bool guiGetConfig(const JsonObject & settings) bool guiGetConfig(const JsonObject & settings)
{ {
settings[FPSTR(F_GUI_TICKPERIOD)] = guiTickPeriod; settings[FPSTR(F_GUI_TICKPERIOD)] = guiTickPeriod;
settings[FPSTR(F_GUI_IDLEPERIOD)] = guiSleepTime; settings[FPSTR(F_GUI_IDLEPERIOD)] = guiSleepTime;
settings[FPSTR(F_GUI_BACKLIGHTPIN)] = guiBacklightPin;
JsonArray array = settings[FPSTR(F_GUI_CALIBRATION)].to<JsonArray>(); JsonArray array = settings[FPSTR(F_GUI_CALIBRATION)].to<JsonArray>();
for(int i = 0; i < 5; i++) { for(int i = 0; i < 5; i++) {
@ -362,6 +417,15 @@ bool guiSetConfig(const JsonObject & settings)
guiTickPeriod = settings[FPSTR(F_GUI_TICKPERIOD)].as<uint8_t>(); guiTickPeriod = settings[FPSTR(F_GUI_TICKPERIOD)].as<uint8_t>();
} }
if(!settings[FPSTR(F_GUI_BACKLIGHTPIN)].isNull()) {
if(guiBacklightPin != settings[FPSTR(F_GUI_BACKLIGHTPIN)].as<int8_t>()) {
debugPrintln(F("guiBacklightPin set"));
}
changed |= guiBacklightPin != settings[FPSTR(F_GUI_BACKLIGHTPIN)].as<int8_t>();
guiBacklightPin = settings[FPSTR(F_GUI_BACKLIGHTPIN)].as<int8_t>();
}
if(!settings[FPSTR(F_GUI_IDLEPERIOD)].isNull()) { if(!settings[FPSTR(F_GUI_IDLEPERIOD)].isNull()) {
if(guiSleepTime != settings[FPSTR(F_GUI_IDLEPERIOD)].as<uint8_t>()) { if(guiSleepTime != settings[FPSTR(F_GUI_IDLEPERIOD)].as<uint8_t>()) {
debugPrintln(F("guiSleepTime set")); debugPrintln(F("guiSleepTime set"));
@ -430,9 +494,15 @@ void guiTakeScreenshot(const char * pFileName)
pFileOut.close(); pFileOut.close();
printf(("[Display] data flushed to %s", pFileName)); printf(("[Display] data flushed to %s", pFileName));
} }
void guiTakeScreenshot(WiFiClient client)
#if defined(ARDUINO_ARCH_ESP8266)
void guiTakeScreenshot(ESP8266WebServer & client)
#endif
#if defined(ARDUINO_ARCH_ESP32)
void guiTakeScreenshot(WebServer & client)
#endif // ESP32{
{ {
webClient = client; webClient = &client;
uint8_t bmpheader[138] = {0x42, 0x4D, 0x8A, 0xB0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x7C, uint8_t bmpheader[138] = {0x42, 0x4D, 0x8A, 0xB0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x7C,
0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x20, 0x00,
@ -440,10 +510,10 @@ void guiTakeScreenshot(WiFiClient client)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x42, 0x47, 0x52, 0x73}; 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x42, 0x47, 0x52, 0x73};
if(client.write(bmpheader, sizeof(bmpheader)) != sizeof(bmpheader)) { if(webClient->client().write(bmpheader, sizeof(bmpheader)) != sizeof(bmpheader)) {
Serial.println("Data sent does not match header size!"); errorPrintln(F("GUI: %sData sent does not match header size"));
} else { } else {
Serial.println("OK BMP Header sent!"); debugPrintln(F("GUI: Bitmap header sent"));
} }
guiSnapshot = 2; guiSnapshot = 2;
@ -451,5 +521,5 @@ void guiTakeScreenshot(WiFiClient client)
lv_refr_now(NULL); /* Will call our disp_drv.disp_flush function */ lv_refr_now(NULL); /* Will call our disp_drv.disp_flush function */
guiSnapshot = 0; guiSnapshot = 0;
printf("[Display] data flushed to webclient"); debugPrintln(F("GUI: Bitmap data flushed to webclient"));
} }

View File

@ -6,19 +6,25 @@
#include "lvgl.h" #include "lvgl.h"
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP8266)
#include <Wifi.h> #include <ESP8266WebServer.h>
#else void guiTakeScreenshot(ESP8266WebServer & client);
#include <ESP8266WiFi.h>
#endif #endif
#if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h>
void guiTakeScreenshot(WebServer & client);
#endif // ESP32
void guiSetup(TFT_eSPI & screen, JsonObject settings); void guiSetup(TFT_eSPI & screen, JsonObject settings);
void guiLoop(void); void guiLoop(void);
void guiStop(void); void guiStop(void);
void guiCalibrate(); void guiCalibrate();
void guiTakeScreenshot(const char * pFileName); void guiTakeScreenshot(const char * pFileName);
void guiTakeScreenshot(WiFiClient client);
void guiSetDim(uint8_t level);
int8_t guiGetDim(void);
bool guiGetConfig(const JsonObject & settings); bool guiGetConfig(const JsonObject & settings);
bool guiSetConfig(const JsonObject & settings); bool guiSetConfig(const JsonObject & settings);

View File

@ -231,12 +231,7 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
if(strTopic == F("page")) { // '[...]/device/command/page' -m '1' == nextionSendCmd("page 1") if(strTopic == F("page")) { // '[...]/device/command/page' -m '1' == nextionSendCmd("page 1")
dispatchPage(strPayload); dispatchPage(strPayload);
} else if(strTopic == F("dim")) { // '[...]/device/command/page' -m '1' == nextionSendCmd("page 1") } else if(strTopic == F("dim")) { // '[...]/device/command/page' -m '1' == nextionSendCmd("page 1")
#if defined(ARDUINO_ARCH_ESP32) dispatchDim(strPayload);
ledcWrite(0, map(strPayload.toInt(), 0, 100, 0, 1023)); // ledChannel and value
#else
analogWrite(D1, map(strPayload.toInt(), 0, 100, 0, 1023));
#endif
} else if(strTopic == F("json")) { // '[...]/device/command/json' -m '["dim=5", "page 1"]' = } else if(strTopic == F("json")) { // '[...]/device/command/json' -m '["dim=5", "page 1"]' =
// nextionSendCmd("dim=50"), nextionSendCmd("page 1") // nextionSendCmd("dim=50"), nextionSendCmd("page 1")
dispatchJson(strPayload); // Send to nextionParseJson() dispatchJson(strPayload); // Send to nextionParseJson()
@ -250,12 +245,8 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
} else { } else {
// espStartOta(strPayload); // espStartOta(strPayload);
} }
} else if(strTopic == F("reboot")) { // '[...]/device/command/reboot' == reboot microcontroller) } else if(strTopic == F("reboot") || strTopic == F("lcdreboot")) {
debugPrintln(F("MQTT: Rebooting device")); dispatchReboot(true);
dispatchCommand(F("reboot"));
} else if(strTopic == F("lcdreboot")) { // '[...]/device/command/lcdreboot' == reboot LCD panel)
debugPrintln(F("MQTT: Rebooting LCD"));
dispatchCommand(F("reboot"));
} else if(strTopic == F("factoryreset")) { // '[...]/device/command/factoryreset' == clear all saved settings) } else if(strTopic == F("factoryreset")) { // '[...]/device/command/factoryreset' == clear all saved settings)
// configClearSaved(); // configClearSaved();
//} else if(strPayload == "") { // '[...]/device/command/p[1].b[4].txt' -m '' == //} else if(strPayload == "") { // '[...]/device/command/p[1].b[4].txt' -m '' ==

View File

@ -1,11 +1,10 @@
#include "hasp_conf.h"
#include <Arduino.h> #include <Arduino.h>
#include "ArduinoJson.h" #include "ArduinoJson.h"
#include "TFT_eSPI.h" #include "TFT_eSPI.h"
#include "hasp_conf.h"
#include "hasp_debug.h" #include "hasp_debug.h"
#include "hasp_eeprom.h"
#include "hasp_spiffs.h" #include "hasp_spiffs.h"
#include "hasp_config.h" #include "hasp_config.h"
#include "hasp_tft.h" #include "hasp_tft.h"
@ -13,32 +12,42 @@
//#include "hasp_ota.h" //#include "hasp_ota.h"
#include "hasp.h" #include "hasp.h"
#if LV_USE_HASP_SPIFFS #if HASP_USE_SPIFFS
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h" #include "SPIFFS.h"
#endif #endif
#include <FS.h> // Include the SPIFFS library #include <FS.h> // Include the SPIFFS library
#endif #endif
#if LV_USE_HASP_WIFI #if HASP_USE_EEPROM
#include "hasp_eeprom.h"
#endif
#if HASP_USE_WIFI
#include "hasp_wifi.h" #include "hasp_wifi.h"
#endif #endif
#if LV_USE_HASP_MQTT #if HASP_USE_MQTT
#include "hasp_mqtt.h" #include "hasp_mqtt.h"
#endif #endif
#if LV_USE_HASP_HTTP #if HASP_USE_HTTP
#include "hasp_http.h" #include "hasp_http.h"
#endif #endif
#if HASP_USE_MDNS
#include "hasp_mdns.h"
#endif
bool isConnected; bool isConnected;
void setup() void setup()
{ {
/* Init Storage */ /* Init Storage */
#if HASP_USE_EEPROM
eepromSetup(); eepromSetup();
#if LV_USE_HASP_SPIFFS #endif
#if HASP_USE_SPIFFS
spiffsSetup(); spiffsSetup();
#endif #endif
@ -46,20 +55,7 @@ void setup()
DynamicJsonDocument settings(1024); DynamicJsonDocument settings(1024);
configSetup(settings); configSetup(settings);
if(!settings[F("pins")][F("TFT_BCKL")].isNull()) { #if HASP_USE_SDCARD
int8_t pin = settings[F("pins")][F("TFT_BCKL")].as<int8_t>();
#if defined(ARDUINO_ARCH_ESP32)
if(pin >= 0)
// configure LED PWM functionalitites
ledcSetup(0, 5000, 10);
// attach the channel to the GPIO to be controlled
ledcAttachPin(pin, 0);
#else
pinMode(pin, OUTPUT);
#endif
}
#if LV_USE_HASP_SDCARD
sdcardSetup(); sdcardSetup();
#endif #endif
@ -72,18 +68,18 @@ void setup()
haspSetup(settings[F("hasp")]); haspSetup(settings[F("hasp")]);
/* Init Network Services */ /* Init Network Services */
#if LV_USE_HASP_WIFI #if HASP_USE_WIFI
wifiSetup(settings[F("wifi")]); wifiSetup(settings[F("wifi")]);
#if LV_USE_HASP_MQTT #if HASP_USE_MQTT
mqttSetup(settings[F("mqtt")]); mqttSetup(settings[F("mqtt")]);
#endif #endif
#if LV_USE_HASP_MDNS #if HASP_USE_MDNS
mdnsSetup(settings[F("mdns")]); mdnsSetup(settings[F("mdns")]);
#endif #endif
#if LV_USE_HASP_HTTP #if HASP_USE_HTTP
httpSetup(settings[F("http")]); httpSetup(settings[F("http")]);
#endif #endif
@ -94,9 +90,11 @@ void setup()
void loop() void loop()
{ {
/* Storage Loops */ /* Storage Loops */
// eepromLoop(); #if HASP_USE_EEPROM
eepromLoop();
#endif
// spiffsLoop(); // spiffsLoop();
#if LV_USE_HASP_SDCARD #if HASP_USE_SDCARD
// sdcardLoop(); // sdcardLoop();
#endif #endif
@ -110,19 +108,19 @@ void loop()
// haspLoop(); // haspLoop();
/* Network Services Loops */ /* Network Services Loops */
#if LV_USE_HASP_WIFI > 0 #if HASP_USE_WIFI
isConnected = wifiLoop(); isConnected = wifiLoop();
#if LV_USE_HASP_MQTT > 0 #if HASP_USE_MQTT
mqttLoop(isConnected); mqttLoop(isConnected);
#endif #endif
#if LV_USE_HASP_HTTP > 0 #if HASP_USE_HTTP
httpLoop(isConnected); httpLoop(isConnected);
#endif #endif
#if LV_USE_HASP_MDNS > 0 #if HASP_USE_MDNS
mdnsLoop(wifiIsConnected); mdnsLoop(isConnected);
#endif #endif
// otaLoop(wifiIsConnected); // otaLoop(wifiIsConnected);