diff --git a/src/hasp.cpp b/src/hasp.cpp index 3fe95863..2e6d0da0 100644 --- a/src/hasp.cpp +++ b/src/hasp.cpp @@ -833,7 +833,7 @@ static void ta_event_cb(lv_obj_t * ta, lv_event_t event) else if(event == LV_EVENT_INSERT) { const char * str = (const char *)lv_event_get_data(); if(str[0] == '\n') { - printf("Ready\n"); + // printf("Ready\n"); } else { // printf("%s\n", lv_ta_get_text(ta)); } @@ -1266,6 +1266,10 @@ static void btn_event_handler(lv_obj_t * obj, lv_event_t event) debugPrintln(buffer); return; + case LV_EVENT_DELETE: + sprintf(buffer, PSTR("HASP: Object deleted"), event); + debugPrintln(buffer); + return; default: sprintf(buffer, PSTR("HASP: Unknown Event %d occured"), event); debugPrintln(buffer); @@ -1347,6 +1351,19 @@ String haspGetVersion() return buffer; } +void haspClearPage(uint16_t pageid) +{ + lv_obj_t * page = get_page(pageid); + if(!page) { + errorPrintln(F("HASP: %sPage ID not defined")); + } else if(page == lv_layer_sys() || page == lv_layer_top()) { + errorPrintln(F("HASP: %sCannot clear a layer")); + } else { + debugPrintln(String(F("HASP: Clearing page ")) + String(pageid)); + lv_obj_clean(pages[pageid]); + } +} + uint16_t haspGetPage() { return current_page; @@ -1664,8 +1681,14 @@ bool haspGetConfig(const JsonObject & settings) bool haspSetConfig(const JsonObject & settings) { + configOutput(settings); bool changed = false; + changed |= configSet(haspStartPage, settings[FPSTR(F_CONFIG_STARTPAGE)], PSTR("haspStartPage")); + changed |= configSet(haspStartDim, settings[FPSTR(F_CONFIG_STARTDIM)], PSTR("haspStartDim")); + changed |= configSet(haspThemeId, settings[FPSTR(F_CONFIG_THEME)], PSTR("haspThemeId")); + changed |= configSet(haspThemeHue, settings[FPSTR(F_CONFIG_HUE)], PSTR("haspThemeHue")); + if(!settings[FPSTR(F_CONFIG_PAGES)].isNull()) { changed |= strcmp(haspPagesPath, settings[FPSTR(F_CONFIG_PAGES)]) != 0; strncpy(haspPagesPath, settings[FPSTR(F_CONFIG_PAGES)], sizeof(haspPagesPath)); @@ -1676,28 +1699,5 @@ bool haspSetConfig(const JsonObject & settings) strncpy(haspZiFontPath, settings[FPSTR(F_CONFIG_ZIFONT)], sizeof(haspZiFontPath)); } - if(!settings[FPSTR(F_CONFIG_STARTPAGE)].isNull()) { - changed |= haspStartPage != settings[FPSTR(F_CONFIG_STARTPAGE)].as(); - haspStartPage = settings[FPSTR(F_CONFIG_STARTPAGE)].as(); - } - - if(!settings[FPSTR(F_CONFIG_STARTDIM)].isNull()) { - changed |= haspStartDim != settings[FPSTR(F_CONFIG_STARTDIM)].as(); - haspStartDim = settings[FPSTR(F_CONFIG_STARTDIM)].as(); - } - - if(!settings[FPSTR(F_CONFIG_THEME)].isNull()) { - changed |= haspThemeId != settings[FPSTR(F_CONFIG_THEME)].as(); - haspThemeId = settings[FPSTR(F_CONFIG_THEME)].as(); - } - - if(!settings[FPSTR(F_CONFIG_HUE)].isNull()) { - changed |= haspThemeHue != settings[FPSTR(F_CONFIG_HUE)].as(); - haspThemeHue = settings[FPSTR(F_CONFIG_HUE)].as(); - } - - serializeJson(settings, Serial); - Serial.println(); - return changed; } \ No newline at end of file diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 830dc40f..a1a8b386 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -19,6 +19,50 @@ #include "hasp_spiffs.h" #include "hasp.h" +void confDebugSet(const char * name) +{ + char buffer[127]; + snprintf(buffer, sizeof(buffer), PSTR("CONF: * %s set"), name); + debugPrintln(buffer); +} + +bool configSet(int8_t & value, const JsonVariant & setting, const char * name) +{ + if(!setting.isNull()) { + int8_t val = setting.as(); + if(value != val) { + confDebugSet(name); + value = val; + return true; + } + } + return false; +} +bool configSet(uint8_t & value, const JsonVariant & setting, const char * name) +{ + if(!setting.isNull()) { + uint8_t val = setting.as(); + if(value != val) { + confDebugSet(name); + value = val; + return true; + } + } + return false; +} +bool configSet(uint16_t & value, const JsonVariant & setting, const char * name) +{ + if(!setting.isNull()) { + uint16_t val = setting.as(); + if(value != val) { + confDebugSet(name); + value = val; + return true; + } + } + return false; +} + bool configChanged() { return false; diff --git a/src/hasp_config.h b/src/hasp_config.h index 6047b123..26915d62 100644 --- a/src/hasp_config.h +++ b/src/hasp_config.h @@ -23,6 +23,7 @@ const char F_GUI_IDLEPERIOD1[] PROGMEM = "idle1"; const char F_GUI_IDLEPERIOD2[] PROGMEM = "idle2"; const char F_GUI_CALIBRATION[] PROGMEM = "calibration"; const char F_GUI_BACKLIGHTPIN[] PROGMEM = "bcklpin"; +const char F_GUI_POINTER[] PROGMEM = "pointer"; const char F_DEBUG_TELEPERIOD[] PROGMEM = "teleperiod"; const char HASP_CONFIG_FILE[] PROGMEM = "/config.json"; @@ -37,4 +38,8 @@ void configWriteConfig(); bool configChanged(void); void configOutput(const JsonObject & settings); +bool configSet(int8_t & value, const JsonVariant & setting, const char * name); +bool configSet(uint8_t & value, const JsonVariant & setting, const char * name); +bool configSet(uint16_t & value, const JsonVariant & setting, const char * name); + #endif \ No newline at end of file diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 82620f20..c872fe30 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -50,15 +50,16 @@ WebServer * webClient; // for snatshot #define TFT_ROTATION 0 #endif -bool guiBacklightIsOn = true; -int8_t guiDimLevel = -1; -int8_t guiBacklightPin = TFT_BCKL; -bool guiAutoCalibrate = true; -uint16_t guiSleepTime1 = 60; // 1 second resolution -uint16_t guiSleepTime2 = 120; // 1 second resolution -uint8_t guiSleeping = 0; // 0 = off, 1 = short, 2 = long -uint8_t guiTickPeriod = 50; -uint8_t guiRotation = TFT_ROTATION; +static bool guiShowPointer = false; +static bool guiBacklightIsOn = true; +static int8_t guiDimLevel = -1; +static int8_t guiBacklightPin = TFT_BCKL; +static bool guiAutoCalibrate = true; +static uint16_t guiSleepTime1 = 60; // 1 second resolution +static uint16_t guiSleepTime2 = 120; // 1 second resolution +static uint8_t guiSleeping = 0; // 0 = off, 1 = short, 2 = long +static uint8_t guiTickPeriod = 50; +static uint8_t guiRotation = TFT_ROTATION; static Ticker tick; /* timer for interrupt handler */ static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */ static uint16_t calData[5] = {0, 65535, 0, 65535, 0}; @@ -344,9 +345,11 @@ void guiSetup(TFT_eSPI & screen, JsonObject settings) indev_drv.read_cb = my_touchpad_read; lv_indev_t * mouse_indev = lv_indev_drv_register(&indev_drv); - lv_obj_t * label = lv_label_create(lv_layer_sys(), NULL); - lv_label_set_text(label, "<"); - lv_indev_set_cursor(mouse_indev, label); // connect the object to the driver + if(guiShowPointer) { + lv_obj_t * label = lv_label_create(lv_layer_sys(), NULL); + lv_label_set_text(label, "<"); + lv_indev_set_cursor(mouse_indev, label); // connect the object to the driver + } /* lv_obj_t * cursor = lv_obj_create(lv_layer_sys(), NULL); // show on every page @@ -460,13 +463,14 @@ bool guiGetConfig(const JsonObject & settings) settings[FPSTR(F_GUI_IDLEPERIOD2)] = guiSleepTime2; settings[FPSTR(F_GUI_BACKLIGHTPIN)] = guiBacklightPin; settings[FPSTR(F_GUI_ROTATION)] = guiRotation; + settings[FPSTR(F_GUI_POINTER)] = guiShowPointer; JsonArray array = settings[FPSTR(F_GUI_CALIBRATION)].to(); - for(int i = 0; i < 5; i++) { + for(uint8_t i = 0; i < 5; i++) { array.add(calData[i]); } - size_t size = serializeJson(settings, Serial); + serializeJson(settings, Serial); Serial.println(); return true; @@ -476,51 +480,22 @@ bool guiGetConfig(const JsonObject & settings) bool guiSetConfig(const JsonObject & settings) { + configOutput(settings); bool changed = false; - if(!settings[FPSTR(F_GUI_TICKPERIOD)].isNull()) { - if(guiTickPeriod != settings[FPSTR(F_GUI_TICKPERIOD)].as()) { - debugPrintln(F("guiTickPeriod set")); + changed |= configSet(guiTickPeriod, settings[FPSTR(F_GUI_TICKPERIOD)], PSTR("guiTickPeriod")); + changed |= configSet(guiBacklightPin, settings[FPSTR(F_GUI_BACKLIGHTPIN)], PSTR("guiBacklightPin")); + changed |= configSet(guiSleepTime1, settings[FPSTR(F_GUI_IDLEPERIOD1)], PSTR("guiSleepTime1")); + changed |= configSet(guiSleepTime2, settings[FPSTR(F_GUI_IDLEPERIOD2)], PSTR("guiSleepTime2")); + changed |= configSet(guiRotation, settings[FPSTR(F_GUI_ROTATION)], PSTR("guiRotation")); + + if(!settings[FPSTR(F_GUI_POINTER)].isNull()) { + if(guiShowPointer != settings[FPSTR(F_GUI_POINTER)].as()) { + debugPrintln(F("guiShowPointer set")); } - changed |= guiTickPeriod != settings[FPSTR(F_GUI_TICKPERIOD)].as(); + changed |= guiShowPointer != settings[FPSTR(F_GUI_POINTER)].as(); - guiTickPeriod = settings[FPSTR(F_GUI_TICKPERIOD)].as(); - } - - if(!settings[FPSTR(F_GUI_BACKLIGHTPIN)].isNull()) { - if(guiBacklightPin != settings[FPSTR(F_GUI_BACKLIGHTPIN)].as()) { - debugPrintln(F("guiBacklightPin set")); - } - changed |= guiBacklightPin != settings[FPSTR(F_GUI_BACKLIGHTPIN)].as(); - - guiBacklightPin = settings[FPSTR(F_GUI_BACKLIGHTPIN)].as(); - } - - if(!settings[FPSTR(F_GUI_IDLEPERIOD1)].isNull()) { - if(guiSleepTime1 != settings[FPSTR(F_GUI_IDLEPERIOD1)].as()) { - debugPrintln(F("guiSleepTime1 set")); - } - changed |= guiSleepTime1 != settings[FPSTR(F_GUI_IDLEPERIOD1)].as(); - - guiSleepTime1 = settings[FPSTR(F_GUI_IDLEPERIOD1)].as(); - } - - if(!settings[FPSTR(F_GUI_IDLEPERIOD2)].isNull()) { - if(guiSleepTime2 != settings[FPSTR(F_GUI_IDLEPERIOD2)].as()) { - debugPrintln(F("guiSleepTime2 set")); - } - changed |= guiSleepTime2 != settings[FPSTR(F_GUI_IDLEPERIOD2)].as(); - - guiSleepTime2 = settings[FPSTR(F_GUI_IDLEPERIOD2)].as(); - } - - if(!settings[FPSTR(F_GUI_ROTATION)].isNull()) { - if(guiRotation != settings[FPSTR(F_GUI_ROTATION)].as()) { - debugPrintln(F("guiRotation set")); - } - changed |= guiRotation != settings[FPSTR(F_GUI_ROTATION)].as(); - - guiRotation = settings[FPSTR(F_GUI_ROTATION)].as(); + guiShowPointer = settings[FPSTR(F_GUI_POINTER)].as(); } if(!settings[FPSTR(F_GUI_CALIBRATION)].isNull()) { @@ -542,9 +517,6 @@ bool guiSetConfig(const JsonObject & settings) changed |= status; } - size_t size = serializeJson(settings, Serial); - Serial.println(); - return changed; } @@ -646,9 +618,11 @@ void guiSendBmpHeader() void guiTakeScreenshot(const char * pFileName) { pFileOut = SPIFFS.open(pFileName, "w"); + char buffer[127]; if(pFileOut == NULL) { - printf("[Display] error: %s cannot be opened", pFileName); + snprintf_P(buffer, sizeof(buffer), PSTR("[Display] error: %s cannot be opened"), pFileName); + debugPrintln(buffer); return; } @@ -660,7 +634,8 @@ void guiTakeScreenshot(const char * pFileName) guiSnapshot = 0; pFileOut.close(); - printf("[Display] data flushed to %s", pFileName); + snprintf_P(buffer, sizeof(buffer), PSTR("[Display] data flushed to %s"), pFileName); + debugPrintln(buffer); } #if defined(ARDUINO_ARCH_ESP8266) diff --git a/src/hasp_http.cpp b/src/hasp_http.cpp index cacec9e9..69e49262 100644 --- a/src/hasp_http.cpp +++ b/src/hasp_http.cpp @@ -125,7 +125,7 @@ String getOption(String value, String label, bool selected) void webSendFooter() { char buffer[127]; - snprintf_P(buffer, sizeof(buffer), "%u.%u.%u", HASP_VERSION_MAJOR, HASP_VERSION_MINOR, HASP_VERSION_REVISION); + snprintf_P(buffer, sizeof(buffer), PSTR("%u.%u.%u"), HASP_VERSION_MAJOR, HASP_VERSION_MINOR, HASP_VERSION_REVISION); webServer.sendContent_P(HTTP_END); webServer.sendContent(buffer); @@ -136,7 +136,7 @@ void webSendPage(String & nodename, uint32_t httpdatalength, bool gohome = false { char buffer[127]; - snprintf_P(buffer, sizeof(buffer), "%u.%u.%u", HASP_VERSION_MAJOR, HASP_VERSION_MINOR, HASP_VERSION_REVISION); + snprintf_P(buffer, sizeof(buffer), PSTR("%u.%u.%u"), HASP_VERSION_MAJOR, HASP_VERSION_MINOR, HASP_VERSION_REVISION); /* Calculate Content Length upfront */ uint16_t contentLength = strlen(buffer); // verion length @@ -150,8 +150,11 @@ void webSendPage(String & nodename, uint32_t httpdatalength, bool gohome = false contentLength += sizeof(HTTP_END) - 1; contentLength += sizeof(HTTP_FOOTER) - 1; - webServer.setContentLength(contentLength + httpdatalength); + snprintf_P(buffer, sizeof(buffer), PSTR("HTTP: Sending page with %u static and %u dynamic bytes"), contentLength, + httpdatalength); + debugPrintln(buffer); + webServer.setContentLength(contentLength + httpdatalength); webServer.send_P(200, PSTR("text/html"), HTTP_DOCTYPE); // 122 sprintf_P(buffer, HTTP_HEADER, nodename.c_str()); webServer.sendContent(buffer); // 17-2+len @@ -160,10 +163,6 @@ void webSendPage(String & nodename, uint32_t httpdatalength, bool gohome = false webServer.sendContent_P(HASP_STYLE); // 145 if(gohome) webServer.sendContent_P(HTTP_META_GO_BACK); // 47 webServer.sendContent_P(HTTP_HEADER_END); // 80 - - snprintf_P(buffer, sizeof(buffer), PSTR("HTTP: Sent page with %u static and %u dynamic bytes"), contentLength, - httpdatalength); - debugPrintln(buffer); } void webHandleRoot() @@ -502,7 +501,7 @@ void handleFileDelete() { if(!httpIsAuthenticated(F("filedelete"))) return; - char mimetype[10]; + char mimetype[127]; sprintf(mimetype, PSTR("text/plain")); if(webServer.args() == 0) { @@ -1123,27 +1122,35 @@ void httpSetup(const JsonObject & settings) haspSetPage(pageid.toInt()); }); - webServer.on("/list", HTTP_GET, handleFileList); + webServer.on(F("/list"), HTTP_GET, handleFileList); // load editor - webServer.on("/edit", HTTP_GET, []() { + webServer.on(F("/edit"), HTTP_GET, []() { if(!handleFileRead("/edit.htm")) { - webServer.send(404, "text/plain", "FileNotFound"); + char mimetype[127]; + sprintf(mimetype, PSTR("text/plain")); + webServer.send_P(404, mimetype, PSTR("FileNotFound")); } }); - webServer.on("/edit", HTTP_PUT, handleFileCreate); - webServer.on("/edit", HTTP_DELETE, handleFileDelete); + webServer.on(F("/edit"), HTTP_PUT, handleFileCreate); + webServer.on(F("/edit"), HTTP_DELETE, handleFileDelete); // first callback is called after the request has ended with all parsed arguments // second callback handles file uploads at that location - webServer.on("/edit", HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, handleFileUpload); + webServer.on(F("/edit"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, handleFileUpload); // get heap status, analog input value and all GPIO statuses in one json call - webServer.on("/all", HTTP_GET, []() { - String json('{'); - json += "\"heap\":" + String(ESP.getFreeHeap()); - json += ", \"analog\":" + String(analogRead(A0)); - json += "}"; - webServer.send(200, "text/json", json); + /*webServer.on(F("/all"), HTTP_GET, []() { + String json; + json.reserve(127); + json += F("{\"heap\":"); + json += String(ESP.getFreeHeap()); + json += F(", \"analog\":"); + json += String(analogRead(A0)); + json += F("}"); + + char mimetype[127]; + sprintf(mimetype, PSTR("text/json")); + webServer.send(200, mimetype, json); json.clear(); - }); + });*/ webServer.on(F("/"), webHandleRoot); webServer.on(F("/about"), webHandleAbout); @@ -1219,8 +1226,11 @@ bool httpGetConfig(const JsonObject & settings) bool httpSetConfig(const JsonObject & settings) { + configOutput(settings); bool changed = false; + changed |= configSet(httpPort, settings[FPSTR(F_CONFIG_PORT)], PSTR("httpPort")); + if(!settings[FPSTR(F_CONFIG_USER)].isNull()) { changed |= strcmp(httpUser, settings[FPSTR(F_CONFIG_USER)]) != 0; strncpy(httpUser, settings[FPSTR(F_CONFIG_USER)], sizeof(httpUser)); @@ -1231,15 +1241,5 @@ bool httpSetConfig(const JsonObject & settings) strncpy(httpPassword, settings[FPSTR(F_CONFIG_PASS)], sizeof(httpPassword)); } - if(!settings[FPSTR(F_CONFIG_PORT)].isNull()) { - if(httpPort != settings[FPSTR(F_CONFIG_PORT)].as()) { - debugPrintln(F("httpPort set")); - } - changed |= httpPort != settings[FPSTR(F_CONFIG_PORT)].as(); - - httpPort = settings[FPSTR(F_CONFIG_PORT)].as(); - } - - configOutput(settings); return changed; } \ No newline at end of file diff --git a/src/hasp_mqtt.cpp b/src/hasp_mqtt.cpp index 06faa368..4855a26c 100644 --- a/src/hasp_mqtt.cpp +++ b/src/hasp_mqtt.cpp @@ -453,8 +453,11 @@ bool mqttGetConfig(const JsonObject & settings) bool mqttSetConfig(const JsonObject & settings) { + configOutput(settings); bool changed = false; + changed |= configSet(mqttPort, settings[FPSTR(F_CONFIG_PORT)], PSTR("mqttPort")); + if(!settings[FPSTR(F_CONFIG_GROUP)].isNull()) { if(mqttGroupName != settings[FPSTR(F_CONFIG_GROUP)].as().c_str()) { debugPrintln(F("mqttGroupName set")); @@ -473,15 +476,6 @@ bool mqttSetConfig(const JsonObject & settings) mqttServer = settings[FPSTR(F_CONFIG_HOST)].as().c_str(); } - if(!settings[FPSTR(F_CONFIG_PORT)].isNull()) { - if(mqttPort != settings[FPSTR(F_CONFIG_PORT)].as()) { - debugPrintln(F("mqttPort set")); - } - changed |= mqttPort != settings[FPSTR(F_CONFIG_PORT)].as(); - - mqttPort = settings[FPSTR(F_CONFIG_PORT)].as(); - } - if(!settings[FPSTR(F_CONFIG_USER)].isNull()) { if(mqttUser != settings[FPSTR(F_CONFIG_USER)].as().c_str()) { debugPrintln(F("mqttUser set")); @@ -491,7 +485,8 @@ bool mqttSetConfig(const JsonObject & settings) mqttUser = settings[FPSTR(F_CONFIG_USER)].as().c_str(); } - if(!settings[FPSTR(F_CONFIG_PASS)].isNull()) { + if(!settings[FPSTR(F_CONFIG_PASS)].isNull() && + settings[FPSTR(F_CONFIG_PASS)].as() != String(FPSTR("********"))) { if(mqttPassword != settings[FPSTR(F_CONFIG_PASS)].as().c_str()) { debugPrintln(F("mqttPassword set")); } @@ -500,6 +495,5 @@ bool mqttSetConfig(const JsonObject & settings) mqttPassword = settings[FPSTR(F_CONFIG_PASS)].as().c_str(); } - configOutput(settings); return changed; } diff --git a/src/hasp_wifi.cpp b/src/hasp_wifi.cpp index 3cea8319..9e4f1b51 100644 --- a/src/hasp_wifi.cpp +++ b/src/hasp_wifi.cpp @@ -150,25 +150,25 @@ void wifiSetup(JsonObject settings) debugPrintln(buffer); haspDisplayAP(apSsdid.c_str(), "haspadmin"); httpReconnect(); - return; - } + } else { - WiFi.mode(WIFI_STA); - snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: Connecting to : %s"), wifiSsid); - debugPrintln(buffer); + WiFi.mode(WIFI_STA); + snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: Connecting to : %s"), wifiSsid); + debugPrintln(buffer); #if defined(ARDUINO_ARCH_ESP8266) - // wifiEventHandler[0] = WiFi.onStationModeConnected(wifiSTAConnected); - gotIpEventHandler = WiFi.onStationModeGotIP(wifiSTAGotIP); // As soon WiFi is connected, start NTP Client - disconnectedEventHandler = WiFi.onStationModeDisconnected(wifiSTADisconnected); - WiFi.setSleepMode(WIFI_NONE_SLEEP); + // wifiEventHandler[0] = WiFi.onStationModeConnected(wifiSTAConnected); + gotIpEventHandler = WiFi.onStationModeGotIP(wifiSTAGotIP); // As soon WiFi is connected, start NTP Client + disconnectedEventHandler = WiFi.onStationModeDisconnected(wifiSTADisconnected); + WiFi.setSleepMode(WIFI_NONE_SLEEP); #endif #if defined(ARDUINO_ARCH_ESP32) - WiFi.onEvent(wifi_callback); - WiFi.setSleep(false); + WiFi.onEvent(wifi_callback); + WiFi.setSleep(false); #endif - WiFi.begin(wifiSsid, wifiPassword); + WiFi.begin(wifiSsid, wifiPassword); + } } bool wifiLoop() @@ -217,6 +217,7 @@ bool wifiGetConfig(const JsonObject & settings) bool wifiSetConfig(const JsonObject & settings) { + configOutput(settings); bool changed = false; if(!settings[FPSTR(F_CONFIG_SSID)].isNull()) { @@ -229,7 +230,6 @@ bool wifiSetConfig(const JsonObject & settings) strncpy(wifiPassword, settings[FPSTR(F_CONFIG_PASS)], sizeof(wifiPassword)); } - configOutput(settings); return changed; }