From 268bcb05db8b7c25f9e653859d750711be757a8e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 25 Apr 2021 02:10:09 +0200 Subject: [PATCH 001/227] Revert "Merge master back into gpio-redesign" --- .gitignore | 3 +- include/lv_conf.h | 4 - include/lv_conf_v7.h | 26 -- include/user_config_override-template.h | 21 +- platformio.ini | 5 +- src/dev/device.cpp | 17 -- src/dev/device.h | 1 - src/dev/esp32/esp32.cpp | 3 - src/hasp/hasp_attribute.cpp | 46 ++-- src/hasp/hasp_attribute.h | 1 - src/hasp/hasp_dispatch.cpp | 16 +- src/hasp/hasp_event.cpp | 11 - src/hasp/hasp_event.h | 1 - src/hasp/hasp_object.cpp | 27 +-- src/hasp_config.cpp | 7 - src/hasp_config.h | 4 - src/hasp_debug.cpp | 2 - src/hasp_debug.h | 40 +++ src/mqtt/hasp_mqtt_pubsubclient.cpp | 65 +++-- src/sys/svc/hasp_http.cpp | 7 +- test/{config_template.yaml => config.yaml} | 8 +- test/test_colors.tavern.yaml | 66 +++-- test/test_cpicker.tavern.yaml | 227 ------------------ test/test_label.tavern.yaml | 101 ++------ test/test_mqtt.tavern.yaml | 44 ++-- test/test_obj.tavern.yaml | 43 +--- test/test_value_str.tavern.yaml | 45 +--- user_setups/darwin_sdl/darwin_sdl_64bits.ini | 2 - .../esp32/arduitouch-esp32_ili9341.ini | 1 - user_setups/esp32/esp32-touchdown.ini | 1 - user_setups/esp32/freetouchdeck.ini | 1 - user_setups/esp32/huzzah32-featherwing-24.ini | 2 - user_setups/esp32/huzzah32-featherwing-35.ini | 2 - user_setups/esp32/lanbon_l8.ini | 1 - user_setups/esp32/m5stack_core2.ini | 1 - user_setups/esp32/ttgo-esp32-lilygo-pi.ini | 1 - user_setups/esp32/wt32-sc01.ini | 1 - user_setups/linux_sdl/linux_sdl_64bits.ini | 2 - user_setups/win32/windows_sdl_64bits.ini | 2 - 39 files changed, 216 insertions(+), 642 deletions(-) rename test/{config_template.yaml => config.yaml} (53%) delete mode 100644 test/test_cpicker.tavern.yaml diff --git a/.gitignore b/.gitignore index ab6f693b..eac47ff6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,13 +5,12 @@ .git .pio data/* +src/user_setups/active/* include/user_config_override.h src/user_config_override.h user_config_override.h platformio_override.ini user_setups/active/* -src/user_setups/active/* -test/config.yaml build_output/* build_output/firmware/*.bin build_output/firmware/*.exe diff --git a/include/lv_conf.h b/include/lv_conf.h index c7ea9aad..7a1d57a6 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -1,7 +1,3 @@ -#ifdef USE_CONFIG_OVERRIDE -#include "user_config_override.h" -#endif - #include "lv_conf_v7.h" #define LV_THEME_DEFAULT_FLAGS LV_THEME_DEFAULT_FLAG diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index 74897617..a4d3b2eb 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -367,19 +367,6 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in #define ROBOTOCONDENSED_REGULAR_48_LATIN1 1 #endif -#ifndef HASP_FONT_SIZE_1 -#define HASP_FONT_SIZE_1 16 -#endif -#ifndef HASP_FONT_SIZE_2 -#define HASP_FONT_SIZE_2 24 -#endif -#ifndef HASP_FONT_SIZE_3 -#define HASP_FONT_SIZE_3 32 -#endif -#ifndef HASP_FONT_SIZE_4 -#define HASP_FONT_SIZE_4 48 -#endif - #else #ifndef HASP_FONT_1 @@ -408,19 +395,6 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in #define ROBOTOCONDENSED_REGULAR_32_LATIN1 1 #endif -#ifndef HASP_FONT_SIZE_1 -#define HASP_FONT_SIZE_1 12 -#endif -#ifndef HASP_FONT_SIZE_2 -#define HASP_FONT_SIZE_2 16 -#endif -#ifndef HASP_FONT_SIZE_3 -#define HASP_FONT_SIZE_3 24 -#endif -#ifndef HASP_FONT_SIZE_4 -#define HASP_FONT_SIZE_4 32 -#endif - #endif /* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. diff --git a/include/user_config_override-template.h b/include/user_config_override-template.h index 9e64d0e1..fd01a783 100644 --- a/include/user_config_override-template.h +++ b/include/user_config_override-template.h @@ -88,28 +88,9 @@ #define D_HTTP_COLOR_BUTTON_RESET "#d43535" // Restart/Reset/Delete button color - Strong red */ -/*************************************************** - * Font Settings - **************************************************/ -// #define HASP_FONT_1 robotocondensed_regular_16_latin1 // Use available fonts from src/fonts directory -// #define HASP_FONT_2 robotocondensed_regular_22_latin1 -// #define HASP_FONT_3 robotocondensed_regular_40_latin1 -// #define HASP_FONT_4 robotocondensed_regular_48_latin1 - -// #define ROBOTOCONDENSED_REGULAR_16_LATIN1 1 // Enable the selected fonts -// #define ROBOTOCONDENSED_REGULAR_22_LATIN1 1 -// #define ROBOTOCONDENSED_REGULAR_40_LATIN1 1 -// #define ROBOTOCONDENSED_REGULAR_48_LATIN1 1 - -// #define HASP_FONT_SIZE_1 16 // Define used font sizes -// #define HASP_FONT_SIZE_2 22 -// #define HASP_FONT_SIZE_3 40 -// #define HASP_FONT_SIZE_4 48 - /*************************************************** * Other Settings **************************************************/ //#define HASP_USE_HA // Enable Home Assistant auto-discovery -//#define HASP_GPIO_TEMPLATE "[2360346,2491680,2623009,2097420,2097678,2097947,0,0]" // Lanbon L8-HS: 3 Relays + Moodlight GPIO config -#endif +#endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 3aab2a92..a73ea958 100644 --- a/platformio.ini +++ b/platformio.ini @@ -49,7 +49,6 @@ build_flags = -D LV_LVGL_H_INCLUDE_SIMPLE ; for lv_drivers -D LV_COMP_CONF_INCLUDE_SIMPLE ; for components -D LV_SYMBOL_DEF_H ; don't load default symbol defines - -D LV_MEM_FULL_DEFRAG_CNT=4 ; stability: run lv_mem_defrag more frequently ; -- ESP build options ------------------------------------ -D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files ; -- ArduinoJson build options ---------------------------- @@ -61,8 +60,8 @@ build_flags = ; -- Hasp build options ---------------------------- -D HASP_VER_MAJ=0 -D HASP_VER_MIN=5 - -D HASP_VER_REV=1 - -D HASP_LOG_LEVEL=LOG_LEVEL_TRACE + -D HASP_VER_REV=0 + -D HASP_LOG_LEVEL=LOG_LEVEL_OUTPUT ${override.build_flags} ; -- Shared library dependencies in all environments diff --git a/src/dev/device.cpp b/src/dev/device.cpp index 3c531343..395a6e43 100644 --- a/src/dev/device.cpp +++ b/src/dev/device.cpp @@ -1,19 +1,2 @@ /* MIT License - Copyright (c) 2019-2021 Francis Van Roie For full license information read the LICENSE file in the project folder */ - -#include "device.h" - -#define Q(x) #x -#define QUOTE(x) Q(x) - -namespace dev { - -const char* BaseDevice::get_model() -{ -#ifdef HASP_MODEL - return QUOTE(HASP_MODEL); -#else - return PIOENV; -#endif -} -} // namespace dev \ No newline at end of file diff --git a/src/dev/device.h b/src/dev/device.h index 2cca34c7..68d1867a 100644 --- a/src/dev/device.h +++ b/src/dev/device.h @@ -41,7 +41,6 @@ class BaseDevice { { return ""; } - const char* get_model(); virtual void init() {} diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp index 66fe647f..6cc4693a 100644 --- a/src/dev/esp32/esp32.cpp +++ b/src/dev/esp32/esp32.cpp @@ -37,17 +37,14 @@ const char* Esp32Device::get_hostname() { return _hostname.c_str(); } - void Esp32Device::set_hostname(const char* hostname) { _hostname = hostname; } - const char* Esp32Device::get_core_version() { return esp_get_idf_version(); // == ESP.getSdkVersion(); } - const char* Esp32Device::get_chip_model() { esp_chip_info_t chip_info; diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index f72b7831..7378e2dd 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -232,7 +232,7 @@ void my_obj_set_value_str_txt(lv_obj_t* obj, uint8_t part, lv_state_t state, con { // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - void* value_str_p = (void*)lv_obj_get_style_value_str(obj, part); + const void* value_str_p = lv_obj_get_style_value_str(obj, part); lv_obj_invalidate(obj); if(text == NULL || text[0] == 0) { @@ -262,21 +262,36 @@ void my_obj_set_value_str_txt(lv_obj_t* obj, uint8_t part, lv_state_t state, con return; } + // lv_obj_set_style_local_value_str(obj, part, state, str_p); + if(value_str_p == text) { /*If set its own text then reallocate it (maybe its size changed)*/ LOG_DEBUG(TAG_ATTR, "%s %d", __FILE__, __LINE__); return; // don't touch the data + + // value_str_p = lv_mem_realloc(value_str_p, strlen(text) + 1); + + // LV_ASSERT_MEM(value_str_p); + // if(value_str_p == NULL) return; + } else { + /*Free the old text*/ + if(value_str_p != NULL) { + // LOG_DEBUG(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + lv_mem_free(value_str_p); + value_str_p = NULL; + // LOG_DEBUG(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + } + + /*Get the size of the text*/ + size_t len = strlen(text) + 1; + + /*Allocate space for the new text*/ + value_str_p = lv_mem_alloc(len); + LV_ASSERT_MEM(value_str_p); + if(value_str_p != NULL) strcpy((char*)value_str_p, text); + lv_obj_set_style_local_value_str(obj, part, state, (char*)value_str_p); } - /*Get the size of the text*/ - size_t len = strlen(text) + 1; - - /*Allocate space for the new text*/ - value_str_p = lv_mem_realloc(value_str_p, len); - LV_ASSERT_MEM(value_str_p); - if(value_str_p != NULL) strcpy((char*)value_str_p, text); - lv_obj_set_style_local_value_str(obj, part, state, (char*)value_str_p); - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); } @@ -448,24 +463,24 @@ static lv_font_t* haspPayloadToFont(const char* payload) #ifndef ARDUINO_ARCH_ESP8266 #ifdef HASP_FONT_1 - case HASP_FONT_SIZE_1: + case 12: return &HASP_FONT_1; #endif #ifdef HASP_FONT_2 - case HASP_FONT_SIZE_2: + case 16: LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_2); return &HASP_FONT_2; #endif #ifdef HASP_FONT_3 - case HASP_FONT_SIZE_3: + case 22: LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_3); return &HASP_FONT_3; #endif #ifdef HASP_FONT_4 - case HASP_FONT_SIZE_4: + case 28: LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_4); return &HASP_FONT_4; #endif @@ -1777,9 +1792,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p } goto attribute_not_found; - case ATTR_COMMENT: - break; // attribute_found - default: hasp_local_style_attr(obj, attr, attr_hash, payload, update); } diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index ca260c85..7a4f11f7 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -266,7 +266,6 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_BACK 57799 /* Object Attributes */ -#define ATTR_COMMENT 62559 #define ATTR_X 120 #define ATTR_Y 121 #define ATTR_W 119 diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 548b37b5..71d33185 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -887,18 +887,15 @@ void dispatch_output_statusupdate(const char*, const char*) { #if HASP_USE_MQTT > 0 - char data[512]; + char data[400]; char topic[16]; { char buffer[128]; haspGetVersion(buffer, sizeof(buffer)); dispatch_get_idle_state(hasp_sleep_state, topic); - snprintf_P(data, sizeof(data), - PSTR("{\"node\":\"%s\",\"manufacturer\":\"" D_MANUFACTURER - "\",\"model\":\"%s\",\"idle\":\"%s\",\"version\":\"%s\",\"uptime\":%lu,"), - haspDevice.get_hostname(), haspDevice.get_model(), topic, buffer, - (unsigned long)(millis() / 1000)); // \"status\":\"available\", + snprintf_P(data, sizeof(data), PSTR("{\"node\":\"%s\",\"idle\":\"%s\",\"version\":\"%s\",\"uptime\":%lu,"), + haspDevice.get_hostname(), topic, buffer, long(millis() / 1000)); // \"status\":\"available\", #if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0 network_get_statusupdate(buffer, sizeof(buffer)); @@ -930,6 +927,13 @@ void dispatch_output_statusupdate(const char*, const char*) dispatch_state_subtopic(topic, data); dispatchLastMillis = millis(); + /* if(updateEspAvailable) { + mqttStatusPayload += F("\"updateEspAvailable\":true,"); + } else { + mqttStatusPayload += F("\"updateEspAvailable\":false,"); + } + */ + #endif } diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index 7e546f5f..ca254cd6 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -555,14 +555,3 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) // dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max); } - -/** - * Called when an object is deleted - * @param obj pointer to a generic object - * @param event type of event that occured - */ -void deleted_event_handler(lv_obj_t* obj, lv_event_t event) -{ - uint8_t hasp_event_id; - translate_event(obj, event, hasp_event_id); -} \ No newline at end of file diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h index b113575f..9b82950a 100644 --- a/src/hasp/hasp_event.h +++ b/src/hasp/hasp_event.h @@ -18,7 +18,6 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event); void selector_event_handler(lv_obj_t* obj, lv_event_t event); void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event); void cpicker_event_handler(lv_obj_t* obj, lv_event_t event); -void deleted_event_handler(lv_obj_t* obj, lv_event_t event); #if HASP_USE_GPIO > 0 void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid); diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index c6beef08..f1c09788 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -489,20 +489,16 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) case LV_HASP_PAGE: case HASP_OBJ_PAGE: obj = lv_page_create(parent_obj, NULL); - if(obj) { - obj->user_data.objid = LV_HASP_PAGE; - lv_obj_set_event_cb(obj, deleted_event_handler); // Needed for memory dealocation - } + if(obj) obj->user_data.objid = LV_HASP_PAGE; + // No event handler for pages break; #if LV_USE_WIN && LVGL_VERSION_MAJOR == 7 case LV_HASP_WINDOW: case HASP_OBJ_WIN: obj = lv_win_create(parent_obj, NULL); - if(obj) { - obj->user_data.objid = LV_HASP_WINDOW; - lv_obj_set_event_cb(obj, deleted_event_handler); // Needed for memory dealocation - } + if(obj) obj->user_data.objid = LV_HASP_WINDOW; + // No event handler for pages break; #endif @@ -554,18 +550,16 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) case LV_HASP_TILEVIEW: case HASP_OBJ_TILEVIEW: obj = lv_tileview_create(parent_obj, NULL); - if(obj) { - obj->user_data.objid = LV_HASP_TILEVIEW; - lv_obj_set_event_cb(obj, deleted_event_handler); // Needed for memory dealocation - } + if(obj) obj->user_data.objid = LV_HASP_TILEVIEW; + + // No event handler for tileviews break; case LV_HASP_TABVIEW: case HASP_OBJ_TABVIEW: obj = lv_tabview_create(parent_obj, NULL); + // No event handler for tabs if(obj) { - lv_obj_set_event_cb(obj, deleted_event_handler); // Needed for memory dealocation - lv_obj_t* tab; tab = lv_tabview_add_tab(obj, "tab 1"); // lv_obj_set_user_data(tab, id + 1); @@ -593,10 +587,7 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) case LV_HASP_SPINNER: case HASP_OBJ_SPINNER: obj = lv_spinner_create(parent_obj, NULL); - if(obj) { - obj->user_data.objid = LV_HASP_SPINNER; - lv_obj_set_event_cb(obj, deleted_event_handler); // Needed for memory dealocation - } + if(obj) obj->user_data.objid = LV_HASP_SPINNER; break; #endif diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 3f2b08c9..4240ceb6 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -152,13 +152,6 @@ void configRead(JsonDocument& settings, bool setupdebug = false) #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 LOG_ERROR(TAG_CONF, F(D_FILE_LOAD_FAILED), configFile.c_str()); - #ifdef HASP_GPIO_TEMPLATE - char json[100]; - snprintf(json, sizeof(json), PSTR("{\"%s\":{\"%s\":%s}}"), (char*)(FPSTR(FP_GPIO)), (char*)(FPSTR(FP_GPIO_CONFIG)), (char*)(FPSTR(HASP_GPIO_TEMPLATE))); - error = deserializeJson(settings, json); - gpioSetConfig(settings[FPSTR(FP_GPIO)]); - #endif - #endif } /* diff --git a/src/hasp_config.h b/src/hasp_config.h index 99224b06..77eb6e01 100644 --- a/src/hasp_config.h +++ b/src/hasp_config.h @@ -71,10 +71,6 @@ const char FP_HASP[] PROGMEM = "hasp"; const char FP_GUI[] PROGMEM = "gui"; const char FP_DEBUG[] PROGMEM = "debug"; -#ifdef HASP_GPIO_TEMPLATE -const char FP_GPIO_TEMPLATE[] PROGMEM = HASP_GPIO_TEMPLATE; -#endif - #endif #endif // HASP_USE_CONFIG \ No newline at end of file diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 83fcad2f..272fa569 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -338,8 +338,6 @@ static void debugPrintLvglMemory(int level, Print* _logOutput) lv_mem_monitor_t mem_mon; lv_mem_monitor(&mem_mon); - if(mem_mon.frag_pct > 20) lv_mem_defrag(); // prevents LED shadow crashing - /* Print LVGL Memory Info */ if(debugAnsiCodes) { if(mem_mon.free_biggest_size > (1024u * 2) && (mem_mon.free_size > 1024u * 2.5) && (mem_mon.frag_pct <= 10)) diff --git a/src/hasp_debug.h b/src/hasp_debug.h index 615308b8..dc1e92c2 100644 --- a/src/hasp_debug.h +++ b/src/hasp_debug.h @@ -85,6 +85,46 @@ void debugStopSyslog(void); std::cout << std::endl; \ fflush(stdout) +/* json keys used in the configfile */ +// const char FP_CONFIG_STARTPAGE[] PROGMEM = "startpage"; +// const char FP_CONFIG_STARTDIM[] PROGMEM = "startdim"; +// const char FP_CONFIG_THEME[] PROGMEM = "theme"; +// const char FP_CONFIG_HUE[] PROGMEM = "hue"; +// const char FP_CONFIG_ZIFONT[] PROGMEM = "font"; +// const char FP_CONFIG_PAGES[] PROGMEM = "pages"; +// const char FP_CONFIG_ENABLE[] PROGMEM = "enable"; +// const char FP_CONFIG_HOST[] PROGMEM = "host"; +// const char FP_CONFIG_PORT[] PROGMEM = "port"; +// const char FP_CONFIG_NAME[] PROGMEM = "name"; +// const char FP_CONFIG_USER[] PROGMEM = "user"; +// const char FP_CONFIG_PASS[] PROGMEM = "pass"; +// const char FP_CONFIG_SSID[] PROGMEM = "ssid"; +// const char FP_CONFIG_GROUP[] PROGMEM = "group"; +// const char FP_CONFIG_BAUD[] PROGMEM = "baud"; +// const char FP_CONFIG_LOG[] PROGMEM = "log"; +// const char FP_CONFIG_PROTOCOL[] PROGMEM = "proto"; +// const char FP_GUI_ROTATION[] PROGMEM = "rotate"; +// const char FP_GUI_INVERT[] PROGMEM = "invert"; +// const char FP_GUI_TICKPERIOD[] PROGMEM = "tick"; +// const char FP_GUI_IDLEPERIOD1[] PROGMEM = "idle1"; +// const char FP_GUI_IDLEPERIOD2[] PROGMEM = "idle2"; +// const char FP_GUI_CALIBRATION[] PROGMEM = "calibration"; +// const char FP_GUI_BACKLIGHTPIN[] PROGMEM = "bckl"; +// const char FP_GUI_POINTER[] PROGMEM = "cursor"; +// const char FP_DEBUG_TELEPERIOD[] PROGMEM = "tele"; +// const char FP_GPIO_CONFIG[] PROGMEM = "config"; + +// const char FP_HASP_CONFIG_FILE[] PROGMEM = "/config.json"; + +// const char FP_WIFI[] PROGMEM = "wifi"; +// const char FP_MQTT[] PROGMEM = "mqtt"; +// const char FP_HTTP[] PROGMEM = "http"; +// const char FP_GPIO[] PROGMEM = "gpio"; +// const char FP_MDNS[] PROGMEM = "mdns"; +// const char FP_HASP[] PROGMEM = "hasp"; +// const char FP_GUI[] PROGMEM = "gui"; +// const char FP_DEBUG[] PROGMEM = "debug"; + #endif #ifdef __cplusplus diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index 17eaa93f..a89da106 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -81,16 +81,12 @@ bool mqttHAautodiscover = true; #define LWT_TOPIC "LWT" -// char mqttServer[16] = MQTT_HOST; -// char mqttUser[23] = MQTT_USER; -// char mqttPassword[32] = MQTT_PASSW; -// char mqttGroupName[16] = MQTT_GROUPNAME; -std::string mqttServer = MQTT_HOST; -std::string mqttUser = MQTT_USER; -std::string mqttPassword = MQTT_PASSW; -std::string mqttGroupName = MQTT_GROUPNAME; - -uint16_t mqttPort = MQTT_PORT; +char mqttServer[16] = MQTT_HOST; +char mqttUser[23] = MQTT_USER; +char mqttPassword[32] = MQTT_PASSW; +// char mqttNodeName[16] = MQTT_NODENAME; +char mqttGroupName[16] = MQTT_GROUPNAME; +uint16_t mqttPort = MQTT_PORT; PubSubClient mqttClient(mqttNetworkClient); int mqttPublish(const char* topic, const char* payload, size_t len, bool retain) @@ -228,7 +224,7 @@ void mqttStart() static uint8_t mqttReconnectCount = 0; // bool mqttFirstConnect = true; - mqttClient.setServer(mqttServer.c_str(), 1883); + mqttClient.setServer(mqttServer, 1883); // mqttClient.setSocketTimeout(10); //in seconds /* Construct unique Client ID*/ @@ -246,8 +242,7 @@ void mqttStart() haspProgressMsg(F(D_MQTT_CONNECTING)); haspProgressVal(mqttReconnectCount * 5); - if(!mqttClient.connect(mqttClientId, mqttUser.c_str(), mqttPassword.c_str(), buffer, 0, true, lastWillPayload, - true)) { + if(!mqttClient.connect(mqttClientId, mqttUser, mqttPassword, buffer, 0, true, lastWillPayload, true)) { // Retry until we give up and restart after connectTimeout seconds mqttReconnectCount++; @@ -292,16 +287,16 @@ void mqttStart() return; } - LOG_INFO(TAG_MQTT, F(D_MQTT_CONNECTED), mqttServer.c_str(), mqttClientId); + LOG_INFO(TAG_MQTT, F(D_MQTT_CONNECTED), mqttServer, mqttClientId); // Subscribe to our incoming topics const __FlashStringHelper* F_topic; F_topic = F("%scommand/#"); mqttSubscribeTo(F_topic, mqttGroupTopic); mqttSubscribeTo(F_topic, mqttNodeTopic); - F_topic = F("%sconfig/#"); - mqttSubscribeTo(F_topic, mqttGroupTopic); - mqttSubscribeTo(F_topic, mqttNodeTopic); + // F_topic = F("%sconfig/#"); + // mqttSubscribeTo(F_topic, mqttGroupTopic); + // mqttSubscribeTo(F_topic, mqttNodeTopic); // mqttSubscribeTo(F("%slight/#"), mqttNodeTopic); // mqttSubscribeTo(F("%sbrightness/#"), mqttNodeTopic); // mqttSubscribeTo(F("%s"LWT_TOPIC), mqttNodeTopic); @@ -328,9 +323,9 @@ void mqttStart() void mqttSetup() { - mqttEnabled = mqttServer.length() > 0 && mqttPort > 0; + mqttEnabled = strlen(mqttServer) > 0 && mqttPort > 0; if(mqttEnabled) { - mqttClient.setServer(mqttServer.c_str(), mqttPort); + mqttClient.setServer(mqttServer, mqttPort); mqttClient.setCallback(mqtt_message_cb); // if(!mqttClient.setBufferSize(1024)) { // LOG_ERROR(TAG_MQTT, F("Buffer allocation failed")); @@ -378,19 +373,19 @@ bool mqttGetConfig(const JsonObject& settings) if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as().c_str()) != 0) changed = true; settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname(); - if(mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as()) changed = true; + if(strcmp(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)].as().c_str()) != 0) changed = true; settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName; - if(mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as()) changed = true; + if(strcmp(mqttServer, settings[FPSTR(FP_CONFIG_HOST)].as().c_str()) != 0) changed = true; settings[FPSTR(FP_CONFIG_HOST)] = mqttServer; if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as()) changed = true; settings[FPSTR(FP_CONFIG_PORT)] = mqttPort; - if(mqttUser != settings[FPSTR(FP_CONFIG_USER)].as().c_str()) changed = true; + if(strcmp(mqttUser, settings[FPSTR(FP_CONFIG_USER)].as().c_str()) != 0) changed = true; settings[FPSTR(FP_CONFIG_USER)] = mqttUser; - if(mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as().c_str()) changed = true; + if(strcmp(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)].as().c_str()) != 0) changed = true; settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword; if(changed) configOutput(settings, TAG_MQTT); @@ -428,33 +423,33 @@ bool mqttSetConfig(const JsonObject& settings) } if(!settings[FPSTR(FP_CONFIG_GROUP)].isNull()) { - changed |= mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as(); - mqttGroupName = settings[FPSTR(FP_CONFIG_GROUP)].as(); + changed |= strcmp(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)]) != 0; + strncpy(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)], sizeof(mqttGroupName)); } - if(mqttGroupName.length() == 0) { - mqttGroupName = String(F("plates")).c_str(); - changed = true; + if(strlen(mqttGroupName) == 0) { + strcpy_P(mqttGroupName, PSTR("plates")); + changed = true; } if(!settings[FPSTR(FP_CONFIG_HOST)].isNull()) { - changed |= mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as(); - mqttServer = settings[FPSTR(FP_CONFIG_HOST)].as(); + changed |= strcmp(mqttServer, settings[FPSTR(FP_CONFIG_HOST)]) != 0; + strncpy(mqttServer, settings[FPSTR(FP_CONFIG_HOST)], sizeof(mqttServer)); } if(!settings[FPSTR(FP_CONFIG_USER)].isNull()) { - changed |= mqttUser != settings[FPSTR(FP_CONFIG_USER)].as(); - mqttUser = settings[FPSTR(FP_CONFIG_USER)].as(); + changed |= strcmp(mqttUser, settings[FPSTR(FP_CONFIG_USER)]) != 0; + strncpy(mqttUser, settings[FPSTR(FP_CONFIG_USER)], sizeof(mqttUser)); } if(!settings[FPSTR(FP_CONFIG_PASS)].isNull() && settings[FPSTR(FP_CONFIG_PASS)].as() != String(FPSTR(D_PASSWORD_MASK))) { - changed |= mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as(); - mqttPassword = settings[FPSTR(FP_CONFIG_PASS)].as(); + changed |= strcmp(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)]) != 0; + strncpy(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)], sizeof(mqttPassword)); } snprintf_P(mqttNodeTopic, sizeof(mqttNodeTopic), PSTR(MQTT_PREFIX "/%s/"), haspDevice.get_hostname()); - snprintf_P(mqttGroupTopic, sizeof(mqttGroupTopic), PSTR(MQTT_PREFIX "/%s/"), mqttGroupName.c_str()); + snprintf_P(mqttGroupTopic, sizeof(mqttGroupTopic), PSTR(MQTT_PREFIX "/%s/"), mqttGroupName); return changed; } diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 506e35f1..3a861317 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -138,7 +138,7 @@ const char HTTP_SCRIPT[] PROGMEM = " + + + + +
+
+
+ + + + \ No newline at end of file diff --git a/data/edit.htm.gz b/data/edit.htm.gz new file mode 100644 index 0000000000000000000000000000000000000000..d9519e4a1cb5784e686a3235cef4d163e78e1fe9 GIT binary patch literal 3753 zcmV;a4p#9WiwFojd5d5I0A*xpbS`LgZ2-L*i+0*J^j92jOYLC{q*=B>oD7nzY4Z-y zF6qg3ge^dcEP1vFq>O*xm1G-3NR#Yr+u9=CE9pLTpMveR{jLf;=`zR#zp`IX?ltDDo*WfWGgQ2MZ zSgp>0e`7?alq9081lIHfkLp#$I(&pE9uNkD2n7LQgSy^E$uyTX#uN#1j~gLjS*INjSMq>K-DtUx_A|C2hwQMSN3A^GDQA6t7_=w{G zG2}F3f~eD;YrP!uFXa)8VNS6xw36W-dUr%TMmz!()TNX()E8I-^(a=fEAfUKWxQ0tkzh-SQ76J$l-D*X%Vne2fR3%hu@q(b<5IVf*^DfO7ey?y`c z!`0UQ+scnWo&;xvb?(132Ych69+J-R{XMIE)c+EeDEj%VLs4Ao z2F*%oZ=<;>;>$g@|Ms^1Q>#_uy+1eJ-EF<=Ze8>)n(fV27hSb4n*Gh*aCmgo`88;M ziJNER=H#H;JS-g@oK$P=tG9!bt#K~7~GCb^7 zo6X}h{OjIZbhP1r0{wS?!#|dqe?5ZExqA$+F3!{c&qH0YBFICP&dBCt_QX0u1=PHs`KeR%>h30z{so zLB-oBgor`}{6>J5SM#Ik>R>VFNyqNmR)Jt0*3G_wO9MqX-$XH75FUT!%uLLsv*FA< z2`Z@ynNabXAN^P=K!z$B5tvKZ*5S7~8KILw~jqu4-R!2OZ53s)~Z&{krZnjO<_AeS(P zR+>Dy_gEsRLJvGNRi5(TJ&NnL{mwgr;-$@Tw*DUaSk~(c`>cT zb`sa8C`nG$Jt*5Z75(^m`tgF46r=c+3Q6Rb-_bhz~c3F zYol6S16TsnQL>9Dj$!Y?<>lGsXS0;SOXf}8kkc3^5oZbRfLYpg0rNh9hUZ|Hmhaw6 zd$jFY=q6Y+g@_6009&RsWz#Wr_%Ll}86Og6I<*yWGy(XA{Zc)Ja6~~*89|4*ocWaa zcV4Cp*f}lN);up|+Ety#S>G~U(*~^+*IC?Scx?Q3a(pO6bcz2Q;Y8SQq|&2Q5Qg@L z4X`&-S0dE%UwItvBY_$sWzkB#7uybZIY2D)yxRe_RAdS;B{Y%Cggwhu=`dGXYd59^ z?K*U&IHYe?L7>2u@hfpDW&<(&7rED=FFpQq^~TX06~#Ggua;*9+c?u?Uc$5HV@^s% zKZki0Yq#!NpMQ66O18cGZN;r+%wHpTk*8Sdg6?OsDxaW`xB^_ypyl)`5VBsO# zSw=8Gn6k??JwF_!g~_ABN+ z6->>vPK0BhF3AFNU(6|73j5@Ny0$fKR~3eC+7m-u<_v^l%V5)p(jOilm<(k&j)MF|3`It!+=3>Mv#mK$hm}9t3(%0D^!9h7C2W(_`E_UA(ioNMeK7@)QS+8AE)cnbm8MF zHOH*3Ra0!SV$Fd|b*qJnDubCXKTmm}stu_1E#$~d3&qw8E4qx1j?w!E#|NE*JWS{4 zELi_H_g)PAGH^K%7M>47y7{zJ34?b{vySZ&OiJvT?h1@T^)^_HVrHZ*mQ=6D9Dlia z@>ix>YDwCz;KzK7<2{sM3(C4Il4&dio>i;X*SSW|^x2#VAPt<27ARm><}~1UUpLH_ z?O-qv9-YS=GAq(n=VV)+f0f8npu@ezyGZ<)Q`+It?i28O4$lVZiSs3nzw*#y+!wn~ zA)Yx_t#PQQwBW)Wz{hVT-ysW-s}gUZV&?>A=b+X3Ifqj?*`p;hn#^IKT90T@08S*9 z%zV|;OyVJz_xlMJpJeiO;(UInQg;KUEaamE^O0D%T?=OdZPUO0$|pOtl+34B+oUkr zA*C3M=U?_c1il9aduEVxKcp7Ux|!9z3swyZv_Z?Qh_I6}5&lqySRZWO6cb_A)#x_i ztT3c{EL)WvnhyNzGm5fNlHn#HY}DSnR-L7T+MIRr@39`SLB?5>jRvIuRq~1S#jhn4 zg?~v_(Fdh*>iJXynZ{enH0$dt1H@}8LL|ROj4ip3dn`37C-AC`V4F9BQpr}&j;hK0 z9NfsqKi~x|R*05x0I9oSJ(6EbLXuK!eQ2MZx)F*YKCa4ouuQF6&QB1{E8b!qF(gUx(P+V+Uzn9=*+?I^-0mExrbFM9gB)&8 z3-x?%(`H1Ge05^4wQiPKH!C`3eqf^qOx!hcj|7bTqzj1KM8R*-JG@O02A_C*hvPZ~ zjY2<4v}60rF1-ez%$b+!Mt`wl^cTIR5Rq0LZ9U&iuWo){*)!+KcQLAgeX4jRQWV<|tinLa^{rYUG90Vo5icCfF$8O%?ZIEW?r| zg9y%Rn`6STRfEVP{}iI|OfDL5ku8vT3G(GLc^gxlE}U7^@$JHO#Hs@DU;50FIDRqU zVMWG&9NkhkUQ-51J7YIP%}cL=2sg}bS>Bd$3a@+e1D+hdUJ~ z>aoLGt4V~9IAHxuk9;=pLsa)9Dcw9N~xhbWB*?+!HY^x1sw(K1}o) zn9m#;ChIF7z;x_=&Fv87>1eUdLQ7B264|1>XMGko&QyluI+NxD_qgf-I=@~7#v^i@ zo2LML>SVY=(h!mc;4OK*UI TlmtH1?=b%cg#_Zumni@M+j38U literal 0 HcmV?d00001 diff --git a/platformio.ini b/platformio.ini index c2fffdad..81234770 100644 --- a/platformio.ini +++ b/platformio.ini @@ -96,7 +96,9 @@ board_upload.flash_size=4MB board_upload.maximum_size = 4194304 board_build.partitions = user_setups/esp32/partition_app1704k_spiffs720k.csv board_build.filesystem = littlefs - +board_build.embed_files = + data/edit.htm.gz + ; ----- crash reporter monitor_filters = esp32_exception_decoder diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index 270f600c..2748858c 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -59,6 +59,7 @@ void dispatch_web_update(const char*, const char* espOtaUrl); void dispatch_statusupdate(const char*, const char*); void dispatch_idle(const char*, const char*); void dispatch_calibrate(const char*, const char*); +void dispatch_wakeup(const char*, const char*); void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid); diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 6233f85d..0fcd0da7 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -94,6 +94,8 @@ ESP8266WebServer webServer(80); #include #include WebServer webServer(80); +extern const uint8_t EDIT_HTM_GZ_START[] asm("_binary_data_edit_htm_gz_start"); +extern const uint8_t EDIT_HTM_GZ_END[] asm("_binary_data_edit_htm_gz_end"); #endif // ESP32 HTTPUpload* upload; @@ -901,7 +903,15 @@ bool handleFileRead(String path) file.close(); return true; } + +#ifdef ARDUINO_ARCH_ESP32 + size_t size = EDIT_HTM_GZ_END - EDIT_HTM_GZ_START; + webServer.sendHeader(F("Content-Encoding"), F("gzip")); + webServer.send_P(200, PSTR("text/html"), (const char*)EDIT_HTM_GZ_START, size); + return true; +#else return false; +#endif } void handleFileUpload() @@ -998,11 +1008,18 @@ void handleFileCreate() } } if(webServer.hasArg(F("init"))) { + dispatch_wakeup(NULL, NULL); hasp_init(); } if(webServer.hasArg(F("load"))) { + dispatch_wakeup(NULL, NULL); hasp_load_json(); } + if(webServer.hasArg(F("page"))) { + uint8_t pageid = atoi(webServer.arg(F("page")).c_str()); + dispatch_wakeup(NULL, NULL); + dispatch_set_page(pageid, LV_SCR_LOAD_ANIM_NONE); + } webServer.send(200, PSTR("text/plain"), ""); } From 9f11cf15f68d9103661e3fd0163229ef85fadf2c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 30 Apr 2021 06:25:07 +0200 Subject: [PATCH 050/227] Fix download option in File Editor --- src/sys/svc/hasp_http.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 0fcd0da7..ea8a9729 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -367,7 +367,7 @@ void webHandleRoot() #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 if(HASP_FS.exists(F("/edit.htm.gz")) || HASP_FS.exists(F("/edit.htm"))) { - httpMessage += F("

"); } #endif @@ -893,22 +893,29 @@ bool handleFileRead(String path) String pathWithGz = path + F(".gz"); if(HASP_FS.exists(pathWithGz) || HASP_FS.exists(path)) { if(HASP_FS.exists(pathWithGz)) path += F(".gz"); + File file = HASP_FS.open(path, "r"); - File file = HASP_FS.open(path, "r"); - String contentType = getContentType(path); - if(path == F("/edit.htm.gz")) { - contentType = F("text/html"); - } + String contentType; + if(webServer.hasArg(F("download"))) + contentType = F("application/octet-stream"); + else + contentType = getContentType(path); + + // if(path == F("/edit.htm.gz")) { + // contentType = F("text/html"); + // } webServer.streamFile(file, contentType); file.close(); return true; } #ifdef ARDUINO_ARCH_ESP32 - size_t size = EDIT_HTM_GZ_END - EDIT_HTM_GZ_START; - webServer.sendHeader(F("Content-Encoding"), F("gzip")); - webServer.send_P(200, PSTR("text/html"), (const char*)EDIT_HTM_GZ_START, size); - return true; + if(path == F("/edit.htm")) { + size_t size = EDIT_HTM_GZ_END - EDIT_HTM_GZ_START; + webServer.sendHeader(F("Content-Encoding"), F("gzip")); + webServer.send_P(200, PSTR("text/html"), (const char*)EDIT_HTM_GZ_START, size); + return true; + } #else return false; #endif From f2f540db7a566e1f07e540d0ff3e4f9ac0e06a1b Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 30 Apr 2021 06:46:59 +0200 Subject: [PATCH 051/227] Improved http file access logging --- src/sys/svc/hasp_http.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index ea8a9729..654d56fb 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -215,7 +215,8 @@ void webHandleHaspConfig(); // } //////////////////////////////////////////////////////////////////////////////////////////////////// -bool httpIsAuthenticated(const __FlashStringHelper* fstr_page) + +bool httpIsAuthenticated() { if(http_config.password[0] != '\0') { // Request HTTP auth if httpPassword is set if(!webServer.authenticate(http_config.user, http_config.password)) { @@ -223,13 +224,19 @@ bool httpIsAuthenticated(const __FlashStringHelper* fstr_page) return false; } } + return true; +} + +bool httpIsAuthenticated(const __FlashStringHelper* fstr_page) +{ + if(!httpIsAuthenticated()) return false; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) LOG_TRACE(TAG_HTTP, F("Sending %S page to client connected from: %s"), fstr_page, webServer.client().remoteIP().toString().c_str()); #else - // LOG_INFO(TAG_HTTP,F("Sending %s page to client connected from: %s"), page, - // String(webServer.client().remoteIP()).c_str()); + // LOG_INFO(TAG_HTTP,F("Sending %s page to client connected from: %s"), page, + // String(webServer.client().remoteIP()).c_str()); #endif return true; @@ -884,7 +891,8 @@ void webHandleFirmwareUpload() #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 bool handleFileRead(String path) { - if(!httpIsAuthenticated(F("fileread"))) return false; + // if(!httpIsAuthenticated(F("fileread"))) return false; + if(!httpIsAuthenticated()) return false; path = webServer.urlDecode(path).substring(0, 31); if(path.endsWith("/")) { @@ -916,9 +924,9 @@ bool handleFileRead(String path) webServer.send_P(200, PSTR("text/html"), (const char*)EDIT_HTM_GZ_START, size); return true; } -#else - return false; #endif + + return false; } void handleFileUpload() @@ -1040,7 +1048,7 @@ void handleFileList() } String path = webServer.arg(F("dir")); - LOG_TRACE(TAG_HTTP, F("handleFileList: %s"), path.c_str()); + // LOG_TRACE(TAG_HTTP, F("handleFileList: %s"), path.c_str()); path.clear(); #if defined(ARDUINO_ARCH_ESP32) @@ -1821,11 +1829,15 @@ void webHandleHaspConfig() void httpHandleNotFound() { // webServer 404 #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 - if(handleFileRead(webServer.uri())) return; + if(handleFileRead(webServer.uri())) { + LOG_TRACE(TAG_HTTP, F("Sending %d %s to client connected from: %s"), 200, webServer.uri().c_str(), + webServer.client().remoteIP().toString().c_str()); + return; + } #endif #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - LOG_TRACE(TAG_HTTP, F("Sending 404 to client connected from: %s"), + LOG_TRACE(TAG_HTTP, F("Sending %d %s to client connected from: %s"), 404, webServer.uri().c_str(), webServer.client().remoteIP().toString().c_str()); #else // LOG_TRACE(TAG_HTTP,F("Sending 404 to client connected from: %s"), String(webServer.client().remoteIP()).c_str()); From 5fccc53d776a1e47c8b98e77b9809e2a7c49c124 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 30 Apr 2021 18:15:49 +0200 Subject: [PATCH 052/227] Minor tweaks --- platformio_override-template.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio_override-template.ini b/platformio_override-template.ini index 25c8ff1d..e191d5e1 100644 --- a/platformio_override-template.ini +++ b/platformio_override-template.ini @@ -5,7 +5,7 @@ [platformio] extra_configs = - ; Uncomment or edit the lines to show more User Setups in the PIO sidebar + ; Uncomment or edit the lines to show more User Setups in the PIO sidebar ; user_setups/darwin_sdl/*.ini ; user_setups/esp32/*.ini ; user_setups/esp8266/*.ini @@ -21,7 +21,7 @@ build_flags = ;region -- Default Build Environments : Used when Build All --- extra_default_envs = - ; Comment unneeded environments or create extra + ; Uncomment specific environments or create extra: ; arduitouch-esp32_ili9341 ; d1-mini-esp32_ili9341 ; d1-mini-esp8266_ili9341 From 41ae86273d761ca3df9aca513e2f497c23ed50e1 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 1 May 2021 00:16:05 +0200 Subject: [PATCH 053/227] Main Menu button, enable lineWrap --- data/edit.htm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/data/edit.htm b/data/edit.htm index 9e655932..4d3f47ec 100644 --- a/data/edit.htm +++ b/data/edit.htm @@ -3,7 +3,7 @@ - File Browser + File Editor "; const char HTTP_SCRIPT[] PROGMEM = ""; + + // String path = F(".html"); + // webServer.send(200, getContentType(path), htmldata); + + htmldata += FPSTR(MAIN_MENU_BUTTON); + + webSendPage(haspDevice.get_hostname(), htmldata.length(), false); + webServer.sendContent(htmldata); + + htmldata.clear(); + webSendFooter(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2121,8 +2144,8 @@ void httpSetup() #endif webServer.on(F("/"), webHandleRoot); - webServer.on(F("/info"), webHandleInfo); - webServer.on(F("/infojson"), webHandleInfoJson); + webServer.on(F("/info"), webHandleInfoJson); + // webServer.on(F("/info"), webHandleInfo); webServer.on(F("/screenshot"), webHandleScreenshot); webServer.on(F("/firmware"), webHandleFirmware); webServer.on(F("/reboot"), httpHandleReboot); From b60d76bef4930bee3e525a6f4a81b75f95c247f6 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 1 May 2021 19:36:09 +0200 Subject: [PATCH 072/227] Text localization information webpage --- src/hasp/hasp.cpp | 20 ++++++++++---------- src/mqtt/hasp_mqtt_paho_single.cpp | 22 +++++++++++----------- src/mqtt/hasp_mqtt_pubsubclient.cpp | 18 +++++++++--------- src/sys/net/hasp_ethernet_esp32.cpp | 20 ++++++++++---------- src/sys/net/hasp_wifi.cpp | 23 ++++++++++------------- 5 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 94ea8b7d..dbd78ec9 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -581,13 +581,13 @@ void hasp_get_info(JsonDocument& doc) JsonObject info = doc.createNestedObject(F(D_MANUFACTURER)); haspGetVersion(size_buf, sizeof(size_buf)); - info[F("Version")] = size_buf; + info[F(D_INFO_VERSION)] = size_buf; buffer = __DATE__; buffer += (" "); buffer += __TIME__; buffer += (" UTC"); // Github buildservers are in UTC - info[F("Build DateTime")] = buffer; + info[F(D_INFO_BUILD_DATETIME)] = buffer; unsigned long time = millis() / 1000; uint16_t day = time / 86400; @@ -617,21 +617,21 @@ void hasp_get_info(JsonDocument& doc) itoa(sec, size_buf, DEC); buffer += size_buf; buffer += "s"; - info[F("Uptime")] = buffer; + info[F(D_INFO_UPTIME)] = buffer; info = doc.createNestedObject(F("Device Memory")); Parser::format_bytes(haspDevice.get_free_heap(), size_buf, sizeof(size_buf)); - info[F("Free Heap")] = size_buf; + info[F(D_INFO_FREE_HEAP)] = size_buf; Parser::format_bytes(haspDevice.get_free_max_block(), size_buf, sizeof(size_buf)); - info[F("Free Block")] = size_buf; - info[F("Fragmentation")] = haspDevice.get_heap_fragmentation(); + info[F(D_INFO_FREE_BLOCK)] = size_buf; + info[F(D_INFO_FRAGMENTATION)] = haspDevice.get_heap_fragmentation(); #if ARDUINO_ARCH_ESP32 if(psramFound()) { Parser::format_bytes(ESP.getFreePsram(), size_buf, sizeof(size_buf)); - info[F("Free PSRam")] = size_buf; + info[F(D_INFO_PSRAM_FREE)] = size_buf; Parser::format_bytes(ESP.getPsramSize(), size_buf, sizeof(size_buf)); - info[F("PSRam Size")] = size_buf; + info[F(D_INFO_PSRAM_SIZE)] = size_buf; } #endif @@ -641,8 +641,8 @@ void hasp_get_info(JsonDocument& doc) Parser::format_bytes(mem_mon.total_size, size_buf, sizeof(size_buf)); info[F("Total")] = size_buf; Parser::format_bytes(mem_mon.free_size, size_buf, sizeof(size_buf)); - info[F("Free")] = size_buf; - info[F("Fragmentation")] = mem_mon.frag_pct; + info[F("Free")] = size_buf; + info[F(D_INFO_FRAGMENTATION)] = mem_mon.frag_pct; info = doc.createNestedObject(F("HASP State")); hasp_get_sleep_state(size_buf); diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp index 57f3a1c4..7b28e2bb 100644 --- a/src/mqtt/hasp_mqtt_paho_single.cpp +++ b/src/mqtt/hasp_mqtt_paho_single.cpp @@ -321,7 +321,7 @@ void mqttStart() conn_opts.password = mqttPassword.c_str(); if((rc = MQTTClient_connect(mqtt_client, &conn_opts)) != MQTTCLIENT_SUCCESS) { - printf("Failed to start connect, return code %d\n", rc); + printf("Failed to connect, return code %d\n", rc); rc = EXIT_FAILURE; // goto destroy_exit; } else { @@ -346,7 +346,7 @@ void mqttStop() // disc_opts.onSuccess = onDisconnect; // disc_opts.onFailure = onDisconnectFailure; if((rc = MQTTClient_disconnect(mqtt_client, 1000)) != MQTTCLIENT_SUCCESS) { - printf("Failed to start disconnect, return code %d\n", rc); + printf("Failed to disconnect, return code %d\n", rc); rc = EXIT_FAILURE; // goto destroy_exit; } @@ -397,21 +397,21 @@ void mqtt_get_info(JsonDocument& doc) { char mqttClientId[64]; - JsonObject info = doc.createNestedObject(F("MQTT")); - info[F("Server")] = mqttServer; - info[F("User")] = mqttUser; - info[F("ClientID")] = haspDevice.get_hostname(); + JsonObject info = doc.createNestedObject(F("MQTT")); + info[F(D_INFO_SERVER)] = mqttServer; + info[F(D_INFO_USERNAME)] = mqttUser; + info[F(D_INFO_CLIENTID)] = haspDevice.get_hostname(); if(mqttIsConnected()) { // Check MQTT connection - info[F("Status")] = F("Connected"); + info[F(D_INFO_STATUS)] = F(D_INFO_CONNECTED); } else { - info[F("Status")] = F("Disconnected, return code: "); + info[F(D_INFO_STATUS)] = F("" D_INFO_DISCONNECTED ", return code: "); // +String(mqttClient.returnCode()); } - info[F("Received")] = mqttReceiveCount; - info[F("Published")] = mqttPublishCount; - info[F("Failed")] = mqttFailedCount; + info[F(D_INFO_RECEIVED)] = mqttReceiveCount; + info[F(D_INFO_PUBLISHED)] = mqttPublishCount; + info[F(D_INFO_FAILED)] = mqttFailedCount; } #endif // USE_PAHO diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index b25aaf2b..354fd6ab 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -385,25 +385,25 @@ void mqtt_get_info(JsonDocument& doc) String mac((char*)0); mac.reserve(64); - JsonObject info = doc.createNestedObject(F("MQTT")); - info[F("Server")] = mqttServer; - info[F("User")] = mqttUser; + JsonObject info = doc.createNestedObject(F("MQTT")); + info[F(D_INFO_SERVER)] = mqttServer; + info[F(D_INFO_USERNAME)] = mqttUser; mac = halGetMacAddress(3, ""); mac.toLowerCase(); snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%s"), haspDevice.get_hostname(), mac.c_str()); - info[F("ClientID")] = mqttClientId; + info[F(D_INFO_CLIENTID)] = mqttClientId; if(mqttIsConnected()) { // Check MQTT connection - info[F("Status")] = F("Connected"); + info[F(D_INFO_STATUS)] = F(D_INFO_CONNECTED); } else { - info[F("Status")] = F("Disconnected, return code: "); + info[F(D_INFO_STATUS)] = F("" D_INFO_DISCONNECTED ", return code: "); // +String(mqttClient.returnCode()); } - info[F("Received")] = mqttReceiveCount; - info[F("Published")] = mqttPublishCount; - info[F("Failed")] = mqttFailedCount; + info[F(D_INFO_RECEIVED)] = mqttReceiveCount; + info[F(D_INFO_PUBLISHED)] = mqttPublishCount; + info[F(D_INFO_FAILED)] = mqttFailedCount; } #if HASP_USE_CONFIG > 0 diff --git a/src/sys/net/hasp_ethernet_esp32.cpp b/src/sys/net/hasp_ethernet_esp32.cpp index 87947064..00737dfe 100644 --- a/src/sys/net/hasp_ethernet_esp32.cpp +++ b/src/sys/net/hasp_ethernet_esp32.cpp @@ -25,13 +25,13 @@ void EthernetEvent(WiFiEvent_t event) eth_connected = true; break; case SYSTEM_EVENT_ETH_GOT_IP: - LOG_TRACE(TAG_ETH, F("MAC Address %s"), ETH.macAddress().c_str()); + LOG_TRACE(TAG_ETH, F(D_INFO_MAC_ADDRESS " %s"), ETH.macAddress().c_str()); ip = ETH.localIP(); LOG_TRACE(TAG_ETH, F("IPv4: %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); if(ETH.fullDuplex()) { - LOG_TRACE(TAG_ETH, F("FULL_DUPLEX")); + LOG_TRACE(TAG_ETH, F(D_INFO_FULL_DUPLEX)); } - LOG_TRACE(TAG_ETH, F("LINK_SPEED %d Mbps"), ETH.linkSpeed()); + LOG_TRACE(TAG_ETH, F(D_INFO_LINK_SPEED " %d Mbps"), ETH.linkSpeed()); eth_connected = true; networkStart(); // Start network services break; @@ -76,19 +76,19 @@ void ethernet_get_info(JsonDocument& doc) String buffer((char*)0); buffer.reserve(64); - JsonObject info = doc.createNestedObject(F("Ethernet")); + JsonObject info = doc.createNestedObject(F(D_INFO_ETHERNET)); buffer = ETH.linkSpeed(); buffer += F(" Mbps"); if(ETH.fullDuplex()) { - buffer += F(" FULL_DUPLEX"); + buffer += F(" " D_INFO_FULL_DUPLEX); } - info[F("Link Speed")] = buffer; - info[F("IP Address")] = ETH.localIP().toString(); - info[F("Gateway")] = ETH.gatewayIP().toString(); - info[F("DNS Server")] = ETH.dnsIP().toString(); - info[F("MAC Address")] = ETH.macAddress(); + info[F(D_INFO_LINK_SPEED)] = buffer; + info[F(D_INFO_IP_ADDRESS)] = ETH.localIP().toString(); + info[F(D_INFO_GATEWAY)] = ETH.gatewayIP().toString(); + info[F(D_INFO_DNS_SERVER)] = ETH.dnsIP().toString(); + info[F(D_INFO_MAC_ADDRESS)] = ETH.macAddress(); } #endif \ No newline at end of file diff --git a/src/sys/net/hasp_wifi.cpp b/src/sys/net/hasp_wifi.cpp index af74b724..a58ffde6 100644 --- a/src/sys/net/hasp_wifi.cpp +++ b/src/sys/net/hasp_wifi.cpp @@ -524,7 +524,7 @@ void wifi_get_info(JsonDocument& doc) String buffer((char*)0); buffer.reserve(64); - JsonObject info = doc.createNestedObject(F("Wifi")); + JsonObject info = doc.createNestedObject(F(D_INFO_WIFI)); int8_t rssi = WiFi.RSSI(); buffer += String(rssi); @@ -542,25 +542,22 @@ void wifi_get_info(JsonDocument& doc) buffer += F("Very Bad)"); } - info[F("SSID")] = String(WiFi.SSID()); - info[F("Signal Strength")] = buffer; + info[F(D_INFO_SSID)] = String(WiFi.SSID()); + info[F(D_INFO_RSSI)] = buffer; #if defined(STM32F4xx) byte mac[6]; WiFi.macAddress(mac); char macAddress[16]; snprintf_P(macAddress, sizeof(macAddress), PSTR("%02x%02x%02x"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - httpMessage += F("
IP Address: "); - httpMessage += String(WiFi.localIP()); - httpMessage += F("
Gateway: "); - httpMessage += String(WiFi.gatewayIP()); - httpMessage += F("
MAC Address: "); - httpMessage += String(macAddress); + info[F(D_INFO_IP_ADDRESS)] = String(WiFi.localIP()); + info[F(D_INFO_GATEWAY)] = String(WiFi.gatewayIP()); + info[F(D_INFO_MAC_ADDRESS)] = String(macAddress); #else - info[F("IP Address")] = WiFi.localIP().toString(); - info[F("Gateway")] = WiFi.gatewayIP().toString(); - info[F("DNS Server")] = WiFi.dnsIP().toString(); - info[F("MAC Address")] = WiFi.macAddress(); + info[F(D_INFO_IP_ADDRESS)] = WiFi.localIP().toString(); + info[F(D_INFO_GATEWAY)] = WiFi.gatewayIP().toString(); + info[F(D_INFO_DNS_SERVER)] = WiFi.dnsIP().toString(); + info[F(D_INFO_MAC_ADDRESS)] = WiFi.macAddress(); #endif } From a1fcdd583fa0942af5f8e7e1819c931b04d29e52 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 1 May 2021 20:29:57 +0200 Subject: [PATCH 073/227] Cache the sketchsize because fetching it is slow --- src/dev/esp32/esp32.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp index 722ddb48..c3e5dc0c 100644 --- a/src/dev/esp32/esp32.cpp +++ b/src/dev/esp32/esp32.cpp @@ -111,8 +111,6 @@ Esp32Device::Esp32Device() if(mac[i] < 0x10) _hardware_id += "0"; _hardware_id += String(mac[i], HEX).c_str(); } - - _sketch_size = ESP.getSketchSize(); // slow: takes ~1 second } void Esp32Device::reboot() @@ -125,6 +123,8 @@ void Esp32Device::show_info() LOG_VERBOSE(TAG_DEV, F("Processor : ESP32")); LOG_VERBOSE(TAG_DEV, F("CPU freq. : %i MHz"), get_cpu_frequency()); // LOG_VERBOSE(TAG_DEV, F("Voltage : %2.2f V"), ESP.getVcc() / 918.0); // 918 empirically determined + + if(_sketch_size == 0) _sketch_size = ESP.getSketchSize(); // slow: takes ~1 second } const char* Esp32Device::get_hostname() @@ -274,6 +274,7 @@ void Esp32Device::get_info(JsonDocument& doc) Parser::format_bytes(ESP.getFlashChipSize(), size_buf, sizeof(size_buf)); // 25ms info[F(D_INFO_FLASH_SIZE)] = size_buf; + if(_sketch_size == 0) _sketch_size = ESP.getSketchSize(); // slow: takes ~1 second Parser::format_bytes(_sketch_size, size_buf, sizeof(size_buf)); info[F(D_INFO_SKETCH_USED)] = size_buf; From 0672e66b3f882177dcc2038a4c30b067e4e063b5 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 1 May 2021 20:32:21 +0200 Subject: [PATCH 074/227] Add translations --- src/hasp/hasp.cpp | 8 ++++---- src/lang/en_US.h | 43 ++++++++++++++++++++++++++++++++++++++++++- src/lang/nl_NL.h | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index dbd78ec9..2882f053 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -619,7 +619,7 @@ void hasp_get_info(JsonDocument& doc) buffer += "s"; info[F(D_INFO_UPTIME)] = buffer; - info = doc.createNestedObject(F("Device Memory")); + info = doc.createNestedObject(F(D_INFO_DEVICE_MEMORY)); Parser::format_bytes(haspDevice.get_free_heap(), size_buf, sizeof(size_buf)); info[F(D_INFO_FREE_HEAP)] = size_buf; Parser::format_bytes(haspDevice.get_free_max_block(), size_buf, sizeof(size_buf)); @@ -635,13 +635,13 @@ void hasp_get_info(JsonDocument& doc) } #endif - info = doc.createNestedObject(F("LVGL Memory")); + info = doc.createNestedObject(F(D_INFO_LVGL_MEMORY)); lv_mem_monitor_t mem_mon; lv_mem_monitor(&mem_mon); Parser::format_bytes(mem_mon.total_size, size_buf, sizeof(size_buf)); - info[F("Total")] = size_buf; + info[F(D_INFO_TOTAL_MEMORY)] = size_buf; Parser::format_bytes(mem_mon.free_size, size_buf, sizeof(size_buf)); - info[F("Free")] = size_buf; + info[F(D_INFO_FREE_MEMORY)] = size_buf; info[F(D_INFO_FRAGMENTATION)] = mem_mon.frag_pct; info = doc.createNestedObject(F("HASP State")); diff --git a/src/lang/en_US.h b/src/lang/en_US.h index 56770bb9..2c184585 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -118,13 +118,54 @@ #define D_HTTP_NEXT_PAGE "Next Page" #define D_HTTP_CALIBRATE "Calibrate" #define D_HTTP_SCREENSHOT "Screenshot" -#define D_HTTP_FILE_BROWSER "File Editor" +#define D_HTTP_FILE_BROWSER "File Editor" // Updated #define D_HTTP_FIRMWARE_UPGRADE "Firmware Upgrade" #define D_HTTP_UPDATE_FIRMWARE "Update Firmware" #define D_HTTP_FACTORY_RESET "Factory Reset" #define D_HTTP_MAIN_MENU "Main Menu" #define D_HTTP_REBOOT "Restart" #define D_HTTP_CONFIGURATION "Configuration" +#define D_HTTP_FOOTER "by Francis Van Roie" // New + +// New +#define D_INFO_VERSION "Version" +#define D_INFO_BUILD_DATETIME "Build DateTime" +#define D_INFO_UPTIME "Uptime" +#define D_INFO_FREE_HEAP "Free Heap" +#define D_INFO_FREE_BLOCK "Free Block" +#define D_INFO_DEVICE_MEMORY "Device Memory" +#define D_INFO_LVGL_MEMORY "LVGL Memory" +#define D_INFO_TOTAL_MEMORY "Total" +#define D_INFO_FREE_MEMORY "Free" +#define D_INFO_FRAGMENTATION "Fragmentation" +#define D_INFO_PSRAM_FREE "PSRam Free" +#define D_INFO_PSRAM_SIZE "PSRam Size" +#define D_INFO_FLASH_SIZE "Flash Size" +#define D_INFO_SKETCH_USED "Program Size Used" +#define D_INFO_SKETCH_FREE "Program Size Free" +#define D_INFO_MODULE "Module" +#define D_INFO_MODEL "Model" +#define D_INFO_FREQUENCY "Frequency" +#define D_INFO_CORE_VERSION "Core Version" +#define D_INFO_RESET_REASON "Reset Reason" +#define D_INFO_STATUS "Status" +#define D_INFO_SERVER "Server" +#define D_INFO_USERNAME "Username" +#define D_INFO_CLIENTID "Client ID" +#define D_INFO_CONNECTED "Connected" +#define D_INFO_DISCONNECTED "Disconnected" +#define D_INFO_RECEIVED "Received" +#define D_INFO_PUBLISHED "Published" +#define D_INFO_FAILED "Failed" +#define D_INFO_ETHERNET "Ethernet" +#define D_INFO_WIFI "Wifi" +#define D_INFO_LINK_SPEED "Link Speed" +#define D_INFO_SSID "SSID" +#define D_INFO_RSSI "Signal Strength" +#define D_INFO_IP_ADDRESS "IP Address" +#define D_INFO_MAC_ADDRESS "MAC Address" +#define D_INFO_GATEWAY "Gateway" +#define D_INFO_DNS_SERVER "DNS Server" #define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:" #define D_OOBE_SCAN_TO_CONNECT "Scan to connect" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index 1ba87519..c52db44e 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -124,6 +124,46 @@ #define D_HTTP_MAIN_MENU "Hoofdmenu" #define D_HTTP_REBOOT "Herstarten" #define D_HTTP_CONFIGURATION "Configuratie" +#define D_HTTP_FOOTER "door Francis Van Roie" + +#define D_INFO_VERSION "Versie" +#define D_INFO_BUILD_DATETIME "Gecompileerd" +#define D_INFO_UPTIME "Opgestart" +#define D_INFO_FREE_HEAP "Vrije Heap" +#define D_INFO_FREE_BLOCK "Vrije blok" +#define D_INFO_DEVICE_MEMORY "Algemeen Geheugen" +#define D_INFO_LVGL_MEMORY "LVGL Geheugen" +#define D_INFO_TOTAL_MEMORY "Totaal" +#define D_INFO_FREE_MEMORY "Vrij" +#define D_INFO_FRAGMENTATION "Fragmentatie" +#define D_INFO_PSRAM_FREE "PSRam Vrij" +#define D_INFO_PSRAM_SIZE "PSRam Grootte" +#define D_INFO_FLASH_SIZE "Flash Grootte" +#define D_INFO_SKETCH_USED "Programma Grootte" +#define D_INFO_SKETCH_FREE "Programma Vrij" +#define D_INFO_MODULE "Module" +#define D_INFO_MODEL "Model" +#define D_INFO_FREQUENCY "Frequentie" +#define D_INFO_CORE_VERSION "ESP-IDF Versie" +#define D_INFO_RESET_REASON "Reden Herstart" +#define D_INFO_STATUS "Status" +#define D_INFO_SERVER "Server" +#define D_INFO_USERNAME "Gerbuiker" +#define D_INFO_CLIENTID "Client ID" +#define D_INFO_CONNECTED "Verbonden" +#define D_INFO_DISCONNECTED "Verbroken" +#define D_INFO_RECEIVED "Ontvangen" +#define D_INFO_PUBLISHED "Gepubliceerd" +#define D_INFO_FAILED "Mislukt" +#define D_INFO_ETHERNET "Ethernet" +#define D_INFO_WIFI "Wifi" +#define D_INFO_LINK_SPEED "Snelheid" +#define D_INFO_SSID "SSID" +#define D_INFO_RSSI "Signaalsterkte" +#define D_INFO_IP_ADDRESS "IP Adres" +#define D_INFO_MAC_ADDRESS "Fysiek adres (MAC)" +#define D_INFO_GATEWAY "Gateway" +#define D_INFO_DNS_SERVER "DNS Server" #define D_OOBE_MSG "Raak het scherm aan om WiFi in te stellen of meld je aan op AP:" #define D_OOBE_SCAN_TO_CONNECT "Scan code" From 5795d531638810246726bfffeb4d3d5ade26cd01 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 1 May 2021 20:32:37 +0200 Subject: [PATCH 075/227] Stylesheet for information page --- src/sys/svc/hasp_http.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 4667ab56..b6783a4a 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -128,8 +128,7 @@ const char HTTP_STYLE[] PROGMEM = // ".button4{background-color:#e7e7e7;color:black;}" // ".button5{background-color:#555555;}" // ".button6{background-color:#4CAF50;}" - "td{padding:5px;width:50%;}" - "th{padding-top:1em;}" + "td{font-size:0.87rem;padding-bottom:0px;padding-top:0px;}th{padding-top:0.5em;}" ""; const char HTTP_SCRIPT[] PROGMEM = ""; @@ -265,6 +263,17 @@ void webSendFooter() #endif } +int webSendCached(int statuscode, char* contenttype, char* data, size_t size) +{ + webServer.sendHeader(F("Cache-Control"), F("public, max-age=604800, immutable")); +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) + webServer.send_P(statuscode, contenttype, data, size); +#else + webServer.send(statuscode, contenttype, data); +#endif + return statuscode; +} + void webSendPage(const char* nodename, uint32_t httpdatalength, bool gohome = false) { { @@ -989,15 +998,12 @@ int handleFileRead(String path) if(path == F("/edit.htm")) { size_t size = EDIT_HTM_GZ_END - EDIT_HTM_GZ_START; webServer.sendHeader(F("Content-Encoding"), F("gzip")); - webServer.send_P(200, PSTR("text/html"), (const char*)EDIT_HTM_GZ_START, size); - return 200; // OK + return webSendCached(200, PSTR("text/html"), (const char*)EDIT_HTM_GZ_START, size); // OK } #endif - if(!strcasecmp_P(path.c_str(), PSTR("/favicon.ico"))) { - webServer.send_P(204, PSTR("image/bmp"), "", 0); // No content - return 204; - } + if(!strcasecmp_P(path.c_str(), PSTR("/favicon.ico"))) + return webSendCached(204, PSTR("image/bmp"), "", 0); // No content return 404; // Not found } @@ -1908,17 +1914,15 @@ void httpHandleNotFound() int statuscode = 404; #endif - if(statuscode == 204) return; // No content - #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) LOG_TRACE(TAG_HTTP, F("Sending %d %s to client connected from: %s"), statuscode, webServer.uri().c_str(), webServer.client().remoteIP().toString().c_str()); #else - // LOG_TRACE(TAG_HTTP,F("Sending 404 to client connected from: %s"), - // String(webServer.client().remoteIP()).c_str()); + // LOG_TRACE(TAG_HTTP,F("Sending 404 to client connected from: %s"), + // String(webServer.client().remoteIP()).c_str()); #endif - if(statuscode == 200) return; // OK + if(statuscode < 300) return; // OK String httpMessage((char*)0); httpMessage.reserve(HTTP_PAGE_SIZE); @@ -2112,6 +2116,7 @@ void httpSetup() // Shared pages webServer.on(F("/about"), webHandleAbout); + webServer.on(F("/css"), []() { webSendCached(200, PSTR("text/css"), HTTP_CSS, sizeof(HTTP_CSS) - 1); }); webServer.onNotFound(httpHandleNotFound); #if HASP_USE_WIFI > 0 From c1a8d04da870a476611374cfa962cbccde850a98 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 3 May 2021 02:22:38 +0200 Subject: [PATCH 102/227] Allow longer wifi ssid and password --- src/hasp_oobe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hasp_oobe.cpp b/src/hasp_oobe.cpp index aa8165d2..3ccf4ef3 100644 --- a/src/hasp_oobe.cpp +++ b/src/hasp_oobe.cpp @@ -52,8 +52,8 @@ static void kb_event_cb(lv_obj_t* event_kb, lv_event_t event) { if(event == LV_EVENT_APPLY) { StaticJsonDocument<256> settings; - char ssid[32] = ""; - char pass[32] = ""; + char ssid[64] = ""; + char pass[64] = ""; lv_obj_t* obj; obj = hasp_find_obj_from_parent_id(oobepage[1], (uint8_t)10); From 5417f8d24ab9a170d64544d63675a9920073d276 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 3 May 2021 02:23:54 +0200 Subject: [PATCH 103/227] Switch other pins in the same group --- src/hasp/hasp_dispatch.cpp | 22 +++++++-- src/hasp/hasp_dispatch.h | 3 +- src/sys/gpio/hasp_gpio.cpp | 95 +++++++++++++++++++++++--------------- src/sys/gpio/hasp_gpio.h | 4 +- 4 files changed, 80 insertions(+), 44 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 52fdec91..6f5743a5 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -105,6 +105,16 @@ void dispatch_json_error(uint8_t tag, DeserializationError& jsonError) LOG_ERROR(tag, F(D_JSON_FAILED " %s"), jsonError.c_str()); } +void dispatch_output_pin_value(uint8_t pin, uint16_t val) +{ + char payload[32]; + char topic[12]; + snprintf_P(topic, sizeof(topic), PSTR("output%d"), pin); + snprintf_P(payload, sizeof(payload), PSTR("%d"), val); + + dispatch_state_subtopic(topic, payload); +} + // p[x].b[y].attr=value static inline bool dispatch_parse_button_attribute(const char* topic_p, const char* payload) { @@ -169,9 +179,15 @@ static void dispatch_gpio(const char* topic, const char* payload) val = atoi(payload); if(val == 0) val = Parser::is_true(payload); - gpio_set_value(pin, val); + gpio_set_pin_value(pin, val); } else { - gpio_get_value(pin); + uint16_t val; + + if(gpio_get_value(pin, val)) { + dispatch_output_pin_value(pin, val); + } else { + LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); + } } } else { LOG_WARNING(TAG_MSGR, F("Invalid pin %s"), topic); @@ -185,7 +201,7 @@ void dispatch_command(const char* topic, const char* payload) { /* ================================= Standard payload commands ======================================= */ - if(dispatch_parse_button_attribute(topic, payload)) return; // matched pxby.attr + if(dispatch_parse_button_attribute(topic, payload)) return; // matched pxby.attr, first for speed // check and execute commands from commands array for(int i = 0; i < nCommands; i++) { diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index 2748858c..2f3f150a 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -62,8 +62,7 @@ void dispatch_calibrate(const char*, const char*); void dispatch_wakeup(const char*, const char*); void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid); - -void dispatch_object_value_changed(lv_obj_t* obj, int16_t state); +void dispatch_output_pin_value(uint8_t pin, uint16_t val); void dispatch_normalized_group_value(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max); diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 3ae93dc0..a0c5b6c4 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -328,36 +328,29 @@ void gpioLoop(void) /* ********************************* State Setters *************************************** */ -bool gpio_get_value(hasp_gpio_config_t gpio) -{ - char payload[32]; - char topic[12]; - snprintf_P(topic, sizeof(topic), PSTR("output%d"), gpio.pin); - snprintf_P(payload, sizeof(payload), PSTR("%d"), gpio.val); - - dispatch_state_subtopic(topic, payload); - return true; -} - -bool gpio_get_value(uint8_t pin) +bool gpio_get_value(uint8_t pin, uint16_t& val) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { - if(gpioConfig[i].pin == pin && gpioConfigInUse(i)) return gpio_get_value(gpioConfig[i]); + if(gpioConfig[i].pin == pin && gpioConfigInUse(i)) { + val = gpioConfig[i].val; + return true; + } } - LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); return false; } -bool gpio_set_value(hasp_gpio_config_t& gpio, int16_t val) +static bool gpio_set_output_value(hasp_gpio_config_t* gpio, int32_t newval) { bool inverted = false; + uint16_t val = 0; // negative values will be zeroed + if(newval > 0) val = newval; // positive values are accepted - switch(gpio.type) { + switch(gpio->type) { case HASP_GPIO_RELAY_INVERTED: inverted = true; case HASP_GPIO_RELAY: - gpio.val = val > 0 ? HIGH : LOW; - digitalWrite(gpio.pin, inverted ? !gpio.val : gpio.val); + gpio->val = val > 0 ? HIGH : LOW; + digitalWrite(gpio->pin, inverted ? !gpio->val : gpio->val); break; case HASP_GPIO_LED_INVERTED: @@ -369,34 +362,34 @@ bool gpio_set_value(hasp_gpio_config_t& gpio, int16_t val) case HASP_GPIO_LED_R: case HASP_GPIO_LED_G: case HASP_GPIO_LED_B: - gpio.val = val >= 255 ? 255 : val > 0 ? val : 0; + gpio->val = val >= 255 ? 255 : val > 0 ? val : 0; #if defined(ARDUINO_ARCH_ESP32) - ledcWrite(gpio.group, gpio.val); // ledChannel and value + ledcWrite(gpio->group, (gpio->val << 4) | (gpio->val >> 4)); // ledChannel and value #else - analogWrite(gpio.pin, gpio.val); // 1023 + analogWrite(gpio->pin, (gpio->val) << 2 | (gpio->val >> 6)); // 1023 #endif break; case HASP_GPIO_PWM_INVERTED: inverted = true; case HASP_GPIO_PWM: - gpio.val = val >= 4095 ? 4095 : val > 0 ? val : 0; + gpio->val = val >= 4095 ? 4095 : val > 0 ? val : 0; #if defined(ARDUINO_ARCH_ESP32) - ledcWrite(gpio.group, inverted ? 4095 - gpio.val : gpio.val); // ledChannel and value + ledcWrite(gpio->group, inverted ? 4095 - gpio->val : gpio->val); // ledChannel and value #else - analogWrite(gpio.pin, (inverted ? 4095 - gpio.val : gpio.val) >> 2); // 1023 + analogWrite(gpio->pin, (inverted ? 4095 - gpio->val : gpio->val) >> 2); // 1023 #endif break; case HASP_GPIO_SERIAL_DIMMER: { - gpio.val = val >= 255 ? 255 : val > 0 ? val : 0; + gpio->val = val >= 255 ? 255 : val > 0 ? val : 0; char command[5] = "\xEF\x02\x00\xED"; /* if(gpio.val == 0) { // command[2] = 0x20; Serial2.print("\xEF\x02\x20\xED"); } else */ { - command[2] = (uint8_t)map(gpio.val, 0, 255, 0, 100); + command[2] = (uint8_t)map(gpio->val, 0, 255, 0, 100); command[3] ^= command[2]; } #if defined(ARDUINO_ARCH_ESP32) @@ -410,21 +403,49 @@ bool gpio_set_value(hasp_gpio_config_t& gpio, int16_t val) default: return false; } - gpio_get_value(gpio); - LOG_VERBOSE(TAG_GPIO, F("Group %d - Pin %d = %d"), gpio.group, gpio.pin, gpio.val); return true; } -bool gpio_set_value(uint8_t pin, int16_t val) +static inline void gpio_set_group_value(uint8_t group, int32_t val) +{ + // Set all pins first, minimizes delays + for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { + hasp_gpio_config_t* gpio = &gpioConfig[k]; + if(gpio->group == group && gpioConfigInUse(k)) gpio_set_output_value(gpio, val); + } + + // Dispatch all values + for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { + if(gpioConfig[k].group == group && gpioConfigInUse(k)) + dispatch_output_pin_value(gpioConfig[k].pin, gpioConfig[k].val); + } +} + +bool gpio_set_pin_value(uint8_t pin, int32_t val) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { - if(gpioConfig[i].pin == pin && gpioConfigInUse(i)) return gpio_set_value(gpioConfig[i], val); + hasp_gpio_config_t* gpio = &gpioConfig[i]; + + if(gpio->pin == pin && gpioConfigInUse(i)) { + + if(gpio->group) { + // Set all pins in the group + gpio_set_group_value(gpio->group, val); + } else { + // Set the single pin value + gpio_set_output_value(gpio, val); + dispatch_output_pin_value(gpio->pin, gpio->val); + } + + LOG_VERBOSE(TAG_GPIO, F("Group %d - Pin %d = %d"), gpio->group, gpio->pin, gpio->val); + return true; + } } LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); return false; } -void gpio_set_normalized_value(hasp_gpio_config_t gpio, int16_t val, int16_t min, int16_t max) +void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int16_t val, int16_t min, int16_t max) { if(min == max) { LOG_ERROR(TAG_GPIO, F("Invalid value range")); @@ -432,7 +453,7 @@ void gpio_set_normalized_value(hasp_gpio_config_t gpio, int16_t val, int16_t min } int16_t newval; - switch(gpio.type) { + switch(gpio->type) { case HASP_GPIO_RELAY: case HASP_GPIO_RELAY_INVERTED: newval = val > min ? HIGH : LOW; @@ -458,7 +479,7 @@ void gpio_set_normalized_value(hasp_gpio_config_t gpio, int16_t val, int16_t min return; } - gpio_set_value(gpio, newval); + gpio_set_output_value(gpio, newval); } void gpio_set_normalized_group_value(uint8_t groupid, int16_t val, int16_t min, int16_t max) @@ -471,7 +492,7 @@ void gpio_set_normalized_group_value(uint8_t groupid, int16_t val, int16_t min, // bool state = Parser::get_event_state(eventid); for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { if(gpioConfig[i].group == groupid) { - gpio_set_normalized_value(gpioConfig[i], val, min, max); + gpio_set_normalized_value(&gpioConfig[i], val, min, max); } } } @@ -485,15 +506,15 @@ void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b) switch(gpioConfig[i].type) { case HASP_GPIO_LED_R: case HASP_GPIO_LED_R_INVERTED: - gpio_set_normalized_value(gpioConfig[i], r, 0, 0xFF); + gpio_set_normalized_value(&gpioConfig[i], r, 0, 0xFF); break; case HASP_GPIO_LED_G: case HASP_GPIO_LED_G_INVERTED: - gpio_set_normalized_value(gpioConfig[i], g, 0, 0xFF); + gpio_set_normalized_value(&gpioConfig[i], g, 0, 0xFF); break; case HASP_GPIO_LED_B: case HASP_GPIO_LED_B_INVERTED: - gpio_set_normalized_value(gpioConfig[i], b, 0, 0xFF); + gpio_set_normalized_value(&gpioConfig[i], b, 0, 0xFF); break; } } diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index cfe67b7b..fc823c8b 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -27,8 +27,8 @@ void gpioEvery5Seconds(void); // void gpio_set_group_onoff(uint8_t groupid, bool ison); void gpio_set_normalized_group_value(uint8_t groupid, int16_t val, int16_t min, int16_t max); // void gpio_set_gpio_state(uint8_t pin, uint16_t state); -bool gpio_get_value(uint8_t pin); -bool gpio_set_value(uint8_t pin, int16_t val); +bool gpio_get_value(uint8_t pin, uint16_t& val); +bool gpio_set_pin_value(uint8_t pin, int32_t val); void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b); void gpio_discovery(JsonArray& relay, JsonArray& led); From 50fb1e0cce00ab046317d20d455c794cf526b5e3 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 3 May 2021 03:32:13 +0200 Subject: [PATCH 104/227] Use webServer.uri() in httpIsAuthenticated instead of fixed strings --- src/sys/svc/hasp_http.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 8424e2c5..18ef3e23 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -233,12 +233,13 @@ bool httpIsAuthenticated() return true; } -bool httpIsAuthenticated(const __FlashStringHelper* fstr_page) +bool httpIsAuthenticated(const __FlashStringHelper* notused) { if(!httpIsAuthenticated()) return false; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - LOG_TRACE(TAG_HTTP, F(D_HTTP_SENDING_PAGE), fstr_page, webServer.client().remoteIP().toString().c_str()); + LOG_TRACE(TAG_HTTP, F(D_HTTP_SENDING_PAGE), webServer.uri().c_str(), + webServer.client().remoteIP().toString().c_str()); #else // LOG_INFO(TAG_HTTP,F(D_HTTP_SENDING_PAGE), page, // String(webServer.client().remoteIP()).c_str()); @@ -263,7 +264,7 @@ void webSendFooter() #endif } -int webSendCached(int statuscode, char* contenttype, char* data, size_t size) +static int webSendCached(int statuscode, const char* contenttype, const char* data, size_t size) { webServer.sendHeader(F("Cache-Control"), F("public, max-age=604800, immutable")); #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) From a9a0492372cbe184771cf112b80ce64e8c770d2f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 3 May 2021 04:05:35 +0200 Subject: [PATCH 105/227] Test Serial1 --- src/sys/gpio/hasp_gpio.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index a0c5b6c4..c38d0f88 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -293,12 +293,12 @@ void gpioSetup() case HASP_GPIO_SERIAL_DIMMER: const char command[9] = "\xEF\x01\x4D\xA3"; // Start Lanbon Dimmer #if defined(ARDUINO_ARCH_ESP32) - Serial2.begin(115200UL, SERIAL_8N1, UART_PIN_NO_CHANGE, gpioConfig[i].pin, 2000); - Serial2.flush(); + Serial1.begin(115200UL, SERIAL_8N1, 14, gpioConfig[i].pin); // , false, 2000 + Serial1.flush(); delay(20); - Serial2.print(" "); + Serial1.print(" "); delay(20); - Serial2.write((const uint8_t*)command, 8); + Serial1.write((const uint8_t*)command, 8); #endif gpio_log_serial_dimmer(command); break; @@ -339,17 +339,20 @@ bool gpio_get_value(uint8_t pin, uint16_t& val) return false; } -static bool gpio_set_output_value(hasp_gpio_config_t* gpio, int32_t newval) +static bool gpio_set_output_value(hasp_gpio_config_t* gpio, int32_t val) { - bool inverted = false; - uint16_t val = 0; // negative values will be zeroed - if(newval > 0) val = newval; // positive values are accepted + if(val >= gpio->max) + gpio->val = gpio->max; + else if(val > 0) + gpio->val = val; + else + gpio->val = 0; + bool inverted = false; switch(gpio->type) { case HASP_GPIO_RELAY_INVERTED: inverted = true; case HASP_GPIO_RELAY: - gpio->val = val > 0 ? HIGH : LOW; digitalWrite(gpio->pin, inverted ? !gpio->val : gpio->val); break; @@ -386,14 +389,14 @@ static bool gpio_set_output_value(hasp_gpio_config_t* gpio, int32_t newval) char command[5] = "\xEF\x02\x00\xED"; /* if(gpio.val == 0) { // command[2] = 0x20; - Serial2.print("\xEF\x02\x20\xED"); + Serial1.print("\xEF\x02\x20\xED"); } else */ { command[2] = (uint8_t)map(gpio->val, 0, 255, 0, 100); command[3] ^= command[2]; } #if defined(ARDUINO_ARCH_ESP32) - Serial2.write((const uint8_t*)command, 4); + Serial1.write((const uint8_t*)command, 4); #endif gpio_log_serial_dimmer(command); From a8a34a1528065c190c86ffa0eaa99faf80d94714 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 4 May 2021 02:19:03 +0200 Subject: [PATCH 106/227] Remove inverted types, add inverted parameter and add DAC --- src/sys/gpio/hasp_gpio.h | 46 ++++++++++++++++++++------------------- src/sys/svc/hasp_http.cpp | 39 ++++++++++++++------------------- 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index fc823c8b..2174fb61 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -18,6 +18,7 @@ struct hasp_gpio_config_t uint8_t gpio_function; // INPUT, OUTPUT, PULLUP, etc uint16_t val; uint16_t max; + bool inverted; }; void gpioSetup(void); @@ -25,7 +26,7 @@ void gpioLoop(void); void gpioEvery5Seconds(void); // void gpio_set_group_onoff(uint8_t groupid, bool ison); -void gpio_set_normalized_group_value(uint8_t groupid, int16_t val, int16_t min, int16_t max); +void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, int32_t max); // void gpio_set_gpio_state(uint8_t pin, uint16_t state); bool gpio_get_value(uint8_t pin, uint16_t& val); bool gpio_set_pin_value(uint8_t pin, int32_t val); @@ -48,44 +49,45 @@ bool gpioSetConfig(const JsonObject& settings); #define HASP_GPIO_FREE 0x00 #define HASP_GPIO_USED 0x01 #define HASP_GPIO_SWITCH 0x02 // User Inputs -#define HASP_GPIO_SWITCH_INVERTED 0x03 +// #define HASP_GPIO_SWITCH_INVERTED 0x03 #define HASP_GPIO_BUTTON 0x04 -#define HASP_GPIO_BUTTON_INVERTED 0x05 +// #define HASP_GPIO_BUTTON_INVERTED 0x05 #define HASP_GPIO_TOUCH 0x06 -#define HASP_GPIO_TOUCH_INVERTED 0x07 +// #define HASP_GPIO_TOUCH_INVERTED 0x07 #define HASP_GPIO_COUNTER_RISE 0x10 // User Counters -#define HASP_GPIO_COUNTER_RISE_INVERTED 0x11 +// #define HASP_GPIO_COUNTER_RISE_INVERTED 0x11 #define HASP_GPIO_COUNTER_FALL 0x12 -#define HASP_GPIO_COUNTER_FALL_INVERTED 0x13 +// #define HASP_GPIO_COUNTER_FALL_INVERTED 0x13 #define HASP_GPIO_COUNTER_BOTH 0x14 -#define HASP_GPIO_COUNTER_BOTH_INVERTED 0x15 +// #define HASP_GPIO_COUNTER_BOTH_INVERTED 0x15 #define HASP_GPIO_RELAY 0x20 // User Outputs -#define HASP_GPIO_RELAY_INVERTED 0x21 +// #define HASP_GPIO_RELAY_INVERTED 0x21 +#define HASP_GPIO_ALL_LEDS 0x22 ... 0x2F #define HASP_GPIO_LED 0x22 -#define HASP_GPIO_LED_INVERTED 0x23 +// #define HASP_GPIO_LED_INVERTED 0x23 #define HASP_GPIO_LED_R 0x24 -#define HASP_GPIO_LED_R_INVERTED 0x25 +// #define HASP_GPIO_LED_R_INVERTED 0x25 #define HASP_GPIO_LED_G 0x26 -#define HASP_GPIO_LED_G_INVERTED 0x27 +// #define HASP_GPIO_LED_G_INVERTED 0x27 #define HASP_GPIO_LED_B 0x28 -#define HASP_GPIO_LED_B_INVERTED 0x29 +// #define HASP_GPIO_LED_B_INVERTED 0x29 #define HASP_GPIO_LED_W 0x2A -#define HASP_GPIO_LED_W_INVERTED 0x2B +// #define HASP_GPIO_LED_W_INVERTED 0x2B #define HASP_GPIO_LED_WW 0x2C -#define HASP_GPIO_LED_WW_INVERTED 0x2D +// #define HASP_GPIO_LED_WW_INVERTED 0x2D #define HASP_GPIO_LED_CW 0x2E -#define HASP_GPIO_LED_CW_INVERTED 0x2F -#define HASP_GPIO_BUZZER 0x30 -#define HASP_GPIO_BUZZER_INVERTED 0x31 -#define HASP_GPIO_HAPTIC 0x32 -#define HASP_GPIO_HAPTIC_INVERTED 0x33 +// #define HASP_GPIO_LED_CW_INVERTED 0x2F #define HASP_GPIO_PWM 0x40 -#define HASP_GPIO_PWM_INVERTED 0x41 +// #define HASP_GPIO_PWM_INVERTED 0x41 #define HASP_GPIO_DAC 0x50 -#define HASP_GPIO_DAC_INVERTED 0x51 +// #define HASP_GPIO_DAC_INVERTED 0x51 #define HASP_GPIO_ADC 0x52 -#define HASP_GPIO_ADC_INVERTED 0x53 +// #define HASP_GPIO_ADC_INVERTED 0x53 #define HASP_GPIO_SERIAL_DIMMER 0x60 +#define HASP_GPIO_BUZZER 0x70 +// #define HASP_GPIO_BUZZER_INVERTED 0x71 +#define HASP_GPIO_HAPTIC 0x72 +// #define HASP_GPIO_HAPTIC_INVERTED 0x73 #define HASP_GPIO_USER 0xFF #ifdef __cplusplus diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 18ef3e23..f6da2ad6 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1547,31 +1547,25 @@ void webHandleGpioConfig() httpMessage += haspDevice.gpio_name(gpio).c_str(); httpMessage += F(""); - switch(conf.type & 0xfe) { + switch(conf.type) { case HASP_GPIO_SWITCH: - // case HASP_GPIO_SWITCH_INVERTED: httpMessage += F("Switch"); break; case HASP_GPIO_BUTTON: - // case HASP_GPIO_BUTTON_INVERTED: httpMessage += F("Button"); break; case HASP_GPIO_LED: - // case HASP_GPIO_LED_INVERTED: httpMessage += F("Led"); break; case HASP_GPIO_LED_R: case HASP_GPIO_LED_G: case HASP_GPIO_LED_B: - // case HASP_GPIO_LED_INVERTED: httpMessage += F("Mood "); break; case HASP_GPIO_RELAY: - // case HASP_GPIO_RELAY_INVERTED: httpMessage += F("Relay"); break; case HASP_GPIO_PWM: - // case HASP_GPIO_PWM_INVERTED: httpMessage += F("PWM"); break; case HASP_GPIO_SERIAL_DIMMER: @@ -1581,7 +1575,7 @@ void webHandleGpioConfig() httpMessage += F("Unknown"); } - switch(conf.type & 0xfe) { + switch(conf.type) { case HASP_GPIO_LED_R: httpMessage += F("Red"); break; @@ -1596,7 +1590,7 @@ void webHandleGpioConfig() httpMessage += F(""); httpMessage += conf.group; httpMessage += F(""); - httpMessage += (conf.type & 0x1) ? F("High") : F("Low"); + httpMessage += (conf.inverted) ? F("Inverted") : F("Normal"); httpMessage += F(""); - // httpMessage += getOption(HASP_GPIO_FREE, F("Unused"), false); - selected = (conf.type == HASP_GPIO_SWITCH) || (conf.type == HASP_GPIO_SWITCH_INVERTED); + selected = (conf.type == HASP_GPIO_SWITCH); httpMessage += getOption(HASP_GPIO_SWITCH, F("Switch"), selected); - selected = (conf.type == HASP_GPIO_BUTTON) || (conf.type == HASP_GPIO_BUTTON_INVERTED); + selected = (conf.type == HASP_GPIO_BUTTON); httpMessage += getOption(HASP_GPIO_BUTTON, F("Button"), selected); - selected = (conf.type == HASP_GPIO_LED) || (conf.type == HASP_GPIO_LED_INVERTED); + selected = (conf.type == HASP_GPIO_LED); httpMessage += getOption(HASP_GPIO_LED, F("Led"), selected); - selected = (conf.type == HASP_GPIO_LED_R) || (conf.type == HASP_GPIO_LED_R_INVERTED); + selected = (conf.type == HASP_GPIO_LED_R); httpMessage += getOption(HASP_GPIO_LED_R, F("Mood Red"), selected); - selected = (conf.type == HASP_GPIO_LED_G) || (conf.type == HASP_GPIO_LED_G_INVERTED); + selected = (conf.type == HASP_GPIO_LED_G); httpMessage += getOption(HASP_GPIO_LED_G, F("Mood Green"), selected); - selected = (conf.type == HASP_GPIO_LED_B) || (conf.type == HASP_GPIO_LED_B_INVERTED); + selected = (conf.type == HASP_GPIO_LED_B); httpMessage += getOption(HASP_GPIO_LED_B, F("Mood Blue"), selected); - selected = (conf.type == HASP_GPIO_RELAY) || (conf.type == HASP_GPIO_RELAY_INVERTED); + selected = (conf.type == HASP_GPIO_RELAY); httpMessage += getOption(HASP_GPIO_RELAY, F("Relay"), selected); + selected = (conf.type == HASP_GPIO_RELAY); + httpMessage += getOption(HASP_GPIO_RELAY, F("DAC"), selected); + selected = (conf.type == HASP_GPIO_SERIAL_DIMMER); httpMessage += getOption(HASP_GPIO_SERIAL_DIMMER, F("Serial Dimmer"), selected); if(digitalPinHasPWM(webServer.arg(0).toInt())) { - selected = (conf.type == HASP_GPIO_PWM) || (conf.type == HASP_GPIO_PWM_INVERTED); + selected = (conf.type == HASP_GPIO_PWM); httpMessage += getOption(HASP_GPIO_PWM, F("PWM"), selected); } httpMessage += F("

"); @@ -1713,11 +1709,8 @@ void webHandleGpioOptions() httpMessage += F("

"); httpMessage += F("

Default State

"); httpMessage += From 0761b3f207114342ecc0ca845121dcb40f6217ed Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 4 May 2021 02:20:19 +0200 Subject: [PATCH 107/227] Add dispatch_normalized_group_values to event handlers --- src/hasp/hasp_dispatch.cpp | 21 ++++++++++--------- src/hasp/hasp_dispatch.h | 2 +- src/hasp/hasp_event.cpp | 42 +++++++++++++++++++++++++++----------- src/hasp/hasp_event.h | 2 ++ 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 6f5743a5..9e6e5e44 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -463,15 +463,15 @@ static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const // // dispatch_output_group_state(groupid, payload); // } -void dispatch_normalized_group_value(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max) +void dispatch_normalized_group_values(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max) { if(groupid == 0) return; LOG_VERBOSE(TAG_MSGR, F("GROUP %d value %d (%d-%d)"), groupid, val, min, max); #if HASP_USE_GPIO > 0 - gpio_set_normalized_group_value(groupid, val, min, max); // Update GPIO states + gpio_set_normalized_group_values(groupid, val, min, max); // Update GPIO states #endif - object_set_normalized_group_value(groupid, obj, val, min, max); // Update onsreen objects + object_set_normalized_group_values(groupid, obj, val, min, max); // Update onsreen objects } /********************************************** Native Commands ****************************************/ @@ -801,13 +801,6 @@ void dispatch_reboot(bool saveConfig) haspDevice.reboot(); } -void dispatch_current_state() -{ - dispatch_statusupdate(NULL, NULL); - dispatch_idle(NULL, NULL); - dispatch_current_page(); -} - /******************************************* Command Wrapper Functions *********************************/ // Periodically publish a JSON string indicating system status @@ -907,6 +900,14 @@ void dispatch_statusupdate(const char*, const char*) #endif } +void dispatch_current_state() +{ + dispatch_statusupdate(NULL, NULL); + dispatch_idle(NULL, NULL); + dispatch_current_page(); + dispatch_send_discovery(NULL, NULL); +} + void dispatch_calibrate(const char*, const char*) { guiCalibrate(); diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index 2f3f150a..be958c1e 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -64,7 +64,7 @@ void dispatch_wakeup(const char*, const char*); void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid); void dispatch_output_pin_value(uint8_t pin, uint16_t val); -void dispatch_normalized_group_value(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max); +void dispatch_normalized_group_values(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max); void dispatch_state_subtopic(const char* subtopic, const char* payload); diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index e6fdd6c7..0b4604fd 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -103,7 +103,7 @@ static bool translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid) // ##################### Value Senders ######################################################## -void event_send_object_data(lv_obj_t* obj, const char* data) +static void event_send_object_data(lv_obj_t* obj, const char* data) { uint8_t pageid; uint8_t objid; @@ -117,7 +117,7 @@ void event_send_object_data(lv_obj_t* obj, const char* data) } // Send out events with a val attribute -void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) +static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) { char data[40]; char eventname[8]; @@ -128,7 +128,7 @@ void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) } // Send out events with a val and text attribute -void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text) +static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text) { char data[200]; char eventname[8]; @@ -157,7 +157,7 @@ void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) } #endif -void log_event(const char* name, lv_event_t event) +static void log_event(const char* name, lv_event_t event) { return; @@ -346,8 +346,12 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname); event_send_object_data(obj, data); } - dispatch_normalized_group_value(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent), - HASP_EVENT_OFF, HASP_EVENT_ON); + + // Update group objects and gpios on release + if(last_value_sent == HASP_EVENT_UP || last_value_sent == HASP_EVENT_RELEASE) { + dispatch_normalized_group_values(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent), + HASP_EVENT_OFF, HASP_EVENT_ON); + } } /** @@ -386,7 +390,11 @@ void toggle_event_handler(lv_obj_t* obj, lv_event_t event) } event_object_val_event(obj, hasp_event_id, last_value_sent); - dispatch_normalized_group_value(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON); + + // Update group objects and gpios on release + if(last_value_sent == HASP_EVENT_UP) { + dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON); + } } /** @@ -450,7 +458,11 @@ void selector_event_handler(lv_obj_t* obj, lv_event_t event) if(hasp_event_id == HASP_EVENT_CHANGED && last_value_sent == val) return; // same value as before last_value_sent = val; event_object_selection_changed(obj, hasp_event_id, val, buffer); - // if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max); + + if(max > 0) // max a cannot be 0, its the divider + if(hasp_event_id == HASP_EVENT_UP || hasp_event_id == LV_EVENT_VALUE_CHANGED) { + dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, 0, max); + } // set the property // snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val); @@ -485,7 +497,11 @@ void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = val; event_object_selection_changed(obj, hasp_event_id, val, buffer); - // if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max); + + // if(max > 0) // max a cannot be 0, its the divider + // if(hasp_event_id == HASP_EVENT_UP || hasp_event_id == LV_EVENT_VALUE_CHANGED) { + // dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, 0, max); + // } } /** @@ -517,7 +533,7 @@ void msgbox_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = val; event_object_selection_changed(obj, hasp_event_id, val, buffer); - // if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max); + // if(max > 0) dispatch_normalized_group_values(obj->user_data.groupid, obj, val, 0, max); } /** @@ -555,7 +571,9 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = val; event_object_val_event(obj, hasp_event_id, val); - dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max); + + if(hasp_event_id == HASP_EVENT_CHANGED && min != max) + dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); } /** @@ -587,5 +605,5 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); event_send_object_data(obj, data); - // dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max); + // dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); } diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h index a679acef..1def8c41 100644 --- a/src/hasp/hasp_event.h +++ b/src/hasp/hasp_event.h @@ -11,6 +11,7 @@ #define HASP_NUM_PAGE_BACK (HASP_NUM_PAGES + 2) #define HASP_NUM_PAGE_NEXT (HASP_NUM_PAGES + 3) +// Object event Handlers void wakeup_event_handler(lv_obj_t* obj, lv_event_t event); void generic_event_handler(lv_obj_t* obj, lv_event_t event); void toggle_event_handler(lv_obj_t* obj, lv_event_t event); @@ -21,6 +22,7 @@ void msgbox_event_handler(lv_obj_t* obj, lv_event_t event); void cpicker_event_handler(lv_obj_t* obj, lv_event_t event); #if HASP_USE_GPIO > 0 +// GPIO event Handler void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid); #endif From 73f0b8e13145ebf62dfbb90ad9f0869bd499ef51 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 4 May 2021 02:21:01 +0200 Subject: [PATCH 108/227] Rename object_set_group_values and object_set_normalized_group_values --- src/hasp/hasp_object.cpp | 12 ++++++------ src/hasp/hasp_object.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 664dea4f..252662a0 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -222,7 +222,7 @@ void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload) // ##################### State Changers ######################################################## -void object_set_group_value(lv_obj_t* parent, uint8_t groupid, int16_t intval) +void object_set_group_values(lv_obj_t* parent, uint8_t groupid, int16_t intval) { if(groupid == 0 || parent == nullptr) return; @@ -233,7 +233,7 @@ void object_set_group_value(lv_obj_t* parent, uint8_t groupid, int16_t intval) if(groupid == child->user_data.groupid) hasp_process_obj_attribute_val(child, NULL, intval, intval, true); /* update grandchildren */ - object_set_group_value(child, groupid, intval); + object_set_group_values(child, groupid, intval); /* check tabs */ if(check_obj_type(child, LV_HASP_TABVIEW)) { @@ -246,7 +246,7 @@ void object_set_group_value(lv_obj_t* parent, uint8_t groupid, int16_t intval) hasp_process_obj_attribute_val(tab, NULL, intval, intval, true); /* tab found, update it */ /* check grandchildren */ - object_set_group_value(tab, groupid, intval); + object_set_group_values(tab, groupid, intval); } //#endif } @@ -256,14 +256,14 @@ void object_set_group_value(lv_obj_t* parent, uint8_t groupid, int16_t intval) } } -// TODO make this a recursive function that goes over all objects only ONCE -void object_set_normalized_group_value(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max) +// Recursive function that goes over all objects only ONCE +void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max) { if(groupid == 0) return; if(min == max) return; for(uint8_t page = 0; page < HASP_NUM_PAGES; page++) { - object_set_group_value(haspPages.get_obj(page), groupid, val); + object_set_group_values(haspPages.get_obj(page), groupid, val); // uint8_t startid = 1; // for(uint8_t objid = startid; objid < 20; objid++) { // lv_obj_t* obj = hasp_find_obj_from_parent_id(get_page_obj(page), objid); diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index 16e4adfb..2b2eecc1 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -75,7 +75,7 @@ void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload); void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload); -void object_set_normalized_group_value(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max); +void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max); #define HASP_OBJ_BAR 1971 #define HASP_OBJ_BTN 3164 From cca762f1b2801f20fd54c64461553ee29652e357 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 4 May 2021 02:21:41 +0200 Subject: [PATCH 109/227] Rework hasp_gpio --- src/sys/gpio/hasp_gpio.cpp | 493 +++++++++++++++++++++---------------- 1 file changed, 277 insertions(+), 216 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index c38d0f88..9616770d 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -23,6 +23,9 @@ static AceButton* button[HASP_NUM_INPUTS]; #define analogWrite(x, y) #endif +#define SCALE_8BIT_TO_12BIT(x) x << 4 | x >> 4 +#define SCALE_8BIT_TO_10BIT(x) x << 2 | x >> 6 + uint8_t gpioUsedInputCount = 0; // An array of button pins, led pins, and the led states. Cannot be const @@ -33,6 +36,7 @@ hasp_gpio_config_t gpioConfig[HASP_NUM_GPIO_CONFIG] = { #if defined(ARDUINO_ARCH_ESP32) #include "driver/uart.h" +#include class TouchConfig : public ButtonConfig { public: @@ -72,7 +76,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but bool state = false; switch(eventType) { case AceButton::kEventPressed: - if(gpioConfig[btnid].type == HASP_GPIO_SWITCH || gpioConfig[btnid].type == HASP_GPIO_SWITCH_INVERTED) { + if(gpioConfig[btnid].type == HASP_GPIO_SWITCH) { eventid = HASP_EVENT_ON; } else { eventid = HASP_EVENT_DOWN; @@ -94,7 +98,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but // state = true; // do not repeat DOWN + LONG + HOLD // break; case AceButton::kEventReleased: - if(gpioConfig[btnid].type == HASP_GPIO_SWITCH || gpioConfig[btnid].type == HASP_GPIO_SWITCH_INVERTED) { + if(gpioConfig[btnid].type == HASP_GPIO_SWITCH) { eventid = HASP_EVENT_OFF; } else { eventid = HASP_EVENT_RELEASE; @@ -195,6 +199,96 @@ void gpioAddSwitch(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8 index, HASP_NUM_INPUTS); } +void gpio_setup_pin(hasp_gpio_config_t* gpio) +{ + uint8_t input_mode; + switch(gpio->gpio_function) { + case OUTPUT: + input_mode = OUTPUT; + break; + case INPUT: + input_mode = INPUT; + break; +#ifndef ARDUINO_ARCH_ESP8266 + case INPUT_PULLDOWN: + input_mode = INPUT_PULLDOWN; + break; +#endif + default: + input_mode = INPUT_PULLUP; + } + + if(gpioIsSystemPin(gpio->pin)) { + LOG_WARNING(TAG_GPIO, F("Invalid pin %d"), gpio->pin); + return; + } + + gpio->max = 255; + + switch(gpio->type) { + case HASP_GPIO_SWITCH: + gpioAddSwitch(gpio->pin, input_mode, HIGH, gpioUsedInputCount); + pinMode(gpio->pin, INPUT_PULLUP); + gpio->max = 0; + break; + + case HASP_GPIO_BUTTON: + gpioAddButton(gpio->pin, input_mode, HIGH, gpioUsedInputCount); + pinMode(gpio->pin, INPUT_PULLUP); + gpio->max = 0; + break; + + case HASP_GPIO_RELAY: + pinMode(gpio->pin, OUTPUT); + gpio->max = 1; // on-off + break; + + case HASP_GPIO_PWM: + gpio->max = 4095; + case HASP_GPIO_ALL_LEDS: + // case HASP_GPIO_BACKLIGHT: + pinMode(gpio->pin, OUTPUT); +#if defined(ARDUINO_ARCH_ESP32) + // configure LED PWM functionalitites + ledcSetup(gpio->group, 20000, 12); + // attach the channel to the GPIO to be controlled + ledcAttachPin(gpio->pin, gpio->group); +#endif + break; + + case HASP_GPIO_DAC: +#if defined(ARDUINO_ARCH_ESP32) + gpio_num_t pin; + if(dac_pad_get_io_num(DAC_CHANNEL_1, &pin) == ESP_OK) + if(gpio->pin == pin) dac_output_enable(DAC_CHANNEL_1); + if(dac_pad_get_io_num(DAC_CHANNEL_2, &pin) == ESP_OK) + if(gpio->pin == pin) dac_output_enable(DAC_CHANNEL_2); +#endif + break; + + case HASP_GPIO_SERIAL_DIMMER: { + const char command[9] = "\xEF\x01\x4D\xA3"; // Start Lanbon Dimmer +#if defined(ARDUINO_ARCH_ESP32) + Serial1.begin(115200UL, SERIAL_8N1, UART_PIN_NO_CHANGE, gpio->pin, true, 2000); + Serial1.flush(); + delay(20); + Serial1.print(" "); + delay(20); + Serial1.write((const uint8_t*)command, 8); +#endif + gpio_log_serial_dimmer(command); + break; + } + + case HASP_GPIO_FREE: + return; + + default: + LOG_WARNING(TAG_GPIO, F("Invalid config -> pin %d - type: %d"), gpio->pin, gpio->type); + } + LOG_VERBOSE(TAG_GPIO, F(D_BULLET "Configured pin %d"), gpio->pin); +} + void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index) { uint8_t i; @@ -228,82 +322,15 @@ void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, void gpioSetup() { + LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTING)); + aceButtonSetup(); for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { - uint8_t input_mode; - switch(gpioConfig[i].gpio_function) { - case OUTPUT: - input_mode = OUTPUT; - break; - case INPUT: - input_mode = INPUT; - break; -#ifndef ARDUINO_ARCH_ESP8266 - case INPUT_PULLDOWN: - input_mode = INPUT_PULLDOWN; - break; -#endif - default: - input_mode = INPUT_PULLUP; - } - - if(gpioIsSystemPin(gpioConfig[i].pin)) { - LOG_WARNING(TAG_GPIO, F("Invalid pin %d"), gpioConfig[i].pin); - // continue; - } - - switch(gpioConfig[i].type) { - case HASP_GPIO_SWITCH: - gpioAddSwitch(gpioConfig[i].pin, input_mode, HIGH, i); - pinMode(gpioConfig[i].pin, INPUT_PULLUP); - break; - case HASP_GPIO_BUTTON: - gpioAddButton(gpioConfig[i].pin, input_mode, HIGH, i); - pinMode(gpioConfig[i].pin, INPUT_PULLUP); - break; - case HASP_GPIO_SWITCH_INVERTED: - gpioAddSwitch(gpioConfig[i].pin, input_mode, LOW, i); - pinMode(gpioConfig[i].pin, INPUT_PULLDOWN); - break; - case HASP_GPIO_BUTTON_INVERTED: - gpioAddButton(gpioConfig[i].pin, input_mode, LOW, i); - pinMode(gpioConfig[i].pin, INPUT_PULLDOWN); - break; - - case HASP_GPIO_RELAY: - case HASP_GPIO_RELAY_INVERTED: - pinMode(gpioConfig[i].pin, OUTPUT); - break; - - case HASP_GPIO_LED ... HASP_GPIO_LED_CW_INVERTED: - // case HASP_GPIO_LED_INVERTED: - case HASP_GPIO_PWM: - case HASP_GPIO_PWM_INVERTED: - // case HASP_GPIO_BACKLIGHT: - pinMode(gpioConfig[i].pin, OUTPUT); -#if defined(ARDUINO_ARCH_ESP32) - // configure LED PWM functionalitites - ledcSetup(gpioConfig[i].group, 20000, 12); - // attach the channel to the GPIO to be controlled - ledcAttachPin(gpioConfig[i].pin, gpioConfig[i].group); -#endif - break; - - case HASP_GPIO_SERIAL_DIMMER: - const char command[9] = "\xEF\x01\x4D\xA3"; // Start Lanbon Dimmer -#if defined(ARDUINO_ARCH_ESP32) - Serial1.begin(115200UL, SERIAL_8N1, 14, gpioConfig[i].pin); // , false, 2000 - Serial1.flush(); - delay(20); - Serial1.print(" "); - delay(20); - Serial1.write((const uint8_t*)command, 8); -#endif - gpio_log_serial_dimmer(command); - break; - } + gpio_setup_pin(&gpioConfig[i]); } + + LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTED)); } void gpioLoop(void) @@ -339,153 +366,145 @@ bool gpio_get_value(uint8_t pin, uint16_t& val) return false; } -static bool gpio_set_output_value(hasp_gpio_config_t* gpio, int32_t val) +static inline int32_t gpio_limit(int32_t val, int32_t min, int32_t max) { - if(val >= gpio->max) - gpio->val = gpio->max; - else if(val > 0) - gpio->val = val; + if(val >= max) return max; + if(val <= min) return min; + return val; +} + +// val is assumed to be 12 bits +static inline bool gpio_set_analog_value(hasp_gpio_config_t* gpio) +{ + uint16_t val = 0; +#if defined(ARDUINO_ARCH_ESP32) + + if(gpio->max == 255) + val = SCALE_8BIT_TO_12BIT(gpio->val); + else if(gpio->max == 4095) + val = gpio->val; + + if(gpio->inverted) val = 4095 - val; + + ledcWrite(gpio->group, val); // 12 bits + return true; // sent + +#elif defined(ARDUINO_ARCH_ESP8266) + + if(gpio->max == 255) + val = SCALE_8BIT_TO_10BIT(gpio->val); + else if(gpio->max == 4095) + val = gpio->val >> 2; + + if(gpio->inverted) val = 1023 - val; + + analogWrite(gpio->pin, val); // 10 bits + return true; // sent + +#else + return false; // not implemented +#endif +} + +static inline bool gpio_set_serial_dimmer(hasp_gpio_config_t* gpio) +{ + char command[5] = "\xEF\x02\x00\xED"; + command[2] = (uint8_t)map(gpio->val, 0, 255, 0, 100); + command[3] ^= command[2]; + +#if defined(ARDUINO_ARCH_ESP32) + Serial1.write((const uint8_t*)command, 4); + gpio_log_serial_dimmer(command); + return true; // sent +#else + gpio_log_serial_dimmer(command); + return false; // not sent +#endif +} + +static inline bool gpio_set_dac_value(hasp_gpio_config_t* gpio) +{ +#ifdef ARDUINO_ARCH_ESP32 + gpio_num_t pin; + if(dac_pad_get_io_num(DAC_CHANNEL_1, &pin) == ESP_OK && gpio->pin == pin) + dac_output_voltage(DAC_CHANNEL_1, gpio->val); + else if(dac_pad_get_io_num(DAC_CHANNEL_2, &pin) == ESP_OK && gpio->pin == pin) + dac_output_voltage(DAC_CHANNEL_2, gpio->val); else - gpio->val = 0; - - bool inverted = false; - switch(gpio->type) { - case HASP_GPIO_RELAY_INVERTED: - inverted = true; - case HASP_GPIO_RELAY: - digitalWrite(gpio->pin, inverted ? !gpio->val : gpio->val); - break; - - case HASP_GPIO_LED_INVERTED: - case HASP_GPIO_LED_R_INVERTED: - case HASP_GPIO_LED_G_INVERTED: - case HASP_GPIO_LED_B_INVERTED: - inverted = true; - case HASP_GPIO_LED: - case HASP_GPIO_LED_R: - case HASP_GPIO_LED_G: - case HASP_GPIO_LED_B: - gpio->val = val >= 255 ? 255 : val > 0 ? val : 0; -#if defined(ARDUINO_ARCH_ESP32) - ledcWrite(gpio->group, (gpio->val << 4) | (gpio->val >> 4)); // ledChannel and value + return false; // not found + return true; // found #else - analogWrite(gpio->pin, (gpio->val) << 2 | (gpio->val >> 6)); // 1023 + return false; // not implemented #endif - break; - - case HASP_GPIO_PWM_INVERTED: - inverted = true; - case HASP_GPIO_PWM: - gpio->val = val >= 4095 ? 4095 : val > 0 ? val : 0; -#if defined(ARDUINO_ARCH_ESP32) - ledcWrite(gpio->group, inverted ? 4095 - gpio->val : gpio->val); // ledChannel and value -#else - analogWrite(gpio->pin, (inverted ? 4095 - gpio->val : gpio->val) >> 2); // 1023 -#endif - break; - - case HASP_GPIO_SERIAL_DIMMER: { - gpio->val = val >= 255 ? 255 : val > 0 ? val : 0; - char command[5] = "\xEF\x02\x00\xED"; - /* if(gpio.val == 0) { - // command[2] = 0x20; - Serial1.print("\xEF\x02\x20\xED"); - } else */ - { - command[2] = (uint8_t)map(gpio->val, 0, 255, 0, 100); - command[3] ^= command[2]; - } -#if defined(ARDUINO_ARCH_ESP32) - Serial1.write((const uint8_t*)command, 4); -#endif - gpio_log_serial_dimmer(command); - - break; - } - - default: - return false; - } - return true; } -static inline void gpio_set_group_value(uint8_t group, int32_t val) -{ - // Set all pins first, minimizes delays - for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { - hasp_gpio_config_t* gpio = &gpioConfig[k]; - if(gpio->group == group && gpioConfigInUse(k)) gpio_set_output_value(gpio, val); - } - - // Dispatch all values - for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { - if(gpioConfig[k].group == group && gpioConfigInUse(k)) - dispatch_output_pin_value(gpioConfig[k].pin, gpioConfig[k].val); - } -} - -bool gpio_set_pin_value(uint8_t pin, int32_t val) +bool gpio_get_pin_config(uint8_t pin, hasp_gpio_config_t** gpio) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { - hasp_gpio_config_t* gpio = &gpioConfig[i]; - - if(gpio->pin == pin && gpioConfigInUse(i)) { - - if(gpio->group) { - // Set all pins in the group - gpio_set_group_value(gpio->group, val); - } else { - // Set the single pin value - gpio_set_output_value(gpio, val); - dispatch_output_pin_value(gpio->pin, gpio->val); - } - - LOG_VERBOSE(TAG_GPIO, F("Group %d - Pin %d = %d"), gpio->group, gpio->pin, gpio->val); + if(gpioConfig[i].pin == pin) { + *gpio = &gpioConfig[i]; return true; } } - LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); return false; } -void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int16_t val, int16_t min, int16_t max) +// Update the actual value of one pin +// The value must be normalized first +static bool gpio_set_output_value(hasp_gpio_config_t* gpio, uint16_t val) { - if(min == max) { - LOG_ERROR(TAG_GPIO, F("Invalid value range")); - return; - } + gpio->val = gpio_limit(val, 0, gpio->max); - int16_t newval; switch(gpio->type) { case HASP_GPIO_RELAY: - case HASP_GPIO_RELAY_INVERTED: - newval = val > min ? HIGH : LOW; - break; - - case HASP_GPIO_LED: - case HASP_GPIO_LED_R: - case HASP_GPIO_LED_G: - case HASP_GPIO_LED_B: - case HASP_GPIO_LED_INVERTED: - case HASP_GPIO_LED_R_INVERTED: - case HASP_GPIO_LED_G_INVERTED: - case HASP_GPIO_LED_B_INVERTED: - newval = map(val, min, max, 0, 255); - break; + digitalWrite(gpio->pin, gpio->inverted ? !gpio->val : gpio->val); + return true; + case HASP_GPIO_ALL_LEDS: case HASP_GPIO_PWM: - case HASP_GPIO_PWM_INVERTED: - newval = map(val, min, max, 0, 4095); - break; + return gpio_set_analog_value(gpio); + + case HASP_GPIO_DAC: + return gpio_set_dac_value(gpio); + + case HASP_GPIO_SERIAL_DIMMER: + return gpio_set_serial_dimmer(gpio); default: - return; + LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not a valid output"), gpio->pin); + return false; // not a valid output } - - gpio_set_output_value(gpio, newval); } -void gpio_set_normalized_group_value(uint8_t groupid, int16_t val, int16_t min, int16_t max) +// Update the normalized value of one pin +void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int32_t val, int32_t min, int32_t max) +{ + if(min != 0 || max != gpio->max) { + if(min == max) { + LOG_ERROR(TAG_GPIO, F("Invalid value range")); + return; + } + + switch(gpio->type) { + case HASP_GPIO_RELAY: + val = val > min ? HIGH : LOW; + break; + + case HASP_GPIO_ALL_LEDS: + case HASP_GPIO_DAC: + case HASP_GPIO_PWM: + case HASP_GPIO_SERIAL_DIMMER: + val = map(val, min, max, 0, gpio->max); + break; + + default: + return; + } + } + gpio_set_output_value(gpio, val); // normalized +} + +/* void gpio_set_normalized_group_values(uint8_t groupid, int16_t val, int16_t min, int16_t max) { if(min == max) { LOG_ERROR(TAG_GPIO, F("Invalid value range")); @@ -498,26 +517,77 @@ void gpio_set_normalized_group_value(uint8_t groupid, int16_t val, int16_t min, gpio_set_normalized_value(&gpioConfig[i], val, min, max); } } +} */ + +// Dispatch all group member values +void gpio_output_group_values(uint8_t group) +{ + for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { + hasp_gpio_config_t* gpio = &gpioConfig[k]; + if(gpio->group == group && gpio->type != HASP_GPIO_BUTTON && + gpio->type != HASP_GPIO_SWITCH && // group members that are outputs + gpioConfigInUse(k)) + dispatch_output_pin_value(gpioConfig[k].pin, gpioConfig[k].val); + } } +// Update the normalized value of all group members +void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, int32_t max) +{ + // Set all pins first, minimizes delays + for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { + hasp_gpio_config_t* gpio = &gpioConfig[k]; + if(gpio->group == group && // group members that are outputs + gpioConfigInUse(k)) + gpio_set_normalized_value(gpio, val, min, max); + } + + gpio_output_group_values(group); + object_set_normalized_group_values(group, NULL, val, min, max); // Update onsreen objects +} + +// Update the value of an output pin and its group members +bool gpio_set_pin_value(uint8_t pin, int32_t val) +{ + hasp_gpio_config_t* gpio = NULL; + + if(!gpio_get_pin_config(pin, &gpio) || !gpio || gpio->type == HASP_GPIO_FREE) { + LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); + return false; + + } else if(gpio->type == HASP_GPIO_BUTTON || gpio->type == HASP_GPIO_SWITCH) { + LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is an input"), pin); + if(gpio->group) gpio_output_group_values(gpio->group); + return false; + } + + if(gpio->group) { + gpio_set_normalized_group_values(gpio->group, val, 0, gpio->max); // Set all pins in the group + LOG_VERBOSE(TAG_GPIO, F("Group %d - Pin %d = %d"), gpio->group, gpio->pin, gpio->val); + + } else { + gpio_set_output_value(gpio, val); // update this gpio value only + dispatch_output_pin_value(gpio->pin, gpio->val); + LOG_VERBOSE(TAG_GPIO, F("No Group - Pin %d = %d"), gpio->pin, gpio->val); + } + + return true; // pin found and set +} + +// Updates the RGB pins directly, rgb are already normalized values void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b) { - // uint16_t max_level = power == 0 ? 0 : map(brightness, 0, 0xFF, 0, 0xFFFFU); - uint16_t max_level = 0xFFFFU; - + // RGBXX https://stackoverflow.com/questions/39949331/how-to-calculate-rgbaw-amber-white-from-rgb-for-leds for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { case HASP_GPIO_LED_R: - case HASP_GPIO_LED_R_INVERTED: - gpio_set_normalized_value(&gpioConfig[i], r, 0, 0xFF); + gpio_set_output_value(&gpioConfig[i], r); break; case HASP_GPIO_LED_G: - case HASP_GPIO_LED_G_INVERTED: - gpio_set_normalized_value(&gpioConfig[i], g, 0, 0xFF); + gpio_set_output_value(&gpioConfig[i], g); break; case HASP_GPIO_LED_B: - case HASP_GPIO_LED_B_INVERTED: - gpio_set_normalized_value(&gpioConfig[i], b, 0, 0xFF); + gpio_set_output_value(&gpioConfig[i], b); break; } } @@ -692,24 +762,15 @@ void gpio_discovery(JsonArray& relay, JsonArray& led) for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { case HASP_GPIO_RELAY: - case HASP_GPIO_RELAY_INVERTED: relay.add(gpioConfig[i].pin); break; - case HASP_GPIO_LED: - // case HASP_GPIO_LED_R: - // case HASP_GPIO_LED_G: - // case HASP_GPIO_LED_B: - case HASP_GPIO_LED_INVERTED: - // case HASP_GPIO_LED_R_INVERTED: - // case HASP_GPIO_LED_G_INVERTED: - // case HASP_GPIO_LED_B_INVERTED: + case HASP_GPIO_DAC: + case HASP_GPIO_LED: // Don't include the moodlight case HASP_GPIO_SERIAL_DIMMER: led.add(gpioConfig[i].pin); break; - case HASP_GPIO_PWM: - case HASP_GPIO_PWM_INVERTED: // pwm.add(gpioConfig[i].pin); break; From 89bca17408343e3c91ec318b6f4610c452e10a5c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 4 May 2021 02:37:32 +0200 Subject: [PATCH 110/227] Update dispatch_normalized_group_values --- src/sys/gpio/hasp_gpio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 9616770d..689d8521 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -110,7 +110,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but event_gpio_input(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid); if(eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG - dispatch_normalized_group_value(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON); + dispatch_normalized_group_values(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON); } /* ********************************* GPIO Setup *************************************** */ From f44e2fc1f2dd132b32acc6e918f79cb43b02de01 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 4 May 2021 04:07:25 +0200 Subject: [PATCH 111/227] Fix gpioSetup on native build --- src/sys/gpio/hasp_gpio.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 689d8521..9e359e27 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -345,9 +345,9 @@ void gpioLoop(void) void gpioSetup(void) { gpioSavePinConfig(0, 3, HASP_GPIO_RELAY, 0, -1); - gpioSavePinConfig(1, 4, HASP_GPIO_RELAY_INVERTED, 0, -1); + gpioSavePinConfig(1, 4, HASP_GPIO_RELAY, 0, -1); gpioSavePinConfig(2, 13, HASP_GPIO_LED, 0, -1); - gpioSavePinConfig(3, 14, HASP_GPIO_LED_INVERTED, 0, -1); + gpioSavePinConfig(3, 14, HASP_GPIO_LEDAC, 0, -1); } void gpioLoop(void) {} From 196eb382faf160b72c5e61113b3ed5fcf08ae41b Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 4 May 2021 18:44:12 +0200 Subject: [PATCH 112/227] Fix typo in native build --- src/sys/gpio/hasp_gpio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 9e359e27..c9131c54 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -347,7 +347,7 @@ void gpioSetup(void) gpioSavePinConfig(0, 3, HASP_GPIO_RELAY, 0, -1); gpioSavePinConfig(1, 4, HASP_GPIO_RELAY, 0, -1); gpioSavePinConfig(2, 13, HASP_GPIO_LED, 0, -1); - gpioSavePinConfig(3, 14, HASP_GPIO_LEDAC, 0, -1); + gpioSavePinConfig(3, 14, HASP_GPIO_DAC, 0, -1); } void gpioLoop(void) {} From 20d711d37c1c19768a7fe30465e3df0de85fe2d1 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 5 May 2021 23:36:09 +0200 Subject: [PATCH 113/227] Add backlight pin GPIO 21 --- user_setups/esp32/huzzah32-featherwing-35.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_setups/esp32/huzzah32-featherwing-35.ini b/user_setups/esp32/huzzah32-featherwing-35.ini index 0555d4b4..de364c1c 100644 --- a/user_setups/esp32/huzzah32-featherwing-35.ini +++ b/user_setups/esp32/huzzah32-featherwing-35.ini @@ -20,7 +20,7 @@ build_flags = -D TFT_DC=33 -D TFT_CS=15 -D TFT_RST=-1 ; RST - -D TFT_BCKL=-1 ; Solder the LITE pad to a PWM enabled pin of the ESP. + -D TFT_BCKL=-1 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21 -D STMPE_CS=32 ;endregion From 036861db3af5eabe13855f2b1006b5f8f34630dd Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 5 May 2021 23:36:28 +0200 Subject: [PATCH 114/227] Add backlight pin GPIO 21 --- user_setups/esp32/huzzah32-featherwing-35.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_setups/esp32/huzzah32-featherwing-35.ini b/user_setups/esp32/huzzah32-featherwing-35.ini index de364c1c..86096861 100644 --- a/user_setups/esp32/huzzah32-featherwing-35.ini +++ b/user_setups/esp32/huzzah32-featherwing-35.ini @@ -20,7 +20,7 @@ build_flags = -D TFT_DC=33 -D TFT_CS=15 -D TFT_RST=-1 ; RST - -D TFT_BCKL=-1 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21 + -D TFT_BCKL=21 ; Solder the LITE pad to a PWM enabled pin of the ESP, like GPIO 21 -D STMPE_CS=32 ;endregion From 1275b32a5eb2a685865b2375db7f5ecd6bb1e330 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 5 May 2021 23:37:04 +0200 Subject: [PATCH 115/227] Bump ArduinoJson to 6.18.0 --- platformio.ini | 2 +- src/hasp_config.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index b695c247..0d919308 100644 --- a/platformio.ini +++ b/platformio.ini @@ -68,7 +68,7 @@ build_flags = ; Warning : don't put comments after github links => causes infinite download loop lib_deps = bxparks/AceButton@^1.8.3 ; GPIO button library - bblanchon/ArduinoJson@^6.17.3 ; Json(l) parser + bblanchon/ArduinoJson@^6.18.0 ; Json(l) parser bblanchon/StreamUtils@1.6.0 ; for EEPromStream knolleary/PubSubClient@^2.8.0 ; MQTT client git+https://github.com/fvanroie/ConsoleInput.git diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index cfdf9482..2e3d678b 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -122,7 +122,7 @@ DeserializationError configParseFile(String& configFile, JsonDocument& settings) } return DeserializationError::InvalidInput; #else - return DeserializationError::NotSupported; + return DeserializationError::InvalidInput; #endif } From 99a83c2f3cef2f25bff757a3f9dde6636db61d65 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 5 May 2021 23:37:23 +0200 Subject: [PATCH 116/227] Fix a compiler warning --- src/hasp_debug.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 748eb1ff..d0e7611b 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -57,6 +57,7 @@ static void debugPrintTimestamp(int level, Print* _logOutput) int rslt = gettimeofday(&curTime, NULL); time_t t = curTime.tv_sec; tm* timeinfo = localtime(&t); + (void*)rslt; debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput); From 5706483d50bf60940cc3286dedb73130fcb0db30 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 01:34:36 +0200 Subject: [PATCH 117/227] Add event_timer_calendar, calendar_event_handler and IRAM_ATTR --- src/hasp/hasp_event.cpp | 136 +++++++++++++++++++++++++++++++++++----- src/hasp/hasp_event.h | 22 ++++--- 2 files changed, 132 insertions(+), 26 deletions(-) diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index 0b4604fd..49d02c0a 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -22,6 +22,9 @@ * ******************************************************************************************** */ +#include +#include + #include "hasplib.h" #include "lv_core/lv_obj.h" // for tabview ext @@ -29,7 +32,7 @@ static lv_style_int_t last_value_sent; static lv_color_t last_color_sent; -void swipe_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR swipe_event_handler(lv_obj_t* obj, lv_event_t event); /** * Clean-up allocated memory before an object is deleted @@ -54,6 +57,73 @@ static void event_delete_object(lv_obj_t* obj) my_obj_set_value_str_text(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL); } +/* ============================== Timer Event ============================ */ +void event_timer_calendar(lv_task_t* task) +{ + lv_obj_t* obj = (lv_obj_t*)task->user_data; + + if(!obj) return lv_task_del(task); // the calendar object for this task was deleted + + lv_calendar_date_t date; + + timeval curTime; + int rslt = gettimeofday(&curTime, NULL); + time_t t = curTime.tv_sec; + tm* timeinfo = localtime(&t); + (void*)rslt; + + if(timeinfo->tm_year < 120) { + lv_task_set_period(task, 60000); // try again in a minute + return; + } else { + uint32_t next_hour = (3600 - (t % 3600)) * 1000; // ms to next top of hour + lv_task_set_period(task, next_hour + 128); // small offset so all tasks don't run at once + } + + date.day = timeinfo->tm_mday; + date.month = timeinfo->tm_mon + 1; // months since January 0-11 + date.year = timeinfo->tm_year + 1900; // years since 1900 + + LOG_VERBOSE(TAG_EVENT, "event_timer_calendar called with user %d:%d:%d", timeinfo->tm_hour, timeinfo->tm_min, + timeinfo->tm_sec); + + lv_calendar_set_today_date(obj, &date); +} + +void event_timer_clock(lv_task_t* task) +{ + lv_obj_t* obj = (lv_obj_t*)task->user_data; + + if(!obj) return lv_task_del(task); // the calendar object for this task was deleted + + timeval curTime; + int rslt = gettimeofday(&curTime, NULL); + time_t seconds = curTime.tv_sec; + tm* timeinfo = localtime(&seconds); + (void*)rslt; + + if(timeinfo->tm_year < 120) { + lv_task_set_period(task, 60000); // try again in a minute + return; + } + + LOG_VERBOSE(TAG_EVENT, "event_timer_clock called with user %d:%d%s", timeinfo->tm_hour, timeinfo->tm_min, + timeinfo->tm_sec); + + uint16_t interval; + lv_task_set_period(task, (interval - (seconds % interval)) * 1000 + 64); // ms to next interval +} + +/* ============================== Timer Event ============================ */ +void event_timer_refresh(lv_task_t* task) +{ + lv_obj_t* obj = (lv_obj_t*)task->user_data; + printf("event_timer_refresh called with user data\n"); + if(!obj) return; + + lv_obj_invalidate(obj); +} + /* ============================== Event Senders ============================ */ /* Takes and lv_obj and finds the pageid and objid @@ -67,7 +137,7 @@ static void event_delete_object(lv_obj_t* obj) * @param event type of event that occured * @param eventid returns the hasp eventid */ -static bool translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid) +static bool IRAM_ATTR translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid) { switch(event) { case LV_EVENT_GESTURE: @@ -103,7 +173,7 @@ static bool translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid) // ##################### Value Senders ######################################################## -static void event_send_object_data(lv_obj_t* obj, const char* data) +static void IRAM_ATTR event_send_object_data(lv_obj_t* obj, const char* data) { uint8_t pageid; uint8_t objid; @@ -117,7 +187,7 @@ static void event_send_object_data(lv_obj_t* obj, const char* data) } // Send out events with a val attribute -static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) +static void IRAM_ATTR event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) { char data[40]; char eventname[8]; @@ -128,7 +198,7 @@ static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) } // Send out events with a val and text attribute -static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text) +static void IRAM_ATTR event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text) { char data[200]; char eventname[8]; @@ -141,7 +211,7 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16 // ##################### Event Handlers ######################################################## #if HASP_USE_GPIO > 0 -void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) +void IRAM_ATTR event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) { char payload[64]; char topic[8]; @@ -219,7 +289,7 @@ static void log_event(const char* name, lv_event_t event) * @param obj pointer to a button matrix * @param event type of event that occured */ -void wakeup_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR wakeup_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("wakeup", event); @@ -232,7 +302,7 @@ void wakeup_event_handler(lv_obj_t* obj, lv_event_t event) } } -void swipe_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR swipe_event_handler(lv_obj_t* obj, lv_event_t event) { if(!obj || obj->user_data.swipeid == 0) return; @@ -260,7 +330,7 @@ void swipe_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a button object * @param event type of event that occured */ -void generic_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR generic_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("generic", event); @@ -359,7 +429,7 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a switch object * @param event type of event that occured */ -void toggle_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR toggle_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("toggle", event); @@ -402,7 +472,7 @@ void toggle_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a dropdown list or roller * @param event type of event that occured */ -void selector_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR selector_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("selector", event); @@ -474,7 +544,7 @@ void selector_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a dropdown list or roller * @param event type of event that occured */ -void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("btnmatrix", event); @@ -509,7 +579,7 @@ void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a dropdown list or roller * @param event type of event that occured */ -void msgbox_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR msgbox_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("msgbox", event); @@ -541,7 +611,7 @@ void msgbox_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a slider * @param event type of event that occured */ -void slider_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR slider_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("slider", event); @@ -581,7 +651,7 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a color picker * @param event type of event that occured */ -void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) +void IRAM_ATTR cpicker_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("cpicker", event); @@ -601,9 +671,41 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) c32.full = lv_color_to32(color); last_color_sent = color; - snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), - eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"color\":\"#\",\"r\":%d,\"g\":%d,\"b\":%d}"), eventname, + c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); event_send_object_data(obj, data); // dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); } + +void IRAM_ATTR calendar_event_handler(lv_obj_t* obj, lv_event_t event) +{ + log_event("calendar", event); + + uint8_t hasp_event_id; + if(event != LV_EVENT_PRESSED && event != LV_EVENT_RELEASED && event != LV_EVENT_VALUE_CHANGED) return; + if(!translate_event(obj, event, hasp_event_id)) return; // Use LV_EVENT_VALUE_CHANGED + + /* Get the new value */ + lv_calendar_date_t* date; + if(hasp_event_id == HASP_EVENT_CHANGED) + date = lv_calendar_get_pressed_date(obj); // pressed date + else + date = lv_calendar_get_showed_date(obj); // current month + if(!date) return; + + lv_style_int_t val = date->day + date->month * 31; + if(hasp_event_id == HASP_EVENT_CHANGED && last_value_sent == val) return; // same value as before + + char data[100]; + char eventname[8]; + Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname)); + + last_value_sent = val; + + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":\"%d\",\"text\":\"%04d-%02d-%02dT00:00:00Z\"}"), + eventname, date->day, date->year, date->month, date->day); + event_send_object_data(obj, data); + + // dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); +} \ No newline at end of file diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h index 1def8c41..df581e6c 100644 --- a/src/hasp/hasp_event.h +++ b/src/hasp/hasp_event.h @@ -11,19 +11,23 @@ #define HASP_NUM_PAGE_BACK (HASP_NUM_PAGES + 2) #define HASP_NUM_PAGE_NEXT (HASP_NUM_PAGES + 3) +// Timer event Handlers +void event_timer_calendar(lv_task_t* task); + // Object event Handlers -void wakeup_event_handler(lv_obj_t* obj, lv_event_t event); -void generic_event_handler(lv_obj_t* obj, lv_event_t event); -void toggle_event_handler(lv_obj_t* obj, lv_event_t event); -void slider_event_handler(lv_obj_t* obj, lv_event_t event); -void selector_event_handler(lv_obj_t* obj, lv_event_t event); -void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event); -void msgbox_event_handler(lv_obj_t* obj, lv_event_t event); -void cpicker_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR wakeup_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR generic_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR toggle_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR slider_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR selector_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR msgbox_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR cpicker_event_handler(lv_obj_t* obj, lv_event_t event); +void IRAM_ATTR calendar_event_handler(lv_obj_t* obj, lv_event_t event); #if HASP_USE_GPIO > 0 // GPIO event Handler -void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid); +void IRAM_ATTR event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid); #endif #endif // HASP_EVENT_H \ No newline at end of file From a84c543700b94aa74970d714db27429cc7d5e415 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 01:34:59 +0200 Subject: [PATCH 118/227] Revert to 6.17.3 because 6.18.0 is not in the registry yet --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 0d919308..b695c247 100644 --- a/platformio.ini +++ b/platformio.ini @@ -68,7 +68,7 @@ build_flags = ; Warning : don't put comments after github links => causes infinite download loop lib_deps = bxparks/AceButton@^1.8.3 ; GPIO button library - bblanchon/ArduinoJson@^6.18.0 ; Json(l) parser + bblanchon/ArduinoJson@^6.17.3 ; Json(l) parser bblanchon/StreamUtils@1.6.0 ; for EEPromStream knolleary/PubSubClient@^2.8.0 ; MQTT client git+https://github.com/fvanroie/ConsoleInput.git From 037da81ceee691bd5121009757ad9d9ce6afab88 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 01:35:42 +0200 Subject: [PATCH 119/227] Add calendar_event_handler and event_timer_calendar --- src/hasp/hasp_object.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 252662a0..8376182a 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -711,8 +711,9 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) obj = lv_calendar_create(parent_obj, NULL); // lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_MID, 0, 20); if(obj) { - lv_obj_set_event_cb(obj, selector_event_handler); + lv_obj_set_event_cb(obj, calendar_event_handler); obj->user_data.objid = LV_HASP_CALENDER; + lv_task_t* task = lv_task_create(event_timer_calendar, 300, LV_TASK_PRIO_LOWEST, (void*)obj); } break; From e9a4359f4d7600e62d2d13e05476bc4a77ea6a22 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 02:39:35 +0200 Subject: [PATCH 120/227] Add IRAM_ATTR --- src/drv/hasp_drv_touch.cpp | 4 ++-- src/drv/tft_driver_tftespi.cpp | 2 +- src/drv/touch/hasp_drv_ft6336u.cpp | 16 ++++++++-------- src/hasp/hasp.cpp | 2 +- src/hasp/hasp_attribute.cpp | 2 +- src/hasp_gui.cpp | 5 +++-- src/main_arduino.cpp | 6 +++--- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/drv/hasp_drv_touch.cpp b/src/drv/hasp_drv_touch.cpp index 317d8f18..c89c0021 100644 --- a/src/drv/hasp_drv_touch.cpp +++ b/src/drv/hasp_drv_touch.cpp @@ -174,7 +174,7 @@ static inline bool drv_touchpad_getXY(int16_t* touchX, int16_t* touchY) return touched; } -bool drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) +bool IRAM_ATTR drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) { #if TOUCH_DRIVER > 0 int16_t touchX = 0; @@ -211,7 +211,7 @@ bool drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) return false; } -void drv_touch_loop() +void IRAM_ATTR drv_touch_loop() { #if TOUCH_DRIVER == 911 GT911_loop(); diff --git a/src/drv/tft_driver_tftespi.cpp b/src/drv/tft_driver_tftespi.cpp index ac418422..b849cf5a 100644 --- a/src/drv/tft_driver_tftespi.cpp +++ b/src/drv/tft_driver_tftespi.cpp @@ -123,7 +123,7 @@ void TftEspi::set_invert(bool invert) tft.invertDisplay(invert); } -void TftEspi::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) +void IRAM_ATTR TftEspi::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) { size_t len = lv_area_get_size(area); diff --git a/src/drv/touch/hasp_drv_ft6336u.cpp b/src/drv/touch/hasp_drv_ft6336u.cpp index 15cc921d..41835cd0 100644 --- a/src/drv/touch/hasp_drv_ft6336u.cpp +++ b/src/drv/touch/hasp_drv_ft6336u.cpp @@ -1,17 +1,17 @@ #if TOUCH_DRIVER == 6336 - #include - #include "FT6336U.h" - #include "ArduinoLog.h" +#include +#include "FT6336U.h" +#include "ArduinoLog.h" - #include "hasp_drv_ft6336u.h" +#include "hasp_drv_ft6336u.h" - #define RST_PIN (TOUCH_RST) // -1 if pin is connected to VCC else set pin number +#define RST_PIN (TOUCH_RST) // -1 if pin is connected to VCC else set pin number -FT6336U * touchpanel; +FT6336U* touchpanel; // Read touch points -bool FT6336U_getXY(int16_t * touchX, int16_t * touchY, bool debug) +bool IRAM_ATTR FT6336U_getXY(int16_t* touchX, int16_t* touchY, bool debug) { if(touchpanel->read_touch_number() != 1) return false; @@ -20,7 +20,7 @@ bool FT6336U_getXY(int16_t * touchX, int16_t * touchY, bool debug) return true; } -void scan(TwoWire & i2c) +void scan(TwoWire& i2c) { byte error, address; int nDevices; diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 203080dc..3e6596b1 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -102,7 +102,7 @@ lv_font_t* hasp_get_font(uint8_t fontid) /** * Check if sleep state needs to be updated */ -bool hasp_update_sleep_state() +bool IRAM_ATTR hasp_update_sleep_state() { uint32_t idle = lv_disp_get_inactive_time(NULL); diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 2ae49d51..6f2f23ac 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -1449,7 +1449,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co * @param update bool: change/set the value if true, dispatch/get value if false * @note setting a value won't return anything, getting will dispatch the value */ -void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update) +void IRAM_ATTR hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update) { // unsigned long start = millis(); if(!obj) { diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 54288d51..91b399e6 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -72,7 +72,8 @@ gui_conf_t gui_settings = {.show_pointer = false, // { // lv_tick_inc(LVGL_TICK_PERIOD); // } -void gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) + +void IRAM_ATTR gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) { haspTft.flush_pixels(disp, area, color_p); } @@ -284,7 +285,7 @@ void guiSetup(void) LOG_INFO(TAG_LVGL, F(D_SERVICE_STARTED)); } -void guiLoop(void) +void IRAM_ATTR guiLoop(void) { #if defined(STM32F4xx) // tick.update(); diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index d42604c5..2d5666d8 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -104,12 +104,12 @@ void setup() slaveSetup(); #endif - mainLastLoopTime = millis() - 1000; // reset loop counter - delay(250); + mainLastLoopTime = -1000; // reset loop counter + delay(20); // guiStart(); } -void loop() +void IRAM_ATTR loop() { guiLoop(); haspLoop(); From 633f122929ab309af8cce276ab090db77463d33e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 02:40:03 +0200 Subject: [PATCH 121/227] Disable debug logging --- src/drv/hasp_drv_touch.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/drv/hasp_drv_touch.cpp b/src/drv/hasp_drv_touch.cpp index c89c0021..438d15d9 100644 --- a/src/drv/hasp_drv_touch.cpp +++ b/src/drv/hasp_drv_touch.cpp @@ -102,13 +102,13 @@ static inline bool drv_touchpad_getXY(int16_t* touchX, int16_t* touchY) touched = Touch_getXY(&normal_x, &normal_y, false); #elif TOUCH_DRIVER == 5206 - touched = FT5206_getXY(&normal_x, &normal_y, false); + touched = FT5206_getXY(&normal_x, &normal_y, false); // no debug #elif TOUCH_DRIVER == 6336 - touched = FT6336U_getXY(&normal_x, &normal_y, true); + touched = FT6336U_getXY(&normal_x, &normal_y, false); // no debug #elif TOUCH_DRIVER == 610 - touched = STMPE610_getXY(&normal_x, &normal_y, drv_touch_rotation, true); + touched = STMPE610_getXY(&normal_x, &normal_y, drv_touch_rotation, false); // no debug #else // xpt2046_alt_drv_read(indev_driver, data); From 46aaa37cc1130eb7401ed27562312cba4278bff6 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 02:40:20 +0200 Subject: [PATCH 122/227] Add IRAM_ATTR --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index b695c247..f918567f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -116,6 +116,7 @@ build_flags = -D NO_GLOBAL_HTTPUPDATE ; dont instantiate httpUpdate ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=61440U ; 60kB lvgl memory + -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments ; -- tft_espi build options ------------------------ From 0b7bda066dcaaf19974facff3cb55adac5faf2f7 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 02:54:34 +0200 Subject: [PATCH 123/227] No IRAM_ATTR available on these platforms --- user_setups/darwin_sdl/darwin_sdl_64bits.ini | 1 + user_setups/linux_sdl/linux_sdl_64bits.ini | 1 + user_setups/win32/windows_sdl_64bits.ini | 1 + 3 files changed, 3 insertions(+) diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini index 9142ead5..caea972a 100644 --- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini +++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini @@ -31,6 +31,7 @@ build_flags = -D HASP_USE_DEBUG=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 + -D IRAM_ATTR= ; No IRAM_ATTR available ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO ;-D LV_LOG_PRINTF=1 ; Add recursive dirs for hal headers search diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini index e1e408d7..1e0c7557 100644 --- a/user_setups/linux_sdl/linux_sdl_64bits.ini +++ b/user_setups/linux_sdl/linux_sdl_64bits.ini @@ -30,6 +30,7 @@ build_flags = -D HASP_USE_DEBUG=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 + -D IRAM_ATTR= ; No IRAM_ATTR available ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO ;-D LV_LOG_PRINTF=1 ; Add recursive dirs for hal headers search diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini index a2c6422b..29f4adf8 100644 --- a/user_setups/win32/windows_sdl_64bits.ini +++ b/user_setups/win32/windows_sdl_64bits.ini @@ -30,6 +30,7 @@ build_flags = -D HASP_USE_DEBUG=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 + -D IRAM_ATTR= ; No IRAM_ATTR available ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO ;-D LV_LOG_PRINTF=1 ; Add recursive dirs for hal headers search From dca9a5d8b8654b74258648440abfa32aef9b8bee Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 03:47:46 +0200 Subject: [PATCH 124/227] Decorate Loop() functions with IRAM_ATTR --- lib/lv_lib_zifont/lv_zifont.cpp | 20 ++++++------ platformio.ini | 5 ++- src/drv/hasp_drv_touch.cpp | 8 ++--- src/drv/hasp_drv_touch.h | 6 ++-- src/drv/touch/hasp_drv_ft6336u.cpp | 2 +- src/drv/touch/hasp_drv_ft6336u.h | 2 +- src/drv/touch/hasp_drv_stmpe610.cpp | 47 ++++++++++++++--------------- src/drv/touch/hasp_drv_stmpe610.h | 4 +-- src/hasp/hasp.cpp | 4 +-- src/hasp/hasp.h | 4 +-- src/hasp/hasp_attribute.cpp | 3 +- src/hasp/hasp_attribute.h | 3 +- src/hasp/hasp_dispatch.cpp | 2 +- src/hasp/hasp_dispatch.h | 2 +- src/hasp/hasp_event.cpp | 32 ++++++++++---------- src/hasp/hasp_event.h | 20 ++++++------ src/hasp_debug.h | 2 +- src/hasp_gui.cpp | 6 ++-- src/hasp_gui.h | 2 +- src/log/hasp_debug.cpp | 2 +- src/main_arduino.cpp | 10 +++--- src/mqtt/hasp_mqtt.h | 2 +- src/mqtt/hasp_mqtt_paho_async.cpp | 2 +- src/mqtt/hasp_mqtt_paho_single.cpp | 2 +- src/mqtt/hasp_mqtt_pubsubclient.cpp | 2 +- src/sys/gpio/hasp_gpio.cpp | 4 +-- src/sys/gpio/hasp_gpio.h | 2 +- src/sys/net/hasp_ethernet_esp32.cpp | 2 +- src/sys/net/hasp_ethernet_esp32.h | 2 +- src/sys/net/hasp_network.cpp | 2 +- src/sys/net/hasp_network.h | 2 +- src/sys/svc/hasp_http.cpp | 2 +- src/sys/svc/hasp_http.h | 2 +- src/sys/svc/hasp_mdns.cpp | 2 +- src/sys/svc/hasp_mdns.h | 2 +- src/sys/svc/hasp_ota.cpp | 2 +- src/sys/svc/hasp_ota.h | 2 +- src/sys/svc/hasp_telnet.cpp | 2 +- src/sys/svc/hasp_telnet.h | 2 +- 39 files changed, 114 insertions(+), 110 deletions(-) diff --git a/lib/lv_lib_zifont/lv_zifont.cpp b/lib/lv_lib_zifont/lv_zifont.cpp index 176c26a4..f801a907 100644 --- a/lib/lv_lib_zifont/lv_zifont.cpp +++ b/lib/lv_lib_zifont/lv_zifont.cpp @@ -55,9 +55,9 @@ enum zifont_codepage_t8_t { ASCII = 0x01, ISO_8859_1 = 0x03, UTF_8 = 0x18 }; /********************** * STATIC PROTOTYPES **********************/ -const uint8_t* IRAM_ATTR lv_font_get_bitmap_fmt_zifont(const lv_font_t* font, uint32_t unicode_letter); -bool IRAM_ATTR lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t* font, lv_font_glyph_dsc_t* dsc_out, - uint32_t unicode_letter, uint32_t unicode_letter_next); +HASP_ATTRIBUTE_FAST_MEM const uint8_t* lv_font_get_bitmap_fmt_zifont(const lv_font_t* font, uint32_t unicode_letter); +HASP_ATTRIBUTE_FAST_MEM bool lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t* font, lv_font_glyph_dsc_t* dsc_out, + uint32_t unicode_letter, uint32_t unicode_letter_next); /********************** * STATIC VARIABLES @@ -83,8 +83,8 @@ static uint8_t* charBitmap_p; * GLOBAL FUNCTIONS **********************/ -static void IRAM_ATTR blackAdd(uint8_t* charBitmap_p, uint16_t pos); -static void IRAM_ATTR colorsAdd(uint8_t* charBitmap_p, uint8_t color1, uint16_t pos); +HASP_ATTRIBUTE_FAST_MEM static void blackAdd(uint8_t* charBitmap_p, uint16_t pos); +HASP_ATTRIBUTE_FAST_MEM static void colorsAdd(uint8_t* charBitmap_p, uint8_t color1, uint16_t pos); // static uint16_t unicode2codepoint(uint32_t unicode, uint8_t codepage); // static void printBuffer(uint8_t * charBitmap_p, uint8_t w, uint8_t h); @@ -282,7 +282,7 @@ int lv_zifont_font_init(lv_font_t** font, const char* font_path, uint16_t size) * @param unicode_letter an unicode letter which bitmap should be get * @return pointer to the bitmap or NULL if not found */ -const uint8_t* IRAM_ATTR lv_font_get_bitmap_fmt_zifont(const lv_font_t* font, uint32_t unicode_letter) +HASP_ATTRIBUTE_FAST_MEM const uint8_t* lv_font_get_bitmap_fmt_zifont(const lv_font_t* font, uint32_t unicode_letter) { /* Bitmap still in buffer */ if(charInBuffer == unicode_letter && charBitmap_p) { @@ -469,8 +469,8 @@ const uint8_t* IRAM_ATTR lv_font_get_bitmap_fmt_zifont(const lv_font_t* font, ui * @return true: descriptor is successfully loaded into `dsc_out`. * false: the letter was not found, no data is loaded to `dsc_out` */ -bool IRAM_ATTR lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t* font, lv_font_glyph_dsc_t* dsc_out, - uint32_t unicode_letter, uint32_t unicode_letter_next) +HASP_ATTRIBUTE_FAST_MEM bool lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t* font, lv_font_glyph_dsc_t* dsc_out, + uint32_t unicode_letter, uint32_t unicode_letter_next) { /* Only ascii characteres supported for now */ // returning true with a box_h of 0 does not display an error @@ -564,7 +564,7 @@ bool IRAM_ATTR lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t* font, lv_font_g return true; } -static void IRAM_ATTR blackAdd(uint8_t* charBitmap_p, uint16_t pos) +HASP_ATTRIBUTE_FAST_MEM static void blackAdd(uint8_t* charBitmap_p, uint16_t pos) { uint8_t col = pos & 0x0001; // remainder uint16_t map_p = pos >> 1; // devide by 2 @@ -576,7 +576,7 @@ static void IRAM_ATTR blackAdd(uint8_t* charBitmap_p, uint16_t pos) } } -static inline void IRAM_ATTR colorsAdd(uint8_t* charBitmap_p, uint8_t color1, uint16_t pos) +HASP_ATTRIBUTE_FAST_MEM static inline void colorsAdd(uint8_t* charBitmap_p, uint8_t color1, uint16_t pos) { uint32_t col = pos & 0x0001; // remainder uint32_t map_p = pos >> 1; // devide by 2 diff --git a/platformio.ini b/platformio.ini index f918567f..04ca7d15 100644 --- a/platformio.ini +++ b/platformio.ini @@ -116,12 +116,13 @@ build_flags = -D NO_GLOBAL_HTTPUPDATE ; dont instantiate httpUpdate ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=61440U ; 60kB lvgl memory - -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR + -D LV_ATTRIBUTE_FAST_MEM= ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments ; -- tft_espi build options ------------------------ ;-D USE_DMA_TO_TFT ; -- openHASP build options ------------------------ + -D HASP_ATTRIBUTE_FAST_MEM=IRAM_ATTR -D HASP_USE_TELNET=1 ;-D HASP_USE_SPIFFS=1 -D HASP_USE_LITTLEFS=1 @@ -189,10 +190,12 @@ build_flags= -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=12288U ; 12kB lvgl memory + -D LV_ATTRIBUTE_FAST_MEM= ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments -D ARDUINOJSON_ENABLE_STD_STRING=1 ; for std::string ; -- openHASP build options ------------------------- + -D HASP_ATTRIBUTE_FAST_MEM= -D HASP_USE_TELNET=1 ;-D HASP_USE_SPIFFS=1 -D HASP_USE_LITTLEFS=1 diff --git a/src/drv/hasp_drv_touch.cpp b/src/drv/hasp_drv_touch.cpp index 438d15d9..900fef4c 100644 --- a/src/drv/hasp_drv_touch.cpp +++ b/src/drv/hasp_drv_touch.cpp @@ -1,10 +1,10 @@ /* MIT License - Copyright (c) 2019-2021 Francis Van Roie For full license information read the LICENSE file in the project folder */ +#include "hasplib.h" + #include "hasp_drv_touch.h" -#include "hasp/hasp.h" #include "drv/tft_driver.h" -#include "lvgl.h" #if TOUCH_DRIVER == 2046 #if defined(USE_FSMC) @@ -174,7 +174,7 @@ static inline bool drv_touchpad_getXY(int16_t* touchX, int16_t* touchY) return touched; } -bool IRAM_ATTR drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) +IRAM_ATTR bool drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) { #if TOUCH_DRIVER > 0 int16_t touchX = 0; @@ -211,7 +211,7 @@ bool IRAM_ATTR drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* dat return false; } -void IRAM_ATTR drv_touch_loop() +IRAM_ATTR void drv_touch_loop() { #if TOUCH_DRIVER == 911 GT911_loop(); diff --git a/src/drv/hasp_drv_touch.h b/src/drv/hasp_drv_touch.h index f1b83f10..d1d3161e 100644 --- a/src/drv/hasp_drv_touch.h +++ b/src/drv/hasp_drv_touch.h @@ -4,14 +4,14 @@ #ifndef HASP_DRV_TOUCH_H #define HASP_DRV_TOUCH_H -#include "lvgl.h" +#include "hasplib.h" #ifndef TOUCH_DRIVER #define TOUCH_DRIVER -1 // No Touch #endif void drv_touch_init(uint8_t rotation); -bool drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data); -void drv_touch_loop(); +IRAM_ATTR bool drv_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data); +IRAM_ATTR void drv_touch_loop(); #endif \ No newline at end of file diff --git a/src/drv/touch/hasp_drv_ft6336u.cpp b/src/drv/touch/hasp_drv_ft6336u.cpp index 41835cd0..07bcd14a 100644 --- a/src/drv/touch/hasp_drv_ft6336u.cpp +++ b/src/drv/touch/hasp_drv_ft6336u.cpp @@ -11,7 +11,7 @@ FT6336U* touchpanel; // Read touch points -bool IRAM_ATTR FT6336U_getXY(int16_t* touchX, int16_t* touchY, bool debug) +HASP_ATTRIBUTE_FAST_MEM bool FT6336U_getXY(int16_t* touchX, int16_t* touchY, bool debug) { if(touchpanel->read_touch_number() != 1) return false; diff --git a/src/drv/touch/hasp_drv_ft6336u.h b/src/drv/touch/hasp_drv_ft6336u.h index a52100e1..afae44c0 100644 --- a/src/drv/touch/hasp_drv_ft6336u.h +++ b/src/drv/touch/hasp_drv_ft6336u.h @@ -8,7 +8,7 @@ #include "hasp_debug.h" // for TAG_DRVR -bool FT6336U_getXY(int16_t* touchX, int16_t* touchY, bool debug); +HASP_ATTRIBUTE_FAST_MEM bool FT6336U_getXY(int16_t* touchX, int16_t* touchY, bool debug); void FT6336U_init(); #endif diff --git a/src/drv/touch/hasp_drv_stmpe610.cpp b/src/drv/touch/hasp_drv_stmpe610.cpp index f1a6df4a..7aa361f4 100644 --- a/src/drv/touch/hasp_drv_stmpe610.cpp +++ b/src/drv/touch/hasp_drv_stmpe610.cpp @@ -1,66 +1,65 @@ #if TOUCH_DRIVER == 610 - #include - #include "Adafruit_STMPE610.h" - #include "ArduinoLog.h" +#include +#include "Adafruit_STMPE610.h" +#include "ArduinoLog.h" - #include "hasp_drv_stmpe610.h" +#include "hasp_drv_stmpe610.h" // This is calibration data for the raw touch data to the screen coordinates - #define TS_MINX 3800 - #define TS_MAXX 100 - #define TS_MINY 100 - #define TS_MAXY 3750 +#define TS_MINX 3800 +#define TS_MAXX 100 +#define TS_MINY 100 +#define TS_MAXY 3750 static Adafruit_STMPE610 touch = Adafruit_STMPE610(STMPE_CS); // Read touch points from global variable -bool IRAM_ATTR STMPE610_getXY(int16_t * touchX, int16_t * touchY, uint8_t touchRotation, bool debug) +HASP_ATTRIBUTE_FAST_MEM bool STMPE610_getXY(int16_t* touchX, int16_t* touchY, uint8_t touchRotation, bool debug) { uint16_t x, y; uint8_t z; - if(! touch.touched()) return false; + if(!touch.touched()) return false; - while (! touch.bufferEmpty()) { + while(!touch.bufferEmpty()) { touch.readData(&x, &y, &z); if(debug) Log.trace(TAG_DRVR, F("STMPE610: x=%i y=%i z=%i r=%i"), x, y, z, touchRotation); } touch.writeRegister8(STMPE_INT_STA, 0xFF); - if (1 == touchRotation) { - #if HX8357D_DRIVER == 1 + if(1 == touchRotation) { +#if HX8357D_DRIVER == 1 y = map(y, TS_MINX, TS_MAXX, 0, TFT_HEIGHT); x = map(x, TS_MINY, TS_MAXY, TFT_WIDTH, 0); - #else +#else x = map(x, TS_MAXX, TS_MINX, 0, TFT_WIDTH); y = map(y, TS_MAXY, TS_MINY, 0, TFT_HEIGHT); - #endif - } else if (2 == touchRotation) { - #if HX8357D_DRIVER == 1 +#endif + } else if(2 == touchRotation) { +#if HX8357D_DRIVER == 1 x = map(x, TS_MAXX, TS_MINX, TFT_WIDTH, 0); y = map(y, TS_MAXY, TS_MINY, 0, TFT_HEIGHT); - #else +#else x = map(x, TS_MAXX, TS_MINX, 0, TFT_WIDTH); y = map(y, TS_MAXY, TS_MINY, 0, TFT_HEIGHT); - #endif +#endif } else { - #if HX8357D_DRIVER == 1 +#if HX8357D_DRIVER == 1 x = map(x, TS_MINX, TS_MAXX, TFT_WIDTH, 0); y = map(y, TS_MINY, TS_MAXY, 0, TFT_HEIGHT); - #else +#else x = map(x, TS_MINX, TS_MAXX, 0, TFT_WIDTH); y = map(y, TS_MINY, TS_MAXY, 0, TFT_HEIGHT); - #endif +#endif } *touchX = x; *touchY = y; return true; - } void STMPE610_init() { - if (! touch.begin()) { + if(!touch.begin()) { Log.trace(TAG_DRVR, F("STMPE610 not found!")); } else { Log.trace(TAG_DRVR, F("STMPE610 touch driver started")); diff --git a/src/drv/touch/hasp_drv_stmpe610.h b/src/drv/touch/hasp_drv_stmpe610.h index 2eb07f99..fe0c3c81 100644 --- a/src/drv/touch/hasp_drv_stmpe610.h +++ b/src/drv/touch/hasp_drv_stmpe610.h @@ -6,9 +6,9 @@ #if TOUCH_DRIVER == 610 - #include "hasp_debug.h" // for TAG_DRVR +#include "hasp_debug.h" // for TAG_DRVR -bool IRAM_ATTR STMPE610_getXY(int16_t * touchX, int16_t * touchY, uint8_t touchRotation, bool debug); +HASP_ATTRIBUTE_FAST_MEM bool STMPE610_getXY(int16_t* touchX, int16_t* touchY, uint8_t touchRotation, bool debug); void STMPE610_init(); #endif diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 3e6596b1..390139f5 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -102,7 +102,7 @@ lv_font_t* hasp_get_font(uint8_t fontid) /** * Check if sleep state needs to be updated */ -bool IRAM_ATTR hasp_update_sleep_state() +HASP_ATTRIBUTE_FAST_MEM bool hasp_update_sleep_state() { uint32_t idle = lv_disp_get_inactive_time(NULL); @@ -470,7 +470,7 @@ void haspSetup(void) * STATIC FUNCTIONS **********************/ -void haspLoop(void) +IRAM_ATTR void haspLoop(void) { dispatchLoop(); } diff --git a/src/hasp/hasp.h b/src/hasp/hasp.h index 35311960..7a946d4b 100644 --- a/src/hasp/hasp.h +++ b/src/hasp/hasp.h @@ -47,7 +47,7 @@ extern "C" { * Create a hasp application */ void haspSetup(void); -void haspLoop(void); +IRAM_ATTR void haspLoop(void); void haspEverySecond(void); void haspReconnect(void); @@ -67,7 +67,7 @@ bool haspSetConfig(const JsonObject& settings); lv_font_t* hasp_get_font(uint8_t fontid); -bool hasp_update_sleep_state(); +HASP_ATTRIBUTE_FAST_MEM bool hasp_update_sleep_state(); void hasp_get_sleep_state(char* payload); void hasp_get_sleep_time(uint16_t& short_time, uint16_t& long_time); void hasp_set_sleep_time(uint16_t short_time, uint16_t long_time); diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 6f2f23ac..5126b830 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -1449,7 +1449,8 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co * @param update bool: change/set the value if true, dispatch/get value if false * @note setting a value won't return anything, getting will dispatch the value */ -void IRAM_ATTR hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update) +HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, + bool update) { // unsigned long start = millis(); if(!obj) { diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index cfad4afe..46d89411 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -16,7 +16,8 @@ void my_obj_set_value_str_text(lv_obj_t* obj, uint8_t part, lv_state_t state, co void my_btnmatrix_map_clear(lv_obj_t* obj); void line_clear_points(lv_obj_t* obj); -void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update); +HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, + bool update); bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool booval, bool update); void attr_out_str(lv_obj_t* obj, const char* attribute, const char* data); diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 9e6e5e44..7c7d83fc 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -991,7 +991,7 @@ void dispatchSetup() /* WARNING: remember to expand the commands array when adding new commands */ } -void dispatchLoop() +IRAM_ATTR void dispatchLoop() { lv_task_handler(); // process animations } diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index be958c1e..edc805c5 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -28,7 +28,7 @@ enum hasp_event_t { // even = released, odd = pressed /* ===== Default Event Processors ===== */ void dispatchSetup(void); -void dispatchLoop(void); +IRAM_ATTR void dispatchLoop(void); void dispatchEverySecond(void); void dispatchStart(void); void dispatchStop(void); diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index 49d02c0a..fe8ad4e4 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -32,7 +32,7 @@ static lv_style_int_t last_value_sent; static lv_color_t last_color_sent; -void IRAM_ATTR swipe_event_handler(lv_obj_t* obj, lv_event_t event); +void swipe_event_handler(lv_obj_t* obj, lv_event_t event); /** * Clean-up allocated memory before an object is deleted @@ -137,7 +137,7 @@ void event_timer_refresh(lv_task_t* task) * @param event type of event that occured * @param eventid returns the hasp eventid */ -static bool IRAM_ATTR translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid) +static bool translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid) { switch(event) { case LV_EVENT_GESTURE: @@ -173,7 +173,7 @@ static bool IRAM_ATTR translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& // ##################### Value Senders ######################################################## -static void IRAM_ATTR event_send_object_data(lv_obj_t* obj, const char* data) +static void event_send_object_data(lv_obj_t* obj, const char* data) { uint8_t pageid; uint8_t objid; @@ -187,7 +187,7 @@ static void IRAM_ATTR event_send_object_data(lv_obj_t* obj, const char* data) } // Send out events with a val attribute -static void IRAM_ATTR event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) +static void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) { char data[40]; char eventname[8]; @@ -198,7 +198,7 @@ static void IRAM_ATTR event_object_val_event(lv_obj_t* obj, uint8_t eventid, int } // Send out events with a val and text attribute -static void IRAM_ATTR event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text) +static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text) { char data[200]; char eventname[8]; @@ -211,7 +211,7 @@ static void IRAM_ATTR event_object_selection_changed(lv_obj_t* obj, uint8_t even // ##################### Event Handlers ######################################################## #if HASP_USE_GPIO > 0 -void IRAM_ATTR event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) +void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) { char payload[64]; char topic[8]; @@ -289,7 +289,7 @@ static void log_event(const char* name, lv_event_t event) * @param obj pointer to a button matrix * @param event type of event that occured */ -void IRAM_ATTR wakeup_event_handler(lv_obj_t* obj, lv_event_t event) +void wakeup_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("wakeup", event); @@ -302,7 +302,7 @@ void IRAM_ATTR wakeup_event_handler(lv_obj_t* obj, lv_event_t event) } } -void IRAM_ATTR swipe_event_handler(lv_obj_t* obj, lv_event_t event) +void swipe_event_handler(lv_obj_t* obj, lv_event_t event) { if(!obj || obj->user_data.swipeid == 0) return; @@ -330,7 +330,7 @@ void IRAM_ATTR swipe_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a button object * @param event type of event that occured */ -void IRAM_ATTR generic_event_handler(lv_obj_t* obj, lv_event_t event) +void generic_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("generic", event); @@ -429,7 +429,7 @@ void IRAM_ATTR generic_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a switch object * @param event type of event that occured */ -void IRAM_ATTR toggle_event_handler(lv_obj_t* obj, lv_event_t event) +void toggle_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("toggle", event); @@ -472,7 +472,7 @@ void IRAM_ATTR toggle_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a dropdown list or roller * @param event type of event that occured */ -void IRAM_ATTR selector_event_handler(lv_obj_t* obj, lv_event_t event) +void selector_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("selector", event); @@ -544,7 +544,7 @@ void IRAM_ATTR selector_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a dropdown list or roller * @param event type of event that occured */ -void IRAM_ATTR btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) +void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("btnmatrix", event); @@ -579,7 +579,7 @@ void IRAM_ATTR btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a dropdown list or roller * @param event type of event that occured */ -void IRAM_ATTR msgbox_event_handler(lv_obj_t* obj, lv_event_t event) +void msgbox_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("msgbox", event); @@ -611,7 +611,7 @@ void IRAM_ATTR msgbox_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a slider * @param event type of event that occured */ -void IRAM_ATTR slider_event_handler(lv_obj_t* obj, lv_event_t event) +void slider_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("slider", event); @@ -651,7 +651,7 @@ void IRAM_ATTR slider_event_handler(lv_obj_t* obj, lv_event_t event) * @param obj pointer to a color picker * @param event type of event that occured */ -void IRAM_ATTR cpicker_event_handler(lv_obj_t* obj, lv_event_t event) +void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("cpicker", event); @@ -678,7 +678,7 @@ void IRAM_ATTR cpicker_event_handler(lv_obj_t* obj, lv_event_t event) // dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); } -void IRAM_ATTR calendar_event_handler(lv_obj_t* obj, lv_event_t event) +void calendar_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("calendar", event); diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h index df581e6c..50f6e40d 100644 --- a/src/hasp/hasp_event.h +++ b/src/hasp/hasp_event.h @@ -15,19 +15,19 @@ void event_timer_calendar(lv_task_t* task); // Object event Handlers -void IRAM_ATTR wakeup_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR generic_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR toggle_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR slider_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR selector_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR msgbox_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR cpicker_event_handler(lv_obj_t* obj, lv_event_t event); -void IRAM_ATTR calendar_event_handler(lv_obj_t* obj, lv_event_t event); +void wakeup_event_handler(lv_obj_t* obj, lv_event_t event); +void generic_event_handler(lv_obj_t* obj, lv_event_t event); +void toggle_event_handler(lv_obj_t* obj, lv_event_t event); +void slider_event_handler(lv_obj_t* obj, lv_event_t event); +void selector_event_handler(lv_obj_t* obj, lv_event_t event); +void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event); +void msgbox_event_handler(lv_obj_t* obj, lv_event_t event); +void cpicker_event_handler(lv_obj_t* obj, lv_event_t event); +void calendar_event_handler(lv_obj_t* obj, lv_event_t event); #if HASP_USE_GPIO > 0 // GPIO event Handler -void IRAM_ATTR event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid); +void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid); #endif #endif // HASP_EVENT_H \ No newline at end of file diff --git a/src/hasp_debug.h b/src/hasp_debug.h index 51dc7bf2..1e5e4055 100644 --- a/src/hasp_debug.h +++ b/src/hasp_debug.h @@ -133,7 +133,7 @@ extern "C" { // Functions used by ANDROID, WINDOWS and POSSIX void debugLvglLogEvent(lv_log_level_t level, const char* file, uint32_t line, const char* funcname, const char* descr); -void debugLoop(void); +IRAM_ATTR void debugLoop(void); void debugEverySecond(void); void debugStart(void); void debugStop(void); diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 91b399e6..f245ca73 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -48,7 +48,7 @@ File pFileOut; #define INVERT_COLORS 0 #endif -// static void IRAM_ATTR lv_tick_handler(void); +// HASP_ATTRIBUTE_FAST_MEM static void lv_tick_handler(void); gui_conf_t gui_settings = {.show_pointer = false, .backlight_pin = TFT_BCKL, @@ -73,7 +73,7 @@ gui_conf_t gui_settings = {.show_pointer = false, // lv_tick_inc(LVGL_TICK_PERIOD); // } -void IRAM_ATTR gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) +IRAM_ATTR void gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) { haspTft.flush_pixels(disp, area, color_p); } @@ -285,7 +285,7 @@ void guiSetup(void) LOG_INFO(TAG_LVGL, F(D_SERVICE_STARTED)); } -void IRAM_ATTR guiLoop(void) +IRAM_ATTR void guiLoop(void) { #if defined(STM32F4xx) // tick.update(); diff --git a/src/hasp_gui.h b/src/hasp_gui.h index cb7500a7..0c8a25d4 100644 --- a/src/hasp_gui.h +++ b/src/hasp_gui.h @@ -17,7 +17,7 @@ struct gui_conf_t /* ===== Default Event Processors ===== */ void guiSetup(void); -void guiLoop(void); +IRAM_ATTR void guiLoop(void); void guiEverySecond(void); void guiStart(void); void guiStop(void); diff --git a/src/log/hasp_debug.cpp b/src/log/hasp_debug.cpp index ffb977a9..ff00a1be 100644 --- a/src/log/hasp_debug.cpp +++ b/src/log/hasp_debug.cpp @@ -333,7 +333,7 @@ void debugSetupWithoutLogging(JsonObject settings) } } -void debugLoop(void) +IRAM_ATTR void debugLoop(void) { int16_t keypress; do { diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index 2d5666d8..ae897bd6 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -68,10 +68,6 @@ void setup() haspSetup(); } -#if HASP_USE_GPIO > 0 - gpioSetup(); -#endif - /**************************** * Apply User Configuration ***************************/ @@ -80,6 +76,10 @@ void setup() mqttSetup(); // Load Hostname before starting WiFi #endif +#if HASP_USE_GPIO > 0 + gpioSetup(); +#endif + #if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0 networkSetup(); #endif @@ -109,7 +109,7 @@ void setup() // guiStart(); } -void IRAM_ATTR loop() +IRAM_ATTR void loop() { guiLoop(); haspLoop(); diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h index ff7a3cdc..af0f02b7 100644 --- a/src/mqtt/hasp_mqtt.h +++ b/src/mqtt/hasp_mqtt.h @@ -23,7 +23,7 @@ typedef enum { } hasp_mqtt_error_t; void mqttSetup(); -void mqttLoop(); +IRAM_ATTR void mqttLoop(); void mqttEvery5Seconds(bool wifiIsConnected); void mqttStart(); void mqttStop(); diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp index aec077ee..323cb80d 100644 --- a/src/mqtt/hasp_mqtt_paho_async.cpp +++ b/src/mqtt/hasp_mqtt_paho_async.cpp @@ -430,7 +430,7 @@ void mqttStop() void mqttSetup(){}; -void mqttLoop(){}; +IRAM_ATTR void mqttLoop(){}; void mqttEvery5Seconds(bool wifiIsConnected){}; diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp index 4113eece..a05ae1a8 100644 --- a/src/mqtt/hasp_mqtt_paho_single.cpp +++ b/src/mqtt/hasp_mqtt_paho_single.cpp @@ -403,7 +403,7 @@ void mqttSetup() printf("%s %d\n", __FILE__, __LINE__); } -void mqttLoop() +IRAM_ATTR void mqttLoop() { int topicLen; char* topicName; // Freed by msgarrvd diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index d3940476..eb096a87 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -355,7 +355,7 @@ void mqttSetup() } } -void mqttLoop(void) +IRAM_ATTR void mqttLoop(void) { if(mqttEnabled) mqttClient.loop(); } diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index c9131c54..44912d9f 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -333,7 +333,7 @@ void gpioSetup() LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTED)); } -void gpioLoop(void) +IRAM_ATTR void gpioLoop(void) { // Should be called every 4-5ms or faster, for the default debouncing time of ~20ms. for(uint8_t i = 0; i < gpioUsedInputCount; i++) { @@ -349,7 +349,7 @@ void gpioSetup(void) gpioSavePinConfig(2, 13, HASP_GPIO_LED, 0, -1); gpioSavePinConfig(3, 14, HASP_GPIO_DAC, 0, -1); } -void gpioLoop(void) +IRAM_ATTR void gpioLoop(void) {} #endif // ARDUINO diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index 2174fb61..25de68b5 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -22,7 +22,7 @@ struct hasp_gpio_config_t }; void gpioSetup(void); -void gpioLoop(void); +IRAM_ATTR void gpioLoop(void); void gpioEvery5Seconds(void); // void gpio_set_group_onoff(uint8_t groupid, bool ison); diff --git a/src/sys/net/hasp_ethernet_esp32.cpp b/src/sys/net/hasp_ethernet_esp32.cpp index 00737dfe..b9cb872b 100644 --- a/src/sys/net/hasp_ethernet_esp32.cpp +++ b/src/sys/net/hasp_ethernet_esp32.cpp @@ -55,7 +55,7 @@ void ethernetSetup() ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLKMODE); } -void ethernetLoop(void) +IRAM_ATTR void ethernetLoop(void) {} bool ethernetEvery5Seconds() diff --git a/src/sys/net/hasp_ethernet_esp32.h b/src/sys/net/hasp_ethernet_esp32.h index 4d8463c4..d8c62dab 100644 --- a/src/sys/net/hasp_ethernet_esp32.h +++ b/src/sys/net/hasp_ethernet_esp32.h @@ -9,7 +9,7 @@ static bool eth_connected = false; void ethernetSetup(); -void ethernetLoop(void); +IRAM_ATTR void ethernetLoop(void); bool ethernetEverySecond(); bool ethernetEvery5Seconds(); diff --git a/src/sys/net/hasp_network.cpp b/src/sys/net/hasp_network.cpp index 272e1ad8..820a85bd 100644 --- a/src/sys/net/hasp_network.cpp +++ b/src/sys/net/hasp_network.cpp @@ -58,7 +58,7 @@ void networkSetup() #endif } -void networkLoop(void) +IRAM_ATTR void networkLoop(void) { #if HASP_USE_ETHERNET > 0 ethernetLoop(); diff --git a/src/sys/net/hasp_network.h b/src/sys/net/hasp_network.h index 7df30a99..15305d80 100644 --- a/src/sys/net/hasp_network.h +++ b/src/sys/net/hasp_network.h @@ -6,7 +6,7 @@ /* ===== Default Event Processors ===== */ void networkSetup(); -void networkLoop(void); +IRAM_ATTR void networkLoop(void); bool networkEvery5Seconds(void); // bool networkEverySecond(void); void networkStart(void); diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index f6da2ad6..5bfc57ea 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -2219,7 +2219,7 @@ void httpReconnect() } //////////////////////////////////////////////////////////////////////////////////////////////////// -void httpLoop(void) +IRAM_ATTR void httpLoop(void) { if(http_config.enable) webServer.handleClient(); } diff --git a/src/sys/svc/hasp_http.h b/src/sys/svc/hasp_http.h index 51313c6d..23be22ca 100644 --- a/src/sys/svc/hasp_http.h +++ b/src/sys/svc/hasp_http.h @@ -16,7 +16,7 @@ struct hasp_http_config_t }; void httpSetup(); -void httpLoop(void); +IRAM_ATTR void httpLoop(void); void httpEvery5Seconds(void); // void httpReconnect(void); void httpStart(void); diff --git a/src/sys/svc/hasp_mdns.cpp b/src/sys/svc/hasp_mdns.cpp index 822c7970..464db38d 100644 --- a/src/sys/svc/hasp_mdns.cpp +++ b/src/sys/svc/hasp_mdns.cpp @@ -78,7 +78,7 @@ void mdnsStart() } } -void mdnsLoop(void) +IRAM_ATTR void mdnsLoop(void) { #if defined(ARDUINO_ARCH_ESP8266) if(mdns_config.enable) { diff --git a/src/sys/svc/hasp_mdns.h b/src/sys/svc/hasp_mdns.h index 2700595b..d81cd3f6 100644 --- a/src/sys/svc/hasp_mdns.h +++ b/src/sys/svc/hasp_mdns.h @@ -13,7 +13,7 @@ struct hasp_mdns_config_t /* ===== Default Event Processors ===== */ void mdnsSetup(); -void mdnsLoop(void); +IRAM_ATTR void mdnsLoop(void); void mdnsStart(void); void mdnsStop(void); diff --git a/src/sys/svc/hasp_ota.cpp b/src/sys/svc/hasp_ota.cpp index c4cc39f8..42bee68c 100644 --- a/src/sys/svc/hasp_ota.cpp +++ b/src/sys/svc/hasp_ota.cpp @@ -200,7 +200,7 @@ void otaSetup(void) } } -void otaLoop(void) +IRAM_ATTR void otaLoop(void) { ArduinoOTA.handle(); } diff --git a/src/sys/svc/hasp_ota.h b/src/sys/svc/hasp_ota.h index 215cd73a..83908539 100644 --- a/src/sys/svc/hasp_ota.h +++ b/src/sys/svc/hasp_ota.h @@ -10,7 +10,7 @@ /* ===== Default Event Processors ===== */ void otaSetup(void); -void otaLoop(void); +IRAM_ATTR void otaLoop(void); void otaEverySecond(void); /* ===== Special Event Processors ===== */ diff --git a/src/sys/svc/hasp_telnet.cpp b/src/sys/svc/hasp_telnet.cpp index 7678d19a..8101cf32 100644 --- a/src/sys/svc/hasp_telnet.cpp +++ b/src/sys/svc/hasp_telnet.cpp @@ -258,7 +258,7 @@ void telnetSetup() } } -void telnetLoop() +IRAM_ATTR void telnetLoop() { // Basic telnet client handling code from: https://gist.github.com/tablatronix/4793677ca748f5f584c95ec4a2b10303 diff --git a/src/sys/svc/hasp_telnet.h b/src/sys/svc/hasp_telnet.h index d35612f0..1e4ebdbb 100644 --- a/src/sys/svc/hasp_telnet.h +++ b/src/sys/svc/hasp_telnet.h @@ -10,7 +10,7 @@ /* ===== Default Event Processors ===== */ void telnetSetup(); -void telnetLoop(void); +IRAM_ATTR void telnetLoop(void); void telnetEvery5Seconds(void); void telnetEverySecond(void); void telnetStart(void); From 0d8b3c2a669b98be5f28219037a194086e44800e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 04:19:27 +0200 Subject: [PATCH 125/227] Add defines --- user_setups/darwin_sdl/darwin_sdl_64bits.ini | 2 ++ user_setups/linux_sdl/linux_sdl_64bits.ini | 2 ++ user_setups/win32/windows_sdl_64bits.ini | 2 ++ 3 files changed, 6 insertions(+) diff --git a/user_setups/darwin_sdl/darwin_sdl_64bits.ini b/user_setups/darwin_sdl/darwin_sdl_64bits.ini index caea972a..4fe98cc7 100644 --- a/user_setups/darwin_sdl/darwin_sdl_64bits.ini +++ b/user_setups/darwin_sdl/darwin_sdl_64bits.ini @@ -31,7 +31,9 @@ build_flags = -D HASP_USE_DEBUG=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 + -D HASP_ATTRIBUTE_FAST_MEM= -D IRAM_ATTR= ; No IRAM_ATTR available + -D PROGMEM= ; No PROGMEM available ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO ;-D LV_LOG_PRINTF=1 ; Add recursive dirs for hal headers search diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini index 1e0c7557..f900faa1 100644 --- a/user_setups/linux_sdl/linux_sdl_64bits.ini +++ b/user_setups/linux_sdl/linux_sdl_64bits.ini @@ -30,7 +30,9 @@ build_flags = -D HASP_USE_DEBUG=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 + -D HASP_ATTRIBUTE_FAST_MEM= -D IRAM_ATTR= ; No IRAM_ATTR available + -D PROGMEM= ; No PROGMEM available ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO ;-D LV_LOG_PRINTF=1 ; Add recursive dirs for hal headers search diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini index 29f4adf8..1812618b 100644 --- a/user_setups/win32/windows_sdl_64bits.ini +++ b/user_setups/win32/windows_sdl_64bits.ini @@ -30,7 +30,9 @@ build_flags = -D HASP_USE_DEBUG=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 + -D HASP_ATTRIBUTE_FAST_MEM= -D IRAM_ATTR= ; No IRAM_ATTR available + -D PROGMEM= ; No PROGMEM available ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO ;-D LV_LOG_PRINTF=1 ; Add recursive dirs for hal headers search From 21bbdb9c32f6576bb9d29d519c09b83318b751d4 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 04:19:41 +0200 Subject: [PATCH 126/227] Cleanup headers --- include/hasp_conf.h | 8 +++++ src/hasp/hasp.h | 5 +-- src/hasp/hasp_dispatch.h | 3 +- src/hasp/hasp_object.h | 71 +++++++++++++++++++------------------- src/hasp/hasp_parser.h | 3 +- src/mqtt/hasp_mqtt.h | 4 +-- src/sys/gpio/hasp_gpio.cpp | 4 +-- src/sys/gpio/hasp_gpio.h | 2 +- 8 files changed, 50 insertions(+), 50 deletions(-) diff --git a/include/hasp_conf.h b/include/hasp_conf.h index ba2bbfff..6501e974 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -240,6 +240,14 @@ static WiFiSpiClass WiFi; #include "sys/svc/hasp_slave.h" #endif +#ifndef HASP_ATTRIBUTE_FAST_MEM +#define HASP_ATTRIBUTE_FAST_MEM +#endif + +#ifndef IRAM_ATTR +#define IRAM_ATTR +#endif + #ifndef FPSTR #define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer)) #endif diff --git a/src/hasp/hasp.h b/src/hasp/hasp.h index 7a946d4b..0db81f9f 100644 --- a/src/hasp/hasp.h +++ b/src/hasp/hasp.h @@ -8,10 +8,7 @@ #include "Arduino.h" #endif -#include "lvgl.h" -#include "hasp_conf.h" - -#include "hasp_conf.h" +#include "hasplib.h" #if HASP_USE_DEBUG > 0 #include "../hasp_debug.h" diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index edc805c5..75f36650 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -4,8 +4,7 @@ #ifndef HASP_DISPATCH_H #define HASP_DISPATCH_H -#include "ArduinoJson.h" -#include "lvgl.h" +#include "hasplib.h" struct dispatch_conf_t { diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index 2b2eecc1..4dcbe5bb 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -4,8 +4,7 @@ #ifndef HASP_OBJECT_H #define HASP_OBJECT_H -#include -#include "lvgl.h" +#include "hasplib.h" const char FP_PAGE[] PROGMEM = "page"; const char FP_ID[] PROGMEM = "id"; @@ -15,50 +14,50 @@ const char FP_PARENTID[] PROGMEM = "parentid"; const char FP_GROUPID[] PROGMEM = "groupid"; enum lv_hasp_obj_type_t { + /* Containers */ + LV_HASP_SCREEN = 1, + LV_HASP_CONTAINER = 2, + LV_HASP_WINDOW = 3, // placeholder + LV_HASP_MSGBOX = 4, // placeholder + LV_HASP_TILEVIEW = 5, // placeholder + LV_HASP_TABVIEW = 6, // placeholder + LV_HASP_TAB = 7, // placeholder + LV_HASP_PAGE = 8, // Obsolete in v8 + /* Controls */ - LV_HASP_OBJECT = 91, // 10 - LV_HASP_BUTTON = 10, // 12 + LV_HASP_OBJECT = 11, + LV_HASP_BUTTON = 12, LV_HASP_BTNMATRIX = 13, LV_HASP_IMGBTN = 14, // placeholder - LV_HASP_CHECKBOX = 11, // 15 - LV_HASP_SWITCH = 40, // 16 - LV_HASP_SLIDER = 30, // 17 + LV_HASP_CHECKBOX = 15, + LV_HASP_SWITCH = 16, + LV_HASP_SLIDER = 17, LV_HASP_TEXTAREA = 18, // placeholder LV_HASP_SPINBOX = 19, // placeholder LV_HASP_CPICKER = 20, - /* Selectors */ - LV_HASP_DROPDOWN = 50, - LV_HASP_ROLLER = 51, - LV_HASP_LIST = 52, // placeholder - LV_HASP_TABLE = 53, - LV_HASP_CALENDER = 54, - - /* Containers */ - LV_HASP_SCREEN = 1, - LV_HASP_CONTAINER = 70, - LV_HASP_WINDOW = 71, // placeholder - LV_HASP_MSGBOX = 72, // placeholder - LV_HASP_TILEVIEW = 73, // placeholder - LV_HASP_TABVIEW = 74, // placeholder - LV_HASP_TAB = 75, // placeholder - LV_HASP_PAGE = 79, // Obsolete in v8 - /* Visualizers */ - LV_HASP_LABEL = 12, // 30 - LV_HASP_GAUGE = 31, - LV_HASP_BAR = 32, - LV_HASP_LMETER = 33, - LV_HASP_LED = 41, // 34 - LV_HASP_ARC = 22, // 35 - LV_HASP_SPINNER = 21, // 36 - LV_HASP_CHART = 37, + LV_HASP_LABEL = 21, + LV_HASP_GAUGE = 22, + LV_HASP_BAR = 23, + LV_HASP_LMETER = 24, + LV_HASP_LED = 25, + LV_HASP_ARC = 26, + LV_HASP_SPINNER = 27, + LV_HASP_CHART = 28, + + /* Selectors */ + LV_HASP_DROPDOWN = 29, + LV_HASP_ROLLER = 30, + LV_HASP_LIST = 31, // placeholder + LV_HASP_TABLE = 32, + LV_HASP_CALENDER = 33, /* Graphics */ - LV_HASP_LINE = 60, - LV_HASP_IMAGE = 61, // placeholder - LV_HASP_CANVAS = 62, // placeholder - LV_HASP_MASK = 63, // placeholder + LV_HASP_LINE = 36, + LV_HASP_IMAGE = 37, // placeholder + LV_HASP_CANVAS = 38, // placeholder + LV_HASP_MASK = 39, // placeholder }; void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id); diff --git a/src/hasp/hasp_parser.h b/src/hasp/hasp_parser.h index 862ee32f..3a2e0118 100644 --- a/src/hasp/hasp_parser.h +++ b/src/hasp/hasp_parser.h @@ -4,8 +4,7 @@ #ifndef HASP_PARSER_H #define HASP_PARSER_H -#include "lvgl.h" -#include "hasp_conf.h" +#include "hasplib.h" class Parser { diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h index af0f02b7..5c8b6f37 100644 --- a/src/mqtt/hasp_mqtt.h +++ b/src/mqtt/hasp_mqtt.h @@ -5,9 +5,7 @@ #define HASP_MQTT_H #include -#include "ArduinoJson.h" - -#include "hasp_conf.h" +#include "hasplib.h" // #if defined(WINDOWS) || defined(POSIX) // #define __FlashStringHelper char diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 44912d9f..b613ca50 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -4,6 +4,7 @@ #include "lv_conf.h" // For timing defines #include "hasplib.h" + #include "hasp_gpio.h" #include "hasp_config.h" @@ -537,8 +538,7 @@ void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, i // Set all pins first, minimizes delays for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { hasp_gpio_config_t* gpio = &gpioConfig[k]; - if(gpio->group == group && // group members that are outputs - gpioConfigInUse(k)) + if(gpio->group == group && gpioConfigInUse(k)) // group members that are outputs gpio_set_normalized_value(gpio, val, min, max); } diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index 25de68b5..8ff2fad3 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -4,7 +4,7 @@ #ifndef HASP_GPIO_H #define HASP_GPIO_H -#include "ArduinoJson.h" +#include "hasplib.h" #ifdef __cplusplus extern "C" { From 983c66e490f064d524ffe543d68902796ee5a50a Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 05:07:31 +0200 Subject: [PATCH 127/227] Add D_INFO_FULL_DUPLEX --- src/lang/en_US.h | 1 + src/lang/hu_HU.h | 19 ++++++++++--------- src/lang/nl_NL.h | 1 + src/lang/ro_RO.h | 1 + src/sys/svc/hasp_http.cpp | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/lang/en_US.h b/src/lang/en_US.h index 0cd8f7e1..0328006a 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -167,6 +167,7 @@ #define D_INFO_ETHERNET "Ethernet" #define D_INFO_WIFI "Wifi" #define D_INFO_LINK_SPEED "Link Speed" +#define D_INFO_FULL_DUPLEX "Full Duplex" #define D_INFO_SSID "SSID" #define D_INFO_RSSI "Signal Strength" #define D_INFO_IP_ADDRESS "IP Address" diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index f315bb06..a9e0ca36 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -4,8 +4,8 @@ #define D_USERNAME "Felhasználónév:" #define D_PASSWORD "Jelszó:" #define D_SSID "SSID:" -#define D_YES "Igen" -#define D_NO "Nem" +#define D_YES "Igen" +#define D_NO "Nem" #define D_ERROR_OUT_OF_MEMORY "Elfogyott a memória" #define D_ERROR_UNKNOWN "Ismeretlen hiba" @@ -30,8 +30,8 @@ #define D_SERVICE_CONNECTED "Csatlakoztatva" #define D_SERVICE_DISCONNECTED "Szétkapcsolva" -#define D_SETTING_ENABLED "Engedélyezve" -#define D_SETTING_DISABLED "Letiltva" +#define D_SETTING_ENABLED "Engedélyezve" +#define D_SETTING_DISABLED "Letiltva" #define D_NETWORK_IP_ADDRESS_RECEIVED "Beállított IP-cím: %s" #define D_NETWORK_ONLINE "online" @@ -52,7 +52,7 @@ #define D_MQTT_SUBSCRIBED "Feliratkozva: %s" #define D_MQTT_NOT_SUBSCRIBED "Nem sikerült feliratkozni: %s" #define D_MQTT_HA_AUTO_DISCOVERY "Regisztrálás HA automatikus felfedezésre" -#define D_MQTT_PAYLOAD_TOO_LONG "Túl hosszú payload (%u bájt)" +#define D_MQTT_PAYLOAD_TOO_LONG "Túl hosszú payload (%u bájt)" #define D_TELNET_CLOSING_CONNECTION "Munkamenet befejezése %s-el" #define D_TELNET_CLIENT_LOGIN_FROM "Kliens bejelentkezés innen: %s" @@ -102,8 +102,8 @@ #define D_OTA_UPDATE_COMPLETE "Az OTA frissítés elkészült" #define D_OTA_UPDATE_APPLY "Firmware alkalmazása és újraindítás" #define D_OTA_UPDATE_FAILED "Az OTA frissítés meghiúsult" -#define D_OTA_UPDATING_FIRMWARE "Firmware frissítés..." -#define D_OTA_UPDATING_FILESYSTEM "Fájlrendszer frissítés..." +#define D_OTA_UPDATING_FIRMWARE "Firmware frissítés..." +#define D_OTA_UPDATING_FILESYSTEM "Fájlrendszer frissítés..." #define D_HTTP_HASP_DESIGN "Képernyő dizájn" #define D_HTTP_INFORMATION "Információk" @@ -132,7 +132,7 @@ #define D_HTTP_MAIN_MENU "Főmenü" #define D_HTTP_REBOOT "Újraindítás" #define D_HTTP_CONFIGURATION "Beállítások" -#define D_HTTP_SENDING_PAGE "%S oldal küldése %s-re" +#define D_HTTP_SENDING_PAGE "%S oldal küldése %s-re" #define D_HTTP_FOOTER "készítette: Francis Van Roie" #define D_INFO_VERSION "Verziószám" @@ -167,6 +167,7 @@ #define D_INFO_ETHERNET "Ethernet" #define D_INFO_WIFI "WiFi" #define D_INFO_LINK_SPEED "Linksebesség" +#define D_INFO_FULL_DUPLEX "Full Duplex" // new #define D_INFO_SSID "SSID" #define D_INFO_RSSI "Jelerősség" #define D_INFO_IP_ADDRESS "IP cím" @@ -178,7 +179,7 @@ #define D_OOBE_SCAN_TO_CONNECT "Szkennelje le a csatlakozáshoz:" #define D_WIFI_CONNECTING_TO "Csatlakozás %s-hez" -#define D_WIFI_CONNECTED_TO "Csatlakozva %s-hez, IP cím kérése..." +#define D_WIFI_CONNECTED_TO "Csatlakozva %s-hez, IP cím kérése..." #define D_WIFI_RSSI_EXCELLENT "Kiváló" #define D_WIFI_RSSI_GOOD "Jó" #define D_WIFI_RSSI_FAIR "Elfogadható" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index 4e4c6eac..d3abcde6 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -166,6 +166,7 @@ #define D_INFO_ETHERNET "Ethernet" #define D_INFO_WIFI "Wifi" #define D_INFO_LINK_SPEED "Snelheid" +#define D_INFO_FULL_DUPLEX "Full Duplex" #define D_INFO_SSID "SSID" #define D_INFO_RSSI "Signaalsterkte" #define D_INFO_IP_ADDRESS "IP Adres" diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 205f7a3a..7f9f4454 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -167,6 +167,7 @@ #define D_INFO_ETHERNET "Ethernet" #define D_INFO_WIFI "WiFi" #define D_INFO_LINK_SPEED "Viteză Link" +#define D_INFO_FULL_DUPLEX "Full Duplex" // new #define D_INFO_SSID "SSID" #define D_INFO_RSSI "Putere semnal" #define D_INFO_IP_ADDRESS "Addresa IP" diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 5bfc57ea..b5732e24 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -744,7 +744,7 @@ void webHandleInfo() httpMessage += String(ETH.linkSpeed()); httpMessage += F(" Mbps"); if(ETH.fullDuplex()) { - httpMessage += F(" FULL_DUPLEX"); + httpMessage += F(" " D_INFO_FULL_DUPLEX); } httpMessage += F("
IP Address: "); httpMessage += String(ETH.localIP().toString()); From 95c37d72fc0362ceccd5eddff2c9a6222d25ef60 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 06:32:27 +0200 Subject: [PATCH 128/227] Add GPIO strings --- src/hasp/hasp.cpp | 4 +-- src/lang/en_US.h | 16 +++++++++ src/lang/hu_HU.h | 16 +++++++++ src/lang/nl_NL.h | 15 +++++++++ src/lang/ro_RO.h | 16 +++++++++ src/sys/svc/hasp_http.cpp | 68 ++++++++++++++++++--------------------- 6 files changed, 97 insertions(+), 38 deletions(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 390139f5..e2c67266 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -233,8 +233,8 @@ void haspProgressVal(uint8_t val) lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0); // lv_obj_set_style_local_value_str(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, ""); - // lv_obj_set_value_str_txt(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL); //TODO: call our custom - // function to free the memory + // lv_obj_set_value_str_txt(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL); + // TODO: call our custom function to free the memory #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) // progress_str.clear(); diff --git a/src/lang/en_US.h b/src/lang/en_US.h index 0328006a..3e02d12c 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -186,4 +186,20 @@ #define D_WIFI_RSSI_WEAK "Weak" #define D_WIFI_RSSI_BAD "Very bad" +// new +#define D_GPIO_SWITCH "Switch" +#define D_GPIO_BUTTON "Button" +#define D_GPIO_LED "Led" +#define D_GPIO_LED_R "Mood Red" +#define D_GPIO_LED_G "Mood Green" +#define D_GPIO_LED_B "Mood Blue" +#define D_GPIO_RELAY "Relay" +#define D_GPIO_PWM "PWM" +#define D_GPIO_DAC "DAC" +#define D_GPIO_SERIAL_DIMMER "Serial Dimmer" +#define D_GPIO_UNKNOWN "Unknown" +#define D_GPIO_PIN "Pin" +#define D_GPIO_GROUP "Group" +#define D_GPIO_GROUP_NONE "None" + #endif \ No newline at end of file diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index a9e0ca36..9628c839 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -186,4 +186,20 @@ #define D_WIFI_RSSI_WEAK "Gyenge" #define D_WIFI_RSSI_BAD "Rossz" +// new +#define D_GPIO_SWITCH "Switch" +#define D_GPIO_BUTTON "Button" +#define D_GPIO_LED "Led" +#define D_GPIO_LED_R "Mood Red" +#define D_GPIO_LED_G "Mood Green" +#define D_GPIO_LED_B "Mood Blue" +#define D_GPIO_RELAY "Relay" +#define D_GPIO_PWM "PWM" +#define D_GPIO_DAC "DAC" +#define D_GPIO_SERIAL_DIMMER "Serial Dimmer" +#define D_GPIO_UNKNOWN "Unknown" +#define D_GPIO_PIN "Pin" +#define D_GPIO_GROUP "Group" +#define D_GPIO_GROUP_NONE "None" + #endif diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index d3abcde6..4a153405 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -185,4 +185,19 @@ #define D_WIFI_RSSI_WEAK "Zwak" #define D_WIFI_RSSI_BAD "Zeer Slecht" +#define D_GPIO_SWITCH "Schakelaar" +#define D_GPIO_BUTTON "Drukknop" +#define D_GPIO_LED "Led" +#define D_GPIO_LED_R "Sfeer Rood" +#define D_GPIO_LED_G "Sfeer Groen" +#define D_GPIO_LED_B "Sfeer Blauw" +#define D_GPIO_RELAY "Relay" +#define D_GPIO_PWM "PWM" +#define D_GPIO_DAC "DAC" +#define D_GPIO_SERIAL_DIMMER "Seriële Dimmer" +#define D_GPIO_UNKNOWN "Onbekend" +#define D_GPIO_PIN "Pin" +#define D_GPIO_GROUP "Groep" +#define D_GPIO_GROUP_NONE "Geen" + #endif \ No newline at end of file diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 7f9f4454..1ba6e6d5 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -186,4 +186,20 @@ #define D_WIFI_RSSI_WEAK "Slabă" #define D_WIFI_RSSI_BAD "Foarte slabă" +// new +#define D_GPIO_SWITCH "Switch" +#define D_GPIO_BUTTON "Button" +#define D_GPIO_LED "Led" +#define D_GPIO_LED_R "Mood Red" +#define D_GPIO_LED_G "Mood Green" +#define D_GPIO_LED_B "Mood Blue" +#define D_GPIO_RELAY "Relay" +#define D_GPIO_PWM "PWM" +#define D_GPIO_DAC "DAC" +#define D_GPIO_SERIAL_DIMMER "Serial Dimmer" +#define D_GPIO_UNKNOWN "Unknown" +#define D_GPIO_PIN "Pin" +#define D_GPIO_GROUP "Group" +#define D_GPIO_GROUP_NONE "None" + #endif diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index b5732e24..016fe261 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1536,7 +1536,8 @@ void webHandleGpioConfig() httpMessage += F("
"); - httpMessage += F(""); + httpMessage += F("
PinTypeGroupDefaultAction
"); for(uint8_t gpio = 0; gpio < NUM_DIGITAL_PINS; gpio++) { for(uint8_t id = 0; id < HASP_NUM_GPIO_CONFIG; id++) { @@ -1549,42 +1550,37 @@ void webHandleGpioConfig() switch(conf.type) { case HASP_GPIO_SWITCH: - httpMessage += F("Switch"); + httpMessage += F(D_GPIO_SWITCH); break; case HASP_GPIO_BUTTON: - httpMessage += F("Button"); + httpMessage += F(D_GPIO_BUTTON); break; case HASP_GPIO_LED: - httpMessage += F("Led"); + httpMessage += F(D_GPIO_LED); break; case HASP_GPIO_LED_R: + httpMessage += F(D_GPIO_LED_R); + break; case HASP_GPIO_LED_G: + httpMessage += F(D_GPIO_LED_G); + break; case HASP_GPIO_LED_B: - httpMessage += F("Mood "); + httpMessage += F(D_GPIO_LED_B); break; case HASP_GPIO_RELAY: - httpMessage += F("Relay"); + httpMessage += F(D_GPIO_RELAY); break; case HASP_GPIO_PWM: - httpMessage += F("PWM"); + httpMessage += F(D_GPIO_PWM); + break; + case HASP_GPIO_DAC: + httpMessage += F(D_GPIO_DAC); break; case HASP_GPIO_SERIAL_DIMMER: - httpMessage += F("Serial Dimmer"); + httpMessage += F(D_GPIO_SERIAL_DIMMER); break; default: - httpMessage += F("Unknown"); - } - - switch(conf.type) { - case HASP_GPIO_LED_R: - httpMessage += F("Red"); - break; - case HASP_GPIO_LED_G: - httpMessage += F("Green"); - break; - case HASP_GPIO_LED_B: - httpMessage += F("Blue"); - break; + httpMessage += F(D_GPIO_UNKNOWN); } httpMessage += F("
" D_GPIO_PIN "Type" D_GPIO_GROUP + "DefaultAction
"); @@ -1651,7 +1647,7 @@ void webHandleGpioOptions() httpMessage += config_id; httpMessage += F(" Options

"); - httpMessage += F("

Pin "); hasp_gpio_config_t conf = gpioGetPinConfig(config_id); for(uint8_t io = 0; io < NUM_DIGITAL_PINS; io++) { @@ -1665,44 +1661,44 @@ void webHandleGpioOptions() httpMessage += F("

Type

"); - httpMessage += F("

Group "); + httpMessage += getOption(0, F(D_GPIO_GROUP_NONE), conf.group == 0); String group((char*)0); group.reserve(10); for(int i = 1; i < 15; i++) { - group = F("Group "); + group = F(D_GPIO_GROUP " "); group += i; httpMessage += getOption(i, group, conf.group == i); } From 04ac201fb2a2e68080de6e22de38aa19458c0694 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 06:47:21 +0200 Subject: [PATCH 129/227] Added more translations --- src/drv/touch/hasp_drv_stmpe610.cpp | 7 +++++-- src/lang/en_US.h | 1 + src/lang/hu_HU.h | 1 + src/lang/nl_NL.h | 1 + src/lang/ro_RO.h | 1 + src/sys/svc/hasp_http.cpp | 2 +- 6 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/drv/touch/hasp_drv_stmpe610.cpp b/src/drv/touch/hasp_drv_stmpe610.cpp index 7aa361f4..3815135b 100644 --- a/src/drv/touch/hasp_drv_stmpe610.cpp +++ b/src/drv/touch/hasp_drv_stmpe610.cpp @@ -1,5 +1,7 @@ #if TOUCH_DRIVER == 610 +#include "hasp_conf.h" + #include #include "Adafruit_STMPE610.h" #include "ArduinoLog.h" @@ -59,10 +61,11 @@ HASP_ATTRIBUTE_FAST_MEM bool STMPE610_getXY(int16_t* touchX, int16_t* touchY, ui void STMPE610_init() { + LOG_INFO(TAG_DRVR, F("STMPE610 " D_SERVICE_STARTING)); if(!touch.begin()) { - Log.trace(TAG_DRVR, F("STMPE610 not found!")); + LOG_ERROR(TAG_DRVR, F("STMPE610 " D_SERVICE_START_FAILED)); } else { - Log.trace(TAG_DRVR, F("STMPE610 touch driver started")); + LOG_INFO(TAG_DRVR, F("STMPE610 " D_SERVICE_STARTED)); } } #endif \ No newline at end of file diff --git a/src/lang/en_US.h b/src/lang/en_US.h index 3e02d12c..bc0116f2 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -21,6 +21,7 @@ #define D_FILE_SAVING "Saving %s" #define D_FILE_SAVED "Saved %s" #define D_FILE_SAVE_FAILED "Failed to save %s" +#define D_FILE_NOT_FOUND "File not found" // new #define D_SERVICE_STARTING "Starting..." #define D_SERVICE_STARTED "Started" diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index 9628c839..835fa205 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -17,6 +17,7 @@ #define D_FILE_LOADING "%s betöltése" #define D_FILE_LOADED "%s betöltve" #define D_FILE_LOAD_FAILED "%s betöltése nem sikerült" +#define D_FILE_NOT_FOUND "File not found" // new #define D_FILE_SAVING "%s mentése" #define D_FILE_SAVED "%s mentve" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index 4a153405..b55e6596 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -21,6 +21,7 @@ #define D_FILE_SAVING "%s bewaren..." #define D_FILE_SAVED "%s bewaard" #define D_FILE_SAVE_FAILED "%s bewaren mislukt" +#define D_FILE_NOT_FOUND "Bestand niet gevonden" // new #define D_SETTING_ENABLED "Ingeschakeld" #define D_SETTING_DISABLED "Uitgeschakeld" diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 1ba6e6d5..2795f3a9 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -21,6 +21,7 @@ #define D_FILE_SAVING "Se salvează %s" #define D_FILE_SAVED "S-a salvat %s" #define D_FILE_SAVE_FAILED "Salvarea %s a eșuat" +#define D_FILE_NOT_FOUND "File not found" // new #define D_SETTING_ENABLED "Activ" #define D_SETTING_DISABLED "Inactiv" diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 016fe261..68c44f3f 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1920,7 +1920,7 @@ void httpHandleNotFound() if(statuscode == 500) httpMessage += F("Internal Server Error"); else - httpMessage += F("File Not Found"); + httpMessage += F(D_FILE_NOT_FOUND); httpMessage += F("\n\nURI: "); httpMessage += webServer.uri(); From 6662d07c2de15e2007c813a94f2e0a1d001dafca Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 17:57:45 +0200 Subject: [PATCH 130/227] Update ArduinoJson and TFT_eSPI --- platformio.ini | 4 ++-- src/hasp/hasp_dispatch.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 04ca7d15..56c7f526 100644 --- a/platformio.ini +++ b/platformio.ini @@ -68,14 +68,14 @@ build_flags = ; Warning : don't put comments after github links => causes infinite download loop lib_deps = bxparks/AceButton@^1.8.3 ; GPIO button library - bblanchon/ArduinoJson@^6.17.3 ; Json(l) parser + bblanchon/ArduinoJson@^6.18.0 ; Json(l) parser bblanchon/StreamUtils@1.6.0 ; for EEPromStream knolleary/PubSubClient@^2.8.0 ; MQTT client git+https://github.com/fvanroie/ConsoleInput.git ;git+https://github.com/andrethomas/TasmotaSlave.git ;git+https://github.com/lvgl/lvgl.git lvgl/lvgl@^7.11.0 ; from PIO library - bodmer/TFT_eSPI@^2.3.66 + bodmer/TFT_eSPI@^2.3.67 ;git+https://github.com/Bodmer/TFT_eSPI.git ; ------ Unused / Test libraries ;https://github.com/netwizeBE/TFT_eSPI.git diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 7c7d83fc..33db5ee7 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -536,8 +536,8 @@ void dispatch_parse_json(const char*, const char* payload) } else if(json.is()) { // handle json as a single command dispatch_text_line(json.as()); - } else if(json.is()) { // handle json as a single command - dispatch_text_line(json.as()); + // } else if(json.is()) { // handle json as a single command + // dispatch_text_line(json.as()); } else { LOG_WARNING(TAG_MSGR, F(D_DISPATCH_COMMAND_NOT_FOUND), payload); From fdc8d86b3ff7c77d4a9035f87581fb75c767a36a Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 18:16:27 +0200 Subject: [PATCH 131/227] Restore the debugPrintHaspHeader --- src/hasp/hasp_dispatch.cpp | 4 ++++ src/hasp_debug.cpp | 39 ++++++++++++++++++++++++-------------- src/log/hasp_debug.cpp | 2 +- src/main_arduino.cpp | 4 ++-- src/main_sdl2.cpp | 2 ++ 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 33db5ee7..23946846 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -966,6 +966,8 @@ void dispatchSetup() // In order of importance : commands are NOT case-sensitive // The command.func() call will receive the full topic and payload parameters! + LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING)); + /* WARNING: remember to expand the commands array when adding new commands */ dispatch_add_command(PSTR("json"), dispatch_parse_json); dispatch_add_command(PSTR("page"), dispatch_page); @@ -989,6 +991,8 @@ void dispatchSetup() dispatch_add_command(PSTR("setupap"), oobeFakeSetup); #endif /* WARNING: remember to expand the commands array when adding new commands */ + + LOG_INFO(TAG_MSGR, F(D_SERVICE_STARTED)); } IRAM_ATTR void dispatchLoop() diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index d0e7611b..8064fa88 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -37,6 +37,7 @@ inline void debugSendAnsiCode(const __FlashStringHelper* code, Print* _logOutput #endif } +/* void debug_timestamp() { timeval curTime; @@ -48,7 +49,7 @@ void debug_timestamp() // strftime(currentTime, 80, "%Y-%m-%d %H:%M.%S", localtime(&t)); strftime(currentTime, 80, "%H:%M:%S", localtime(&t)); printf("[%s.%03d] ", currentTime, milli); -} +} */ static void debugPrintTimestamp(int level, Print* _logOutput) { /* Print Current Time */ @@ -64,8 +65,8 @@ static void debugPrintTimestamp(int level, Print* _logOutput) if(timeinfo->tm_year >= 120) { unsigned long int milli = curTime.tv_usec / 1000; char buffer[24]; - strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S", timeinfo); // Literal String - // strftime(buffer, sizeof(buffer), "[%H:%M:%S.", timeinfo); // Literal String + // strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S", timeinfo); // Literal String + strftime(buffer, sizeof(buffer), "[%H:%M:%S", timeinfo); // Literal String #ifdef ARDUINO _logOutput->printf(PSTR("%s.%03lu]"), buffer, milli); @@ -178,23 +179,33 @@ void debugLvglLogEvent(lv_log_level_t level, const char* file, uint32_t line, co // Send the HASP header and version to the output device specified void debugPrintHaspHeader(Print* output) { - // if(debugAnsiCodes) debug_print(output,TERM_COLOR_YELLOW); - - // debug_newline(output); - // debug_print(output, F("" - // " _____ _____ _____ _____\r\n" - // " | | | _ | __| _ |\r\n" - // " | | |__ | __|\r\n" - // " |__|__|__|__|_____|__|\r\n" - // " Home Automation Switch Plate\r\n" - // " Open Hardware edition v")); - char buffer[32]; + char buffer[16]; haspGetVersion(buffer, sizeof(buffer)); + #ifdef ARDUINO + if(debugAnsiCodes) output->print(TERM_COLOR_YELLOW); + output->println(); + output->print(F("\r\n" + " open____ _____ _____ _____\r\n" + " | | | _ | __| _ |\r\n" + " | | |__ | __|\r\n" + " |__|__|__|__|_____|__|\r\n" + " Home Automation Switch Plate\r\n" + " Open Hardware edition v")); output->println(buffer); + output->println(); #else + if(debugAnsiCodes) debug_print(output, TERM_COLOR_YELLOW); + debug_print(output, F("\r\n" + " open____ _____ _____ _____\r\n" + " | | | _ | __| _ |\r\n" + " | | |__ | __|\r\n" + " |__|__|__|__|_____|__|\r\n" + " Home Automation Switch Plate\r\n" + " Open Hardware edition v")); debug_print(output, buffer); debug_newline(output); + debug_newline(output); #endif } diff --git a/src/log/hasp_debug.cpp b/src/log/hasp_debug.cpp index ff00a1be..522c18a0 100644 --- a/src/log/hasp_debug.cpp +++ b/src/log/hasp_debug.cpp @@ -328,7 +328,7 @@ void debugSetupWithoutLogging(JsonObject settings) debugPrintHaspHeader(&Serial); Serial.flush(); - LOG_INFO(TAG_DEBG, F(D_SERVICE_STARTED " @ %u baud"), baudrate); + LOG_INFO(TAG_DEBG, F(D_SERVICE_STARTED " @ %u Bps"), baudrate); LOG_INFO(TAG_DEBG, F("Environment: " PIOENV)); } } diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index ae897bd6..4d3c23f6 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -57,9 +57,9 @@ void setup() configSetup(); // also runs debugSetupWithoutLogging(), debugSetup() and debugStart() #endif + dispatchSetup(); // before hasp and oobe, asap after logging starts guiSetup(); - debugSetup(); // Init the console - dispatchSetup(); // for hasp and oobe + debugSetup(); // Init the console #if HASP_USE_CONFIG > 0 if(!oobeSetup()) diff --git a/src/main_sdl2.cpp b/src/main_sdl2.cpp index 97f96586..75ce1ae9 100644 --- a/src/main_sdl2.cpp +++ b/src/main_sdl2.cpp @@ -276,7 +276,9 @@ int main(int argc, char* argv[]) // printf("%s %d\n", __FILE__, __LINE__); // fflush(stdout); + debugPrintHaspHeader(stdout); LOG_NOTICE(TAG_MAIN, "pre setup"); + setup(); LOG_TRACE(TAG_MAIN, "loop started"); From 55d45f29c8fbda9df1c7f7fd04510732170bc35d Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 18:19:32 +0200 Subject: [PATCH 132/227] Fix compiler warnings --- src/hasp/hasp_event.cpp | 4 ++-- src/hasp_debug.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index fe8ad4e4..4c27d210 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -70,7 +70,7 @@ void event_timer_calendar(lv_task_t* task) int rslt = gettimeofday(&curTime, NULL); time_t t = curTime.tv_sec; tm* timeinfo = localtime(&t); - (void*)rslt; + (void)rslt; // unused if(timeinfo->tm_year < 120) { lv_task_set_period(task, 60000); // try again in a minute @@ -100,7 +100,7 @@ void event_timer_clock(lv_task_t* task) int rslt = gettimeofday(&curTime, NULL); time_t seconds = curTime.tv_sec; tm* timeinfo = localtime(&seconds); - (void*)rslt; + (void)rslt; // unused if(timeinfo->tm_year < 120) { lv_task_set_period(task, 60000); // try again in a minute diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 8064fa88..85383777 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -58,7 +58,7 @@ static void debugPrintTimestamp(int level, Print* _logOutput) int rslt = gettimeofday(&curTime, NULL); time_t t = curTime.tv_sec; tm* timeinfo = localtime(&t); - (void*)rslt; + (void)rslt; // unused debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput); From 8fbab678b3fbaa64c73b435de93b6f3013def40c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 18:30:15 +0200 Subject: [PATCH 133/227] Add D_TIMESTAMP to lang.h --- src/hasp_debug.cpp | 6 +++--- src/lang/lang.h | 13 ++++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 85383777..12fe6258 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -66,7 +66,7 @@ static void debugPrintTimestamp(int level, Print* _logOutput) unsigned long int milli = curTime.tv_usec / 1000; char buffer[24]; // strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S", timeinfo); // Literal String - strftime(buffer, sizeof(buffer), "[%H:%M:%S", timeinfo); // Literal String + strftime(buffer, sizeof(buffer), "[" D_TIMESTAMP, timeinfo); // Literal String #ifdef ARDUINO _logOutput->printf(PSTR("%s.%03lu]"), buffer, milli); @@ -78,9 +78,9 @@ static void debugPrintTimestamp(int level, Print* _logOutput) uint32_t msecs = millis(); #ifdef ARDUINO - _logOutput->printf(PSTR("[%15d.%03d]"), msecs / 1000, msecs % 1000); + _logOutput->printf(PSTR("[" D_TIME_MILLIS ".%03d]"), msecs / 1000, msecs % 1000); #else - debug_print(_logOutput, PSTR("[%15d.%03d]"), msecs / 1000, msecs % 1000); + debug_print(_logOutput, PSTR("[" D_TIME_MILLIS ".%03d]"), msecs / 1000, msecs % 1000); #endif } } diff --git a/src/lang/lang.h b/src/lang/lang.h index 74b95923..7be7e779 100644 --- a/src/lang/lang.h +++ b/src/lang/lang.h @@ -2,12 +2,12 @@ #define HASP_LANG_H #ifndef HASP_LANGUAGE - #include "en_US.h" +#include "en_US.h" #else - #define QUOTEME(x) QUOTEME_1(x) - #define QUOTEME_1(x) #x - #define INCLUDE_FILE(x) QUOTEME(x.h) - #include INCLUDE_FILE(HASP_LANGUAGE) +#define QUOTEME(x) QUOTEME_1(x) +#define QUOTEME_1(x) #x +#define INCLUDE_FILE(x) QUOTEME(x.h) +#include INCLUDE_FILE(HASP_LANGUAGE) #endif // language independent defines @@ -15,4 +15,7 @@ #define D_BULLET " * " #define D_MANUFACTURER "openHASP" +#define D_TIMESTAMP "%H:%M:%S" // Used when reference time is set from NTP +#define D_TIME_MILLIS "%8d" // Used when no reference clock could be set + #endif \ No newline at end of file From 76ae1560189a4a7a847ab2785b82ad3b15b2cdf3 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 21:26:11 +0200 Subject: [PATCH 134/227] Add separate hasp_console --- include/hasp_conf.h | 8 ++++ src/hasp_config.cpp | 4 +- src/hasp_debug.cpp | 5 ++- src/hasp_debug.h | 10 ++--- src/log/hasp_debug.cpp | 49 ++++++++-------------- src/main_arduino copy.cpp | 3 +- src/main_arduino.cpp | 13 ++++-- src/main_sdl2.cpp | 2 - src/sys/svc/hasp_console.cpp | 78 ++++++++++++++++++++++++++++++++++++ src/sys/svc/hasp_console.h | 36 +++++++++++++++++ 10 files changed, 160 insertions(+), 48 deletions(-) create mode 100644 src/sys/svc/hasp_console.cpp create mode 100644 src/sys/svc/hasp_console.h diff --git a/include/hasp_conf.h b/include/hasp_conf.h index 6501e974..af8c8473 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -63,6 +63,10 @@ #define HASP_USE_TELNET 0 #endif +#ifndef HASP_USE_CONSOLE +#define HASP_USE_CONSOLE 1 +#endif + /* Filesystem */ #define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0) @@ -217,6 +221,10 @@ static WiFiSpiClass WiFi; #include "sys/svc/hasp_http.h" #endif +#if HASP_USE_CONSOLE > 0 +#include "sys/svc/hasp_console.h" +#endif + #if HASP_USE_TELNET > 0 #include "sys/svc/hasp_telnet.h" #endif diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 2e3d678b..3b315507 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -76,7 +76,7 @@ bool configSet(uint16_t& value, const JsonVariant& setting, const __FlashStringH void configSetupDebug(JsonDocument& settings) { - debugSetupWithoutLogging(settings[FPSTR(FP_DEBUG)]); + debugSetup(settings[FPSTR(FP_DEBUG)]); debugStart(); // Debug started, now we can use it; HASP header sent } @@ -158,7 +158,7 @@ DeserializationError configRead(JsonDocument& settings, bool setupdebug = false) configRestorePasswords(settings, wifiPass, mqttPass, httpPass); LOG_INFO(TAG_CONF, F(D_FILE_LOADED), configFile.c_str()); - if(setupdebug) debugSetup(); + // if(setupdebug) debugSetup(); return error; } diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 12fe6258..1fbc44a8 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -86,8 +86,6 @@ static void debugPrintTimestamp(int level, Print* _logOutput) } /* ===== Default Event Processors ===== */ -// void debugSetupWithoutLogging(JsonObject settings); -// void debugSetup(); static inline void debug_flush() { @@ -243,6 +241,9 @@ void debug_get_tag(uint8_t tag, char* buffer) memcpy_P(buffer, PSTR("HAL "), 5); break; + case TAG_CONS: + memcpy_P(buffer, PSTR("CONS"), 5); + break; case TAG_DEBG: memcpy_P(buffer, PSTR("DBUG"), 5); break; diff --git a/src/hasp_debug.h b/src/hasp_debug.h index 1e5e4055..c60ffc13 100644 --- a/src/hasp_debug.h +++ b/src/hasp_debug.h @@ -14,8 +14,7 @@ #include "ArduinoLog.h" /* ===== Default Event Processors ===== */ -void debugSetupWithoutLogging(JsonObject settings); -void debugSetup(); +void debugSetup(JsonObject settings); /* ===== Special Event Processors ===== */ @@ -163,9 +162,10 @@ enum { TAG_EVENT = 8, TAG_DEBG = 10, - TAG_TELN = 11, - TAG_SYSL = 12, - TAG_TASM = 13, + TAG_CONS = 11, + TAG_TELN = 12, + TAG_SYSL = 13, + TAG_TASM = 14, TAG_CONF = 20, TAG_GUI = 21, diff --git a/src/log/hasp_debug.cpp b/src/log/hasp_debug.cpp index 522c18a0..3e41b88b 100644 --- a/src/log/hasp_debug.cpp +++ b/src/log/hasp_debug.cpp @@ -39,10 +39,6 @@ #include "hasp/hasp_dispatch.h" #include "hasp/hasp.h" -// #ifdef USE_CONFIG_OVERRIDE -// #include "user_config_override.h" -// #endif - #ifndef SERIAL_SPEED #define SERIAL_SPEED 115200 #endif @@ -66,7 +62,6 @@ // static String debugOutput((char *)0); // static StringStream debugStream((String &)debugOutput); -// extern char mqttNodeName[16]; // const char* syslogAppName = APP_NAME; char debugSyslogHost[32] = SYSLOG_SERVER; uint16_t debugSyslogPort = SYSLOG_PORT; @@ -92,9 +87,6 @@ uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10 extern bool debugSerialStarted; extern bool debugAnsiCodes; -ConsoleInput debugConsole(&Serial, HASP_CONSOLE_BUFFER); - -unsigned long debugLastMillis = 0; extern dispatch_conf_t dispatch_setings; // #if HASP_USE_SYSLOG > 0 @@ -106,14 +98,6 @@ extern dispatch_conf_t dispatch_setings; // } // #endif -void debugSetup() -{ - // memset(serialInputBuffer, 0, sizeof(serialInputBuffer)); - // serialInputIndex = 0; - LOG_TRACE(TAG_DEBG, F(D_SERVICE_STARTING)); // Starting console - debugConsole.setLineCallback(dispatch_text_line); -} - void debugStartSyslog() { @@ -293,13 +277,14 @@ void debugPrintSuffix(uint8_t tag, int level, Print* _logOutput) _logOutput->println(); if(_logOutput == &Serial) { - debugConsole.update(); + console_update_prompt(); } else { _logOutput->print("hasp > "); } } -void debugSetupWithoutLogging(JsonObject settings) +// Do NOT call Log function before debugSetup is called +void debugSetup(JsonObject settings) { Log.begin(LOG_LEVEL_WARNING, true); Log.setPrefix(debugPrintPrefix); // Uncomment to get timestamps as prefix @@ -335,23 +320,23 @@ void debugSetupWithoutLogging(JsonObject settings) IRAM_ATTR void debugLoop(void) { - int16_t keypress; - do { - switch(keypress = debugConsole.readKey()) { + /* int16_t keypress; + do { + switch(keypress = debugConsole.readKey()) { - case ConsoleInput::KEY_PAGE_UP: - dispatch_page_next(LV_SCR_LOAD_ANIM_NONE); - break; + case ConsoleInput::KEY_PAGE_UP: + dispatch_page_next(LV_SCR_LOAD_ANIM_NONE); + break; - case ConsoleInput::KEY_PAGE_DOWN: - dispatch_page_prev(LV_SCR_LOAD_ANIM_NONE); - break; + case ConsoleInput::KEY_PAGE_DOWN: + dispatch_page_prev(LV_SCR_LOAD_ANIM_NONE); + break; - case(ConsoleInput::KEY_FN)...(ConsoleInput::KEY_FN + 12): - dispatch_set_page(keypress - ConsoleInput::KEY_FN, LV_SCR_LOAD_ANIM_NONE); - break; - } - } while(keypress != 0); + case(ConsoleInput::KEY_FN)...(ConsoleInput::KEY_FN + 12): + dispatch_set_page(keypress - ConsoleInput::KEY_FN, LV_SCR_LOAD_ANIM_NONE); + break; + } + } while(keypress != 0); */ } void printLocalTime() diff --git a/src/main_arduino copy.cpp b/src/main_arduino copy.cpp index dcc98250..0e2b192d 100644 --- a/src/main_arduino copy.cpp +++ b/src/main_arduino copy.cpp @@ -54,12 +54,11 @@ void setup() * Read & Apply User Configuration ***************************/ #if HASP_USE_CONFIG > 0 - configSetup(); // also runs debugSetupWithoutLogging(), debugSetup() and debugStart() + configSetup(); // also runs debugSetup() and debugStart() #endif dispatchSetup(); guiSetup(); - debugSetup(); // Init the console #if HASP_USE_GPIO > 0 gpioSetup(); diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index 4d3c23f6..b990b941 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -54,12 +54,11 @@ void setup() * Read & Apply User Configuration ***************************/ #if HASP_USE_CONFIG > 0 - configSetup(); // also runs debugSetupWithoutLogging(), debugSetup() and debugStart() + configSetup(); // also runs debugSetup() and debugStart() #endif dispatchSetup(); // before hasp and oobe, asap after logging starts guiSetup(); - debugSetup(); // Init the console #if HASP_USE_CONFIG > 0 if(!oobeSetup()) @@ -96,6 +95,10 @@ void setup() httpSetup(); #endif +#if HASP_USE_CONSOLE > 0 + consoleSetup(); +#endif + #if HASP_USE_TELNET > 0 telnetSetup(); #endif @@ -123,9 +126,13 @@ IRAM_ATTR void loop() mqttLoop(); #endif // MQTT - debugLoop(); // Console + // debugLoop(); haspDevice.loop(); +#if HASP_USE_CONSOLE > 0 + consoleLoop(); +#endif + /* Timer Loop */ if(millis() - mainLastLoopTime >= 1000) { diff --git a/src/main_sdl2.cpp b/src/main_sdl2.cpp index 75ce1ae9..78fdf2e1 100644 --- a/src/main_sdl2.cpp +++ b/src/main_sdl2.cpp @@ -120,8 +120,6 @@ void setup() // hal_setup(); guiSetup(); - // debugSetup(); // Init the console - printf("%s %d\n", __FILE__, __LINE__); dispatchSetup(); // for hasp and oobe haspSetup(); diff --git a/src/sys/svc/hasp_console.cpp b/src/sys/svc/hasp_console.cpp new file mode 100644 index 00000000..e6ab31ce --- /dev/null +++ b/src/sys/svc/hasp_console.cpp @@ -0,0 +1,78 @@ +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#include "hasplib.h" + +#if HASP_USE_CONSOLE > 0 + +#include "ConsoleInput.h" + +#include "hasp_debug.h" +#include "hasp_config.h" +#include "hasp_console.h" + +#include "../../hasp/hasp_dispatch.h" + +uint8_t consoleInputEnabled = true; +ConsoleInput debugConsole(&Serial, HASP_CONSOLE_BUFFER); + +void console_update_prompt() +{ + debugConsole.update(); +} + +void consoleSetup() +{ + LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING)); + debugConsole.setLineCallback(dispatch_text_line); + LOG_INFO(TAG_CONS, F(D_SERVICE_STARTED)); +} + +IRAM_ATTR void consoleLoop() +{ + if(!consoleInputEnabled) return; + + int16_t keypress; + do { + switch(keypress = debugConsole.readKey()) { + + case ConsoleInput::KEY_PAGE_UP: + dispatch_page_next(LV_SCR_LOAD_ANIM_NONE); + break; + + case ConsoleInput::KEY_PAGE_DOWN: + dispatch_page_prev(LV_SCR_LOAD_ANIM_NONE); + break; + + case(ConsoleInput::KEY_FN)...(ConsoleInput::KEY_FN + 12): + dispatch_set_page(keypress - ConsoleInput::KEY_FN, LV_SCR_LOAD_ANIM_NONE); + break; + } + } while(keypress != 0); +} + +#if HASP_USE_CONFIG > 0 +bool consoleGetConfig(const JsonObject& settings) +{ + bool changed = false; + + if(changed) configOutput(settings, TAG_CONS); + return changed; +} + +/** Set console Configuration. + * + * Read the settings from json and sets the application variables. + * + * @param[in] settings JsonObject with the config settings. + **/ +bool consoleSetConfig(const JsonObject& settings) +{ + configOutput(settings, TAG_CONS); + bool changed = false; + + return changed; +} +#endif // HASP_USE_CONFIG + +#endif \ No newline at end of file diff --git a/src/sys/svc/hasp_console.h b/src/sys/svc/hasp_console.h new file mode 100644 index 00000000..e0ed31c9 --- /dev/null +++ b/src/sys/svc/hasp_console.h @@ -0,0 +1,36 @@ +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_CONSOLE_H +#define HASP_CONSOLE_H + +#if HASP_USE_CONSOLE > 0 + +#include "hasplib.h" + +/* ===== Default Event Processors ===== */ +void consoleSetup(); +IRAM_ATTR void consoleLoop(void); +void consoleEvery5Seconds(void); +void consoleEverySecond(void); +void consoleStart(void); +void consoleStop(void); + +/* ===== Special Event Processors ===== */ +void console_update_prompt(); + +/* ===== Getter and Setter Functions ===== */ + +/* ===== Read/Write Configuration ===== */ +#if HASP_USE_CONFIG > 0 +bool consoleSetConfig(const JsonObject& settings); +bool consoleGetConfig(const JsonObject& settings); +#endif + +#define CONSOLE_UNAUTHENTICATED 0 +#define CONSOLE_USERNAME_OK 10 +#define CONSOLE_USERNAME_NOK 99 +#define CONSOLE_AUTHENTICATED 255 + +#endif +#endif From b414e2360114a82074e68a7ed39a915bdbb5ea3f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 6 May 2021 21:44:05 +0200 Subject: [PATCH 135/227] Add discovery command --- src/hasp/hasp_dispatch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 23946846..160cd2d3 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -40,7 +40,7 @@ dispatch_conf_t dispatch_setings = {.teleperiod = 300}; uint32_t dispatchLastMillis = -3000000; // force discovery uint8_t nCommands = 0; -haspCommand_t commands[19]; +haspCommand_t commands[20]; struct moodlight_t { @@ -986,6 +986,7 @@ void dispatchSetup() dispatch_add_command(PSTR("reboot"), dispatch_reboot); dispatch_add_command(PSTR("restart"), dispatch_reboot); dispatch_add_command(PSTR("screenshot"), dispatch_screenshot); + dispatch_add_command(PSTR("discovery"), dispatch_send_discovery); dispatch_add_command(PSTR("factoryreset"), dispatch_factory_reset); #if HASP_USE_CONFIG > 0 dispatch_add_command(PSTR("setupap"), oobeFakeSetup); From 90a6299279ded3d3faf249df788ef08b4e05fde7 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 7 May 2021 00:04:44 +0200 Subject: [PATCH 136/227] Allow updating a text attribute with empty string --- src/hasp/hasp_dispatch.cpp | 33 ++++++++++++++++++--------------- src/hasp/hasp_dispatch.h | 3 ++- src/hasp/hasp_object.cpp | 4 ++-- src/hasp/hasp_object.h | 2 +- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 160cd2d3..f25a822c 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -116,7 +116,7 @@ void dispatch_output_pin_value(uint8_t pin, uint16_t val) } // p[x].b[y].attr=value -static inline bool dispatch_parse_button_attribute(const char* topic_p, const char* payload) +static inline bool dispatch_parse_button_attribute(const char* topic_p, const char* payload, bool update) { long num; char* pEnd; @@ -161,7 +161,7 @@ static inline bool dispatch_parse_button_attribute(const char* topic_p, const ch if(*topic_p != '.') return false; // obligated seperator topic_p++; - hasp_process_attribute(pageid, objid, topic_p, payload); + hasp_process_attribute(pageid, objid, topic_p, payload, update); return true; } @@ -197,11 +197,11 @@ static void dispatch_gpio(const char* topic, const char* payload) } // objectattribute=value -void dispatch_command(const char* topic, const char* payload) +void dispatch_command(const char* topic, const char* payload, bool update) { /* ================================= Standard payload commands ======================================= */ - if(dispatch_parse_button_attribute(topic, payload)) return; // matched pxby.attr, first for speed + if(dispatch_parse_button_attribute(topic, payload, update)) return; // matched pxby.attr, first for speed // check and execute commands from commands array for(int i = 0; i < nCommands; i++) { @@ -254,16 +254,16 @@ void dispatch_command(const char* topic, const char* payload) } // Strip command/config prefix from the topic and process the payload -void dispatch_topic_payload(const char* topic, const char* payload) +void dispatch_topic_payload(const char* topic, const char* payload, bool update) { - if(!strcmp_P(topic, PSTR("command"))) { + if(!strcmp_P(topic, PSTR(HASP_TOPIC_COMMAND))) { dispatch_text_line((char*)payload); return; } - if(topic == strstr_P(topic, PSTR("command/"))) { // startsWith command/ + if(topic == strstr_P(topic, PSTR(HASP_TOPIC_COMMAND "/"))) { // startsWith command/ topic += 8u; - dispatch_command(topic, (char*)payload); + dispatch_command(topic, (char*)payload, update); return; } @@ -275,7 +275,7 @@ void dispatch_topic_payload(const char* topic, const char* payload) } #endif - dispatch_command(topic, (char*)payload); // dispatch as is + dispatch_command(topic, (char*)payload, update); // dispatch as is } // Parse one line of text and execute the command @@ -284,14 +284,16 @@ void dispatch_text_line(const char* cmnd) size_t pos1 = std::string(cmnd).find("="); size_t pos2 = std::string(cmnd).find(" "); size_t pos = 0; + bool update = false; // Find what comes first, ' ' or '=' - if(pos1 != std::string::npos) { - if(pos2 != std::string::npos) { + if(pos1 != std::string::npos) { // '=' found + if(pos2 != std::string::npos) { // ' ' found pos = (pos1 < pos2 ? pos1 : pos2); } else { pos = pos1; } + update = pos == pos1; // equal sign wins } else { pos = (pos2 != std::string::npos) ? pos2 : 0; @@ -306,12 +308,13 @@ void dispatch_text_line(const char* cmnd) memcpy(topic, cmnd, sizeof(topic) - 1); // topic is before '=', payload is after '=' position - LOG_TRACE(TAG_MSGR, F("%s=%s"), topic, cmnd + pos + 1); - dispatch_topic_payload(topic, cmnd + pos + 1); + update |= strlen(cmnd + pos + 1) > 0; // equal sign OR space with payload + LOG_TRACE(TAG_MSGR, update ? F("%s=%s") : F("%s%s"), topic, cmnd + pos + 1); + dispatch_topic_payload(topic, cmnd + pos + 1, update); } else { char empty_payload[1] = {0}; - LOG_TRACE(TAG_MSGR, F("%s=%s"), cmnd, empty_payload); - dispatch_topic_payload(cmnd, empty_payload); + LOG_TRACE(TAG_MSGR, cmnd); + dispatch_topic_payload(cmnd, empty_payload, false); } } diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index 75f36650..73c63e0e 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -33,7 +33,7 @@ void dispatchStart(void); void dispatchStop(void); /* ===== Special Event Processors ===== */ -void dispatch_topic_payload(const char* topic, const char* payload); +void dispatch_topic_payload(const char* topic, const char* payload, bool update); void dispatch_text_line(const char* cmnd); #ifdef ARDUINO @@ -56,6 +56,7 @@ void dispatch_current_page(); void dispatch_backlight(const char*, const char* payload); void dispatch_web_update(const char*, const char* espOtaUrl); void dispatch_statusupdate(const char*, const char*); +void dispatch_send_discovery(const char*, const char*); void dispatch_idle(const char*, const char*); void dispatch_calibrate(const char*, const char*); void dispatch_wakeup(const char*, const char*); diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 8376182a..3339f9ed 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -285,10 +285,10 @@ void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int1 //////////////////////////////////////////////////////////////////////////////////////////////////// // Used in the dispatcher & hasp_new_object -void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload) +void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload, bool update) { if(lv_obj_t* obj = hasp_find_obj_from_parent_id(haspPages.get_obj(pageid), objid)) { - hasp_process_obj_attribute(obj, attr, payload, strlen(payload) > 0); + hasp_process_obj_attribute(obj, attr, payload, update); // || strlen(payload) > 0); } else { LOG_WARNING(TAG_HASP, F(D_OBJECT_UNKNOWN " " HASP_OBJECT_NOTATION), pageid, objid); } diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index 4dcbe5bb..dd62a5ea 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -72,7 +72,7 @@ void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level); void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload); -void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload); +void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload, bool update); void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max); From 75f76a7f3e30f59b4cc52212757e1b87c825bd70 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 7 May 2021 00:37:42 +0200 Subject: [PATCH 137/227] Add HASP_TOPIC_COMMAND and HASP_USE_BROADCAST --- include/hasp_conf.h | 4 ++ src/mqtt/hasp_mqtt.h | 2 + src/mqtt/hasp_mqtt_ha.cpp | 9 ++-- src/mqtt/hasp_mqtt_paho_async.cpp | 4 +- src/mqtt/hasp_mqtt_paho_single.cpp | 22 +++++++-- src/mqtt/hasp_mqtt_pubsubclient.cpp | 74 +++++++++++++++++------------ 6 files changed, 75 insertions(+), 40 deletions(-) diff --git a/include/hasp_conf.h b/include/hasp_conf.h index af8c8473..ba16d3b4 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -43,6 +43,10 @@ #define HASP_USE_MQTT (HASP_HAS_NETWORK) #endif +#ifndef HASP_USE_BROADCAST +#define HASP_USE_BROADCAST 1 +#endif + #ifndef MQTT_NODENAME #define MQTT_NODENAME "plate" #endif diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h index 5c8b6f37..c341d9b4 100644 --- a/src/mqtt/hasp_mqtt.h +++ b/src/mqtt/hasp_mqtt.h @@ -39,6 +39,8 @@ bool mqttGetConfig(const JsonObject& settings); bool mqttSetConfig(const JsonObject& settings); #endif +#define HASP_TOPIC_COMMAND "command" + // #ifndef WINDOWS // String mqttGetNodename(void); // #endif diff --git a/src/mqtt/hasp_mqtt_ha.cpp b/src/mqtt/hasp_mqtt_ha.cpp index 35e035a1..02793e3c 100644 --- a/src/mqtt/hasp_mqtt_ha.cpp +++ b/src/mqtt/hasp_mqtt_ha.cpp @@ -187,13 +187,13 @@ void mqtt_ha_register_backlight() // start from static keys and values that do not change deserializeJson(doc, F("{" - "\"cmd_t\":\"~command/light\"," + "\"cmd_t\":\"~" HASP_TOPIC_COMMAND "/light\"," "\"stat_t\":\"~state/light\"," "\"pl_on\":\"on\"," "\"pl_off\":\"off\"," "\"avty_t\":\"~LWT\"," "\"bri_stat_t\":\"~state/dim\"," - "\"bri_cmd_t\":\"~command/dim\"," + "\"bri_cmd_t\":\"~" HASP_TOPIC_COMMAND "/dim\"," "\"bri_scl\":100}")); mqtt_ha_add_device_ids(doc); mqtt_ha_add_unique_id(doc, item); @@ -215,7 +215,7 @@ void mqtt_ha_register_moodlight() // start from static keys and values that do not change deserializeJson(doc, F("{" - "\"cmd_t\":\"~command/moodlight\"," + "\"cmd_t\":\"~" HASP_TOPIC_COMMAND "/moodlight\"," "\"stat_t\":\"~state/moodlight\"," "\"platform\":\"mqtt\"," "\"schema\":\"json\"," @@ -273,7 +273,8 @@ void mqtt_ha_register_activepage() snprintf_P(item, sizeof(item), PSTR("page")); // start from static keys and values that do not change - deserializeJson(doc, F("{\"cmd_t\":\"~command/page\",\"stat_t\":\"~state/page\",\"avty_t\":\"~LWT\"}")); + deserializeJson(doc, + F("{\"cmd_t\":\"~" HASP_TOPIC_COMMAND "/page\",\"stat_t\":\"~state/page\",\"avty_t\":\"~LWT\"}")); mqtt_ha_add_device_ids(doc); mqtt_ha_add_unique_id(doc, item); diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp index 323cb80d..e50f6df0 100644 --- a/src/mqtt/hasp_mqtt_paho_async.cpp +++ b/src/mqtt/hasp_mqtt_paho_async.cpp @@ -254,8 +254,8 @@ void onConnect(void* context, MQTTAsync_successData* response) printf("Successful connection\n"); - mqtt_subscribe(context, TOPIC "command/#"); - mqtt_subscribe(context, TOPIC "command"); + mqtt_subscribe(context, TOPIC HASP_TOPIC_COMMAND "/#"); + mqtt_subscribe(context, TOPIC HASP_TOPIC_COMMAND); mqtt_subscribe(context, TOPIC "light"); mqtt_subscribe(context, TOPIC "dim"); diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp index a05ae1a8..46069000 100644 --- a/src/mqtt/hasp_mqtt_paho_single.cpp +++ b/src/mqtt/hasp_mqtt_paho_single.cpp @@ -139,9 +139,18 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length) // Group topic topic += mqttGroupTopic.length(); // shorten topic - dispatch_topic_payload(topic, (const char*)payload); + dispatch_topic_payload(topic, (const char*)payload, length > 0); return; +#ifdef HASP_USE_BROADCAST + } else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/broadcast/"))) { // broadcast discovery topic + + // broadcast topic + topic += strlen(MQTT_PREFIX "/broadcast/"); // shorten topic + dispatch_topic_payload(topic, (const char*)payload, length > 0); + return; +#endif + #ifdef HASP_USE_HA } else if(topic == strstr_P(topic, PSTR("homeassistant/status"))) { // HA discovery topic if(mqttHAautodiscover && !strcasecmp_P((char*)payload, PSTR("online"))) { @@ -170,7 +179,7 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length) // LOG_TRACE(TAG_MQTT, F("ignoring LWT = online")); } } else { - dispatch_topic_payload(topic, (const char*)payload); + dispatch_topic_payload(topic, (const char*)payload, length > 0); } } @@ -269,10 +278,10 @@ static void onConnect(void* context) LOG_VERBOSE(TAG_MQTT, D_MQTT_CONNECTED, mqttServer.c_str(), haspDevice.get_hostname()); - topic = mqttGroupTopic + "command/#"; + topic = mqttGroupTopic + HASP_TOPIC_COMMAND "/#"; mqtt_subscribe(mqtt_client, topic.c_str()); - topic = mqttNodeTopic + "command/#"; + topic = mqttNodeTopic + HASP_TOPIC_COMMAND "/#"; mqtt_subscribe(mqtt_client, topic.c_str()); topic = mqttGroupTopic + "config/#"; @@ -281,6 +290,11 @@ static void onConnect(void* context) topic = mqttNodeTopic + "config/#"; mqtt_subscribe(mqtt_client, topic.c_str()); +#ifdef HASP_USE_BROADCAST + topic = MQTT_PREFIX "/broadcast/" HASP_TOPIC_COMMAND "/#"; + mqtt_subscribe(mqtt_client, topic.c_str()); +#endif + /* Home Assistant auto-configuration */ #ifdef HASP_USE_HA topic = "homeassistant/status"; diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index eb096a87..4b24efae 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -184,9 +184,18 @@ static void mqtt_message_cb(char* topic, byte* payload, unsigned int length) // Group topic topic += strlen(mqttGroupTopic); // shorten topic - dispatch_topic_payload(topic, (const char*)payload); + dispatch_topic_payload(topic, (const char*)payload, length > 0); return; +#ifdef HASP_USE_BROADCAST + } else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/broadcast/"))) { // broadcast discovery topic + + // Broadcast topic + topic += strlen_P(PSTR(MQTT_PREFIX "/broadcast/")); // shorten topic + dispatch_topic_payload(topic, (const char*)payload, length > 0); + return; +#endif + #ifdef HASP_USE_HA } else if(topic == strstr_P(topic, PSTR("homeassistant/status"))) { // HA discovery topic if(mqttHAautodiscover && !strcasecmp_P((char*)payload, PSTR("online"))) { @@ -203,34 +212,36 @@ static void mqtt_message_cb(char* topic, byte* payload, unsigned int length) } // catch a dangling LWT from a previous connection if it appears - if(!strcmp_P(topic, PSTR(LWT_TOPIC))) { // endsWith LWT - if(!strcasecmp_P((char*)payload, PSTR("offline"))) { - { - char msg[8]; - char tmp_topic[strlen(mqttNodeTopic) + 8]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic); - snprintf_P(msg, sizeof(msg), PSTR("online")); + /* if(!strcmp_P(topic, PSTR(LWT_TOPIC))) { // endsWith LWT + if(!strcasecmp_P((char*)payload, PSTR("offline"))) { + { + char msg[8]; + char tmp_topic[strlen(mqttNodeTopic) + 8]; + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic); + snprintf_P(msg, sizeof(msg), PSTR("online")); - // /*bool res =*/mqttClient.publish(tmp_topic, msg, true); - mqttPublish(tmp_topic, msg, true); - } - - } else { - // LOG_TRACE(TAG_MQTT, F("ignoring LWT = online")); - } - } else { - dispatch_topic_payload(topic, (const char*)payload); + // bool res = + mqttClient.publish(tmp_topic, msg, true); + mqttPublish(tmp_topic, msg, true); + } + } + else + { + // LOG_TRACE(TAG_MQTT, F("ignoring LWT = online")); + } + } + else */ + { + dispatch_topic_payload(topic, (const char*)payload, length > 0); } } -static void mqttSubscribeTo(const __FlashStringHelper* format, const char* data) +static void mqttSubscribeTo(const char* topic) { - char tmp_topic[strlen_P((PGM_P)format) + 2 + strlen(data)]; - snprintf_P(tmp_topic, sizeof(tmp_topic), (PGM_P)format, data); - if(mqttClient.subscribe(tmp_topic)) { - LOG_VERBOSE(TAG_MQTT, F(D_BULLET D_MQTT_SUBSCRIBED), tmp_topic); + if(mqttClient.subscribe(topic)) { + LOG_VERBOSE(TAG_MQTT, F(D_BULLET D_MQTT_SUBSCRIBED), topic); } else { - LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_SUBSCRIBED), tmp_topic); + LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_SUBSCRIBED), topic); } } @@ -308,17 +319,20 @@ void mqttStart() LOG_INFO(TAG_MQTT, F(D_MQTT_CONNECTED), mqttServer, mqttClientId); // Subscribe to our incoming topics - const __FlashStringHelper* F_topic; - F_topic = F("%scommand/#"); - mqttSubscribeTo(F_topic, mqttGroupTopic); - mqttSubscribeTo(F_topic, mqttNodeTopic); + char topic[64]; + snprintf_P(topic, sizeof(topic), PSTR("%s" HASP_TOPIC_COMMAND "/#"), mqttGroupTopic); + mqttSubscribeTo(topic); + snprintf_P(topic, sizeof(topic), PSTR("%s" HASP_TOPIC_COMMAND "/#"), mqttNodeTopic); + mqttSubscribeTo(topic); // F_topic = F("%sconfig/#"); // mqttSubscribeTo(F_topic, mqttGroupTopic); - // mqttSubscribeTo(F_topic, mqttNodeTopic); - // mqttSubscribeTo(F("%slight/#"), mqttNodeTopic); - // mqttSubscribeTo(F("%sbrightness/#"), mqttNodeTopic); // mqttSubscribeTo(F("%s"LWT_TOPIC), mqttNodeTopic); +#ifdef HASP_USE_BROADCAST + snprintf_P(topic, sizeof(topic), PSTR(MQTT_PREFIX "/broadcast/" HASP_TOPIC_COMMAND "/#")); + mqttSubscribeTo(topic); +#endif + /* Home Assistant auto-configuration */ #ifdef HASP_USE_HA if(mqttHAautodiscover) mqttSubscribeTo(F("hass/status"), mqttClientId); From f80cd90d94829c8e29b05192cee03499f31cb511 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 7 May 2021 01:27:13 +0200 Subject: [PATCH 138/227] Cleanup MQTT_TOPIC defines --- src/hasp/hasp_dispatch.cpp | 8 ++-- src/mqtt/hasp_mqtt.h | 51 +++++++++++++++++++++--- src/mqtt/hasp_mqtt_ha.cpp | 31 ++++++++------- src/mqtt/hasp_mqtt_paho_async.cpp | 46 ++++------------------ src/mqtt/hasp_mqtt_paho_single.cpp | 54 +++++++------------------ src/mqtt/hasp_mqtt_pubsubclient.cpp | 61 ++++++++--------------------- 6 files changed, 103 insertions(+), 148 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index f25a822c..16e73965 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -256,12 +256,12 @@ void dispatch_command(const char* topic, const char* payload, bool update) // Strip command/config prefix from the topic and process the payload void dispatch_topic_payload(const char* topic, const char* payload, bool update) { - if(!strcmp_P(topic, PSTR(HASP_TOPIC_COMMAND))) { + if(!strcmp_P(topic, PSTR(MQTT_TOPIC_COMMAND))) { dispatch_text_line((char*)payload); return; } - if(topic == strstr_P(topic, PSTR(HASP_TOPIC_COMMAND "/"))) { // startsWith command/ + if(topic == strstr_P(topic, PSTR(MQTT_TOPIC_COMMAND "/"))) { // startsWith command/ topic += 8u; dispatch_command(topic, (char*)payload, update); return; @@ -832,10 +832,10 @@ void dispatch_send_discovery(const char*, const char*) size_t len = serializeJson(doc, data); switch(mqtt_send_discovery(data, len)) { case MQTT_ERR_OK: - LOG_TRACE(TAG_MQTT_PUB, F("discovery => %s"), data); + LOG_TRACE(TAG_MQTT_PUB, F(MQTT_TOPIC_DISCOVERY " => %s"), data); break; case MQTT_ERR_PUB_FAIL: - LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " discovery => %s"), data); + LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " " MQTT_TOPIC_DISCOVERY " => %s"), data); break; case MQTT_ERR_NO_CONN: LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED)); diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h index c341d9b4..52e08715 100644 --- a/src/mqtt/hasp_mqtt.h +++ b/src/mqtt/hasp_mqtt.h @@ -39,10 +39,49 @@ bool mqttGetConfig(const JsonObject& settings); bool mqttSetConfig(const JsonObject& settings); #endif -#define HASP_TOPIC_COMMAND "command" - -// #ifndef WINDOWS -// String mqttGetNodename(void); -// #endif - +#ifndef MQTT_PREFIX +#define MQTT_PREFIX "hasp" #endif + +#ifndef MQTT_TOPIC_STATE +#define MQTT_TOPIC_STATE "state" +#endif + +#ifndef MQTT_TOPIC_COMMAND +#define MQTT_TOPIC_COMMAND "command" +#endif + +#ifndef MQTT_TOPIC_DISCOVERY +#define MQTT_TOPIC_DISCOVERY "discovery" +#endif + +#ifndef MQTT_TOPIC_BROADCAST +#define MQTT_TOPIC_BROADCAST "broadcast" +#endif + +#define MQTT_TOPIC_LWT "LWT" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// These defaults may be overwritten with values saved by the web interface + +#ifndef MQTT_GROUPNAME +#define MQTT_GROUPNAME "plates"; +#endif + +#ifndef MQTT_HOST +#define MQTT_HOST ""; +#endif + +#ifndef MQTT_PORT +#define MQTT_PORT 1883; +#endif + +#ifndef MQTT_USER +#define MQTT_USER ""; +#endif + +#ifndef MQTT_PASSW +#define MQTT_PASSW ""; +#endif + +#endif // HASP_MQTT_H \ No newline at end of file diff --git a/src/mqtt/hasp_mqtt_ha.cpp b/src/mqtt/hasp_mqtt_ha.cpp index 02793e3c..a4adbd41 100644 --- a/src/mqtt/hasp_mqtt_ha.cpp +++ b/src/mqtt/hasp_mqtt_ha.cpp @@ -106,7 +106,7 @@ void mqtt_ha_register_button(uint8_t page, uint8_t id) char buffer[128]; snprintf_P(buffer, sizeof(buffer), PSTR(HASP_OBJECT_NOTATION), page, id); doc[F("stype")] = buffer; // subtype = "p0b0" - snprintf_P(buffer, sizeof(buffer), PSTR("~state/" HASP_OBJECT_NOTATION), page, id); + snprintf_P(buffer, sizeof(buffer), PSTR("~" MQTT_TOPIC_STATE "/" HASP_OBJECT_NOTATION), page, id); doc[F("t")] = buffer; // topic doc[F("atype")] = "trigger"; // automation_type @@ -148,7 +148,7 @@ void mqtt_ha_register_switch(uint8_t page, uint8_t id) char buffer[128]; snprintf_P(buffer, sizeof(buffer), PSTR(HASP_OBJECT_NOTATION), page, id); doc[F("stype")] = buffer; // subtype = "p0b0" - snprintf_P(buffer, sizeof(buffer), PSTR("~state/" HASP_OBJECT_NOTATION), page, id); + snprintf_P(buffer, sizeof(buffer), PSTR("~" MQTT_TOPIC_STATE "/" HASP_OBJECT_NOTATION), page, id); doc[F("t")] = buffer; // topic doc[F("atype")] = F("binary_sensor"); // automation_type @@ -169,7 +169,7 @@ void mqtt_ha_register_connectivity() // start from static keys and values that do not change deserializeJson(doc, F("{\"device_class\":\"connectivity\",\"stat_t\":\"~LWT\",\"pl_on\":\"online\",\"pl_off\":" - "\"offline\",\"json_attr_t\":\"~state/statusupdate\"}")); + "\"offline\",\"json_attr_t\":\"~" MQTT_TOPIC_STATE "/statusupdate\"}")); mqtt_ha_add_device_ids(doc); mqtt_ha_add_unique_id(doc, item); @@ -187,13 +187,13 @@ void mqtt_ha_register_backlight() // start from static keys and values that do not change deserializeJson(doc, F("{" - "\"cmd_t\":\"~" HASP_TOPIC_COMMAND "/light\"," - "\"stat_t\":\"~state/light\"," + "\"cmd_t\":\"~" MQTT_TOPIC_COMMAND "/light\"," + "\"stat_t\":\"~" MQTT_TOPIC_STATE "/light\"," "\"pl_on\":\"on\"," "\"pl_off\":\"off\"," "\"avty_t\":\"~LWT\"," - "\"bri_stat_t\":\"~state/dim\"," - "\"bri_cmd_t\":\"~" HASP_TOPIC_COMMAND "/dim\"," + "\"bri_stat_t\":\"~" MQTT_TOPIC_STATE "/dim\"," + "\"bri_cmd_t\":\"~" MQTT_TOPIC_COMMAND "/dim\"," "\"bri_scl\":100}")); mqtt_ha_add_device_ids(doc); mqtt_ha_add_unique_id(doc, item); @@ -215,8 +215,8 @@ void mqtt_ha_register_moodlight() // start from static keys and values that do not change deserializeJson(doc, F("{" - "\"cmd_t\":\"~" HASP_TOPIC_COMMAND "/moodlight\"," - "\"stat_t\":\"~state/moodlight\"," + "\"cmd_t\":\"~" MQTT_TOPIC_COMMAND "/moodlight\"," + "\"stat_t\":\"~" MQTT_TOPIC_STATE "/moodlight\"," "\"platform\":\"mqtt\"," "\"schema\":\"json\"," "\"rgb\":true," @@ -225,12 +225,12 @@ void mqtt_ha_register_moodlight() /* deserializeJson(doc, F("{" "\"cmd_t\":\"~command/moodlight\"," - // "\"stat_t\":\"~state/moodlight\"," + // "\"stat_t\":\"~" MQTT_TOPIC_STATE "/moodlight\"," "\"avty_t\":\"~LWT\"," - "\"bri_stat_t\":\"~state/moodlight/dim\"," + "\"bri_stat_t\":\"~" MQTT_TOPIC_STATE "/moodlight/dim\"," "\"bri_cmd_t\":\"~command/moodlight/dim\"," "\"bri_scl\":100," - "\"rgb_stat_t\":\"~state/moodlight/rgb\"," + "\"rgb_stat_t\":\"~" MQTT_TOPIC_STATE "/moodlight/rgb\"," "\"rgb_cmd_t\":\"~command/moodlight/rgb\"}")); */ mqtt_ha_add_device_ids(doc); @@ -256,7 +256,8 @@ void mqtt_ha_register_idle() snprintf_P(item, sizeof(item), PSTR("idle")); // start from static keys and values that do not change - deserializeJson(doc, F("{\"stat_t\":\"~state/idle\",\"avty_t\":\"~LWT\",\"json_attr_t\":\"~state/statusupdate\"}")); + deserializeJson(doc, F("{\"stat_t\":\"~" MQTT_TOPIC_STATE + "/idle\",\"avty_t\":\"~LWT\",\"json_attr_t\":\"~" MQTT_TOPIC_STATE "/statusupdate\"}")); mqtt_ha_add_device_ids(doc); mqtt_ha_add_unique_id(doc, item); @@ -273,8 +274,8 @@ void mqtt_ha_register_activepage() snprintf_P(item, sizeof(item), PSTR("page")); // start from static keys and values that do not change - deserializeJson(doc, - F("{\"cmd_t\":\"~" HASP_TOPIC_COMMAND "/page\",\"stat_t\":\"~state/page\",\"avty_t\":\"~LWT\"}")); + deserializeJson(doc, F("{\"cmd_t\":\"~" MQTT_TOPIC_COMMAND "/page\",\"stat_t\":\"~" MQTT_TOPIC_STATE + "/page\",\"avty_t\":\"~LWT\"}")); mqtt_ha_add_device_ids(doc); mqtt_ha_add_unique_id(doc, item); diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp index e50f6df0..609af505 100644 --- a/src/mqtt/hasp_mqtt_paho_async.cpp +++ b/src/mqtt/hasp_mqtt_paho_async.cpp @@ -63,36 +63,6 @@ const char* mqttGroupTopic = TOPIC; bool mqttEnabled = false; bool mqttHAautodiscover = true; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// These defaults may be overwritten with values saved by the web interface -#ifndef MQTT_HOST -#define MQTT_HOST ""; -#endif - -#ifndef MQTT_PORT -#define MQTT_PORT 1883; -#endif - -#ifndef MQTT_USER -#define MQTT_USER ""; -#endif - -#ifndef MQTT_PASSW -#define MQTT_PASSW ""; -#endif -#ifndef MQTT_NODENAME -#define MQTT_NODENAME ""; -#endif -#ifndef MQTT_GROUPNAME -#define MQTT_GROUPNAME ""; -#endif - -#ifndef MQTT_PREFIX -#define MQTT_PREFIX "hasp" -#endif - -#define LWT_TOPIC "LWT" - std::recursive_mutex dispatch_mtx; std::recursive_mutex publish_mtx; @@ -164,12 +134,12 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length) } // catch a dangling LWT from a previous connection if it appears - if(!strcmp_P(topic, PSTR(LWT_TOPIC))) { // endsWith LWT + if(!strcmp_P(topic, PSTR(MQTT_TOPIC_LWT))) { // endsWith LWT if(!strcasecmp_P((char*)payload, PSTR("offline"))) { { char msg[8]; char tmp_topic[strlen(mqttNodeTopic) + 8]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_LWT), mqttNodeTopic); snprintf_P(msg, sizeof(msg), PSTR("online")); // /*bool res =*/mqttClient.publish(tmp_topic, msg, true); @@ -254,12 +224,12 @@ void onConnect(void* context, MQTTAsync_successData* response) printf("Successful connection\n"); - mqtt_subscribe(context, TOPIC HASP_TOPIC_COMMAND "/#"); - mqtt_subscribe(context, TOPIC HASP_TOPIC_COMMAND); + mqtt_subscribe(context, TOPIC MQTT_TOPIC_COMMAND "/#"); + mqtt_subscribe(context, TOPIC MQTT_TOPIC_COMMAND); mqtt_subscribe(context, TOPIC "light"); mqtt_subscribe(context, TOPIC "dim"); - mqttPublish(TOPIC LWT_TOPIC, "online", false); + mqttPublish(TOPIC MQTT_TOPIC_LWT, "online", false); mqtt_send_object_state(0, 0, "connected"); std::cout << std::endl; @@ -340,15 +310,15 @@ bool mqttIsConnected() void mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload) { char tmp_topic[strlen(mqttNodeTopic) + 20]; - printf(("%sstate/%s\n"), mqttNodeTopic, subtopic); - snprintf_P(tmp_topic, sizeof(tmp_topic), ("%sstate/%s"), mqttNodeTopic, subtopic); + printf(("%s" MQTT_TOPIC_STATE "/%s\n"), mqttNodeTopic, subtopic); + snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic, subtopic); mqttPublish(tmp_topic, payload, false); } void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload) { char tmp_topic[strlen(mqttNodeTopic) + 20]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/p%ub%u"), mqttNodeTopic, pageid, btnid); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/p%ub%u"), mqttNodeTopic, pageid, btnid); mqttPublish(tmp_topic, payload, false); } diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp index 46069000..7ec6409e 100644 --- a/src/mqtt/hasp_mqtt_paho_single.cpp +++ b/src/mqtt/hasp_mqtt_paho_single.cpp @@ -63,34 +63,6 @@ uint32_t mqttPublishCount; uint32_t mqttReceiveCount; uint32_t mqttFailedCount; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// These defaults may be overwritten with values saved by the web interface -#ifndef MQTT_HOST -#define MQTT_HOST "10.1.0.208"; -#endif - -#ifndef MQTT_PORT -#define MQTT_PORT 1883; -#endif - -#ifndef MQTT_USER -#define MQTT_USER "hasp"; -#endif - -#ifndef MQTT_PASSW -#define MQTT_PASSW "hasp"; -#endif - -#ifndef MQTT_GROUPNAME -#define MQTT_GROUPNAME "plates"; -#endif - -#ifndef MQTT_PREFIX -#define MQTT_PREFIX "hasp" -#endif - -#define LWT_TOPIC "LWT" - std::string mqttServer = MQTT_HOST; std::string mqttUser = MQTT_USER; std::string mqttPassword = MQTT_PASSW; @@ -143,10 +115,11 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length) return; #ifdef HASP_USE_BROADCAST - } else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/broadcast/"))) { // broadcast discovery topic + } else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST + "/"))) { // /" MQTT_TOPIC_BROADCAST "/ discovery topic - // broadcast topic - topic += strlen(MQTT_PREFIX "/broadcast/"); // shorten topic + // /" MQTT_TOPIC_BROADCAST "/ topic + topic += strlen(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/"); // shorten topic dispatch_topic_payload(topic, (const char*)payload, length > 0); return; #endif @@ -167,7 +140,7 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length) } // catch a dangling LWT from a previous connection if it appears - if(!strcmp_P(topic, PSTR(LWT_TOPIC))) { // endsWith LWT + if(!strcmp_P(topic, PSTR(MQTT_TOPIC_LWT))) { // endsWith LWT if(!strcasecmp_P((char*)payload, PSTR("offline"))) { { char msg[8]; @@ -251,22 +224,23 @@ bool mqttIsConnected() int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload) { char tmp_topic[mqttNodeTopic.length() + 20]; - // printf(("%sstate/%s\n"), mqttNodeTopic, subtopic); - snprintf_P(tmp_topic, sizeof(tmp_topic), ("%sstate/%s"), mqttNodeTopic.c_str(), subtopic); + // printf(("%s" MQTT_TOPIC_STATE "/%s\n"), mqttNodeTopic, subtopic); + snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic.c_str(), subtopic); return mqttPublish(tmp_topic, payload, strlen(payload), false); } int mqtt_send_discovery(const char* payload, size_t len) { char tmp_topic[20]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/discovery")); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/" MQTT_TOPIC_DISCOVERY)); return mqttPublish(tmp_topic, payload, len, false); } int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload) { char tmp_topic[mqttNodeTopic.length() + 20]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/p%ub%u"), mqttNodeTopic.c_str(), pageid, btnid); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/p%ub%u"), mqttNodeTopic.c_str(), pageid, + btnid); return mqttPublish(tmp_topic, payload, strlen(payload), false); } @@ -278,10 +252,10 @@ static void onConnect(void* context) LOG_VERBOSE(TAG_MQTT, D_MQTT_CONNECTED, mqttServer.c_str(), haspDevice.get_hostname()); - topic = mqttGroupTopic + HASP_TOPIC_COMMAND "/#"; + topic = mqttGroupTopic + MQTT_TOPIC_COMMAND "/#"; mqtt_subscribe(mqtt_client, topic.c_str()); - topic = mqttNodeTopic + HASP_TOPIC_COMMAND "/#"; + topic = mqttNodeTopic + MQTT_TOPIC_COMMAND "/#"; mqtt_subscribe(mqtt_client, topic.c_str()); topic = mqttGroupTopic + "config/#"; @@ -291,7 +265,7 @@ static void onConnect(void* context) mqtt_subscribe(mqtt_client, topic.c_str()); #ifdef HASP_USE_BROADCAST - topic = MQTT_PREFIX "/broadcast/" HASP_TOPIC_COMMAND "/#"; + topic = MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/" MQTT_TOPIC_COMMAND "/#"; mqtt_subscribe(mqtt_client, topic.c_str()); #endif @@ -412,7 +386,7 @@ void mqttSetup() printf("%s %d\n", __FILE__, __LINE__); mqttLwtTopic = mqttNodeTopic; - mqttLwtTopic += LWT_TOPIC; + mqttLwtTopic += MQTT_TOPIC_LWT; printf("%s %d\n", __FILE__, __LINE__); } diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index 4b24efae..229e02be 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -54,36 +54,6 @@ uint32_t mqttPublishCount; uint32_t mqttReceiveCount; uint32_t mqttFailedCount; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// These defaults may be overwritten with values saved by the web interface -#ifndef MQTT_HOST -#define MQTT_HOST ""; -#endif - -#ifndef MQTT_PORT -#define MQTT_PORT 1883; -#endif - -#ifndef MQTT_USER -#define MQTT_USER ""; -#endif - -#ifndef MQTT_PASSW -#define MQTT_PASSW ""; -#endif -#ifndef MQTT_NODENAME -#define MQTT_NODENAME ""; -#endif -#ifndef MQTT_GROUPNAME -#define MQTT_GROUPNAME ""; -#endif - -#ifndef MQTT_PREFIX -#define MQTT_PREFIX "hasp" -#endif - -#define LWT_TOPIC "LWT" - char mqttServer[16] = MQTT_HOST; char mqttUser[23] = MQTT_USER; char mqttPassword[32] = MQTT_PASSW; @@ -130,8 +100,8 @@ bool mqtt_send_lwt(bool online) char tmp_payload[8]; char tmp_topic[strlen(mqttNodeTopic) + 4]; strncpy(tmp_topic, mqttNodeTopic, sizeof(tmp_topic)); - strncat_P(tmp_topic, PSTR(LWT_TOPIC), sizeof(tmp_topic)); - // snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic); + strncat_P(tmp_topic, PSTR(MQTT_TOPIC_LWT), sizeof(tmp_topic)); + // snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_LWT), mqttNodeTopic); size_t len = snprintf_P(tmp_payload, sizeof(tmp_payload), online ? PSTR("online") : PSTR("offline")); bool res = mqttPublish(tmp_topic, tmp_payload, len, true); @@ -142,21 +112,22 @@ bool mqtt_send_lwt(bool online) int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload) { char tmp_topic[strlen(mqttNodeTopic) + 16]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/" HASP_OBJECT_NOTATION), mqttNodeTopic, pageid, btnid); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/" HASP_OBJECT_NOTATION), mqttNodeTopic, + pageid, btnid); return mqttPublish(tmp_topic, payload, false); } int mqtt_send_state(const char* subtopic, const char* payload) { char tmp_topic[strlen(mqttNodeTopic) + 20]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/%s"), mqttNodeTopic, subtopic); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic, subtopic); return mqttPublish(tmp_topic, payload, false); } int mqtt_send_discovery(const char* payload, size_t len) { char tmp_topic[20]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/discovery")); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/" MQTT_TOPIC_DISCOVERY)); return mqttPublish(tmp_topic, payload, len, false); } @@ -188,10 +159,10 @@ static void mqtt_message_cb(char* topic, byte* payload, unsigned int length) return; #ifdef HASP_USE_BROADCAST - } else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/broadcast/"))) { // broadcast discovery topic + } else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/"))) { // broadcast topic // Broadcast topic - topic += strlen_P(PSTR(MQTT_PREFIX "/broadcast/")); // shorten topic + topic += strlen_P(PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/")); // shorten topic dispatch_topic_payload(topic, (const char*)payload, length > 0); return; #endif @@ -212,12 +183,12 @@ static void mqtt_message_cb(char* topic, byte* payload, unsigned int length) } // catch a dangling LWT from a previous connection if it appears - /* if(!strcmp_P(topic, PSTR(LWT_TOPIC))) { // endsWith LWT + /* if(!strcmp_P(topic, PSTR(MQTT_TOPIC_LWT))) { // endsWith LWT if(!strcasecmp_P((char*)payload, PSTR("offline"))) { { char msg[8]; char tmp_topic[strlen(mqttNodeTopic) + 8]; - snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic); + snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_LWT), mqttNodeTopic); snprintf_P(msg, sizeof(msg), PSTR("online")); // bool res = @@ -266,8 +237,8 @@ void mqttStart() } // Attempt to connect and set LWT and Clean Session - snprintf_P(buffer, sizeof(buffer), PSTR("%s" LWT_TOPIC), mqttNodeTopic); // lastWillTopic - snprintf_P(lastWillPayload, sizeof(lastWillPayload), PSTR("offline")); // lastWillPayload + snprintf_P(buffer, sizeof(buffer), PSTR("%s" MQTT_TOPIC_LWT), mqttNodeTopic); // lastWillTopic + snprintf_P(lastWillPayload, sizeof(lastWillPayload), PSTR("offline")); // lastWillPayload haspProgressMsg(F(D_MQTT_CONNECTING)); haspProgressVal(mqttReconnectCount * 5); @@ -320,16 +291,16 @@ void mqttStart() // Subscribe to our incoming topics char topic[64]; - snprintf_P(topic, sizeof(topic), PSTR("%s" HASP_TOPIC_COMMAND "/#"), mqttGroupTopic); + snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_COMMAND "/#"), mqttGroupTopic); mqttSubscribeTo(topic); - snprintf_P(topic, sizeof(topic), PSTR("%s" HASP_TOPIC_COMMAND "/#"), mqttNodeTopic); + snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_COMMAND "/#"), mqttNodeTopic); mqttSubscribeTo(topic); // F_topic = F("%sconfig/#"); // mqttSubscribeTo(F_topic, mqttGroupTopic); - // mqttSubscribeTo(F("%s"LWT_TOPIC), mqttNodeTopic); + // mqttSubscribeTo(F("%s"MQTT_TOPIC_LWT), mqttNodeTopic); #ifdef HASP_USE_BROADCAST - snprintf_P(topic, sizeof(topic), PSTR(MQTT_PREFIX "/broadcast/" HASP_TOPIC_COMMAND "/#")); + snprintf_P(topic, sizeof(topic), PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/" MQTT_TOPIC_COMMAND "/#")); mqttSubscribeTo(topic); #endif From 9bf154ccb08a6004ba30a8ab28216504049bb210 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 7 May 2021 04:02:32 +0200 Subject: [PATCH 139/227] Implement hasp_find_obj_from_page_id and obj_get_type --- src/hasp/hasp.cpp | 6 +- src/hasp/hasp_attribute.cpp | 440 +++++++++++++++++++++++------------- src/hasp/hasp_object.h | 8 +- 3 files changed, 292 insertions(+), 162 deletions(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index e2c67266..e9c01756 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -225,7 +225,7 @@ void haspReconnect() void haspProgressVal(uint8_t val) { lv_obj_t* layer = lv_disp_get_layer_sys(NULL); - lv_obj_t* bar = hasp_find_obj_from_parent_id(haspPages.get_obj(255), (uint8_t)10); + lv_obj_t* bar = hasp_find_obj_from_page_id(255U, 10U); if(layer && bar) { if(val == 255) { if(!lv_obj_get_hidden(bar)) { @@ -254,9 +254,7 @@ void haspProgressVal(uint8_t val) // Sets the value string of the global progress bar void haspProgressMsg(const char* msg) { - lv_obj_t* bar = hasp_find_obj_from_parent_id(haspPages.get_obj(255), (uint8_t)10); - - if(bar) { + if(lv_obj_t* bar = hasp_find_obj_from_page_id(255U, 10U)) { char value_str[10]; snprintf_P(value_str, sizeof(value_str), PSTR("value_str")); hasp_process_obj_attribute(bar, value_str, msg, true); diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 5126b830..af70789e 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -324,6 +324,13 @@ void my_btnmatrix_map_clear(lv_obj_t* obj) } } +void my_msgbox_map_clear(lv_obj_t* obj) +{ + lv_msgbox_ext_t* ext = (lv_msgbox_ext_t*)lv_obj_get_ext_attr(obj); + if(ext && ext->btnm) my_btnmatrix_map_clear(ext->btnm); // Clear the button map if it exists yet +} + +/* static void my_btnmatrix_map_create(lv_obj_t* obj, const char* payload) { // const char** map_p = lv_btnmatrix_get_map_array(obj); @@ -366,7 +373,7 @@ static void my_btnmatrix_map_create(lv_obj_t* obj, const char* payload) } memset(buffer_addr, 0, tot_len); // Important, last index needs to be 0 => empty string "" - /* Point of no return, destroy & free the previous map */ + // Point of no return, destroy & free the previous map / LOG_VERBOSE(TAG_ATTR, F("%s %d map addr: %x"), __FILE__, __LINE__, map_data_str); my_btnmatrix_map_clear(obj); // Free previous map @@ -391,6 +398,107 @@ static void my_btnmatrix_map_create(lv_obj_t* obj, const char* payload) LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); lv_btnmatrix_set_map(obj, map_data_str); LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); +}*/ + +// Create new btnmatrix button map from json array +const char** my_map_create(const char* payload) +{ + // Reserve memory for JsonDocument + size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 256; + DynamicJsonDocument map_doc(maxsize); + DeserializationError jsonError = deserializeJson(map_doc, payload); + + if(jsonError) { // Couldn't parse incoming JSON payload + dispatch_json_error(TAG_ATTR, jsonError); + return NULL; + } + + JsonArray arr = map_doc.as(); // Parse payload + + size_t tot_len = sizeof(char*) * (arr.size() + 1); + const char** map_data_str = (const char**)lv_mem_alloc(tot_len); + if(map_data_str == NULL) { + LOG_ERROR(TAG_ATTR, F("Out of memory while creating button map")); + return NULL; + } + memset(map_data_str, 0, tot_len); + + // Create buffer + tot_len = 0; + for(JsonVariant btn : arr) { + tot_len += strlen(btn.as()) + 1; + } + tot_len++; // trailing '\0' + LOG_VERBOSE(TAG_ATTR, F("Array Size = %d, Map Length = %d"), arr.size(), tot_len); + + char* buffer_addr = (char*)lv_mem_alloc(tot_len); + if(buffer_addr == NULL) { + lv_mem_free(map_data_str); + LOG_ERROR(TAG_ATTR, F("Out of memory while creating button map")); + return NULL; + } + memset(buffer_addr, 0, tot_len); // Important, last index needs to be 0 => empty string "" + + /* Point of no return, destroy & free the previous map */ + LOG_VERBOSE(TAG_ATTR, F("%s %d map addr: %x"), __FILE__, __LINE__, map_data_str); + // my_btnmatrix_map_clear(obj); // Free previous map + + // Fill buffer + size_t index = 0; + size_t pos = 0; + LOG_VERBOSE(TAG_ATTR, F("%s %d lbl addr: %x"), __FILE__, __LINE__, buffer_addr); + for(JsonVariant btn : arr) { + // size_t len = btn.as().length() + 1; + size_t len = strlen(btn.as()) + 1; + LOG_VERBOSE(TAG_ATTR, F(D_BULLET "Adding button: %s (%d bytes) %x"), btn.as(), len, + buffer_addr + pos); + // LOG_VERBOSE(TAG_ATTR, F(D_BULLET "Adding button: %s (%d bytes) %x"), btn.as().c_str(), len, + // buffer_addr + pos); + memccpy(buffer_addr + pos, btn.as(), 0, len); // Copy the label text into the buffer + // memccpy(buffer_addr + pos, btn.as().c_str(), 0, len); // Copy the label text into the buffer + map_data_str[index++] = buffer_addr + pos; // save pointer to the label in the array + pos += len; + } + map_data_str[index] = buffer_addr + pos; // save pointer to the last \0 byte + + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + return map_data_str; +} + +static void my_btnmatrix_set_map(lv_obj_t* obj, const char* payload) +{ + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + const char** map = my_map_create(payload); + if(!map) return; + + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + my_btnmatrix_map_clear(obj); // Free previous map + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + lv_btnmatrix_set_map(obj, map); + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); +} + +static void my_msgbox_set_map(lv_obj_t* obj, const char* payload) +{ + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + const char** map = my_map_create(payload); + if(!map) return; + + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + my_msgbox_map_clear(obj); // Free previous map + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + lv_msgbox_add_btns(obj, map); + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); +} + +static void my_msgbox_map_create(lv_obj_t* obj, const char* payload) +{ + const char** map = my_map_create(payload); + if(!map) return; + + my_btnmatrix_map_clear(obj); // Free previous map + lv_btnmatrix_set_map(obj, map); + LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); } void line_clear_points(lv_obj_t* obj) @@ -550,7 +658,7 @@ lv_obj_t* FindButtonLabel(lv_obj_t* btn) lv_obj_t* label = lv_obj_get_child_back(btn, NULL); #if 1 if(label) { - if(check_obj_type(label, LV_HASP_LABEL)) { + if(obj_check_type(label, LV_HASP_LABEL)) { return label; } #else @@ -559,7 +667,7 @@ lv_obj_t* FindButtonLabel(lv_obj_t* btn) lv_obj_get_type(label, &list); const char* objtype = list.type[0]; - if(check_obj_type(objtype, LV_HASP_LABEL)) { + if(obj_check_type(objtype, LV_HASP_LABEL)) { return label; } #endif @@ -593,7 +701,7 @@ static bool haspGetLabelText(lv_obj_t* obj, char** text) lv_obj_t* label = lv_obj_get_child_back(obj, NULL); if(label) { #if 1 - if(check_obj_type(label, LV_HASP_LABEL)) { + if(obj_check_type(label, LV_HASP_LABEL)) { *text = lv_label_get_text(label); return true; } @@ -601,7 +709,7 @@ static bool haspGetLabelText(lv_obj_t* obj, char** text) lv_obj_type_t list; lv_obj_get_type(label, &list); - if(check_obj_type(list.type[0], LV_HASP_LABEL)) { + if(obj_check_type(list.type[0], LV_HASP_LABEL)) { text = lv_label_get_text(label); return true; } @@ -639,7 +747,7 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch // lv_obj_get_type(obj, &list); // const char * objtype = list.type[0]; - if(check_obj_type(obj, LV_HASP_BUTTON)) { + if(obj_check_type(obj, LV_HASP_BUTTON)) { switch(index) { case 1: state = LV_BTN_STATE_PRESSED; @@ -670,12 +778,12 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch #error "LV_SLIDER, LV_BAR, LV_ARC, LV_SWITCH parts should match!" #endif - if(check_obj_type(obj, LV_HASP_SLIDER) || check_obj_type(obj, LV_HASP_SWITCH) || check_obj_type(obj, LV_HASP_ARC) || - check_obj_type(obj, LV_HASP_BAR)) { + if(obj_check_type(obj, LV_HASP_SLIDER) || obj_check_type(obj, LV_HASP_SWITCH) || obj_check_type(obj, LV_HASP_ARC) || + obj_check_type(obj, LV_HASP_BAR)) { if(index == 1) { part = LV_SLIDER_PART_INDIC; } else if(index == 2) { - if(!check_obj_type(obj, LV_HASP_BAR)) part = LV_SLIDER_PART_KNOB; + if(!obj_check_type(obj, LV_HASP_BAR)) part = LV_SLIDER_PART_KNOB; } else { part = LV_SLIDER_PART_BG; } @@ -683,7 +791,7 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch return; } - if(check_obj_type(obj, LV_HASP_CHECKBOX)) { + if(obj_check_type(obj, LV_HASP_CHECKBOX)) { if(index == 1) { part = LV_CHECKBOX_PART_BULLET; } else { @@ -693,7 +801,7 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch return; } - if(check_obj_type(obj, LV_HASP_CPICKER)) { + if(obj_check_type(obj, LV_HASP_CPICKER)) { if(index == 1) { part = LV_CPICKER_PART_KNOB; } else { @@ -703,7 +811,7 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch return; } - if(check_obj_type(obj, LV_HASP_ROLLER)) { + if(obj_check_type(obj, LV_HASP_ROLLER)) { if(index == 1) { part = LV_ROLLER_PART_SELECTED; } else { @@ -713,7 +821,7 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch return; } - // if(check_obj_type(obj, LV_HASP_LMETER)) { + // if(obj_check_type(obj, LV_HASP_LMETER)) { // state = LV_STATE_DEFAULT; // return; // } @@ -901,12 +1009,12 @@ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t at if(font) { LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, *font); uint8_t count = 3; - if(check_obj_type(obj, LV_HASP_ROLLER)) count = my_roller_get_visible_row_count(obj); + if(obj_check_type(obj, LV_HASP_ROLLER)) count = my_roller_get_visible_row_count(obj); lv_obj_set_style_local_text_font(obj, part, state, font); - if(check_obj_type(obj, LV_HASP_ROLLER)) lv_roller_set_visible_row_count(obj, count); + if(obj_check_type(obj, LV_HASP_ROLLER)) lv_roller_set_visible_row_count(obj, count); lv_obj_set_style_local_text_font(obj, part, state, font); // again, for roller - if(check_obj_type(obj, LV_HASP_DROPDOWN)) { // issue #43 + if(obj_check_type(obj, LV_HASP_DROPDOWN)) { // issue #43 lv_obj_set_style_local_text_font(obj, LV_DROPDOWN_PART_MAIN, state, font); lv_obj_set_style_local_text_font(obj, LV_DROPDOWN_PART_LIST, state, font); lv_obj_set_style_local_text_font(obj, LV_DROPDOWN_PART_SELECTED, state, font); @@ -1085,7 +1193,7 @@ static void hasp_process_arc_attribute(lv_obj_t* obj, const char* attr_p, uint16 uint16_t val = atoi(payload); char* attr = (char*)attr_p; - if(*attr == '.') attr++; // strip leading '.' + // if(*attr == '.') attr++; // strip leading '.' switch(attr_hash) { case ATTR_TYPE: @@ -1131,7 +1239,7 @@ static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr_p, uin uint16_t angle = lv_linemeter_get_scale_angle(obj); char* attr = (char*)attr_p; - if(*attr == '.') attr++; // strip leading '.' + // if(*attr == '.') attr++; // strip leading '.' switch(attr_hash) { case ATTR_TYPE: @@ -1160,7 +1268,7 @@ static void hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr_p, u uint16_t val = atoi(payload); char* attr = (char*)attr_p; - if(*attr == '.') attr++; // strip leading '.' + // if(*attr == '.') attr++; // strip leading '.' switch(attr_hash) { case ATTR_DIRECTION: @@ -1200,7 +1308,7 @@ static void hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr_p, uint uint16_t angle = lv_gauge_get_scale_angle(obj); char* attr = (char*)attr_p; - if(*attr == '.') attr++; // strip leading '.' + // if(*attr == '.') attr++; // strip leading '.' switch(attr_hash) { case ATTR_CRITICAL_VALUE: @@ -1277,7 +1385,7 @@ static void hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con // lv_obj_get_type(obj, &list); // const char * objtype = list.type[0]; - if(check_obj_type(obj, LV_HASP_BUTTON)) { + if(obj_check_type(obj, LV_HASP_BUTTON)) { if(update) { haspSetLabelText(obj, payload); } else { @@ -1286,23 +1394,23 @@ static void hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con } return; } - if(check_obj_type(obj, LV_HASP_LABEL)) { + if(obj_check_type(obj, LV_HASP_LABEL)) { return update ? lv_label_set_text(obj, payload) : attr_out_str(obj, attr, lv_label_get_text(obj)); } - if(check_obj_type(obj, LV_HASP_CHECKBOX)) { + if(obj_check_type(obj, LV_HASP_CHECKBOX)) { return update ? lv_checkbox_set_text(obj, payload) : attr_out_str(obj, attr, lv_checkbox_get_text(obj)); } - if(check_obj_type(obj, LV_HASP_DROPDOWN)) { + if(obj_check_type(obj, LV_HASP_DROPDOWN)) { char buffer[128]; lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); return attr_out_str(obj, attr, buffer); } - if(check_obj_type(obj, LV_HASP_ROLLER)) { + if(obj_check_type(obj, LV_HASP_ROLLER)) { char buffer[128]; lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); return attr_out_str(obj, attr, buffer); } - if(check_obj_type(obj, LV_HASP_MSGBOX)) { + if(obj_check_type(obj, LV_HASP_MSGBOX)) { if(update) { lv_msgbox_set_text(obj, payload); // lv_obj_realign(obj); /* Realign to the center */ @@ -1311,7 +1419,7 @@ static void hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con } return; } - if(check_obj_type(obj, LV_HASP_TABVIEW)) { + if(obj_check_type(obj, LV_HASP_TABVIEW)) { if(update) { uint16_t id = lv_tabview_get_tab_act(obj); if(id < lv_tabview_get_tab_count(obj)) lv_tabview_set_tab_name(obj, id, (char*)payload); @@ -1321,7 +1429,7 @@ static void hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con return; } #if LV_USE_WIN != 0 - if(check_obj_type(obj, LV_HASP_WINDOW)) { + if(obj_check_type(obj, LV_HASP_WINDOW)) { // return update ? lv_win_set_title(obj, (const char *)payload) : attr_out_str(obj, attr, // lv_win_get_title(obj)); } @@ -1332,7 +1440,7 @@ static void hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool boolval, bool update) { - if(check_obj_type(obj, LV_HASP_BUTTON)) { + if(obj_check_type(obj, LV_HASP_BUTTON)) { if(lv_btn_get_checkable(obj)) { if(update) { if(intval) @@ -1345,30 +1453,30 @@ bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t int } else { return false; // not checkable } - } else if(check_obj_type(obj, LV_HASP_CHECKBOX)) { + } else if(obj_check_type(obj, LV_HASP_CHECKBOX)) { update ? lv_checkbox_set_checked(obj, boolval) : attr_out_int(obj, attr, lv_checkbox_is_checked(obj)); - } else if(check_obj_type(obj, LV_HASP_SWITCH)) { + } else if(obj_check_type(obj, LV_HASP_SWITCH)) { if(update) boolval ? lv_switch_on(obj, LV_ANIM_ON) : lv_switch_off(obj, LV_ANIM_ON); else attr_out_int(obj, attr, lv_switch_get_state(obj)); - } else if(check_obj_type(obj, LV_HASP_DROPDOWN)) { + } else if(obj_check_type(obj, LV_HASP_DROPDOWN)) { lv_dropdown_set_selected(obj, (uint16_t)intval); - } else if(check_obj_type(obj, LV_HASP_LMETER)) { + } else if(obj_check_type(obj, LV_HASP_LMETER)) { update ? lv_linemeter_set_value(obj, intval) : attr_out_int(obj, attr, lv_linemeter_get_value(obj)); - } else if(check_obj_type(obj, LV_HASP_SLIDER)) { + } else if(obj_check_type(obj, LV_HASP_SLIDER)) { update ? lv_slider_set_value(obj, intval, LV_ANIM_ON) : attr_out_int(obj, attr, lv_slider_get_value(obj)); - } else if(check_obj_type(obj, LV_HASP_LED)) { + } else if(obj_check_type(obj, LV_HASP_LED)) { update ? lv_led_set_bright(obj, (uint8_t)intval) : attr_out_int(obj, attr, lv_led_get_bright(obj)); - } else if(check_obj_type(obj, LV_HASP_ARC)) { + } else if(obj_check_type(obj, LV_HASP_ARC)) { update ? lv_arc_set_value(obj, intval) : attr_out_int(obj, attr, lv_arc_get_value(obj)); - } else if(check_obj_type(obj, LV_HASP_GAUGE)) { + } else if(obj_check_type(obj, LV_HASP_GAUGE)) { update ? lv_gauge_set_value(obj, 0, intval) : attr_out_int(obj, attr, lv_gauge_get_value(obj, 0)); - } else if(check_obj_type(obj, LV_HASP_ROLLER)) { + } else if(obj_check_type(obj, LV_HASP_ROLLER)) { lv_roller_set_selected(obj, (uint16_t)intval, LV_ANIM_ON); - } else if(check_obj_type(obj, LV_HASP_BAR)) { + } else if(obj_check_type(obj, LV_HASP_BAR)) { update ? lv_bar_set_value(obj, intval, LV_ANIM_ON) : attr_out_int(obj, attr, lv_bar_get_value(obj)); - } else if(check_obj_type(obj, LV_HASP_TABVIEW)) { + } else if(obj_check_type(obj, LV_HASP_TABVIEW)) { update ? lv_tabview_set_tab_act(obj, intval, LV_ANIM_ON) : attr_out_int(obj, attr, lv_tabview_get_tab_act(obj)); } else { return false; @@ -1388,7 +1496,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co // lv_obj_get_type(obj, &list); // const char * objtype = list.type[0]; - if(check_obj_type(obj, LV_HASP_SLIDER)) { + if(obj_check_type(obj, LV_HASP_SLIDER)) { int16_t min = lv_slider_get_min_value(obj); int16_t max = lv_slider_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max @@ -1396,7 +1504,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co : attr_out_int(obj, attr, set_min ? min : max); } - if(check_obj_type(obj, LV_HASP_GAUGE)) { + if(obj_check_type(obj, LV_HASP_GAUGE)) { int32_t min = lv_gauge_get_min_value(obj); int32_t max = lv_gauge_get_max_value(obj); if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return; // prevent setting min=max @@ -1404,7 +1512,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co : attr_out_int(obj, attr, set_min ? min : max); } - if(check_obj_type(obj, LV_HASP_ARC)) { + if(obj_check_type(obj, LV_HASP_ARC)) { int16_t min = lv_arc_get_min_value(obj); int16_t max = lv_arc_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max @@ -1412,7 +1520,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co : attr_out_int(obj, attr, set_min ? min : max); } - if(check_obj_type(obj, LV_HASP_BAR)) { + if(obj_check_type(obj, LV_HASP_BAR)) { int16_t min = lv_bar_get_min_value(obj); int16_t max = lv_bar_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max @@ -1420,7 +1528,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co : attr_out_int(obj, attr, set_min ? min : max); } - if(check_obj_type(obj, LV_HASP_LMETER)) { + if(obj_check_type(obj, LV_HASP_LMETER)) { int32_t min = lv_linemeter_get_min_value(obj); int32_t max = lv_linemeter_get_max_value(obj); if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return; // prevent setting min=max @@ -1428,7 +1536,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co : attr_out_int(obj, attr, set_min ? min : max); } - if(check_obj_type(obj, LV_HASP_CHART)) { + if(obj_check_type(obj, LV_HASP_CHART)) { int16_t min = my_chart_get_min_value(obj); int16_t max = my_chart_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max @@ -1459,7 +1567,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } char* attr = (char*)attr_p; - if(*attr == '.') attr++; // strip leading '.' + // if(*attr == '.') attr++; // strip leading '.' uint16_t attr_hash = Parser::get_sdbm(attr); int16_t val = atoi(payload); @@ -1486,7 +1594,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha case ATTR_OBJ: if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); - attr_out_str(obj, attr, get_obj_type_name(obj)); + attr_out_str(obj, attr, obj_get_type_name(obj)); break; // attribute_found case ATTR_OBJID: @@ -1505,7 +1613,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha case ATTR_W: if(update) { lv_obj_set_width(obj, val); - if(check_obj_type(obj, LV_HASP_CPICKER)) { + if(obj_check_type(obj, LV_HASP_CPICKER)) { #if LVGL_VERSION_MAJOR == 7 lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC : LV_CPICKER_TYPE_RECT); @@ -1519,7 +1627,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha case ATTR_H: if(update) { lv_obj_set_height(obj, val); - if(check_obj_type(obj, LV_HASP_CPICKER)) { + if(obj_check_type(obj, LV_HASP_CPICKER)) { #if LVGL_VERSION_MAJOR == 7 lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC : LV_CPICKER_TYPE_RECT); @@ -1546,7 +1654,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha break; // attribute_found case ATTR_COLOR: - if(check_obj_type(obj, LV_HASP_CPICKER)) { + if(obj_check_type(obj, LV_HASP_CPICKER)) { if(update) { lv_color32_t c; if(Parser::haspPayloadToColor(payload, c)) @@ -1587,7 +1695,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha break; // attribute_found case ATTR_SRC: - if(check_obj_type(obj, LV_HASP_IMAGE)) { + if(obj_check_type(obj, LV_HASP_IMAGE)) { if(update) { return lv_img_set_src(obj, payload); } else { @@ -1610,124 +1718,144 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha : attr_out_int(obj, attr, lv_gauge_get_angle_offset(obj)); */ case ATTR_ROWS: - if(check_obj_type(obj, LV_HASP_ROLLER)) { - update ? lv_roller_set_visible_row_count(obj, (uint8_t)val) - : attr_out_int(obj, attr, my_roller_get_visible_row_count(obj)); - } else if(check_obj_type(obj, LV_HASP_TABLE)) { - update ? lv_table_set_row_cnt(obj, (uint8_t)val) : attr_out_int(obj, attr, lv_table_get_row_cnt(obj)); - } else { - goto attribute_not_found; + switch(obj_get_type(obj)) { + case LV_HASP_ROLLER: + update ? lv_roller_set_visible_row_count(obj, (uint8_t)val) + : attr_out_int(obj, attr, my_roller_get_visible_row_count(obj)); + break; + case LV_HASP_TABLE: + update ? lv_table_set_row_cnt(obj, (uint8_t)val) + : attr_out_int(obj, attr, lv_table_get_row_cnt(obj)); + break; + default: + goto attribute_not_found; } break; // attribute_found case ATTR_COLS: - if(check_obj_type(obj, LV_HASP_TABLE)) { + if(obj_check_type(obj, LV_HASP_TABLE)) { update ? lv_table_set_col_cnt(obj, (uint8_t)val) : attr_out_int(obj, attr, lv_table_get_col_cnt(obj)); } else { goto attribute_not_found; } break; // attribute_found - // case ATTR_RECT: - // if(check_obj_type(obj, LV_HASP_CPICKER)) { - // lv_cpicker_set_type(obj, is_true(payload) ? LV_CPICKER_TYPE_RECT : LV_CPICKER_TYPE_DISC); - // return; - // } - // break; - case ATTR_ALIGN: - if(check_obj_type(obj, LV_HASP_BUTTON)) { - lv_obj_t* label = FindButtonLabel(obj); - if(label == NULL) + switch(obj_get_type(obj)) { + case LV_HASP_BUTTON: { + lv_obj_t* label = FindButtonLabel(obj); + if(label == NULL) + goto attribute_not_found; + else + update ? lv_label_set_align(label, val) : attr_out_int(obj, attr, lv_label_get_align(label)); + } break; + case LV_HASP_BTNMATRIX: + update ? lv_btnmatrix_set_align(obj, val) : attr_out_int(obj, attr, lv_btnmatrix_get_align(obj)); + break; + case LV_HASP_LABEL: + update ? lv_label_set_align(obj, val) : attr_out_int(obj, attr, lv_label_get_align(obj)); + break; + case LV_HASP_ROLLER: + update ? lv_roller_set_align(obj, val) : attr_out_int(obj, attr, lv_roller_get_align(obj)); + break; + default: goto attribute_not_found; - else - update ? lv_label_set_align(label, val) : attr_out_int(obj, attr, lv_label_get_align(label)); - - } else if(check_obj_type(obj, LV_HASP_BTNMATRIX)) { - update ? lv_btnmatrix_set_align(obj, val) : attr_out_int(obj, attr, lv_btnmatrix_get_align(obj)); - } else if(check_obj_type(obj, LV_HASP_LABEL)) { - update ? lv_label_set_align(obj, val) : attr_out_int(obj, attr, lv_label_get_align(obj)); - } else if(check_obj_type(obj, LV_HASP_ROLLER)) { - update ? lv_roller_set_align(obj, val) : attr_out_int(obj, attr, lv_roller_get_align(obj)); - } else { - goto attribute_not_found; } break; // attribute_found case ATTR_MODE: - if(check_obj_type(obj, LV_HASP_BUTTON)) { - lv_obj_t* label = FindButtonLabel(obj); - if(label) { - hasp_process_label_long_mode(label, payload, update); - lv_obj_set_width(label, lv_obj_get_width(obj)); - } - } else if(check_obj_type(obj, LV_HASP_LABEL)) { - hasp_process_label_long_mode(obj, payload, update); - } else if(check_obj_type(obj, LV_HASP_ROLLER)) { - if(update) { - lv_roller_set_options(obj, lv_roller_get_options(obj), (lv_roller_mode_t)Parser::is_true(payload)); - } else { - lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); - attr_out_int(obj, attr, ext->mode); - } - } else { - goto attribute_not_found; + switch(obj_get_type(obj)) { + case LV_HASP_BUTTON: { + lv_obj_t* label = FindButtonLabel(obj); + if(label) { + hasp_process_label_long_mode(label, payload, update); + lv_obj_set_width(label, lv_obj_get_width(obj)); + } + } break; + case LV_HASP_LABEL: + hasp_process_label_long_mode(obj, payload, update); + break; + case LV_HASP_ROLLER: + if(update) { + lv_roller_set_options(obj, lv_roller_get_options(obj), + (lv_roller_mode_t)Parser::is_true(payload)); + } else { + lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); + attr_out_int(obj, attr, ext->mode); + } + break; + default: + goto attribute_not_found; } break; // attribute_found case ATTR_TOGGLE: - if(check_obj_type(obj, LV_HASP_BUTTON)) { - if(update) { - bool toggle = Parser::is_true(payload); - lv_btn_set_checkable(obj, toggle); - lv_obj_set_event_cb(obj, toggle ? toggle_event_handler : generic_event_handler); - } else { - attr_out_int(obj, attr, lv_btn_get_checkable(obj)); - } - } else if(check_obj_type(obj, LV_HASP_BTNMATRIX)) { - if(update) { - bool toggle = Parser::is_true(payload); - if(toggle) { - lv_btnmatrix_set_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); + switch(obj_get_type(obj)) { + case LV_HASP_BUTTON: + if(update) { + bool toggle = Parser::is_true(payload); + lv_btn_set_checkable(obj, toggle); + lv_obj_set_event_cb(obj, toggle ? toggle_event_handler : generic_event_handler); } else { - lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); - lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECK_STATE); + attr_out_int(obj, attr, lv_btn_get_checkable(obj)); } - } else { - attr_out_int(obj, attr, lv_btn_get_checkable(obj)); - } - } else { - goto attribute_not_found; + break; + case LV_HASP_BTNMATRIX: + if(update) { + bool toggle = Parser::is_true(payload); + if(toggle) { + lv_btnmatrix_set_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); + } else { + lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); + lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECK_STATE); + } + } else { + attr_out_int(obj, attr, lv_btn_get_checkable(obj)); + } + break; + default: + goto attribute_not_found; } break; // attribute_found case ATTR_OPTIONS: - if(check_obj_type(obj, LV_HASP_DROPDOWN)) { - if(update) { - lv_dropdown_set_options(obj, payload); - } else { - attr_out_str(obj, attr, lv_dropdown_get_options(obj)); - } - } else if(check_obj_type(obj, LV_HASP_ROLLER)) { - if(update) { - lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); - lv_roller_set_options(obj, payload, ext->mode); - } else { - attr_out_str(obj, attr, lv_roller_get_options(obj)); - } - } else if(check_obj_type(obj, LV_HASP_BTNMATRIX)) { - if(update) { - my_btnmatrix_map_create(obj, payload); - } else { - attr_out_str(obj, attr_p, "Not implemented"); // TODO : Literal String - } - } else { - goto attribute_not_found; + switch(obj_get_type(obj)) { + case LV_HASP_DROPDOWN: + if(update) { + lv_dropdown_set_options(obj, payload); + } else { + attr_out_str(obj, attr, lv_dropdown_get_options(obj)); + } + break; + case LV_HASP_ROLLER: + if(update) { + lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); + lv_roller_set_options(obj, payload, ext->mode); + } else { + attr_out_str(obj, attr, lv_roller_get_options(obj)); + } + break; + case LV_HASP_BTNMATRIX: + if(update) { + my_btnmatrix_set_map(obj, payload); + } else { + attr_out_str(obj, attr_p, "Not implemented"); // TODO : Literal String + } + break; + case LV_HASP_MSGBOX: + if(update) { + my_msgbox_set_map(obj, payload); + } else { + attr_out_str(obj, attr_p, "Not implemented"); // TODO : Literal String + } + break; + default: + goto attribute_not_found; } break; // attribute_found case ATTR_ONE_CHECK: - if(check_obj_type(obj, LV_HASP_BTNMATRIX)) { + if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { if(update) { lv_btnmatrix_set_one_check(obj, Parser::is_true(payload)); } else { @@ -1739,7 +1867,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha break; case ATTR_BTN_POS: - if(check_obj_type(obj, LV_HASP_TABVIEW)) { + if(obj_check_type(obj, LV_HASP_TABVIEW)) { if(update) { lv_tabview_set_btns_pos(obj, val); } else { @@ -1751,7 +1879,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha break; case ATTR_COUNT: - if(check_obj_type(obj, LV_HASP_TABVIEW)) { + if(obj_check_type(obj, LV_HASP_TABVIEW)) { if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); attr_out_int(obj, attr_p, lv_tabview_get_tab_count(obj)); @@ -1762,7 +1890,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha // case ATTR_MODAL: case ATTR_AUTO_CLOSE: - if(check_obj_type(obj, LV_HASP_MSGBOX)) { + if(obj_check_type(obj, LV_HASP_MSGBOX)) { if(update) { lv_msgbox_start_auto_close(obj, val); } else { @@ -1785,14 +1913,18 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha case ATTR_END_ANGLE: case ATTR_START_ANGLE1: case ATTR_END_ANGLE1: - if(check_obj_type(obj, LV_HASP_ARC)) { - hasp_process_arc_attribute(obj, attr_p, attr_hash, payload, update); - } else if(check_obj_type(obj, LV_HASP_GAUGE)) { - hasp_process_gauge_attribute(obj, attr_p, attr_hash, payload, update); - } else if(check_obj_type(obj, LV_HASP_LMETER)) { - hasp_process_lmeter_attribute(obj, attr_p, attr_hash, payload, update); - } else { - goto attribute_not_found; + switch(obj_get_type(obj)) { + case LV_HASP_ARC: + hasp_process_arc_attribute(obj, attr_p, attr_hash, payload, update); + break; + case LV_HASP_GAUGE: + hasp_process_gauge_attribute(obj, attr_p, attr_hash, payload, update); + break; + case LV_HASP_LMETER: + hasp_process_lmeter_attribute(obj, attr_p, attr_hash, payload, update); + break; + default: + goto attribute_not_found; } break; // attribute_found @@ -1802,7 +1934,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha case ATTR_CLOSE: case ATTR_MAX_HEIGHT: case ATTR_SHOW_SELECTED: - if(check_obj_type(obj, LV_HASP_DROPDOWN)) { + if(obj_check_type(obj, LV_HASP_DROPDOWN)) { hasp_process_dropdown_attribute(obj, attr_p, attr_hash, payload, update); } else { goto attribute_not_found; @@ -1810,7 +1942,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha break; // attribute_found case ATTR_RED: // TODO: remove temp RED - if(check_obj_type(obj, LV_HASP_BTNMATRIX)) { + if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { my_btnmatrix_map_clear(obj); // TODO : remove this test property } else { goto attribute_not_found; @@ -1845,7 +1977,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha case ATTR_NEXT: case ATTR_PREV: case ATTR_BACK: - if(check_obj_type(obj, LV_HASP_SCREEN)) { + if(obj_check_type(obj, LV_HASP_SCREEN)) { hasp_process_page_attributes(obj, attr_p, attr_hash, val, update); break; // attribute_found } diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index dd62a5ea..e98a1a86 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -63,11 +63,11 @@ enum lv_hasp_obj_type_t { void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id); lv_obj_t* hasp_find_obj_from_parent_id(lv_obj_t* parent, uint8_t objid); -// lv_obj_t * hasp_find_obj_from_page_id(uint8_t pageid, uint8_t objid); +lv_obj_t* hasp_find_obj_from_page_id(uint8_t pageid, uint8_t objid); bool hasp_find_id_from_obj(lv_obj_t* obj, uint8_t* pageid, uint8_t* objid); -// bool check_obj_type_str(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype); -const char* get_obj_type_name(lv_obj_t* obj); -bool check_obj_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype); +const char* obj_get_type_name(lv_obj_t* obj); +bool obj_check_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype); +lv_hasp_obj_type_t obj_get_type(lv_obj_t* obj); void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level); void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload); From 70b6f983e9eeb758812d04d51101bbda08ca5deb Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 7 May 2021 04:03:52 +0200 Subject: [PATCH 140/227] Implement obj_get_type, code cleanup and msgbox fix --- src/hasp/hasp_object.cpp | 151 ++++++++++++--------------------------- 1 file changed, 46 insertions(+), 105 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 3339f9ed..222111c4 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -17,12 +17,12 @@ #include "hasplib.h" -const char** btnmatrix_default_map; // memory pointer to lvgl default btnmatrix map -const char* msgbox_default_map[] = {"OK" - ""}; // memory pointer to hasp default msgbox map +const char** btnmatrix_default_map; // memory pointer to lvgl default btnmatrix map +const char* msgbox_default_map[] = {"OK", ""}; // memory pointer to hasp default msgbox map // ##################### Object Finders ######################################################## +// Return a child object from a parent with a specific objid lv_obj_t* hasp_find_obj_from_parent_id(lv_obj_t* parent, uint8_t objid) { if(objid == 0 || parent == nullptr) return parent; @@ -38,7 +38,7 @@ lv_obj_t* hasp_find_obj_from_parent_id(lv_obj_t* parent, uint8_t objid) if(grandchild) return grandchild; /* grandchild found, return it */ /* check tabs */ - if(check_obj_type(child, LV_HASP_TABVIEW)) { + if(obj_check_type(child, LV_HASP_TABVIEW)) { uint16_t tabcount = lv_tabview_get_tab_count(child); for(uint16_t i = 0; i < tabcount; i++) { lv_obj_t* tab = lv_tabview_get_tab(child, i); @@ -57,11 +57,13 @@ lv_obj_t* hasp_find_obj_from_parent_id(lv_obj_t* parent, uint8_t objid) return NULL; } -// lv_obj_t * hasp_find_obj_from_page_id(uint8_t pageid, uint8_t objid) -// { -// return hasp_find_obj_from_parent_id(get_page_obj(pageid), objid); -// } +// Return the object with a specific pageid and objid +lv_obj_t* hasp_find_obj_from_page_id(uint8_t pageid, uint8_t objid) +{ + return hasp_find_obj_from_parent_id(haspPages.get_obj(pageid), objid); +} +// Return the pageid and objid of an object bool hasp_find_id_from_obj(lv_obj_t* obj, uint8_t* pageid, uint8_t* objid) { if(!obj || !haspPages.get_id(obj, pageid)) return false; @@ -70,87 +72,13 @@ bool hasp_find_id_from_obj(lv_obj_t* obj, uint8_t* pageid, uint8_t* objid) return true; } -/** - * Check if an lvgl object typename corresponds to a given HASP object ID - * @param lvobjtype a char* to a string - * @param haspobjtype the HASP object ID to check against - * @return true or false wether the types match - * @note - */ -// bool check_obj_type_str(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype) -// { -// lvobjtype += 3; // skip "lv_" - -// switch(haspobjtype) { -// case LV_HASP_BTNMATRIX: -// return (strcmp_P(lvobjtype, PSTR("btnmatrix")) == 0); -// case LV_HASP_TABLE: -// return (strcmp_P(lvobjtype, PSTR("table")) == 0); -// case LV_HASP_BUTTON: -// return (strcmp_P(lvobjtype, PSTR("btn")) == 0); -// case LV_HASP_LABEL: -// return (strcmp_P(lvobjtype, PSTR("label")) == 0); -// case LV_HASP_CHECKBOX: -// return (strcmp_P(lvobjtype, PSTR("checkbox")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cb")) == 0); -// case LV_HASP_DROPDOWN: -// return (strcmp_P(lvobjtype, PSTR("dropdown")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_ddlist")) == 0); -// case LV_HASP_CPICKER: -// return (strcmp_P(lvobjtype, PSTR("cpicker")) == 0); -// case LV_HASP_SPINNER: -// return (strcmp_P(lvobjtype, PSTR("spinner")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_preload")) == 0); -// case LV_HASP_SLIDER: -// return (strcmp_P(lvobjtype, PSTR("slider")) == 0); -// case LV_HASP_GAUGE: -// return (strcmp_P(lvobjtype, PSTR("gauge")) == 0); -// case LV_HASP_ARC: -// return (strcmp_P(lvobjtype, PSTR("arc")) == 0); -// case LV_HASP_BAR: -// return (strcmp_P(lvobjtype, PSTR("bar")) == 0); -// case LV_HASP_LMETER: -// return (strcmp_P(lvobjtype, PSTR("linemeter")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_lmeter")) == 0) -// case LV_HASP_ROLLER: -// return (strcmp_P(lvobjtype, PSTR("roller")) == 0); -// case LV_HASP_SWITCH: -// return (strcmp_P(lvobjtype, PSTR("switch")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_sw")) == 0) -// case LV_HASP_LED: -// return (strcmp_P(lvobjtype, PSTR("led")) == 0); -// case LV_HASP_IMAGE: -// return (strcmp_P(lvobjtype, PSTR("img")) == 0); -// case LV_HASP_IMGBTN: -// return (strcmp_P(lvobjtype, PSTR("imgbtn")) == 0); -// case LV_HASP_CONTAINER: -// return (strcmp_P(lvobjtype, PSTR("container")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0) -// case LV_HASP_OBJECT: -// return (strcmp_P(lvobjtype, PSTR("page")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0) -// case LV_HASP_PAGE: -// return (strcmp_P(lvobjtype, PSTR("obj")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0) -// case LV_HASP_TABVIEW: -// return (strcmp_P(lvobjtype, PSTR("tabview")) == 0); -// case LV_HASP_TILEVIEW: -// return (strcmp_P(lvobjtype, PSTR("tileview")) == 0); -// case LV_HASP_CHART: -// return (strcmp_P(lvobjtype, PSTR("chart")) == 0); -// case LV_HASP_CANVAS: -// return (strcmp_P(lvobjtype, PSTR("canvas")) == 0); -// case LV_HASP_CALENDER: -// return (strcmp_P(lvobjtype, PSTR("calender")) == 0); -// case LV_HASP_MSGBOX: -// return (strcmp_P(lvobjtype, PSTR("msgbox")) == 0); -// case LV_HASP_WINDOW: -// return (strcmp_P(lvobjtype, PSTR("win")) == 0); - -// default: -// return false; -// } -// } - /** * Get the object type name of an object * @param obj an lv_obj_t* of the object to check its type * @return name of the object type * @note */ -const char* get_obj_type_name(lv_obj_t* obj) +const char* obj_get_type_name(lv_obj_t* obj) { lv_obj_type_t list; lv_obj_get_type(obj, &list); @@ -165,7 +93,7 @@ const char* get_obj_type_name(lv_obj_t* obj) * @return true or false wether the types match * @note */ -bool check_obj_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) +bool obj_check_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) { #if 1 return obj->user_data.objid == (uint8_t)haspobjtype; @@ -173,19 +101,28 @@ bool check_obj_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) lv_obj_type_t list; lv_obj_get_type(obj, &list); const char* objtype = list.type[0]; - return check_obj_type(objtype, haspobjtype); + return obj_check_type(objtype, haspobjtype); #endif } +/** + * Get the hasp object type of a given LVGL object + * @param obj an lv_obj_t* of the object to check its type + * @return lv_hasp_obj_type_t + * @note + */ +lv_hasp_obj_type_t obj_get_type(lv_obj_t* obj) +{ + return (lv_hasp_obj_type_t)obj->user_data.objid; +} + void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level) { if(parent == nullptr) return; /* Output parent info */ - lv_obj_type_t list; - lv_obj_get_type(parent, &list); - const char* objtype = list.type[0]; - LOG_VERBOSE(TAG_HASP, F("[%d] " HASP_OBJECT_NOTATION " %s"), level, pageid, parent->user_data.id, objtype); + LOG_VERBOSE(TAG_HASP, F("[%d] " HASP_OBJECT_NOTATION " %s"), level, pageid, parent->user_data.id, + obj_get_type_name(parent)); lv_obj_t* child; child = lv_obj_get_child(parent, NULL); @@ -198,7 +135,7 @@ void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level) } /* check tabs */ - if(check_obj_type(parent, LV_HASP_TABVIEW)) { + if(obj_check_type(parent, LV_HASP_TABVIEW)) { #if 1 uint16_t tabcount = lv_tabview_get_tab_count(parent); for(uint16_t i = 0; i < tabcount; i++) { @@ -236,7 +173,7 @@ void object_set_group_values(lv_obj_t* parent, uint8_t groupid, int16_t intval) object_set_group_values(child, groupid, intval); /* check tabs */ - if(check_obj_type(child, LV_HASP_TABVIEW)) { + if(obj_check_type(child, LV_HASP_TABVIEW)) { //#if LVGL_VERSION_MAJOR == 7 uint16_t tabcount = lv_tabview_get_tab_count(child); for(uint16_t i = 0; i < tabcount; i++) { @@ -287,7 +224,7 @@ void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int1 // Used in the dispatcher & hasp_new_object void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload, bool update) { - if(lv_obj_t* obj = hasp_find_obj_from_parent_id(haspPages.get_obj(pageid), objid)) { + if(lv_obj_t* obj = hasp_find_obj_from_page_id(pageid, objid)) { hasp_process_obj_attribute(obj, attr, payload, update); // || strlen(payload) > 0); } else { LOG_WARNING(TAG_HASP, F(D_OBJECT_UNKNOWN " " HASP_OBJECT_NOTATION), pageid, objid); @@ -362,9 +299,8 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) config.remove(FPSTR(FP_PARENTID)); } - uint16_t sdbm = 0; - uint8_t groupid = config[FPSTR(FP_GROUPID)].as(); - uint8_t id = config[FPSTR(FP_ID)].as(); + uint16_t sdbm = 0; + uint8_t id = config[FPSTR(FP_ID)].as(); config.remove(FPSTR(FP_ID)); /* Create the object if it does not exist */ @@ -701,7 +637,7 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) lv_obj_align(obj, NULL, LV_ALIGN_CENTER, 0, 0); lv_obj_set_auto_realign(obj, true); lv_obj_set_event_cb(obj, msgbox_event_handler); - // if(msgbox_default_map) lv_msgbox_add_btns(obj, msgbox_default_map); + if(msgbox_default_map) lv_msgbox_add_btns(obj, msgbox_default_map); obj->user_data.objid = LV_HASP_MSGBOX; } break; @@ -713,7 +649,8 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) if(obj) { lv_obj_set_event_cb(obj, calendar_event_handler); obj->user_data.objid = LV_HASP_CALENDER; - lv_task_t* task = lv_task_create(event_timer_calendar, 300, LV_TASK_PRIO_LOWEST, (void*)obj); + lv_task_t* task = lv_task_create(event_timer_calendar, 25, LV_TASK_PRIO_LOWEST, (void*)obj); + (void)task; // unused } break; @@ -734,30 +671,34 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) lv_obj_set_gesture_parent(obj, false); /* id tag the object */ - // lv_obj_set_user_data(obj, id); obj->user_data.id = id; - // obj->user_data.groupid = groupid; // get/set in atttr + uint8_t temp; // needed for debug tests + (void)temp; + +#ifdef HASP_DEBUG /** testing start **/ - uint8_t temp; if(!hasp_find_id_from_obj(obj, &pageid, &temp)) { LOG_ERROR(TAG_HASP, F(D_OBJECT_LOST)); return; } +#endif +#if HASP_LOG_LEVEL >= LOG_LEVEL_VERBOSE /** verbose reporting **/ - lv_obj_type_t list; - lv_obj_get_type(obj, &list); - LOG_VERBOSE(TAG_HASP, F(D_BULLET HASP_OBJECT_NOTATION " = %s"), pageid, temp, list.type[0]); + LOG_VERBOSE(TAG_HASP, F(D_BULLET HASP_OBJECT_NOTATION " = %s"), pageid, id, obj_get_type_name(obj)); +#endif +#ifdef HASP_DEBUG /* test double-check */ - lv_obj_t* test = hasp_find_obj_from_parent_id(haspPages.get_obj(pageid), (uint8_t)temp); - if(test != obj) { + lv_obj_t* test = hasp_find_obj_from_page_id(pageid, (uint8_t)temp); + if(test != obj || temp != id) { LOG_ERROR(TAG_HASP, F(D_OBJECT_MISMATCH)); return; } else { // object created successfully } +#endif } else { // object already exists From 0be87a7c5130bcf15287b2cf61456da8087f7acd Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 7 May 2021 04:37:43 +0200 Subject: [PATCH 141/227] Indent the object tree --- src/hasp/hasp_object.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 222111c4..cde049d6 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -121,7 +121,12 @@ void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level) if(parent == nullptr) return; /* Output parent info */ - LOG_VERBOSE(TAG_HASP, F("[%d] " HASP_OBJECT_NOTATION " %s"), level, pageid, parent->user_data.id, + char indent[31]; + memset(indent, 32, 31); + if(level < 15) indent[level * 2] = 0; + indent[30] = 0; + + LOG_VERBOSE(TAG_HASP, F("%s- " HASP_OBJECT_NOTATION ": %s"), indent, pageid, parent->user_data.id, obj_get_type_name(parent)); lv_obj_t* child; From a6da2a60e732f35ef9098486fb0f29d22b84ad52 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 7 May 2021 15:16:19 +0200 Subject: [PATCH 142/227] Add tab Text property --- src/hasp/hasp_attribute.cpp | 130 ++++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 49 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index af70789e..63aa0ffe 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -173,9 +173,8 @@ static bool attribute_update_lv_property(lv_obj_t * obj, const char * attr_p, ui } #endif -const char* my_tabview_get_tab_name(lv_obj_t* tabview) +const char* my_tabview_get_tab_name(lv_obj_t* tabview, uint16_t id) { - uint16_t id = lv_tabview_get_tab_act(tabview); if(id >= lv_tabview_get_tab_count(tabview)) return NULL; lv_tabview_ext_t* ext = (lv_tabview_ext_t*)lv_obj_get_ext_attr(tabview); @@ -682,7 +681,7 @@ lv_obj_t* FindButtonLabel(lv_obj_t* btn) } // OK -static inline void haspSetLabelText(lv_obj_t* obj, const char* value) +static inline void my_btn_set_text(lv_obj_t* obj, const char* value) { lv_obj_t* label = FindButtonLabel(obj); if(label) { @@ -691,7 +690,7 @@ static inline void haspSetLabelText(lv_obj_t* obj, const char* value) } // OK -static bool haspGetLabelText(lv_obj_t* obj, char** text) +static bool my_btn_get_text(lv_obj_t* obj, char** text) { if(!obj) { LOG_WARNING(TAG_ATTR, F("Button not defined")); @@ -716,7 +715,7 @@ static bool haspGetLabelText(lv_obj_t* obj, char** text) #endif } else { - LOG_WARNING(TAG_ATTR, F("haspGetLabelText NULL Pointer encountered")); + LOG_WARNING(TAG_ATTR, F("my_btn_get_text NULL Pointer encountered")); } return false; @@ -1385,57 +1384,90 @@ static void hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con // lv_obj_get_type(obj, &list); // const char * objtype = list.type[0]; - if(obj_check_type(obj, LV_HASP_BUTTON)) { - if(update) { - haspSetLabelText(obj, payload); - } else { - char* text = NULL; - if(haspGetLabelText(obj, &text) && text) attr_out_str(obj, attr, text); + switch(obj_get_type(obj)) { + + case LV_HASP_BUTTON: + if(update) { + my_btn_set_text(obj, payload); + } else { + char* text = NULL; + if(my_btn_get_text(obj, &text) && text) attr_out_str(obj, attr, text); + } + return; + + case LV_HASP_LABEL: + return update ? lv_label_set_text(obj, payload) : attr_out_str(obj, attr, lv_label_get_text(obj)); + + case LV_HASP_CHECKBOX: + return update ? lv_checkbox_set_text(obj, payload) : attr_out_str(obj, attr, lv_checkbox_get_text(obj)); + + case LV_HASP_DROPDOWN: { + char buffer[128]; + lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); + return attr_out_str(obj, attr, buffer); } - return; - } - if(obj_check_type(obj, LV_HASP_LABEL)) { - return update ? lv_label_set_text(obj, payload) : attr_out_str(obj, attr, lv_label_get_text(obj)); - } - if(obj_check_type(obj, LV_HASP_CHECKBOX)) { - return update ? lv_checkbox_set_text(obj, payload) : attr_out_str(obj, attr, lv_checkbox_get_text(obj)); - } - if(obj_check_type(obj, LV_HASP_DROPDOWN)) { - char buffer[128]; - lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); - return attr_out_str(obj, attr, buffer); - } - if(obj_check_type(obj, LV_HASP_ROLLER)) { - char buffer[128]; - lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); - return attr_out_str(obj, attr, buffer); - } - if(obj_check_type(obj, LV_HASP_MSGBOX)) { - if(update) { - lv_msgbox_set_text(obj, payload); - // lv_obj_realign(obj); /* Realign to the center */ - } else { - attr_out_str(obj, attr, lv_msgbox_get_text(obj)); + + case LV_HASP_ROLLER: { + char buffer[128]; + lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); + return attr_out_str(obj, attr, buffer); } - return; - } - if(obj_check_type(obj, LV_HASP_TABVIEW)) { - if(update) { + + case LV_HASP_MSGBOX: + if(update) { + lv_msgbox_set_text(obj, payload); + // lv_obj_realign(obj); /* Realign to the center */ + } else { + attr_out_str(obj, attr, lv_msgbox_get_text(obj)); + } + return; + + case LV_HASP_TABVIEW: { uint16_t id = lv_tabview_get_tab_act(obj); - if(id < lv_tabview_get_tab_count(obj)) lv_tabview_set_tab_name(obj, id, (char*)payload); - } else { - attr_out_str(obj, attr, my_tabview_get_tab_name(obj)); + if(id < lv_tabview_get_tab_count(obj)) { + if(update) { + lv_tabview_set_tab_name(obj, id, (char*)payload); + } else { + attr_out_str(obj, attr, my_tabview_get_tab_name(obj, id)); + } + } + return; } - return; - } + + case LV_HASP_TAB: { + lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up + if(!content) return LOG_WARNING(TAG_ATTR, F("content not found"), attr); + + lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up + if(!tabview) return LOG_WARNING(TAG_ATTR, F("Tabview not found"), attr); + + if(!obj_check_type(tabview, LV_HASP_TABVIEW)) + return LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); + + for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { + if(obj == lv_tabview_get_tab(tabview, id)) { + if(update) { + lv_tabview_set_tab_name(tabview, id, (char*)payload); + } else { + attr_out_str(obj, attr, my_tabview_get_tab_name(tabview, id)); + } + return; + } + } + LOG_WARNING(TAG_ATTR, F("Tab not found"), attr); + return; + } + #if LV_USE_WIN != 0 - if(obj_check_type(obj, LV_HASP_WINDOW)) { - // return update ? lv_win_set_title(obj, (const char *)payload) : attr_out_str(obj, attr, - // lv_win_get_title(obj)); - } + case LV_HASP_WINDOW: + // return update ? lv_win_set_title(obj, (const char *)payload) : attr_out_str(obj, attr, + // lv_win_get_title(obj)); + return; #endif - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); + default: + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); + } } bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool boolval, bool update) From 452b086a8e397b0c09283e32b40f21b803a8fe2f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 03:01:17 +0200 Subject: [PATCH 143/227] Speed optimization --- platformio.ini | 2 +- src/main_arduino.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 56c7f526..3bf62d55 100644 --- a/platformio.ini +++ b/platformio.ini @@ -190,7 +190,7 @@ build_flags= -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=12288U ; 12kB lvgl memory - -D LV_ATTRIBUTE_FAST_MEM= + -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments -D ARDUINOJSON_ENABLE_STD_STRING=1 ; for std::string diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index b990b941..94c8d440 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -169,9 +169,9 @@ IRAM_ATTR void loop() } #ifdef ARDUINO_ARCH_ESP8266 - delay(2); + delay((lv_task_get_idle() >> 6) + 1); // 1..2 ms #else - delay(6); + delay((lv_task_get_idle() >> 4) + 1); // 1..7 ms #endif } From 74439711b1841d7496c67bcb345e3bb978a80c2e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 03:01:33 +0200 Subject: [PATCH 144/227] Add power flag --- src/sys/gpio/hasp_gpio.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index 8ff2fad3..62ec3beb 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -12,13 +12,14 @@ extern "C" { struct hasp_gpio_config_t { - uint8_t pin; // pin number - uint8_t group; // groupid - uint8_t type; // switch, button, ... - uint8_t gpio_function; // INPUT, OUTPUT, PULLUP, etc + uint8_t gpio_function : 8; // INPUT, OUTPUT, PULLUP, etc + uint8_t pin : 8; // pin number + uint8_t group : 6; // groupid + uint8_t inverted : 1; + uint8_t power : 1; + uint8_t type; // switch, button, ... uint16_t val; uint16_t max; - bool inverted; }; void gpioSetup(void); From dc43fb66009a9f352bd21891f2ff3f0d08a989ec Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 03:02:18 +0200 Subject: [PATCH 145/227] Add timer events --- src/hasp/hasp_event.cpp | 40 +++++++++++++++++++++++++++++----------- src/hasp/hasp_event.h | 1 + src/hasp/hasp_object.cpp | 19 +++++++++++++++++-- src/hasp/hasp_object.h | 7 +++++++ 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index 4c27d210..a7f93b19 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -60,9 +60,16 @@ static void event_delete_object(lv_obj_t* obj) /* ============================== Timer Event ============================ */ void event_timer_calendar(lv_task_t* task) { - lv_obj_t* obj = (lv_obj_t*)task->user_data; + hasp_task_user_data_t* data = (hasp_task_user_data_t*)task->user_data; + lv_obj_t* obj; - if(!obj) return lv_task_del(task); // the calendar object for this task was deleted + if(data) obj = hasp_find_obj_from_page_id(data->pageid, data->objid); + if(!obj || !data) { + if(data) lv_mem_free(data); // the object that the user_data points to is gone + lv_task_del(task); // the calendar object for this task was deleted + LOG_WARNING(TAG_EVENT, "event_timer_calendar could not find the linked object"); + return; + } lv_calendar_date_t date; @@ -74,10 +81,12 @@ void event_timer_calendar(lv_task_t* task) if(timeinfo->tm_year < 120) { lv_task_set_period(task, 60000); // try again in a minute + LOG_WARNING(TAG_EVENT, "event_timer_calendar could not sync the clock"); return; } else { uint32_t next_hour = (3600 - (t % 3600)) * 1000; // ms to next top of hour - lv_task_set_period(task, next_hour + 128); // small offset so all tasks don't run at once + // lv_task_set_period(task, next_hour + 128); // small offset so all tasks don't run at once + lv_task_set_period(task, data->interval); } date.day = timeinfo->tm_mday; @@ -92,9 +101,16 @@ void event_timer_calendar(lv_task_t* task) void event_timer_clock(lv_task_t* task) { - lv_obj_t* obj = (lv_obj_t*)task->user_data; + hasp_task_user_data_t* data = (hasp_task_user_data_t*)task->user_data; + lv_obj_t* obj; - if(!obj) return lv_task_del(task); // the calendar object for this task was deleted + if(data) obj = hasp_find_obj_from_page_id(data->pageid, data->objid); + if(!obj || !data) { + if(data) lv_mem_free(data); // the object that the user_data points to is gone + lv_task_del(task); // the calendar object for this task was deleted + LOG_WARNING(TAG_EVENT, "event_timer_clock could not find the linked object"); + return; + } timeval curTime; int rslt = gettimeofday(&curTime, NULL); @@ -102,16 +118,18 @@ void event_timer_clock(lv_task_t* task) tm* timeinfo = localtime(&seconds); (void)rslt; // unused + char buffer[24]; if(timeinfo->tm_year < 120) { - lv_task_set_period(task, 60000); // try again in a minute - return; + snprintf_P(buffer, sizeof(buffer), PSTR("%il"), seconds); + } else { + strftime(buffer, sizeof(buffer), D_TIMESTAMP, timeinfo); // Literal String } - LOG_VERBOSE(TAG_EVENT, "event_timer_clock called with user %d:%d%s", timeinfo->tm_hour, timeinfo->tm_min, - timeinfo->tm_sec); + // LOG_VERBOSE(TAG_EVENT, "event_timer_clock called with user %d:%d:%d", timeinfo->tm_hour, timeinfo->tm_min, + // timeinfo->tm_sec); - uint16_t interval; - lv_task_set_period(task, (interval - (seconds % interval)) * 1000 + 64); // ms to next interval + lv_label_set_text(obj, buffer); + lv_task_set_period(task, data->interval); } /* ============================== Timer Event ============================ */ diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h index 50f6e40d..79ebcc8f 100644 --- a/src/hasp/hasp_event.h +++ b/src/hasp/hasp_event.h @@ -13,6 +13,7 @@ // Timer event Handlers void event_timer_calendar(lv_task_t* task); +void event_timer_clock(lv_task_t* task); // Object event Handlers void wakeup_event_handler(lv_obj_t* obj, lv_event_t event); diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index cde049d6..a20a2afe 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -96,6 +96,7 @@ const char* obj_get_type_name(lv_obj_t* obj) bool obj_check_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) { #if 1 + if(!obj) return false; return obj->user_data.objid == (uint8_t)haspobjtype; #else lv_obj_type_t list; @@ -267,6 +268,18 @@ int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) return i; } +static void object_add_task(lv_obj_t* obj, uint8_t pageid, uint8_t objid, lv_task_cb_t task_xcb, uint16_t interval) +{ + hasp_task_user_data_t* user_data = (hasp_task_user_data_t*)lv_mem_alloc(sizeof(hasp_task_user_data_t)); + if(!user_data) return; + + user_data->pageid = pageid; + user_data->objid = objid; + user_data->interval = interval; + lv_task_t* task = lv_task_create(task_xcb, 25, LV_TASK_PRIO_LOWEST, (void*)user_data); + (void)task; // unused +} + /** * Create a new object according to the json config * @param config Json representation for this object @@ -385,6 +398,8 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) lv_label_set_recolor(obj, true); lv_obj_set_event_cb(obj, generic_event_handler); obj->user_data.objid = LV_HASP_LABEL; + + // object_add_task(obj, pageid, id, event_timer_clock, 1000); } break; @@ -654,8 +669,8 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) if(obj) { lv_obj_set_event_cb(obj, calendar_event_handler); obj->user_data.objid = LV_HASP_CALENDER; - lv_task_t* task = lv_task_create(event_timer_calendar, 25, LV_TASK_PRIO_LOWEST, (void*)obj); - (void)task; // unused + + object_add_task(obj, pageid, id, event_timer_calendar, 5000); } break; diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index e98a1a86..e5d00107 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -13,6 +13,13 @@ const char FP_OBJID[] PROGMEM = "objid"; const char FP_PARENTID[] PROGMEM = "parentid"; const char FP_GROUPID[] PROGMEM = "groupid"; +typedef struct +{ + uint8_t pageid; + uint8_t objid; + uint16_t interval; +} hasp_task_user_data_t; + enum lv_hasp_obj_type_t { /* Containers */ LV_HASP_SCREEN = 1, From 1528e487958c89d666bf03766580303ec828ac29 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 03:03:24 +0200 Subject: [PATCH 146/227] Log mqtt data in errors and warnings --- src/hasp/hasp_dispatch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 16e73965..1ecd1541 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -69,10 +69,10 @@ void dispatch_state_subtopic(const char* subtopic, const char* payload) LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " %s => %s"), subtopic, payload); break; case MQTT_ERR_NO_CONN: - LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED)); + LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED " %s => %s"), subtopic, payload); break; default: - LOG_ERROR(TAG_MQTT, F(D_ERROR_UNKNOWN)); + LOG_ERROR(TAG_MQTT, F(D_ERROR_UNKNOWN " %s => %s"), subtopic, payload); } #endif From f5328a35b734d56a08876bd5e611b1f60f141eed Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 08:08:02 +0200 Subject: [PATCH 147/227] LV_ATTRIBUTE_FAST_MEM only on ESP32 --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 3bf62d55..8d84a093 100644 --- a/platformio.ini +++ b/platformio.ini @@ -116,7 +116,7 @@ build_flags = -D NO_GLOBAL_HTTPUPDATE ; dont instantiate httpUpdate ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=61440U ; 60kB lvgl memory - -D LV_ATTRIBUTE_FAST_MEM= + -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments ; -- tft_espi build options ------------------------ @@ -190,7 +190,7 @@ build_flags= -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=12288U ; 12kB lvgl memory - -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR + -D LV_ATTRIBUTE_FAST_MEM= ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments -D ARDUINOJSON_ENABLE_STD_STRING=1 ; for std::string From 2dc871f8bf7b51116faf45fc280a6cf5a226c62c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 08:08:32 +0200 Subject: [PATCH 148/227] Don't use HASP_ATTRIBUTE_FAST_MEM --- src/hasp/hasp_attribute.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index 46d89411..24632b6e 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -14,10 +14,10 @@ lv_chart_series_t* my_chart_get_series(lv_obj_t* chart, uint8_t ser_num); void my_obj_set_value_str_text(lv_obj_t* obj, uint8_t part, lv_state_t state, const char* text); void my_btnmatrix_map_clear(lv_obj_t* obj); +void my_msgbox_map_clear(lv_obj_t* obj); void line_clear_points(lv_obj_t* obj); -HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, - bool update); +void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update); bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool booval, bool update); void attr_out_str(lv_obj_t* obj, const char* attribute, const char* data); @@ -28,6 +28,27 @@ void attr_out_color(lv_obj_t* obj, const char* attribute, lv_color_t color); } /* extern "C" */ #endif +struct hasp_attr_update16_const_t +{ + lv_hasp_obj_type_t obj_type; + void (*set)(lv_obj_t*, uint16_t); + uint16_t (*get)(const lv_obj_t*); +}; + +struct hasp_attr_update16_t +{ + lv_hasp_obj_type_t obj_type; + void (*set)(lv_obj_t*, uint16_t); + uint16_t (*get)(lv_obj_t*); +}; + +struct hasp_attr_update_char_const_t +{ + lv_hasp_obj_type_t obj_type; + void (*set)(lv_obj_t*, const char*); + const char* (*get)(const lv_obj_t*); +}; + #define _HASP_ATTRIBUTE(prop_name, func_name, value_type) \ static inline void attribute_##func_name(lv_obj_t* obj, uint8_t part, lv_state_t state, bool update, \ const char* attr, value_type val) \ @@ -285,6 +306,7 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_SRC 4964 #define ATTR_ID 6715 #define ATTR_ANIM_TIME 59451 +#define ATTR_ANIM_SPEED 281 // methods #define ATTR_DELETE 50027 From e31b6810010e9ff3edc58a03a02637ddbfdfd574 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 08:08:56 +0200 Subject: [PATCH 149/227] Improve wifi retry interval --- src/sys/net/hasp_wifi.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sys/net/hasp_wifi.cpp b/src/sys/net/hasp_wifi.cpp index db547cad..a415b4a7 100644 --- a/src/sys/net/hasp_wifi.cpp +++ b/src/sys/net/hasp_wifi.cpp @@ -446,11 +446,11 @@ bool wifiEvery5Seconds() } else { wifiReconnectCounter++; if(wifiReconnectCounter > 45) { - LOG_ERROR(TAG_WIFI, F("Retries exceed %u: Rebooting..."), wifiReconnectCounter); + LOG_ERROR(TAG_WIFI, F("Retries exceeded %d: Rebooting..."), wifiReconnectCounter); dispatch_reboot(false); } - LOG_WARNING(TAG_WIFI, F("No Connection... retry %u"), wifiReconnectCounter); - if(wifiReconnectCounter % 6 == 0) { + LOG_WARNING(TAG_WIFI, F("No Connection... retry %d"), wifiReconnectCounter); + if(wifiReconnectCounter % 2 == 0) { wifiReconnect(); } return false; From afdd106df8c4140d2eaa19e6079f91da3bbbdd92 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 08:09:55 +0200 Subject: [PATCH 150/227] Declare more lv_obj_t* as const --- src/hasp/hasp_object.cpp | 13 +++++++------ src/hasp/hasp_object.h | 10 +++++----- src/hasp/hasp_page.cpp | 2 +- src/hasp/hasp_page.h | 3 ++- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index a20a2afe..20bc41f3 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -64,7 +64,7 @@ lv_obj_t* hasp_find_obj_from_page_id(uint8_t pageid, uint8_t objid) } // Return the pageid and objid of an object -bool hasp_find_id_from_obj(lv_obj_t* obj, uint8_t* pageid, uint8_t* objid) +bool hasp_find_id_from_obj(const lv_obj_t* obj, uint8_t* pageid, uint8_t* objid) { if(!obj || !haspPages.get_id(obj, pageid)) return false; if(obj->user_data.id == 0 && obj != haspPages.get_obj(*pageid)) return false; @@ -78,7 +78,7 @@ bool hasp_find_id_from_obj(lv_obj_t* obj, uint8_t* pageid, uint8_t* objid) * @return name of the object type * @note */ -const char* obj_get_type_name(lv_obj_t* obj) +const char* obj_get_type_name(const lv_obj_t* obj) { lv_obj_type_t list; lv_obj_get_type(obj, &list); @@ -93,7 +93,7 @@ const char* obj_get_type_name(lv_obj_t* obj) * @return true or false wether the types match * @note */ -bool obj_check_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) +bool obj_check_type(const lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) { #if 1 if(!obj) return false; @@ -112,12 +112,12 @@ bool obj_check_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) * @return lv_hasp_obj_type_t * @note */ -lv_hasp_obj_type_t obj_get_type(lv_obj_t* obj) +lv_hasp_obj_type_t obj_get_type(const lv_obj_t* obj) { return (lv_hasp_obj_type_t)obj->user_data.objid; } -void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level) +void hasp_object_tree(const lv_obj_t* parent, uint8_t pageid, uint16_t level) { if(parent == nullptr) return; @@ -239,7 +239,8 @@ void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, con // ##################### Object Creator ######################################################## -int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) +// Called from hasp_new_object only to process all attributes +static inline int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) { int i = 0; #if defined(WINDOWS) || defined(POSIX) diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index e5d00107..35095330 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -71,11 +71,11 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id); lv_obj_t* hasp_find_obj_from_parent_id(lv_obj_t* parent, uint8_t objid); lv_obj_t* hasp_find_obj_from_page_id(uint8_t pageid, uint8_t objid); -bool hasp_find_id_from_obj(lv_obj_t* obj, uint8_t* pageid, uint8_t* objid); -const char* obj_get_type_name(lv_obj_t* obj); -bool obj_check_type(lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype); -lv_hasp_obj_type_t obj_get_type(lv_obj_t* obj); -void hasp_object_tree(lv_obj_t* parent, uint8_t pageid, uint16_t level); +bool hasp_find_id_from_obj(const lv_obj_t* obj, uint8_t* pageid, uint8_t* objid); +const char* obj_get_type_name(const lv_obj_t* obj); +bool obj_check_type(const lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype); +lv_hasp_obj_type_t obj_get_type(const lv_obj_t* obj); +void hasp_object_tree(const lv_obj_t* parent, uint8_t pageid, uint16_t level); void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload); diff --git a/src/hasp/hasp_page.cpp b/src/hasp/hasp_page.cpp index c8f304ec..91ea4929 100644 --- a/src/hasp/hasp_page.cpp +++ b/src/hasp/hasp_page.cpp @@ -178,7 +178,7 @@ lv_obj_t* Page::get_obj(uint8_t pageid) return _pages[pageid - PAGE_START_INDEX]; } -bool Page::get_id(lv_obj_t* obj, uint8_t* pageid) +bool Page::get_id(const lv_obj_t* obj, uint8_t* pageid) { lv_obj_t* page = lv_obj_get_screen(obj); diff --git a/src/hasp/hasp_page.h b/src/hasp/hasp_page.h index d649c8fb..1872eb5f 100644 --- a/src/hasp/hasp_page.h +++ b/src/hasp/hasp_page.h @@ -45,6 +45,7 @@ class Page { uint8_t get_next(uint8_t pageid); uint8_t get_prev(uint8_t pageid); uint8_t get_back(uint8_t pageid); + void set_next(uint8_t pageid, uint8_t nextid); void set_prev(uint8_t pageid, uint8_t previd); void set_back(uint8_t pageid, uint8_t backid); @@ -52,7 +53,7 @@ class Page { uint8_t get(); void load_jsonl(const char* pagesfile); lv_obj_t* get_obj(uint8_t pageid); - bool get_id(lv_obj_t* obj, uint8_t* pageid); + bool get_id(const lv_obj_t* obj, uint8_t* pageid); bool is_valid(uint8_t pageid); }; From b49818e8c27603be73d4b646c36c943128aca55a Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 08:10:51 +0200 Subject: [PATCH 151/227] Fix missing hex color code --- src/hasp/hasp_event.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index a7f93b19..cfcccdc4 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -40,7 +40,7 @@ void swipe_event_handler(lv_obj_t* obj, lv_event_t event); */ static void event_delete_object(lv_obj_t* obj) { - switch(obj->user_data.objid) { + switch(obj_get_type(obj)) { case LV_HASP_LINE: line_clear_points(obj); break; @@ -49,8 +49,15 @@ static void event_delete_object(lv_obj_t* obj) my_btnmatrix_map_clear(obj); break; + case LV_HASP_MSGBOX: + my_msgbox_map_clear(obj); + break; + case LV_HASP_GAUGE: break; + + default: + break; } // TODO: delete value_str data for ALL parts @@ -61,7 +68,7 @@ static void event_delete_object(lv_obj_t* obj) void event_timer_calendar(lv_task_t* task) { hasp_task_user_data_t* data = (hasp_task_user_data_t*)task->user_data; - lv_obj_t* obj; + lv_obj_t* obj = NULL; if(data) obj = hasp_find_obj_from_page_id(data->pageid, data->objid); if(!obj || !data) { @@ -118,9 +125,9 @@ void event_timer_clock(lv_task_t* task) tm* timeinfo = localtime(&seconds); (void)rslt; // unused - char buffer[24]; + char buffer[24] = {0}; if(timeinfo->tm_year < 120) { - snprintf_P(buffer, sizeof(buffer), PSTR("%il"), seconds); + snprintf_P(buffer, sizeof(buffer), PSTR("%d"), seconds); } else { strftime(buffer, sizeof(buffer), D_TIMESTAMP, timeinfo); // Literal String } @@ -689,8 +696,8 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) c32.full = lv_color_to32(color); last_color_sent = color; - snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"color\":\"#\",\"r\":%d,\"g\":%d,\"b\":%d}"), eventname, - c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), + eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); event_send_object_data(obj, data); // dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); From 392083c9dcc6a6669a80d3fc9e181a4aa08481e6 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 8 May 2021 09:01:37 +0200 Subject: [PATCH 152/227] Add anim_time and anim_speed attributes, major housekeeping --- src/hasp/hasp_attribute.cpp | 523 +++++++++++++++++++----------------- 1 file changed, 283 insertions(+), 240 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 63aa0ffe..de2fc262 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -173,7 +173,7 @@ static bool attribute_update_lv_property(lv_obj_t * obj, const char * attr_p, ui } #endif -const char* my_tabview_get_tab_name(lv_obj_t* tabview, uint16_t id) +const char* my_tabview_get_tab_name(const lv_obj_t* tabview, uint16_t id) { if(id >= lv_tabview_get_tab_count(tabview)) return NULL; @@ -490,16 +490,6 @@ static void my_msgbox_set_map(lv_obj_t* obj, const char* payload) LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); } -static void my_msgbox_map_create(lv_obj_t* obj, const char* payload) -{ - const char** map = my_map_create(payload); - if(!map) return; - - my_btnmatrix_map_clear(obj); // Free previous map - lv_btnmatrix_set_map(obj, map); - LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); -} - void line_clear_points(lv_obj_t* obj) { lv_line_ext_t* ext = (lv_line_ext_t*)lv_obj_get_ext_attr(obj); @@ -689,21 +679,25 @@ static inline void my_btn_set_text(lv_obj_t* obj, const char* value) } } +// OK - lvgl does not return a const char * +static const char* my_label_get_text(const lv_obj_t* label) +{ + return lv_label_get_text(label); // library does not return const +} + // OK -static bool my_btn_get_text(lv_obj_t* obj, char** text) +static const char* my_btn_get_text(const lv_obj_t* obj) { if(!obj) { LOG_WARNING(TAG_ATTR, F("Button not defined")); - return false; + return NULL; } lv_obj_t* label = lv_obj_get_child_back(obj, NULL); if(label) { #if 1 - if(obj_check_type(label, LV_HASP_LABEL)) { - *text = lv_label_get_text(label); - return true; - } + if(obj_check_type(label, LV_HASP_LABEL)) return lv_label_get_text(label); + #else lv_obj_type_t list; lv_obj_get_type(label, &list); @@ -718,7 +712,7 @@ static bool my_btn_get_text(lv_obj_t* obj, char** text) LOG_WARNING(TAG_ATTR, F("my_btn_get_text NULL Pointer encountered")); } - return false; + return NULL; } static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, char* attr_out, uint8_t& part, @@ -826,6 +820,72 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch // } } +void my_tabview_set_text(lv_obj_t* obj, const char* payload) +{ + uint16_t id = lv_tabview_get_tab_act(obj); + if(id < lv_tabview_get_tab_count(obj)) { + lv_tabview_set_tab_name(obj, id, (char*)payload); + } +} + +const char* my_tabview_get_text(const lv_obj_t* obj) +{ + uint16_t id = lv_tabview_get_tab_act(obj); + if(id < lv_tabview_get_tab_count(obj)) { + return my_tabview_get_tab_name(obj, id); + } else { + return NULL; + } +} + +void my_tab_set_text(lv_obj_t* obj, const char* payload) +{ + lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up + if(!content) return LOG_WARNING(TAG_ATTR, F("content not found")); + + lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up + if(!tabview) return LOG_WARNING(TAG_ATTR, F("Tabview not found")); + + if(!obj_check_type(tabview, LV_HASP_TABVIEW)) + return LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); + + for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { + if(obj == lv_tabview_get_tab(tabview, id)) { + lv_tabview_set_tab_name(tabview, id, (char*)payload); + return; + } + } + LOG_WARNING(TAG_ATTR, F("Tab not found")); +} + +const char* my_tab_get_text(const lv_obj_t* obj) +{ + lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up + if(!content) { + LOG_WARNING(TAG_ATTR, F("content not found")); + return NULL; + } + + lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up + if(!tabview) { + LOG_WARNING(TAG_ATTR, F("Tabview not found")); + return NULL; + } + + if(!obj_check_type(tabview, LV_HASP_TABVIEW)) { + LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); + return NULL; + } + + for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { + if(obj == lv_tabview_get_tab(tabview, id)) { + return my_tabview_get_tab_name(tabview, id); + } + } + LOG_WARNING(TAG_ATTR, F("Tab not found")); + return NULL; +} + /** * Change or Retrieve the value of a local attribute of an object PART * @param obj lv_obj_t*: the object to get/set the attribute @@ -836,7 +896,7 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch * @note setting a value won't return anything, getting will dispatch the value */ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, const char* payload, - bool update) + bool update, bool& result) { char attr[32]; uint8_t part = LV_OBJ_PART_MAIN; @@ -852,6 +912,8 @@ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t at * when using hasp_out use attr_p for the original attribute name * *************************************************************** */ + result = true; // default return + switch(attr_hash) { /* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/ @@ -1161,9 +1223,6 @@ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t at return attribute_pattern_opa(obj, part, state, update, attr_p, (lv_opa_t)var); case ATTR_PATTERN_RECOLOR_OPA: return attribute_pattern_recolor_opa(obj, part, state, update, attr_p, (lv_opa_t)var); - case ATTR_PATTERN_IMAGE: - // return lv_obj_set_style_local_pattern_image(obj, part, state, (constvoid *)var); - break; case ATTR_PATTERN_RECOLOR: { if(update) { lv_color32_t c; @@ -1176,13 +1235,22 @@ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t at return; } + case ATTR_PATTERN_IMAGE: + // return lv_obj_set_style_local_pattern_image(obj, part, state, (constvoid *)var); + // return; + /* Image attributes */ // Todo /* Transition attributes */ // Todo + + default: + break; } + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN " (%d)"), attr_p, attr_hash); + result = false; } static void hasp_process_arc_attribute(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, const char* payload, @@ -1228,18 +1296,15 @@ static void hasp_process_arc_attribute(lv_obj_t* obj, const char* attr_p, uint16 LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr_p); } -static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, const char* payload, +static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, bool update) { - // We already know it's a linemeter object uint16_t val = atoi(payload); + // We already know it's a linemeter object uint16_t line_count = lv_linemeter_get_line_count(obj); uint16_t angle = lv_linemeter_get_scale_angle(obj); - char* attr = (char*)attr_p; - // if(*attr == '.') attr++; // strip leading '.' - switch(attr_hash) { case ATTR_TYPE: return (update) ? lv_linemeter_set_mirror(obj, val != 0) @@ -1256,19 +1321,16 @@ static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr_p, uin return (update) ? lv_linemeter_set_scale(obj, val, line_count) : attr_out_int(obj, attr, angle); } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr_p); + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); } -static void hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, const char* payload, +static void hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, bool update) { - // We already know it's a gauge object int16_t intval = atoi(payload); uint16_t val = atoi(payload); - char* attr = (char*)attr_p; - // if(*attr == '.') attr++; // strip leading '.' - + // We already know it's a gauge object switch(attr_hash) { case ATTR_DIRECTION: return (update) ? lv_dropdown_set_dir(obj, intval) : attr_out_int(obj, attr, lv_dropdown_get_dir(obj)); @@ -1292,10 +1354,10 @@ static void hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr_p, u : attr_out_int(obj, attr, lv_dropdown_get_show_selected(obj)); } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr_p); + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); } -static void hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, const char* payload, +static bool hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, bool update) { // We already know it's a gauge object @@ -1306,29 +1368,31 @@ static void hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr_p, uint uint16_t line_count = lv_gauge_get_line_count(obj); uint16_t angle = lv_gauge_get_scale_angle(obj); - char* attr = (char*)attr_p; - // if(*attr == '.') attr++; // strip leading '.' - switch(attr_hash) { case ATTR_CRITICAL_VALUE: - return (update) ? lv_gauge_set_critical_value(obj, intval) - : attr_out_int(obj, attr, lv_gauge_get_critical_value(obj)); + (update) ? lv_gauge_set_critical_value(obj, intval) + : attr_out_int(obj, attr, lv_gauge_get_critical_value(obj)); + return true; // found case ATTR_ANGLE: - return (update) ? lv_gauge_set_scale(obj, val, line_count, label_count) : attr_out_int(obj, attr, angle); + (update) ? lv_gauge_set_scale(obj, val, line_count, label_count) : attr_out_int(obj, attr, angle); + return true; // found case ATTR_LINE_COUNT: - return (update) ? lv_gauge_set_scale(obj, angle, val, label_count) : attr_out_int(obj, attr, line_count); + (update) ? lv_gauge_set_scale(obj, angle, val, label_count) : attr_out_int(obj, attr, line_count); + return true; // found case ATTR_LABEL_COUNT: - return (update) ? lv_gauge_set_scale(obj, angle, line_count, val) : attr_out_int(obj, attr, label_count); + (update) ? lv_gauge_set_scale(obj, angle, line_count, val) : attr_out_int(obj, attr, label_count); + return true; // found case ATTR_ROTATION: - return (update) ? lv_gauge_set_angle_offset(obj, val) - : attr_out_int(obj, attr, lv_gauge_get_angle_offset(obj)); + (update) ? lv_gauge_set_angle_offset(obj, val) : attr_out_int(obj, attr, lv_gauge_get_angle_offset(obj)); + return true; // found case ATTR_FORMAT: if(update) { + // TODO : getter needed switch(val) { case 1: lv_gauge_set_formatter_cb(obj, gauge_format_10); @@ -1346,16 +1410,17 @@ static void hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr_p, uint lv_gauge_set_formatter_cb(obj, NULL); } } - return; + return true; // found } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr_p); + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); + return false; } // ##################### Common Attributes ######################################################## -static void hasp_process_page_attributes(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, uint8_t val, - bool update) +static inline void hasp_process_page_attributes(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, uint8_t val, + bool update) { uint8_t pageid; @@ -1377,97 +1442,87 @@ static void hasp_process_page_attributes(lv_obj_t* obj, const char* attr_p, uint } } -static void hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, const char* payload, bool update) +static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, const char* payload, bool update) { - /* Attributes depending on objecttype */ - // lv_obj_type_t list; - // lv_obj_get_type(obj, &list); - // const char * objtype = list.type[0]; + hasp_attr_update_char_const_t text[] = { + {LV_HASP_BUTTON, my_btn_set_text, my_btn_get_text}, + {LV_HASP_LABEL, lv_label_set_text, my_label_get_text}, + {LV_HASP_CHECKBOX, lv_checkbox_set_text, lv_checkbox_get_text}, + {LV_HASP_TABVIEW, my_tabview_set_text, my_tabview_get_text}, + {LV_HASP_TAB, my_tab_set_text, my_tab_get_text}, +#if LV_USE_WIN != 0 + {LV_HASP_WINDOW, lv_win_set_title, lv_win_get_title}, +#endif + {LV_HASP_MSGBOX, lv_msgbox_set_text, lv_msgbox_get_text} + }; - switch(obj_get_type(obj)) { - - case LV_HASP_BUTTON: + for(int i = 0; i < sizeof(text) / sizeof(text[0]); i++) { + if(obj_check_type(obj, text[i].obj_type)) { if(update) { - my_btn_set_text(obj, payload); + text[i].set(obj, payload); } else { - char* text = NULL; - if(my_btn_get_text(obj, &text) && text) attr_out_str(obj, attr, text); + attr_out_str(obj, attr, text[i].get(obj)); } - return; - - case LV_HASP_LABEL: - return update ? lv_label_set_text(obj, payload) : attr_out_str(obj, attr, lv_label_get_text(obj)); - - case LV_HASP_CHECKBOX: - return update ? lv_checkbox_set_text(obj, payload) : attr_out_str(obj, attr, lv_checkbox_get_text(obj)); + return true; + } + } + // Special cases + // {LV_HASP_DROPDOWN, set_text_not_implemented, my_dropdown_get_text}, + // {LV_HASP_ROLLER, set_text_not_implemented, my_roller_get_text}, + switch(obj_get_type(obj)) { case LV_HASP_DROPDOWN: { char buffer[128]; lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); - return attr_out_str(obj, attr, buffer); + attr_out_str(obj, attr, buffer); + return true; } - case LV_HASP_ROLLER: { char buffer[128]; lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); - return attr_out_str(obj, attr, buffer); + attr_out_str(obj, attr, buffer); + return true; } - - case LV_HASP_MSGBOX: - if(update) { - lv_msgbox_set_text(obj, payload); - // lv_obj_realign(obj); /* Realign to the center */ - } else { - attr_out_str(obj, attr, lv_msgbox_get_text(obj)); - } - return; - - case LV_HASP_TABVIEW: { - uint16_t id = lv_tabview_get_tab_act(obj); - if(id < lv_tabview_get_tab_count(obj)) { - if(update) { - lv_tabview_set_tab_name(obj, id, (char*)payload); - } else { - attr_out_str(obj, attr, my_tabview_get_tab_name(obj, id)); - } - } - return; - } - - case LV_HASP_TAB: { - lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up - if(!content) return LOG_WARNING(TAG_ATTR, F("content not found"), attr); - - lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up - if(!tabview) return LOG_WARNING(TAG_ATTR, F("Tabview not found"), attr); - - if(!obj_check_type(tabview, LV_HASP_TABVIEW)) - return LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); - - for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { - if(obj == lv_tabview_get_tab(tabview, id)) { - if(update) { - lv_tabview_set_tab_name(tabview, id, (char*)payload); - } else { - attr_out_str(obj, attr, my_tabview_get_tab_name(tabview, id)); - } - return; - } - } - LOG_WARNING(TAG_ATTR, F("Tab not found"), attr); - return; - } - -#if LV_USE_WIN != 0 - case LV_HASP_WINDOW: - // return update ? lv_win_set_title(obj, (const char *)payload) : attr_out_str(obj, attr, - // lv_win_get_title(obj)); - return; -#endif - default: LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); } + return false; +} + +static inline bool attr_anim_time(lv_obj_t* obj, const char* attr, uint16_t val, bool update) +{ + { // Use anim_time for const lv_obj getters + hasp_attr_update16_const_t anim_time[] = {{LV_HASP_BAR, lv_bar_set_anim_time, lv_bar_get_anim_time}, + {LV_HASP_SWITCH, lv_switch_set_anim_time, lv_switch_get_anim_time}, + {LV_HASP_LIST, lv_list_set_anim_time, lv_list_get_anim_time}, + {LV_HASP_MSGBOX, lv_msgbox_set_anim_time, lv_msgbox_get_anim_time}, + {LV_HASP_PAGE, lv_page_set_anim_time, lv_page_get_anim_time}, + {LV_HASP_ROLLER, lv_roller_set_anim_time, lv_roller_get_anim_time}, + {LV_HASP_TABVIEW, lv_tabview_set_anim_time, lv_tabview_get_anim_time}, + {LV_HASP_WINDOW, lv_win_set_anim_time, lv_win_get_anim_time}}; + + int count = sizeof(anim_time) / sizeof(anim_time[0]); + for(int i = 0; i < count; i++) { + if(obj_check_type(obj, anim_time[i].obj_type)) { + update ? anim_time[i].set(obj, val) : attr_out_int(obj, attr, anim_time[i].get(obj)); + return true; + } + } + } + + { // Re-use anim_time for non-const lv_obj getters + hasp_attr_update16_t anim_time[] = {{LV_HASP_SLIDER, lv_slider_set_anim_time, lv_slider_get_anim_time}, + {LV_HASP_TILEVIEW, lv_tileview_set_anim_time, lv_tileview_get_anim_time}}; + + int count = sizeof(anim_time) / sizeof(anim_time[0]); + for(int i = 0; i < count; i++) { + if(obj_check_type(obj, anim_time[i].obj_type)) { + update ? anim_time[i].set(obj, val) : attr_out_int(obj, attr, anim_time[i].get(obj)); + return true; + } + } + } + return false; } bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool boolval, bool update) @@ -1523,11 +1578,6 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co int16_t val = atoi(payload); int32_t val32 = strtol(payload, nullptr, DEC); - /* Attributes depending on objecttype */ - // lv_obj_type_t list; - // lv_obj_get_type(obj, &list); - // const char * objtype = list.type[0]; - if(obj_check_type(obj, LV_HASP_SLIDER)) { int16_t min = lv_slider_get_min_value(obj); int16_t max = lv_slider_get_max_value(obj); @@ -1589,8 +1639,7 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co * @param update bool: change/set the value if true, dispatch/get value if false * @note setting a value won't return anything, getting will dispatch the value */ -HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, - bool update) +void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update) { // unsigned long start = millis(); if(!obj) { @@ -1602,45 +1651,45 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha // if(*attr == '.') attr++; // strip leading '.' uint16_t attr_hash = Parser::get_sdbm(attr); - int16_t val = atoi(payload); + int32_t val = atoi(payload); /* 16-bit Hash Lookup Table */ switch(attr_hash) { case ATTR_ID: update ? (void)(obj->user_data.id = (uint8_t)val) : attr_out_int(obj, attr, obj->user_data.id); - break; // attribute_found + return; // attribute_found case ATTR_GROUPID: update ? (void)(obj->user_data.groupid = (uint8_t)val) : attr_out_int(obj, attr, obj->user_data.groupid); - break; // attribute_found + return; // attribute_found case ATTR_ACTION: update ? (void)(obj->user_data.actionid = Parser::get_action_id(payload)) : attr_out_int(obj, attr, obj->user_data.actionid); - break; // attribute_found + return; // attribute_found case ATTR_TRANSITION: update ? (void)(obj->user_data.transitionid = (uint8_t)val) : attr_out_int(obj, attr, obj->user_data.transitionid); - break; // attribute_found + return; // attribute_found case ATTR_OBJ: if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); attr_out_str(obj, attr, obj_get_type_name(obj)); - break; // attribute_found + return; // attribute_found case ATTR_OBJID: if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); attr_out_int(obj, attr, obj->user_data.objid); - break; // attribute_found + return; // attribute_found case ATTR_X: update ? lv_obj_set_x(obj, val) : attr_out_int(obj, attr, lv_obj_get_x(obj)); - break; // attribute_found + return; // attribute_found case ATTR_Y: update ? lv_obj_set_y(obj, val) : attr_out_int(obj, attr, lv_obj_get_y(obj)); - break; // attribute_found + return; // attribute_found case ATTR_W: if(update) { @@ -1654,7 +1703,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_int(obj, attr, lv_obj_get_width(obj)); } - break; // attribute_found + return; // attribute_found case ATTR_H: if(update) { @@ -1668,22 +1717,22 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_int(obj, attr, lv_obj_get_height(obj)); } - break; // attribute_found + return; // attribute_found case ATTR_VIS: update ? lv_obj_set_hidden(obj, !Parser::is_true(payload)) : attr_out_int(obj, attr, !lv_obj_get_hidden(obj)); - break; // attribute_found + return; // attribute_found case ATTR_HIDDEN: update ? lv_obj_set_hidden(obj, Parser::is_true(payload)) : attr_out_int(obj, attr, lv_obj_get_hidden(obj)); - break; // attribute_found + return; // attribute_found case ATTR_TXT: // TODO: remove LOG_WARNING(TAG_HASP, F("txt property is obsolete, use text instead")); case ATTR_TEXT: hasp_process_obj_attribute_text(obj, attr, payload, update); - break; // attribute_found + return; // attribute_found case ATTR_COLOR: if(obj_check_type(obj, LV_HASP_CPICKER)) { @@ -1694,106 +1743,110 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_color(obj, attr, lv_cpicker_get_color(obj)); } - } else { - goto attribute_not_found; + return; // attribute_found } - break; // attribute_found + break; // not found case ATTR_VAL: - if(!hasp_process_obj_attribute_val(obj, attr, atoi(payload), Parser::is_true(payload), update)) - goto attribute_not_found; - break; // attribute_found + if(hasp_process_obj_attribute_val(obj, attr, atoi(payload), Parser::is_true(payload), update)) + return; // attribute_found + break; // not found case ATTR_MIN: hasp_process_obj_attribute_range(obj, attr, payload, update, true, false); - break; // attribute_found + return; // attribute_found case ATTR_MAX: hasp_process_obj_attribute_range(obj, attr, payload, update, false, true); - break; // attribute_found + return; // attribute_found case ATTR_OPACITY: update ? lv_obj_set_style_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, val) : attr_out_int(obj, attr, lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN)); - break; // attribute_found + return; // attribute_found case ATTR_ENABLED: update ? lv_obj_set_click(obj, Parser::is_true(payload)) : attr_out_int(obj, attr, lv_obj_get_click(obj)); - break; // attribute_found + return; // attribute_found case ATTR_SWIPE: update ? (void)(obj->user_data.swipeid = Parser::is_true(payload) % 16) : attr_out_int(obj, attr, obj->user_data.swipeid); - break; // attribute_found + return; // attribute_found case ATTR_SRC: if(obj_check_type(obj, LV_HASP_IMAGE)) { if(update) { - return lv_img_set_src(obj, payload); + lv_img_set_src(obj, payload); } else { switch(lv_img_src_get_type(obj)) { case LV_IMG_SRC_FILE: return attr_out_str(obj, attr, lv_img_get_file_name(obj)); case LV_IMG_SRC_SYMBOL: return attr_out_str(obj, attr, (char*)lv_img_get_src(obj)); - default: - return; } } - } else { - goto attribute_not_found; + return; // attribute_found } - break; // attribute_found + break; // not found - /* case ATTR_ANIM_TIME: - return (update) ? lv_anim_time(obj, val) - : attr_out_int(obj, attr, lv_gauge_get_angle_offset(obj)); */ + case ATTR_ANIM_SPEED: + if(obj_check_type(obj, LV_HASP_LABEL)) { + update ? lv_label_set_anim_speed(obj, (uint16_t)val) + : attr_out_int(obj, attr, lv_label_get_anim_speed(obj)); + return; // attribute_found + } + break; // not found + + case ATTR_ANIM_TIME: + if(attr_anim_time(obj, attr, val, update)) return; // attribute_found + break; // not found case ATTR_ROWS: switch(obj_get_type(obj)) { case LV_HASP_ROLLER: update ? lv_roller_set_visible_row_count(obj, (uint8_t)val) : attr_out_int(obj, attr, my_roller_get_visible_row_count(obj)); - break; + return; // attribute_found case LV_HASP_TABLE: update ? lv_table_set_row_cnt(obj, (uint8_t)val) : attr_out_int(obj, attr, lv_table_get_row_cnt(obj)); - break; + return; // attribute_found default: - goto attribute_not_found; + break; // not found } - break; // attribute_found + break; // not found case ATTR_COLS: if(obj_check_type(obj, LV_HASP_TABLE)) { update ? lv_table_set_col_cnt(obj, (uint8_t)val) : attr_out_int(obj, attr, lv_table_get_col_cnt(obj)); - } else { - goto attribute_not_found; + return; // attribute_found } - break; // attribute_found + break; // not found case ATTR_ALIGN: switch(obj_get_type(obj)) { case LV_HASP_BUTTON: { lv_obj_t* label = FindButtonLabel(obj); - if(label == NULL) - goto attribute_not_found; - else + if(label) { update ? lv_label_set_align(label, val) : attr_out_int(obj, attr, lv_label_get_align(label)); - } break; + return; // attribute_found + } + break; // not found + } case LV_HASP_BTNMATRIX: update ? lv_btnmatrix_set_align(obj, val) : attr_out_int(obj, attr, lv_btnmatrix_get_align(obj)); - break; + return; // attribute_found case LV_HASP_LABEL: update ? lv_label_set_align(obj, val) : attr_out_int(obj, attr, lv_label_get_align(obj)); - break; + return; // attribute_found case LV_HASP_ROLLER: update ? lv_roller_set_align(obj, val) : attr_out_int(obj, attr, lv_roller_get_align(obj)); - break; + return; // attribute_found default: - goto attribute_not_found; + break; // not found } - break; // attribute_found + break; // not found case ATTR_MODE: switch(obj_get_type(obj)) { @@ -1803,10 +1856,11 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha hasp_process_label_long_mode(label, payload, update); lv_obj_set_width(label, lv_obj_get_width(obj)); } - } break; + return; // attribute_found + } case LV_HASP_LABEL: hasp_process_label_long_mode(obj, payload, update); - break; + return; // attribute_found case LV_HASP_ROLLER: if(update) { lv_roller_set_options(obj, lv_roller_get_options(obj), @@ -1815,11 +1869,11 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); attr_out_int(obj, attr, ext->mode); } - break; + return; // attribute_found default: - goto attribute_not_found; + break; // not found } - break; // attribute_found + break; // not found case ATTR_TOGGLE: switch(obj_get_type(obj)) { @@ -1831,7 +1885,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_int(obj, attr, lv_btn_get_checkable(obj)); } - break; + return; // attribute_found case LV_HASP_BTNMATRIX: if(update) { bool toggle = Parser::is_true(payload); @@ -1844,11 +1898,11 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_int(obj, attr, lv_btn_get_checkable(obj)); } - break; + return; // attribute_found default: - goto attribute_not_found; + break; // not found } - break; // attribute_found + break; // not found case ATTR_OPTIONS: switch(obj_get_type(obj)) { @@ -1858,7 +1912,7 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_str(obj, attr, lv_dropdown_get_options(obj)); } - break; + return; // attribute_found case LV_HASP_ROLLER: if(update) { lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); @@ -1866,25 +1920,25 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_str(obj, attr, lv_roller_get_options(obj)); } - break; + return; // attribute_found case LV_HASP_BTNMATRIX: if(update) { my_btnmatrix_set_map(obj, payload); } else { attr_out_str(obj, attr_p, "Not implemented"); // TODO : Literal String } - break; + return; // attribute_found case LV_HASP_MSGBOX: if(update) { my_msgbox_set_map(obj, payload); } else { attr_out_str(obj, attr_p, "Not implemented"); // TODO : Literal String } - break; + return; // attribute_found default: - goto attribute_not_found; + break; // not found } - break; // attribute_found + break; // not found case ATTR_ONE_CHECK: if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { @@ -1893,10 +1947,9 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_int(obj, attr_p, lv_btnmatrix_get_one_check(obj)); } - } else { - goto attribute_not_found; + return; // attribute_found } - break; + break; // not found case ATTR_BTN_POS: if(obj_check_type(obj, LV_HASP_TABVIEW)) { @@ -1905,20 +1958,17 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { attr_out_int(obj, attr_p, lv_tabview_get_btns_pos(obj)); } - } else { - goto attribute_not_found; + return; // attribute_found } - break; + break; // not found case ATTR_COUNT: if(obj_check_type(obj, LV_HASP_TABVIEW)) { if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); attr_out_int(obj, attr_p, lv_tabview_get_tab_count(obj)); - - } else { - goto attribute_not_found; + return; // attribute_found } - break; + break; // not found // case ATTR_MODAL: case ATTR_AUTO_CLOSE: @@ -1928,10 +1978,9 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha } else { lv_msgbox_stop_auto_close(obj); } - } else { - goto attribute_not_found; + return; // attribute_found } - break; + break; // not found case ATTR_CRITICAL_VALUE: case ATTR_ANGLE: @@ -1948,17 +1997,17 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha switch(obj_get_type(obj)) { case LV_HASP_ARC: hasp_process_arc_attribute(obj, attr_p, attr_hash, payload, update); - break; + return; // attribute_found case LV_HASP_GAUGE: - hasp_process_gauge_attribute(obj, attr_p, attr_hash, payload, update); - break; + if(hasp_process_gauge_attribute(obj, attr_p, attr_hash, payload, update)) return; // attribute_found + break; // not found case LV_HASP_LMETER: hasp_process_lmeter_attribute(obj, attr_p, attr_hash, payload, update); - break; + return; // attribute_found default: - goto attribute_not_found; + break; // not found } - break; // attribute_found + break; // not found case ATTR_DIRECTION: case ATTR_SYMBOL: @@ -1968,64 +2017,58 @@ HASP_ATTRIBUTE_FAST_MEM void hasp_process_obj_attribute(lv_obj_t* obj, const cha case ATTR_SHOW_SELECTED: if(obj_check_type(obj, LV_HASP_DROPDOWN)) { hasp_process_dropdown_attribute(obj, attr_p, attr_hash, payload, update); - } else { - goto attribute_not_found; + return; // attribute_found } - break; // attribute_found + break; // not found case ATTR_RED: // TODO: remove temp RED if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { my_btnmatrix_map_clear(obj); // TODO : remove this test property - } else { - goto attribute_not_found; + return; // attribute_found } - break; + break; // not found /* ***** Methods ***** */ case ATTR_DELETE: if(!lv_obj_get_parent(obj)) { LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attr_p); - return; + } else { + lv_obj_del_async(obj); } - lv_obj_del_async(obj); - break; // attribute_found + return; // attribute_found case ATTR_TO_FRONT: if(!lv_obj_get_parent(obj)) { LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attr_p); - return; + } else { + lv_obj_move_foreground(obj); } - lv_obj_move_foreground(obj); - break; // attribute_found + return; // attribute_found case ATTR_TO_BACK: if(!lv_obj_get_parent(obj)) { LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attr_p); - return; + } else { + lv_obj_move_background(obj); } - lv_obj_move_background(obj); - break; // attribute_found + return; // attribute_found case ATTR_NEXT: case ATTR_PREV: case ATTR_BACK: if(obj_check_type(obj, LV_HASP_SCREEN)) { hasp_process_page_attributes(obj, attr_p, attr_hash, val, update); - break; // attribute_found + return; // attribute_found } - goto attribute_not_found; + break; // not found - default: - hasp_local_style_attr(obj, attr, attr_hash, payload, update); - goto attribute_found; + default: { + bool result; + hasp_local_style_attr(obj, attr, attr_hash, payload, update, result); + if(result) return; // attribute_found + } } -attribute_found: - // LOG_VERBOSE(TAG_ATTR, F("%s (%d)"), attr_p, attr_hash); - // LOG_VERBOSE(TAG_ATTR, F("%s (%d) took %d ms."), attr_p, attr_hash, millis() - start); - return; - -attribute_not_found: LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN " (%d)"), attr_p, attr_hash); } From 333185a472ba114718c3628c08e09344b68e135e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 9 May 2021 23:07:36 +0200 Subject: [PATCH 153/227] Adjust partitions to use all remaining space for lfs filesystem --- platformio.ini | 3 ++- user_setups/esp32/esp32-touchdown.ini | 1 + user_setups/esp32/freetouchdeck.ini | 1 + user_setups/esp32/huzzah32-featherwing-24.ini | 2 ++ user_setups/esp32/huzzah32-featherwing-35.ini | 2 ++ user_setups/esp32/lanbon_l8.ini | 4 ++-- user_setups/esp32/lolin-d32-pro_ili9341.ini | 3 +-- user_setups/esp32/m5stack_core2.ini | 3 +-- user_setups/esp32/partition_app1280k_spiffs1472k.csv | 6 ------ user_setups/esp32/partition_app1300k_spiffs1216k.csv | 6 ------ user_setups/esp32/partition_app1536k_spiffs1024k.csv | 6 ------ user_setups/esp32/partition_app1704k_spiffs720k.csv | 6 ------ user_setups/esp32/partition_app2000k_spiffs4000k.csv | 6 ------ user_setups/esp32/partitions_16MB.csv | 9 +++++++++ user_setups/esp32/partitions_2MB.csv | 8 ++++++++ user_setups/esp32/partitions_32MB.csv | 9 +++++++++ user_setups/esp32/partitions_4MB.csv | 9 +++++++++ user_setups/esp32/partitions_8MB.csv | 9 +++++++++ user_setups/esp32/ttgo-esp32-lilygo-pi.ini | 3 +-- 19 files changed, 57 insertions(+), 39 deletions(-) delete mode 100644 user_setups/esp32/partition_app1280k_spiffs1472k.csv delete mode 100644 user_setups/esp32/partition_app1300k_spiffs1216k.csv delete mode 100644 user_setups/esp32/partition_app1536k_spiffs1024k.csv delete mode 100644 user_setups/esp32/partition_app1704k_spiffs720k.csv delete mode 100644 user_setups/esp32/partition_app2000k_spiffs4000k.csv create mode 100644 user_setups/esp32/partitions_16MB.csv create mode 100644 user_setups/esp32/partitions_2MB.csv create mode 100644 user_setups/esp32/partitions_32MB.csv create mode 100644 user_setups/esp32/partitions_4MB.csv create mode 100644 user_setups/esp32/partitions_8MB.csv diff --git a/platformio.ini b/platformio.ini index 8d84a093..9c379c5c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -94,7 +94,7 @@ platform = espressif32@^3.2.0 board_upload.flash_size=4MB board_upload.maximum_size = 4194304 -board_build.partitions = user_setups/esp32/partition_app1704k_spiffs720k.csv +board_build.partitions = user_setups/esp32/partitions_4MB.csv board_build.filesystem = littlefs board_build.embed_files = data/edit.htm.gz @@ -117,6 +117,7 @@ build_flags = ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=61440U ; 60kB lvgl memory -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR + ;-D LV_FS_PC_PATH="/lfs" ; this needs to match the vfs mount pount ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments ; -- tft_espi build options ------------------------ diff --git a/user_setups/esp32/esp32-touchdown.ini b/user_setups/esp32/esp32-touchdown.ini index 61ae1322..f02387e0 100644 --- a/user_setups/esp32/esp32-touchdown.ini +++ b/user_setups/esp32/esp32-touchdown.ini @@ -12,6 +12,7 @@ build_flags = ${env.build_flags} ${esp32.build_flags} ${esp32.vspi} ; Use VSPI hardware SPI bus + -D HASP_MODEL="ESP32 Touchdown" ;region -- TFT_eSPI build options ------------------------ -D USER_SETUP_LOADED=1 diff --git a/user_setups/esp32/freetouchdeck.ini b/user_setups/esp32/freetouchdeck.ini index 9bd6aebf..de662271 100644 --- a/user_setups/esp32/freetouchdeck.ini +++ b/user_setups/esp32/freetouchdeck.ini @@ -11,6 +11,7 @@ board = esp32dev build_flags = ${env.build_flags} ${esp32.build_flags} + -D HASP_MODEL="FreeTouchDeck" ;region -- TFT_eSPI build options ------------------------ -D USER_SETUP_LOADED=1 diff --git a/user_setups/esp32/huzzah32-featherwing-24.ini b/user_setups/esp32/huzzah32-featherwing-24.ini index 2c1d23fc..ecbb68e0 100644 --- a/user_setups/esp32/huzzah32-featherwing-24.ini +++ b/user_setups/esp32/huzzah32-featherwing-24.ini @@ -12,6 +12,8 @@ board = featheresp32 build_flags = ${env.build_flags} ${esp32.build_flags} + -D HASP_MODEL="Adafruit Featherwing 2.4" + ;region -- TFT_eSPI build options ------------------------ ${lcd.featherwing-24} -D TFT_MISO=19 diff --git a/user_setups/esp32/huzzah32-featherwing-35.ini b/user_setups/esp32/huzzah32-featherwing-35.ini index 86096861..27775bf6 100644 --- a/user_setups/esp32/huzzah32-featherwing-35.ini +++ b/user_setups/esp32/huzzah32-featherwing-35.ini @@ -12,6 +12,8 @@ board = featheresp32 build_flags = ${env.build_flags} ${esp32.build_flags} + -D HASP_MODEL="Adafruit Featherwing 3.2" + ;region -- TFT_eSPI build options ------------------------ ${lcd.featherwing-35} -D TFT_MISO=19 diff --git a/user_setups/esp32/lanbon_l8.ini b/user_setups/esp32/lanbon_l8.ini index 780fb0ab..6c8e6606 100644 --- a/user_setups/esp32/lanbon_l8.ini +++ b/user_setups/esp32/lanbon_l8.ini @@ -8,15 +8,15 @@ [env:lanbon_l8] extends = esp32 board = esp32dev - board_upload.flash_size=8MB board_upload.maximum_size = 8388608 -board_build.partitions = user_setups/esp32/partition_app2000k_spiffs4000k.csv +board_build.partitions = user_setups/esp32/partitions_8MB.csv build_flags = ${env.build_flags} ${esp32.build_flags} ${esp32.ps_ram} + -D HASP_MODEL="Lanbon L8" ;region -- TFT_eSPI build options ------------------------ ${lcd.st7789v} diff --git a/user_setups/esp32/lolin-d32-pro_ili9341.ini b/user_setups/esp32/lolin-d32-pro_ili9341.ini index 7967a72c..83a53575 100644 --- a/user_setups/esp32/lolin-d32-pro_ili9341.ini +++ b/user_setups/esp32/lolin-d32-pro_ili9341.ini @@ -10,10 +10,9 @@ [env:lolin-d32-pro_ili9341] extends = esp32 board = lolin_d32_pro - board_upload.flash_size=16MB board_upload.maximum_size = 16777216 -board_build.partitions = user_setups/esp32/partition_app2000k_spiffs4000k.csv +board_build.partitions = user_setups/esp32/partitions_16MB.csv build_flags = ${env.build_flags} diff --git a/user_setups/esp32/m5stack_core2.ini b/user_setups/esp32/m5stack_core2.ini index 7eaa0427..bf336aec 100644 --- a/user_setups/esp32/m5stack_core2.ini +++ b/user_setups/esp32/m5stack_core2.ini @@ -8,10 +8,9 @@ [env:m5stack-core2] extends = esp32 board = esp32dev - board_upload.flash_size=16MB board_upload.maximum_size = 16777216 -board_build.partitions = user_setups/esp32/partition_app2000k_spiffs4000k.csv +board_build.partitions = user_setups/esp32/partitions_16MB.csv build_flags = ${env.build_flags} diff --git a/user_setups/esp32/partition_app1280k_spiffs1472k.csv b/user_setups/esp32/partition_app1280k_spiffs1472k.csv deleted file mode 100644 index 47367800..00000000 --- a/user_setups/esp32/partition_app1280k_spiffs1472k.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size,Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xE000, 0x2000, -app0, app, ota_0, 0x10000, 0x140000, -app1, app, ota_1, 0x150000, 0x140000, -spiffs, data, spiffs, 0x290000, 0x170000, diff --git a/user_setups/esp32/partition_app1300k_spiffs1216k.csv b/user_setups/esp32/partition_app1300k_spiffs1216k.csv deleted file mode 100644 index d361047a..00000000 --- a/user_setups/esp32/partition_app1300k_spiffs1216k.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x160000, -app1, app, ota_1, 0x170000, 0x160000, -spiffs, data, spiffs, 0x2D0000, 0x130000, diff --git a/user_setups/esp32/partition_app1536k_spiffs1024k.csv b/user_setups/esp32/partition_app1536k_spiffs1024k.csv deleted file mode 100644 index 414702e0..00000000 --- a/user_setups/esp32/partition_app1536k_spiffs1024k.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x180000, -app1, app, ota_1, 0x190000, 0x180000, -spiffs, data, spiffs, 0x310000, 0x0F0000, diff --git a/user_setups/esp32/partition_app1704k_spiffs720k.csv b/user_setups/esp32/partition_app1704k_spiffs720k.csv deleted file mode 100644 index cd96d227..00000000 --- a/user_setups/esp32/partition_app1704k_spiffs720k.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x1A0000, -app1, app, ota_1, 0x1B0000, 0x1A0000, -spiffs, data, spiffs, 0x350000, 0x0B0000, diff --git a/user_setups/esp32/partition_app2000k_spiffs4000k.csv b/user_setups/esp32/partition_app2000k_spiffs4000k.csv deleted file mode 100644 index 0ada1ac6..00000000 --- a/user_setups/esp32/partition_app2000k_spiffs4000k.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x1F0000, -app1, app, ota_1, 0x200000, 0x1F0000, -spiffs, data, spiffs, 0x3F0000, 0x410000, diff --git a/user_setups/esp32/partitions_16MB.csv b/user_setups/esp32/partitions_16MB.csv new file mode 100644 index 00000000..6d259294 --- /dev/null +++ b/user_setups/esp32/partitions_16MB.csv @@ -0,0 +1,9 @@ +# Two application partitions of ~2.0 MB +# 12 MB filesystem +# +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 36K, 20K, +otadata, data, ota, 56K, 8K, +app0, app, ota_0, 64K, 2016K, +app1, app, ota_1, 2080K, 2016K, +spiffs, data, spiffs, 4M, 12M, \ No newline at end of file diff --git a/user_setups/esp32/partitions_2MB.csv b/user_setups/esp32/partitions_2MB.csv new file mode 100644 index 00000000..19840001 --- /dev/null +++ b/user_setups/esp32/partitions_2MB.csv @@ -0,0 +1,8 @@ +# One single application partition of 1.625 MB +# 320 kB filesystem +# +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 36K, 20K, +otadata, data, ota, 56K, 8K, +app0, app, ota_0, 64K, 1664K, +spiffs, data, spiffs, 1728K, 320K, diff --git a/user_setups/esp32/partitions_32MB.csv b/user_setups/esp32/partitions_32MB.csv new file mode 100644 index 00000000..49b445b8 --- /dev/null +++ b/user_setups/esp32/partitions_32MB.csv @@ -0,0 +1,9 @@ +# Two application partitions of ~2.0 MB +# 28 MB filesystem +# +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 36K, 20K, +otadata, data, ota, 56K, 8K, +app0, app, ota_0, 64K, 2016K, +app1, app, ota_1, 2080K, 2016K, +spiffs, data, spiffs, 4M, 28M, diff --git a/user_setups/esp32/partitions_4MB.csv b/user_setups/esp32/partitions_4MB.csv new file mode 100644 index 00000000..733ff0c5 --- /dev/null +++ b/user_setups/esp32/partitions_4MB.csv @@ -0,0 +1,9 @@ +# Two application partitions of 1664 kB +# 704 kB filesystem +# +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 36K, 20K, +otadata, data, ota, 56K, 8K, +app0, app, ota_0, 64K, 1664K, +app1, app, ota_1, 1728K, 1664K, +spiffs, data, spiffs, 3392K, 704K, diff --git a/user_setups/esp32/partitions_8MB.csv b/user_setups/esp32/partitions_8MB.csv new file mode 100644 index 00000000..241440b9 --- /dev/null +++ b/user_setups/esp32/partitions_8MB.csv @@ -0,0 +1,9 @@ +# Two application partitions of ~2.0 MB +# 4 MB filesystem +# +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 36K, 20K, +otadata, data, ota, 56K, 8K, +app0, app, ota_0, 64K, 2016K, +app1, app, ota_1, 2080K, 2016K, +spiffs, data, spiffs, 4M, 4M, diff --git a/user_setups/esp32/ttgo-esp32-lilygo-pi.ini b/user_setups/esp32/ttgo-esp32-lilygo-pi.ini index d6bffca3..53ea2d09 100644 --- a/user_setups/esp32/ttgo-esp32-lilygo-pi.ini +++ b/user_setups/esp32/ttgo-esp32-lilygo-pi.ini @@ -8,10 +8,9 @@ [env:ttgo-esp32-lilygo-pi] extends = esp32 board = esp32dev - board_upload.flash_size=16MB board_upload.maximum_size = 16777216 -board_build.partitions = user_setups/esp32/partition_app2000k_spiffs4000k.csv +board_build.partitions = user_setups/esp32/partitions_16MB.csv build_flags = ${env.build_flags} From 33e3fbb71efc318866313aacdbd3a04c019a18a5 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 9 May 2021 23:41:54 +0200 Subject: [PATCH 154/227] Align partition boundaries on 64 kB --- user_setups/esp32/partitions_16MB.csv | 10 +++++----- user_setups/esp32/partitions_32MB.csv | 10 +++++----- user_setups/esp32/partitions_8MB.csv | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/user_setups/esp32/partitions_16MB.csv b/user_setups/esp32/partitions_16MB.csv index 6d259294..45bb999d 100644 --- a/user_setups/esp32/partitions_16MB.csv +++ b/user_setups/esp32/partitions_16MB.csv @@ -1,9 +1,9 @@ -# Two application partitions of ~2.0 MB -# 12 MB filesystem +# Two application partitions of 2.0 MB +# Filesystem: ~12 MB # # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 36K, 20K, otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 2016K, -app1, app, ota_1, 2080K, 2016K, -spiffs, data, spiffs, 4M, 12M, \ No newline at end of file +app0, app, ota_0, 64K, 2048K, +app1, app, ota_1, 2112K, 2048K, +spiffs, data, spiffs, 4160K, 12224K, diff --git a/user_setups/esp32/partitions_32MB.csv b/user_setups/esp32/partitions_32MB.csv index 49b445b8..d3cfde77 100644 --- a/user_setups/esp32/partitions_32MB.csv +++ b/user_setups/esp32/partitions_32MB.csv @@ -1,9 +1,9 @@ -# Two application partitions of ~2.0 MB -# 28 MB filesystem +# Two application partitions of 2.0 MB +# Filesystem: ~28 MB # # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 36K, 20K, otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 2016K, -app1, app, ota_1, 2080K, 2016K, -spiffs, data, spiffs, 4M, 28M, +app0, app, ota_0, 64K, 2048K, +app1, app, ota_1, 2112K, 2048K, +spiffs, data, spiffs, 4160K, 28608K, diff --git a/user_setups/esp32/partitions_8MB.csv b/user_setups/esp32/partitions_8MB.csv index 241440b9..741b8fb2 100644 --- a/user_setups/esp32/partitions_8MB.csv +++ b/user_setups/esp32/partitions_8MB.csv @@ -1,9 +1,9 @@ -# Two application partitions of ~2.0 MB -# 4 MB filesystem +# Two application partitions of 2.0 MB +# Filesystem: ~4 MB # # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 36K, 20K, otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 2016K, -app1, app, ota_1, 2080K, 2016K, -spiffs, data, spiffs, 4M, 4M, +app0, app, ota_0, 64K, 2048K, +app1, app, ota_1, 2112K, 2048K, +spiffs, data, spiffs, 4160K, 4032K, From cb4daf442cd0d861a33b36981a45db348c1a66c4 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:36:05 +0200 Subject: [PATCH 155/227] Add png support --- include/lv_conf_v7.h | 12 +- lib/lv_fs_if/lv_fs_pc.c | 10 +- lib/lv_fs_if/lv_fs_spiffs.cpp | 304 +++++++++++------------ platformio.ini | 5 +- src/hasp/hasp.cpp | 2 +- src/hasp/hasp_attribute.cpp | 1 + src/hasp/hasp_event.cpp | 4 + src/hasp_png.cpp | 43 ++++ src/hasp_png.h | 25 ++ user_setups/win32/windows_sdl_64bits.ini | 2 + 10 files changed, 233 insertions(+), 175 deletions(-) create mode 100644 src/hasp_png.cpp create mode 100644 src/hasp_png.h diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index e2ca2c18..2782c1e6 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -187,16 +187,16 @@ typedef void* lv_group_user_data_t; typedef void* lv_fs_drv_user_data_t; /*File system interface*/ -#define LV_USE_FS_IF 0 +#define LV_USE_FS_IF 1 #if LV_USE_FS_IF # define LV_FS_IF_FATFS '\0' #if defined(STM32F4xx) // || defined(ARDUINO_ARCH_ESP8266) # define LV_FS_IF_PC '\0' -# define LV_FS_IF_SPIFFS '\0' // internal esp Flash +//# define LV_FS_IF_SPIFFS '\0' // internal esp Flash #else -# define LV_FS_IF_PC '\0' +# define LV_FS_IF_PC 'L' // Local filesystem # define LV_FS_IF_POSIX '\0' -# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash +//# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash #endif #endif /*LV_USE_FS_IF*/ @@ -226,6 +226,10 @@ typedef void* lv_fs_drv_user_data_t; /*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ typedef void* lv_img_decoder_user_data_t; +#if (HASP_USE_PNGDECODE > 0) && (LV_USE_FILESYSTEM > 0) +//#define LV_PNG_USE_LV_FILESYSTEM 1 +#endif + /*===================== * Compiler settings *====================*/ diff --git a/lib/lv_fs_if/lv_fs_pc.c b/lib/lv_fs_if/lv_fs_pc.c index 6bdca94d..d32e1418 100644 --- a/lib/lv_fs_if/lv_fs_pc.c +++ b/lib/lv_fs_if/lv_fs_pc.c @@ -24,10 +24,12 @@ * DEFINES *********************/ #ifndef LV_FS_PC_PATH -#ifndef WIN32 -#define LV_FS_PC_PATH "/fs" /*Projet root*/ +#if defined(ESP32) +#define LV_FS_PC_PATH "/littlefs" /*Projet root*/ +#elif defined(WIN32) +#define LV_FS_PC_PATH "./" /*Projet root*/ #else -#define LV_FS_PC_PATH ".\\" /*Projet root*/ +#define LV_FS_PC_PATH "" /*Projet root*/ #endif #endif /*LV_FS_PATH*/ @@ -144,11 +146,11 @@ static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_ #ifndef WIN32 char buf[256]; sprintf(buf, LV_FS_PC_PATH "/%s", path); - printf("%s\n", buf); #else char buf[256]; sprintf(buf, LV_FS_PC_PATH "\\%s", path); #endif + printf("Opening file: %s\n", path); file_t f = fopen(buf, flags); if(f == NULL) { diff --git a/lib/lv_fs_if/lv_fs_spiffs.cpp b/lib/lv_fs_if/lv_fs_spiffs.cpp index c33fb2c1..dbc184fb 100644 --- a/lib/lv_fs_if/lv_fs_spiffs.cpp +++ b/lib/lv_fs_if/lv_fs_spiffs.cpp @@ -22,6 +22,8 @@ #define LV_FS_SPIFFS SPIFFS #elif HASP_USE_LITTLEFS > 0 #include "LITTLEFS.h" + +#include "esp_littlefs.h" #define LV_FS_SPIFFS LITTLEFS #endif #elif defined(ARDUINO_ARCH_ESP8266) @@ -45,13 +47,13 @@ **********************/ /* Create a type to store the required data about your file.*/ -typedef File lv_spiffs_file_t; +typedef FILE* lv_spiffs_file_t; /*Similarly to `file_t` create a type for directory reading too */ #if defined(ARDUINO_ARCH_ESP32) -typedef File lv_spiffs_dir_t; +typedef FILE* lv_spiffs_dir_t; #elif defined(ARDUINO_ARCH_ESP8266) -typedef Dir lv_spiffs_dir_t; +typedef Dir* lv_spiffs_dir_t; #define FILE_READ "r" #define FILE_WRITE "r+" #endif @@ -93,6 +95,7 @@ void lv_fs_if_spiffs_init(void) /*---------------------------------------------------- * Initialize your storage device and File System * -------------------------------------------------*/ + Log.verbose(88, "File system init start"); fs_init(); /*--------------------------------------------------- @@ -114,16 +117,17 @@ void lv_fs_if_spiffs_init(void) fs_drv.tell_cb = fs_tell; fs_drv.free_space_cb = fs_free; fs_drv.size_cb = fs_size; - fs_drv.remove_cb = fs_remove; - fs_drv.rename_cb = fs_rename; - fs_drv.trunc_cb = fs_trunc; + // fs_drv.remove_cb = fs_remove; + // fs_drv.rename_cb = fs_rename; + // fs_drv.trunc_cb = fs_trunc; - fs_drv.rddir_size = sizeof(lv_spiffs_dir_t); - fs_drv.dir_close_cb = fs_dir_close; - fs_drv.dir_open_cb = fs_dir_open; - fs_drv.dir_read_cb = fs_dir_read; + // fs_drv.rddir_size = sizeof(lv_spiffs_dir_t); + // fs_drv.dir_close_cb = fs_dir_close; + // fs_drv.dir_open_cb = fs_dir_open; + // fs_drv.dir_read_cb = fs_dir_read; lv_fs_drv_register(&fs_drv); + Log.verbose(88, "File system init complete"); } /********************** @@ -133,7 +137,42 @@ void lv_fs_if_spiffs_init(void) /* Initialize your Storage device and File system. */ static void fs_init(void) { - LV_FS_SPIFFS.begin(); + esp_vfs_littlefs_conf_t conf = {.base_path = "/lfs", .partition_label = "spiffs", .format_if_mount_failed = false}; + + esp_err_t res = esp_vfs_littlefs_register(&conf); + + if(res != ESP_OK) { + if(res == ESP_FAIL) { + Log.error(88, "Failed to mount or format filesystem"); + } else if(res == ESP_ERR_NOT_FOUND) { + Log.error(88, "Failed to find LittleFS partition"); + } else { + Log.error(88, "Failed to initialize LittleFS (%s)", esp_err_to_name(res)); + } + return; + } + + size_t total = 0, used = 0; + res = esp_littlefs_info(conf.partition_label, &total, &used); + if(res != ESP_OK) { + Log.error(88, "Failed to get LittleFS partition information (%s)", esp_err_to_name(res)); + } else { + Log.verbose(88, "Partition size: total: %d, used: %d", total, used); + } + + // Use POSIX and C standard library functions to work with files. + // First create a file. + Log.verbose(88, "Opening file /lfs/hello.txt"); + FILE* f = fopen("/lfs/hello.txt", "w"); + if(f == NULL) { + Log.error(88, "Failed to open file for writing"); + return; + } + fprintf(f, "LittleFS Rocks!\n"); + fclose(f); + Log.verbose(88, "File written"); + + Log.verbose(88, "LittleFS init OK"); } /** @@ -148,35 +187,35 @@ static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_ { (void)drv; /*Unused*/ - char filename[32]; - snprintf_P(filename, sizeof(filename), PSTR("/%s"), path); + const char* flags = ""; - lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; - if(fp == NULL) return LV_FS_RES_INV_PARAM; + if(mode == LV_FS_MODE_WR) + flags = "w"; + else if(mode == LV_FS_MODE_RD) + flags = "r"; + else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) + flags = "rb+"; - LOG_VERBOSE(TAG_LVFS, F("Opening %s"), filename); - lv_spiffs_file_t file = LV_FS_SPIFFS.open(filename, mode == LV_FS_MODE_WR ? FILE_WRITE : FILE_READ); + /*Make the path relative to the current directory (the projects root folder)*/ - LOG_VERBOSE(TAG_LVFS, F("%d"), __LINE__); - if(!file) { - LOG_VERBOSE(TAG_LVFS, F("Invalid file")); - return LV_FS_RES_NOT_EX; + char complete_path[strlen(path) + 1]; + complete_path[0] = '/'; + complete_path[1] = '\0'; + strcat(complete_path, path); - // } else if((*fp).isDirectory()) { - // LOG_VERBOSE(TAG_LVFS, F("Cannot open directory as a file")); - // return LV_FS_RES_UNKNOWN; + Log.verbose(88, "Opening file %s", path); + lv_spiffs_file_t f = fopen(path, flags); + if(f == NULL) return LV_FS_RES_UNKNOWN; - } else { - // f.seek(0, SeekSet); - // LOG_VERBOSE(TAG_LVFS,F("Assigning %s"), f.name()); - LOG_VERBOSE(TAG_LVFS, F("%d"), __LINE__); - // LOG_VERBOSE(TAG_LVFS,F("Copying %s"), f.name()); - LOG_VERBOSE(TAG_LVFS, F("%d - %x - %d"), __LINE__, fp, sizeof(lv_spiffs_file_t)); - // memcpy(fp,&file,sizeof(lv_spiffs_file_t)); - LOG_VERBOSE(TAG_LVFS, F("%d"), __LINE__); - *fp = file; - return LV_FS_RES_OK; - } + /*Be sure we are the beginning of the file*/ + fseek(f, 0, SEEK_SET); + + /* 'file_p' is pointer to a file descriptor and + * we need to store our file descriptor here*/ + lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/ + *fp = f; + Log.verbose(88, "Open eof file_p %d", feof(*fp)); + return LV_FS_RES_OK; } /** @@ -188,23 +227,10 @@ static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_ */ static lv_fs_res_t fs_close(lv_fs_drv_t* drv, void* file_p) { - (void)drv; /*Unused*/ - lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; - if(fp == NULL) return LV_FS_RES_INV_PARAM; - - lv_spiffs_file_t file = *fp; - - if(!file) { - LOG_VERBOSE(TAG_LVFS, F("Invalid file")); - return LV_FS_RES_NOT_EX; - - } else if(file.isDirectory()) { - return LV_FS_RES_UNKNOWN; - - } else { - file.close(); - return LV_FS_RES_OK; - } + (void)drv; /*Unused*/ + lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/ + fclose(*fp); + return LV_FS_RES_OK; } /** @@ -219,33 +245,11 @@ static lv_fs_res_t fs_close(lv_fs_drv_t* drv, void* file_p) */ static lv_fs_res_t fs_read(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { - (void)drv; /*Unused*/ - lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; - if(fp == NULL) return LV_FS_RES_INV_PARAM; - - lv_spiffs_file_t file = *fp; - - if(!file) { - LOG_ERROR(TAG_LVFS, F("Invalid file")); - return LV_FS_RES_NOT_EX; - - } else { - // LOG_VERBOSE(TAG_LVFS, F("Reading %u bytes from %s at position %u"), btr, file.name(), file.position()); - uint32_t len = 0; - char* chp = (char*)buf; - if(chp != NULL && btr > 0) - len = file.readBytes(chp, btr); - else - LOG_VERBOSE(TAG_LVFS, F("Buffer is NULL"), btr, file.name(), file.position()); - - if(br != NULL) - *br = len; - else - LOG_VERBOSE(TAG_LVFS, F("BYTESREAD is NULL"), btr, file.name(), file.position()); - - Serial.print("!"); - return LV_FS_RES_OK; - } + (void)drv; /*Unused*/ + lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/ + Log.verbose(88, "Read eof %d", feof(*fp)); + *br = fread(buf, 1, btr, *fp); + return LV_FS_RES_OK; } /** @@ -259,18 +263,10 @@ static lv_fs_res_t fs_read(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t b */ static lv_fs_res_t fs_write(lv_fs_drv_t* drv, void* file_p, const void* buf, uint32_t btw, uint32_t* bw) { - (void)drv; /*Unused*/ - lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p; - // File file = fp; - - if(!file) { - // LOG_VERBOSE(TAG_LVFS,F("Invalid file")); - return LV_FS_RES_NOT_EX; - - } else { - *bw = (uint32_t)file.write((byte*)buf, btw); - return LV_FS_RES_OK; - } + (void)drv; /*Unused*/ + lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/ + Log.verbose(88, "Write eof %d", feof(*fp)); + *bw = fwrite(buf, 1, btw, *fp); } /** @@ -283,18 +279,10 @@ static lv_fs_res_t fs_write(lv_fs_drv_t* drv, void* file_p, const void* buf, uin */ static lv_fs_res_t fs_seek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { - (void)drv; /*Unused*/ - lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p; - // File file = fp; - - if(!file) { - // LOG_VERBOSE(TAG_LVFS,F("Invalid file")); - return LV_FS_RES_NOT_EX; - - } else { - file.seek(pos, SeekSet); - return LV_FS_RES_OK; - } + (void)drv; /*Unused*/ + lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/ + fseek(*fp, pos, SEEK_SET); + return LV_FS_RES_OK; } /** @@ -306,18 +294,12 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) */ static lv_fs_res_t fs_size(lv_fs_drv_t* drv, void* file_p, uint32_t* size_p) { - (void)drv; /*Unused*/ - lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p; - // File file = fp; - - if(!file) { - // LOG_VERBOSE(TAG_LVFS,F("Invalid file")); - return LV_FS_RES_NOT_EX; - - } else { - *size_p = (uint32_t)file.size(); - return LV_FS_RES_OK; - } + (void)drv; /*Unused*/ + lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/ + fseek(*fp, 0L, SEEK_END); + *size_p = ftell(*fp); + fseek(*fp, 0L, SEEK_SET); + return LV_FS_RES_OK; } /** @@ -330,18 +312,10 @@ static lv_fs_res_t fs_size(lv_fs_drv_t* drv, void* file_p, uint32_t* size_p) */ static lv_fs_res_t fs_tell(lv_fs_drv_t* drv, void* file_p, uint32_t* pos_p) { - (void)drv; /*Unused*/ - lv_spiffs_file_t file = *(lv_spiffs_file_t*)file_p; - // File file = fp; - - if(!file) { - // LOG_VERBOSE(TAG_LVFS,F("Invalid file")); - return LV_FS_RES_NOT_EX; - - } else { - *pos_p = (uint32_t)file.position(); - return LV_FS_RES_OK; - } + (void)drv; /*Unused*/ + lv_spiffs_file_t* fp = (lv_spiffs_file_t*)file_p; /*Just avoid the confusing casings*/ + *pos_p = ftell(*fp); + return LV_FS_RES_OK; } /** @@ -439,25 +413,25 @@ static lv_fs_res_t fs_free(lv_fs_drv_t* drv, uint32_t* total_p, uint32_t* free_p * @param path path to a directory * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path) -{ - lv_spiffs_dir_t dir; +// static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path) +// { +// lv_spiffs_dir_t dir; -#if defined(ARDUINO_ARCH_ESP32) - dir = LV_FS_SPIFFS.open(path); - if(!dir) { - return LV_FS_RES_UNKNOWN; - } -#endif +// #if defined(ARDUINO_ARCH_ESP32) +// dir = &LV_FS_SPIFFS.open(path); +// if(!dir) { +// return LV_FS_RES_UNKNOWN; +// } +// #endif -#if defined(ARDUINO_ARCH_ESP8266) - dir = LV_FS_SPIFFS.openDir(path); -#endif +// #if defined(ARDUINO_ARCH_ESP8266) +// dir = LV_FS_SPIFFS.openDir(path); +// #endif - lv_spiffs_dir_t* dp = (lv_spiffs_dir_t*)dir_p; /*Just avoid the confusing casings*/ - *dp = dir; - return LV_FS_RES_OK; -} +// lv_spiffs_dir_t* dp = (lv_spiffs_dir_t*)dir_p; /*Just avoid the confusing casings*/ +// *dp = dir; +// return LV_FS_RES_OK; +// } /** * Read the next filename form a directory. @@ -467,31 +441,31 @@ static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path) * @param fn pointer to a buffer to store the filename * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_dir_read(lv_fs_drv_t* drv, void* dir_p, char* fn) -{ - lv_spiffs_dir_t dir = *(lv_spiffs_dir_t*)dir_p; /*Convert type*/ +// static lv_fs_res_t fs_dir_read(lv_fs_drv_t* drv, void* dir_p, char* fn) +// { +// lv_spiffs_dir_t dir = *(lv_spiffs_dir_t*)dir_p; /*Convert type*/ -#if defined(ARDUINO_ARCH_ESP32) - File file = dir.openNextFile(); - if(file) { - strcpy(fn, file.name()); - return LV_FS_RES_OK; - } else { - return LV_FS_RES_UNKNOWN; - } -#endif +// #if defined(ARDUINO_ARCH_ESP32) +// File file = dir.openNextFile(); +// if(file) { +// strcpy(fn, file.name()); +// return LV_FS_RES_OK; +// } else { +// return LV_FS_RES_UNKNOWN; +// } +// #endif -#if defined(ARDUINO_ARCH_ESP8266) - if(dir.next()) { - strcpy(fn, dir.fileName().c_str()); - return LV_FS_RES_OK; - } else { - return LV_FS_RES_UNKNOWN; - } -#endif +// #if defined(ARDUINO_ARCH_ESP8266) +// if(dir.next()) { +// strcpy(fn, dir.fileName().c_str()); +// return LV_FS_RES_OK; +// } else { +// return LV_FS_RES_UNKNOWN; +// } +// #endif - return LV_FS_RES_NOT_IMP; -} +// return LV_FS_RES_NOT_IMP; +// } /** * Close the directory reading diff --git a/platformio.ini b/platformio.ini index 9c379c5c..755e97ff 100644 --- a/platformio.ini +++ b/platformio.ini @@ -117,7 +117,8 @@ build_flags = ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=61440U ; 60kB lvgl memory -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR - ;-D LV_FS_PC_PATH="/lfs" ; this needs to match the vfs mount pount + ;-D LV_FS_PC_PATH="//littlefs" ; this needs to match the vfs mount pount + -D LODEPNG_NO_COMPILE_ALLOCATORS ; use PSram functions ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments ; -- tft_espi build options ------------------------ @@ -130,6 +131,7 @@ build_flags = ;-D HASP_USE_EEPROM=1 -D HASP_USE_CONFIG=1 ; Native application, not library -D LV_LOG_TRACE_TIMER=1 + -D HASP_USE_PNGDECODE=1 ; -- LittleFS build options ------------------------ ;-D CONFIG_LITTLEFS_FOR_IDF_3_2 ; obsolete in IDF 3.3 @@ -146,6 +148,7 @@ lib_ignore = lib_deps = LittleFS_esp32 + git+https://github.com/lvgl/lv_lib_png.git ps_ram = -DBOARD_HAS_PSRAM diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index e9c01756..78aca9e2 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -305,7 +305,7 @@ void haspSetup(void) /******* File System Test ********************************************************************/ // lv_fs_file_t f; // lv_fs_res_t res; - // res = lv_fs_open(&f, "E:/config.json", LV_FS_MODE_RD); + // res = lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD); // if(res == LV_FS_RES_OK) // LOG_VERBOSE(TAG_HASP, F("Opening config.json OK")); // else diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index de2fc262..a178b3dc 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -1777,6 +1777,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p case ATTR_SRC: if(obj_check_type(obj, LV_HASP_IMAGE)) { if(update) { + lv_img_cache_invalidate_src(lv_img_get_src(obj)); lv_img_set_src(obj, payload); } else { switch(lv_img_src_get_type(obj)) { diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index cfcccdc4..a81f026e 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -53,6 +53,10 @@ static void event_delete_object(lv_obj_t* obj) my_msgbox_map_clear(obj); break; + case LV_HASP_IMAGE: + lv_img_cache_invalidate_src(NULL); + break; + case LV_HASP_GAUGE: break; diff --git a/src/hasp_png.cpp b/src/hasp_png.cpp new file mode 100644 index 00000000..ef9517a7 --- /dev/null +++ b/src/hasp_png.cpp @@ -0,0 +1,43 @@ + +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifdef LODEPNG_NO_COMPILE_ALLOCATORS + +#include +#include "hasplib.h" +#include "hasp_png.h" + +void* lodepng_malloc(size_t size) +{ +#ifdef LODEPNG_MAX_ALLOC + if(size > LODEPNG_MAX_ALLOC) return 0; +#endif + +#ifdef ESP32 + return psramFound() ? ps_malloc(size) : malloc(size); +#else + return malloc(size); +#endif +} + +/* NOTE: when realloc returns NULL, it leaves the original memory untouched */ +void* lodepng_realloc(void* ptr, size_t new_size) +{ +#ifdef LODEPNG_MAX_ALLOC + if(new_size > LODEPNG_MAX_ALLOC) return 0; +#endif + +#ifdef ESP32 + return psramFound() ? ps_realloc(ptr, new_size) : realloc(ptr, new_size); +#else + return realloc(ptr, new_size); +#endif +} + +void lodepng_free(void* ptr) +{ + free(ptr); +} + +#endif // LODEPNG_NO_COMPILE_ALLOCATORS \ No newline at end of file diff --git a/src/hasp_png.h b/src/hasp_png.h new file mode 100644 index 00000000..0fa8b8fb --- /dev/null +++ b/src/hasp_png.h @@ -0,0 +1,25 @@ +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_PNG_H +#define HASP_PNG_H + +#include + +#ifdef LODEPNG_NO_COMPILE_ALLOCATORS + +#ifdef __cplusplus +extern "C" { +#endif + +void* lodepng_malloc(size_t size); +void* lodepng_realloc(void* ptr, size_t new_size); +void lodepng_free(void* ptr); + +#ifdef __cplusplus +} +#endif + +#endif // LODEPNG_NO_COMPILE_ALLOCATORS + +#endif // HASP_PNG_H \ No newline at end of file diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini index 1812618b..b85d97a6 100644 --- a/user_setups/win32/windows_sdl_64bits.ini +++ b/user_setups/win32/windows_sdl_64bits.ini @@ -28,6 +28,7 @@ build_flags = -D HASP_USE_GPIO=1 -D HASP_USE_CONFIG=0 ; Standalone application, as library -D HASP_USE_DEBUG=1 + -D HASP_USE_PNGDECODE=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 -D HASP_ATTRIBUTE_FAST_MEM= @@ -83,6 +84,7 @@ lib_deps = https://github.com/eclipse/paho.mqtt.c.git bblanchon/ArduinoJson@^6.17.2 ; Json(l) parser https://github.com/fvanroie/lv_drivers + git+https://github.com/lvgl/lv_lib_png.git lib_ignore = paho From ff59b554274092620c344fe023eeb1f041b7310b Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:36:35 +0200 Subject: [PATCH 156/227] Use default settings if filesystem is unavailable --- src/hasp_config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 3b315507..3f0afa47 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -403,7 +403,7 @@ void configSetup() #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 if(!filesystemSetup()) { LOG_ERROR(TAG_CONF, F("FILE: SPI flash init failed. Unable to mount FS: Using default settings...")); - return; + // return; // Keep going and initialize the console with default settings } #endif configRead(settings, true); From 0f60213557366e821da47ff1426ed3780fea0bba Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:36:54 +0200 Subject: [PATCH 157/227] Use HASP_FS over SPIFFS --- src/hasp_filesystem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hasp_filesystem.cpp b/src/hasp_filesystem.cpp index 6a014e7d..78a1101a 100644 --- a/src/hasp_filesystem.cpp +++ b/src/hasp_filesystem.cpp @@ -16,7 +16,7 @@ void filesystemInfo() { // Get all information of your SPIFFS #if 0 FSInfo fs_info; - SPIFFS.info(fs_info); + HASP_FS.info(fs_info); Serial.println("File system info."); @@ -71,9 +71,9 @@ void filesystemList() { #if HASP_USE_SPIFFS > 0 #if defined(ARDUINO_ARCH_ESP8266) - if(!SPIFFS.begin()) { + if(!HASP_FS.begin()) { #else - if(!SPIFFS.begin(true)) { + if(!HASP_FS.begin(true)) { // default vfs path: /littlefs #endif LOG_ERROR(TAG_FILE, F("Flash file system not mouted.")); } else { @@ -81,7 +81,7 @@ void filesystemList() LOG_VERBOSE(TAG_FILE, F("Listing files on the internal flash:")); #if defined(ARDUINO_ARCH_ESP32) - File root = SPIFFS.open("/"); + File root = HASP_FS.open("/"); File file = root.openNextFile(); while(file) { LOG_VERBOSE(TAG_FILE, F(" * %s (%u bytes)"), file.name(), (uint32_t)file.size()); @@ -89,7 +89,7 @@ void filesystemList() } #endif #if defined(ARDUINO_ARCH_ESP8266) - Dir dir = SPIFFS.openDir("/"); + Dir dir = HASP_FS.openDir("/"); while(dir.next()) { LOG_VERBOSE(TAG_FILE, F(" * %s (%u bytes)"), dir.fileName().c_str(), (uint32_t)dir.fileSize()); } From 0b9f7ec3ead0b33c49fc41f012442f0359a0bba4 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:38:27 +0200 Subject: [PATCH 158/227] Load pages.jsonl in native applications --- src/hasp/hasp_page.cpp | 43 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/hasp/hasp_page.cpp b/src/hasp/hasp_page.cpp index 91ea4929..acc737c6 100644 --- a/src/hasp/hasp_page.cpp +++ b/src/hasp/hasp_page.cpp @@ -2,6 +2,7 @@ For full license information read the LICENSE file in the project folder */ #include "hasplib.h" +#include namespace hasp { @@ -158,14 +159,50 @@ void Page::load_jsonl(const char* pagesfile) file.close(); LOG_INFO(TAG_HASP, F(D_FILE_LOADED), pagesfile); -#else -#if HASP_USE_EEPROM > 0 +#elif HASP_USE_EEPROM > 0 LOG_TRACE(TAG_HASP, F("Loading jsonl from EEPROM...")); EepromStream eepromStream(4096, 1024); dispatch_parse_jsonl(eepromStream); LOG_INFO(TAG_HASP, F("Loaded jsonl from EEPROM")); -#endif + +#else + + char path[strlen(pagesfile) + 4]; + path[0] = '.'; + path[1] = '\0'; + strcat(path, pagesfile); + path[1] = '\\'; + + LOG_TRACE(TAG_HASP, F("Loading %s from disk..."), path); + std::ifstream f(path); // taking file as inputstream + if(f) { + dispatch_parse_jsonl(f); + } + f.close(); + LOG_INFO(TAG_HASP, F("Loaded %s from disk"), path); + + // char path[strlen(pagesfile) + 4]; + // path[0] = '\0'; + // strcat(path, "L:/"); + // strcat(path, pagesfile); + + // lv_fs_file_t file; + // lv_fs_res_t res; + // res = lv_fs_open(&file, path, LV_FS_MODE_RD); + // if(res == LV_FS_RES_OK) { + // LOG_VERBOSE(TAG_HASP, F("Opening %s"), path); + // } else { + // LOG_ERROR(TAG_HASP, F("TEST Opening %q from FS failed %d"), path, res); + // } + + // dispatch_parse_jsonl(file); + // res = lv_fs_close(&file); + // if(res == LV_FS_RES_OK) { + // LOG_VERBOSE(TAG_HASP, F("Closing %s OK"), path); + // } else { + // LOG_ERROR(TAG_HASP, F("Closing %s on FS failed %d"), path, res); + // } #endif } From 7555b64220a5d12461b874911999a588f53d5b76 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:39:07 +0200 Subject: [PATCH 159/227] Tweaks to WiFi disconnect and rssi info --- src/sys/net/hasp_wifi.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sys/net/hasp_wifi.cpp b/src/sys/net/hasp_wifi.cpp index a415b4a7..9cfa1af8 100644 --- a/src/sys/net/hasp_wifi.cpp +++ b/src/sys/net/hasp_wifi.cpp @@ -354,13 +354,13 @@ bool wifiShowAP(char* ssid, char* pass) static void wifiReconnect(void) { #if defined(ARDUINO_ARCH_ESP8266) - WiFi.disconnect(true); + WiFi.disconnect(); WiFi.begin(wifiSsid, wifiPassword); WiFi.hostname(haspDevice.get_hostname()); #elif defined(ARDUINO_ARCH_ESP32) // https://github.com/espressif/arduino-esp32/issues/3438#issuecomment-721428310 - WiFi.disconnect(true); + WiFi.disconnect(); WiFi.begin(wifiSsid, wifiPassword, WIFI_ALL_CHANNEL_SCAN); // WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); // causes 255.255.255.255 IP errors WiFi.setHostname(haspDevice.get_hostname()); @@ -532,11 +532,11 @@ void wifi_get_info(JsonDocument& doc) if(rssi >= -50) { buffer += F(D_WIFI_RSSI_EXCELLENT ")"); - } else if(rssi >= -60) { + } else if(rssi >= -59) { buffer += F(D_WIFI_RSSI_GOOD ")"); - } else if(rssi >= -70) { + } else if(rssi >= -68) { buffer += F(D_WIFI_RSSI_FAIR ")"); - } else if(rssi >= -80) { + } else if(rssi >= -77) { buffer += F(D_WIFI_RSSI_WEAK ")"); } else { buffer += F(D_WIFI_RSSI_BAD ")"); From d380c24bcfaac68bb5bb29b4b61e38eb05341058 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:39:35 +0200 Subject: [PATCH 160/227] Use w and h in setAddrWindow --- src/drv/tft_driver_tftespi.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/drv/tft_driver_tftespi.cpp b/src/drv/tft_driver_tftespi.cpp index b849cf5a..54052644 100644 --- a/src/drv/tft_driver_tftespi.cpp +++ b/src/drv/tft_driver_tftespi.cpp @@ -123,19 +123,27 @@ void TftEspi::set_invert(bool invert) tft.invertDisplay(invert); } +/* Update TFT */ void IRAM_ATTR TftEspi::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) { - size_t len = lv_area_get_size(area); + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + // size_t len = lv_area_get_size(area); + uint32_t len = w * h; - /* Update TFT */ - tft.startWrite(); /* Start new TFT transaction */ - tft.setWindow(area->x1, area->y1, area->x2, area->y2); /* set the working window */ #ifdef USE_DMA_TO_TFT - tft.pushPixelsDMA((uint16_t*)color_p, len); /* Write words at once */ + tft.startWrite(); /* Start new TFT transaction */ + // tft.setWindow(area->x1, area->y1, area->x2, area->y2); + tft.setAddrWindow(area->x1, area->y1, w, h); /* set the working window */ + tft.pushPixelsDMA((uint16_t*)color_p, len); /* Write words at once */ + tft.endWrite(); /* terminate TFT transaction */ #else - tft.pushPixels((uint16_t*)color_p, len); /* Write words at once */ + tft.startWrite(); /* Start new TFT transaction */ + // tft.setWindow(area->x1, area->y1, area->x2, area->y2); + tft.setAddrWindow(area->x1, area->y1, w, h); /* set the working window */ + tft.pushPixels((uint16_t*)color_p, len); /* Write words at once */ + tft.endWrite(); /* terminate TFT transaction */ #endif - tft.endWrite(); /* terminate TFT transaction */ /* Tell lvgl that flushing is done */ lv_disp_flush_ready(disp); From 1765a087c3c563f7ca3a16071f52618100711cf2 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:41:28 +0200 Subject: [PATCH 161/227] Add support for filesystem, png and tftWidth/tftHeight --- src/hasp_gui.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index f245ca73..4dbee301 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -27,7 +27,7 @@ //#include "Ticker.h" #if HASP_USE_PNGDECODE > 0 -#include "png_decoder.h" +#include "lv_png.h" #endif #define BACKLIGHT_CHANNEL 0 // pwm channel 0-15 @@ -56,8 +56,8 @@ gui_conf_t gui_settings = {.show_pointer = false, .invert_display = INVERT_COLORS, .cal_data = {0, 65535, 0, 65535, 0}}; -// static int8_t guiDimLevel = 100; -// bool guiBacklightIsOn; +uint16_t tft_width = TFT_WIDTH; +uint16_t tft_height = TFT_HEIGHT; // #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) // static Ticker tick; /* timer for interrupt handler */ @@ -95,13 +95,13 @@ void guiCalibrate(void) #endif } -void guiSetup(void) +void guiSetup() { // Register logger to capture lvgl_init output LOG_TRACE(TAG_TFT, F(D_SERVICE_STARTING)); // Initialize the TFT - haspTft.init(240, 320); + haspTft.init(tft_width, tft_height); haspTft.set_rotation(gui_settings.rotation); haspTft.set_invert(gui_settings.invert_display); haspTft.show_info(); @@ -168,6 +168,9 @@ void guiSetup(void) LOG_FATAL(TAG_GUI, F(D_ERROR_OUT_OF_MEMORY)); } + LOG_VERBOSE(TAG_LVGL, F("Version : %u.%u.%u %s"), LVGL_VERSION_MAJOR, LVGL_VERSION_MINOR, LVGL_VERSION_PATCH, + PSTR(LVGL_VERSION_INFO)); + /* Initialize the display driver */ static lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); @@ -195,17 +198,28 @@ void guiSetup(void) /* Initialize Filesystems */ #if LV_USE_FS_IF != 0 - // _lv_fs_init(); // lvgl File System -- not neaded, it done in lv_init() when LV_USE_FILESYSTEM is set + //_lv_fs_init(); // lvgl File System -- not neaded, it done in lv_init() when LV_USE_FILESYSTEM is set LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_ENABLED)); lv_fs_if_init(); // auxilary file system drivers - filesystem_list_path("S:/fs/"); + filesystem_list_path("L:/"); + + lv_fs_file_t f; + lv_fs_res_t res; + res = lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD); + if(res == LV_FS_RES_OK) { + LOG_VERBOSE(TAG_HASP, F("TEST Opening config.json OK")); + lv_fs_close(&f); + } else { + LOG_ERROR(TAG_HASP, F("TEST Opening config.json from FS failed %d"), res); + } + #else LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_DISABLED)); #endif /* Initialize PNG decoder */ #if HASP_USE_PNGDECODE > 0 - png_decoder_init(); + lv_png_init(); #endif #ifdef USE_DMA_TO_TFT @@ -217,9 +231,6 @@ void guiSetup(void) /* Setup Backlight Control Pin */ haspDevice.set_backlight_pin(gui_settings.backlight_pin); - LOG_VERBOSE(TAG_LVGL, F("Version : %u.%u.%u %s"), LVGL_VERSION_MAJOR, LVGL_VERSION_MINOR, LVGL_VERSION_PATCH, - PSTR(LVGL_VERSION_INFO)); - #ifdef LV_MEM_SIZE LOG_VERBOSE(TAG_LVGL, F("MEM size : %d"), LV_MEM_SIZE); #endif From 6ea6c8c2978d2640f02ce453dfef1a6988b1e18a Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 06:41:43 +0200 Subject: [PATCH 162/227] Revert to fixed delays --- src/main_arduino.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index 94c8d440..dbbe961c 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -169,9 +169,10 @@ IRAM_ATTR void loop() } #ifdef ARDUINO_ARCH_ESP8266 - delay((lv_task_get_idle() >> 6) + 1); // 1..2 ms + delay(2); // ms #else - delay((lv_task_get_idle() >> 4) + 1); // 1..7 ms + delay(5); // ms + // delay((lv_task_get_idle() >> 5) + 3); // 2..5 ms #endif } From 75b65aa523bd1299395e64f88d052abcceadbcc3 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 09:50:08 +0200 Subject: [PATCH 163/227] Add image_recolor properties --- src/hasp/hasp_attribute.cpp | 296 ++++++++++++++++++++---------------- src/hasp/hasp_attribute.h | 5 + 2 files changed, 167 insertions(+), 134 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index a178b3dc..ac4c644c 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -1240,7 +1240,21 @@ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t at // return; /* Image attributes */ - // Todo + case ATTR_IMAGE_RECOLOR_OPA: + return attribute_image_recolor_opa(obj, part, state, update, attr_p, (lv_opa_t)var); + case ATTR_IMAGE_OPA: + return attribute_image_opa(obj, part, state, update, attr_p, (lv_opa_t)var); + case ATTR_IMAGE_RECOLOR: { + if(update) { + lv_color32_t c; + if(Parser::haspPayloadToColor(payload, c)) + lv_obj_set_style_local_image_recolor(obj, part, state, + lv_color_make(c.ch.red, c.ch.green, c.ch.blue)); + } else { + attr_out_color(obj, attr, lv_obj_get_style_image_recolor(obj, part)); + } + return; + } /* Transition attributes */ // Todo @@ -1253,21 +1267,20 @@ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t at result = false; } -static void hasp_process_arc_attribute(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, const char* payload, +static bool hasp_process_arc_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, bool update) { - // We already know it's a arc object uint16_t val = atoi(payload); - char* attr = (char*)attr_p; - // if(*attr == '.') attr++; // strip leading '.' - + // We already know it's a arc object switch(attr_hash) { case ATTR_TYPE: - return (update) ? lv_arc_set_type(obj, val % 3) : attr_out_int(obj, attr, lv_arc_get_type(obj)); + (update) ? lv_arc_set_type(obj, val % 3) : attr_out_int(obj, attr, lv_arc_get_type(obj)); + return true; case ATTR_ROTATION: - return (update) ? lv_arc_set_rotation(obj, val) : attr_out_int(obj, attr, my_arc_get_rotation(obj)); + (update) ? lv_arc_set_rotation(obj, val) : attr_out_int(obj, attr, my_arc_get_rotation(obj)); + return true; case ATTR_ADJUSTABLE: if(update) { @@ -1277,26 +1290,29 @@ static void hasp_process_arc_attribute(lv_obj_t* obj, const char* attr_p, uint16 } else { attr_out_int(obj, attr, lv_arc_get_adjustable(obj)); } - return; + return true; case ATTR_START_ANGLE: - return (update) ? lv_arc_set_bg_start_angle(obj, val) - : attr_out_int(obj, attr, lv_arc_get_bg_angle_start(obj)); + (update) ? lv_arc_set_bg_start_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_bg_angle_start(obj)); + return true; case ATTR_END_ANGLE: - return (update) ? lv_arc_set_bg_end_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_bg_angle_end(obj)); + (update) ? lv_arc_set_bg_end_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_bg_angle_end(obj)); + return true; case ATTR_START_ANGLE1: - return (update) ? lv_arc_set_start_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_angle_start(obj)); + (update) ? lv_arc_set_start_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_angle_start(obj)); + return true; case ATTR_END_ANGLE1: - return (update) ? lv_arc_set_end_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_angle_end(obj)); + (update) ? lv_arc_set_end_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_angle_end(obj)); + return true; } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr_p); + return false; } -static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, +static bool hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, bool update) { uint16_t val = atoi(payload); @@ -1307,24 +1323,27 @@ static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr, uint1 switch(attr_hash) { case ATTR_TYPE: - return (update) ? lv_linemeter_set_mirror(obj, val != 0) - : attr_out_int(obj, attr, lv_linemeter_get_mirror(obj)); + (update) ? lv_linemeter_set_mirror(obj, val != 0) : attr_out_int(obj, attr, lv_linemeter_get_mirror(obj)); + return true; case ATTR_ROTATION: - return (update) ? lv_linemeter_set_angle_offset(obj, val) - : attr_out_int(obj, attr, lv_linemeter_get_angle_offset(obj)); + (update) ? lv_linemeter_set_angle_offset(obj, val) + : attr_out_int(obj, attr, lv_linemeter_get_angle_offset(obj)); + return true; case ATTR_LINE_COUNT: - return (update) ? lv_linemeter_set_scale(obj, angle, val) : attr_out_int(obj, attr, line_count); + (update) ? lv_linemeter_set_scale(obj, angle, val) : attr_out_int(obj, attr, line_count); + return true; case ATTR_ANGLE: - return (update) ? lv_linemeter_set_scale(obj, val, line_count) : attr_out_int(obj, attr, angle); + (update) ? lv_linemeter_set_scale(obj, val, line_count) : attr_out_int(obj, attr, angle); + return true; } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); + return false; } -static void hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, +static bool hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, bool update) { int16_t intval = atoi(payload); @@ -1333,28 +1352,33 @@ static void hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr, uin // We already know it's a gauge object switch(attr_hash) { case ATTR_DIRECTION: - return (update) ? lv_dropdown_set_dir(obj, intval) : attr_out_int(obj, attr, lv_dropdown_get_dir(obj)); + (update) ? lv_dropdown_set_dir(obj, intval) : attr_out_int(obj, attr, lv_dropdown_get_dir(obj)); + return true; case ATTR_SYMBOL: - return (update) ? lv_dropdown_set_symbol(obj, payload) - : attr_out_str(obj, attr, lv_dropdown_get_symbol(obj)); + (update) ? lv_dropdown_set_symbol(obj, payload) : attr_out_str(obj, attr, lv_dropdown_get_symbol(obj)); + return true; case ATTR_OPEN: - return lv_dropdown_open(obj); + lv_dropdown_open(obj); + return true; case ATTR_CLOSE: - return lv_dropdown_close(obj); + lv_dropdown_close(obj); + return true; case ATTR_MAX_HEIGHT: - return (update) ? lv_dropdown_set_max_height(obj, intval) - : attr_out_int(obj, attr, lv_dropdown_get_max_height(obj)); + (update) ? lv_dropdown_set_max_height(obj, intval) + : attr_out_int(obj, attr, lv_dropdown_get_max_height(obj)); + return true; case ATTR_SHOW_SELECTED: - return (update) ? lv_dropdown_set_show_selected(obj, val) - : attr_out_int(obj, attr, lv_dropdown_get_show_selected(obj)); + (update) ? lv_dropdown_set_show_selected(obj, val) + : attr_out_int(obj, attr, lv_dropdown_get_show_selected(obj)); + return true; } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); + return false; } static bool hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, @@ -1413,14 +1437,13 @@ static bool hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr, uint16 return true; // found } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); return false; } // ##################### Common Attributes ######################################################## -static inline void hasp_process_page_attributes(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, uint8_t val, - bool update) +static bool hasp_process_page_attributes(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, uint8_t val, + bool update) { uint8_t pageid; @@ -1428,18 +1451,19 @@ static inline void hasp_process_page_attributes(lv_obj_t* obj, const char* attr_ switch(attr_hash) { case ATTR_NEXT: update ? haspPages.set_next(pageid, val) : attr_out_int(obj, attr_p, haspPages.get_next(pageid)); - break; + return true; case ATTR_PREV: update ? haspPages.set_prev(pageid, val) : attr_out_int(obj, attr_p, haspPages.get_prev(pageid)); - break; + return true; // case ATTR_BACK: default: update ? haspPages.set_back(pageid, val) : attr_out_int(obj, attr_p, haspPages.get_back(pageid)); - break; + return true; } } + return false; } static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, const char* payload, bool update) @@ -1484,12 +1508,12 @@ static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con return true; } default: - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); + break; } return false; } -static inline bool attr_anim_time(lv_obj_t* obj, const char* attr, uint16_t val, bool update) +static bool attr_anim_time(lv_obj_t* obj, const char* attr, uint16_t val, bool update) { { // Use anim_time for const lv_obj getters hasp_attr_update16_const_t anim_time[] = {{LV_HASP_BAR, lv_bar_set_anim_time, lv_bar_get_anim_time}, @@ -1572,7 +1596,7 @@ bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t int return true; } -static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, const char* payload, bool update, +static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, const char* payload, bool update, bool set_min, bool set_max) { int16_t val = atoi(payload); @@ -1581,52 +1605,58 @@ static void hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co if(obj_check_type(obj, LV_HASP_SLIDER)) { int16_t min = lv_slider_get_min_value(obj); int16_t max = lv_slider_get_max_value(obj); - if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max - return update ? lv_slider_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); + if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max + update ? lv_slider_set_range(obj, set_min ? val : min, set_max ? val : max) + : attr_out_int(obj, attr, set_min ? min : max); + return true; } if(obj_check_type(obj, LV_HASP_GAUGE)) { int32_t min = lv_gauge_get_min_value(obj); int32_t max = lv_gauge_get_max_value(obj); - if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return; // prevent setting min=max - return update ? lv_gauge_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) - : attr_out_int(obj, attr, set_min ? min : max); + if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max + update ? lv_gauge_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) + : attr_out_int(obj, attr, set_min ? min : max); + return true; } if(obj_check_type(obj, LV_HASP_ARC)) { int16_t min = lv_arc_get_min_value(obj); int16_t max = lv_arc_get_max_value(obj); - if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max - return update ? lv_arc_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); + if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max + update ? lv_arc_set_range(obj, set_min ? val : min, set_max ? val : max) + : attr_out_int(obj, attr, set_min ? min : max); + return true; } if(obj_check_type(obj, LV_HASP_BAR)) { int16_t min = lv_bar_get_min_value(obj); int16_t max = lv_bar_get_max_value(obj); - if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max - return update ? lv_bar_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); + if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max + update ? lv_bar_set_range(obj, set_min ? val : min, set_max ? val : max) + : attr_out_int(obj, attr, set_min ? min : max); + return true; } if(obj_check_type(obj, LV_HASP_LMETER)) { int32_t min = lv_linemeter_get_min_value(obj); int32_t max = lv_linemeter_get_max_value(obj); - if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return; // prevent setting min=max - return update ? lv_linemeter_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) - : attr_out_int(obj, attr, set_min ? min : max); + if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max + update ? lv_linemeter_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) + : attr_out_int(obj, attr, set_min ? min : max); + return true; } if(obj_check_type(obj, LV_HASP_CHART)) { int16_t min = my_chart_get_min_value(obj); int16_t max = my_chart_get_max_value(obj); - if(update && (set_min ? val : min) == (set_max ? val : max)) return; // prevent setting min=max - return update ? lv_chart_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); + if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max + update ? lv_chart_set_range(obj, set_min ? val : min, set_max ? val : max) + : attr_out_int(obj, attr, set_min ? min : max); + return true; } - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN), attr); + return false; } // ##################### Default Attributes ######################################################## @@ -1679,7 +1709,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p return; // attribute_found case ATTR_OBJID: - if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); + if(update && val != obj->user_data.objid) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); attr_out_int(obj, attr, obj->user_data.objid); return; // attribute_found @@ -1753,12 +1783,12 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p break; // not found case ATTR_MIN: - hasp_process_obj_attribute_range(obj, attr, payload, update, true, false); - return; // attribute_found + if(hasp_process_obj_attribute_range(obj, attr, payload, update, true, false)) return; // attribute_found + break; case ATTR_MAX: - hasp_process_obj_attribute_range(obj, attr, payload, update, false, true); - return; // attribute_found + if(hasp_process_obj_attribute_range(obj, attr, payload, update, false, true)) return; // attribute_found + break; case ATTR_OPACITY: update ? lv_obj_set_style_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, val) @@ -1774,23 +1804,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p : attr_out_int(obj, attr, obj->user_data.swipeid); return; // attribute_found - case ATTR_SRC: - if(obj_check_type(obj, LV_HASP_IMAGE)) { - if(update) { - lv_img_cache_invalidate_src(lv_img_get_src(obj)); - lv_img_set_src(obj, payload); - } else { - switch(lv_img_src_get_type(obj)) { - case LV_IMG_SRC_FILE: - return attr_out_str(obj, attr, lv_img_get_file_name(obj)); - case LV_IMG_SRC_SYMBOL: - return attr_out_str(obj, attr, (char*)lv_img_get_src(obj)); - } - } - return; // attribute_found - } - break; // not found - case ATTR_ANIM_SPEED: if(obj_check_type(obj, LV_HASP_LABEL)) { update ? lv_label_set_anim_speed(obj, (uint16_t)val) @@ -1801,7 +1814,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p case ATTR_ANIM_TIME: if(attr_anim_time(obj, attr, val, update)) return; // attribute_found - break; // not found + break; case ATTR_ROWS: switch(obj_get_type(obj)) { @@ -1983,45 +1996,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p } break; // not found - case ATTR_CRITICAL_VALUE: - case ATTR_ANGLE: - case ATTR_LABEL_COUNT: - case ATTR_LINE_COUNT: - case ATTR_FORMAT: - case ATTR_TYPE: - case ATTR_ROTATION: - case ATTR_ADJUSTABLE: - case ATTR_START_ANGLE: - case ATTR_END_ANGLE: - case ATTR_START_ANGLE1: - case ATTR_END_ANGLE1: - switch(obj_get_type(obj)) { - case LV_HASP_ARC: - hasp_process_arc_attribute(obj, attr_p, attr_hash, payload, update); - return; // attribute_found - case LV_HASP_GAUGE: - if(hasp_process_gauge_attribute(obj, attr_p, attr_hash, payload, update)) return; // attribute_found - break; // not found - case LV_HASP_LMETER: - hasp_process_lmeter_attribute(obj, attr_p, attr_hash, payload, update); - return; // attribute_found - default: - break; // not found - } - break; // not found - - case ATTR_DIRECTION: - case ATTR_SYMBOL: - case ATTR_OPEN: - case ATTR_CLOSE: - case ATTR_MAX_HEIGHT: - case ATTR_SHOW_SELECTED: - if(obj_check_type(obj, LV_HASP_DROPDOWN)) { - hasp_process_dropdown_attribute(obj, attr_p, attr_hash, payload, update); - return; // attribute_found - } - break; // not found - case ATTR_RED: // TODO: remove temp RED if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { my_btnmatrix_map_clear(obj); // TODO : remove this test property @@ -2053,21 +2027,75 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p lv_obj_move_background(obj); } return; // attribute_found + } - case ATTR_NEXT: - case ATTR_PREV: - case ATTR_BACK: - if(obj_check_type(obj, LV_HASP_SCREEN)) { - hasp_process_page_attributes(obj, attr_p, attr_hash, val, update); + // Properties by object type + switch(obj_get_type(obj)) { + case LV_HASP_IMAGE: + switch(attr_hash) { + case ATTR_OFFSET_X: + update ? lv_img_set_offset_x(obj, val) : attr_out_int(obj, attr, lv_img_get_offset_x(obj)); + return; + case ATTR_OFFSET_Y: + update ? lv_img_set_offset_y(obj, val) : attr_out_int(obj, attr, lv_img_get_offset_y(obj)); + return; + case ATTR_AUTO_SIZE: + update ? lv_img_set_auto_size(obj, !!val) : attr_out_int(obj, attr, lv_img_get_auto_size(obj)); + return; + case ATTR_SRC: + if(update) { + lv_img_cache_invalidate_src(lv_img_get_src(obj)); + lv_img_set_src(obj, payload); + } else { + switch(lv_img_src_get_type(obj)) { + case LV_IMG_SRC_FILE: + return attr_out_str(obj, attr, lv_img_get_file_name(obj)); + case LV_IMG_SRC_SYMBOL: + return attr_out_str(obj, attr, (char*)lv_img_get_src(obj)); + } + } + return; // attribute_found + } + break; // not found + + case LV_HASP_PAGE: + if(hasp_process_page_attributes(obj, attr_p, attr_hash, val, update)) { return; // attribute_found } break; // not found - default: { - bool result; - hasp_local_style_attr(obj, attr, attr_hash, payload, update, result); - if(result) return; // attribute_found - } + case LV_HASP_DROPDOWN: + if(hasp_process_dropdown_attribute(obj, attr_p, attr_hash, payload, update)) { + return; // attribute_found + } + break; // not found + + case LV_HASP_ARC: + if(hasp_process_arc_attribute(obj, attr_p, attr_hash, payload, update)) { + return; // attribute_found + } + break; // not found + + case LV_HASP_GAUGE: + if(hasp_process_gauge_attribute(obj, attr_p, attr_hash, payload, update)) { + return; // attribute_found + } + break; // not found + + case LV_HASP_LMETER: + if(hasp_process_lmeter_attribute(obj, attr_p, attr_hash, payload, update)) { + return; // attribute_found + } + break; // not found + + default: + break; + } + + { + bool result; + hasp_local_style_attr(obj, attr, attr_hash, payload, update, result); + if(result) return; // attribute_found } LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN " (%d)"), attr_p, attr_hash); diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index 24632b6e..b10bd8dc 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -348,6 +348,11 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_MODAL 7405 #define ATTR_AUTO_CLOSE 7880 +// Image +#define ATTR_OFFSET_X 65388 +#define ATTR_OFFSET_Y 65389 +#define ATTR_AUTO_SIZE 63729 + /* hasp user data */ #define ATTR_ACTION 42102 #define ATTR_TRANSITION 10933 From 06fac902fdbe5a78a9b5a8b1f06390f22bceb18f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 09:50:34 +0200 Subject: [PATCH 164/227] Don't inline some functions --- src/hasp/hasp_object.cpp | 2 +- src/hasp_oobe.cpp | 2 +- src/sys/svc/hasp_telnet.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 20bc41f3..e443f15d 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -240,7 +240,7 @@ void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, con // ##################### Object Creator ######################################################## // Called from hasp_new_object only to process all attributes -static inline int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) +static int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) { int i = 0; #if defined(WINDOWS) || defined(POSIX) diff --git a/src/hasp_oobe.cpp b/src/hasp_oobe.cpp index 3ccf4ef3..6a298840 100644 --- a/src/hasp_oobe.cpp +++ b/src/hasp_oobe.cpp @@ -25,7 +25,7 @@ static lv_obj_t* oobepage[2]; static lv_obj_t* oobekb; lv_obj_t* pwd_ta; -static inline void oobeSetPage(uint8_t pageid) +static void oobeSetPage(uint8_t pageid) { lv_scr_load(oobepage[pageid]); lv_obj_invalidate(lv_disp_get_layer_sys(NULL)); diff --git a/src/sys/svc/hasp_telnet.cpp b/src/sys/svc/hasp_telnet.cpp index 8101cf32..647395ad 100644 --- a/src/sys/svc/hasp_telnet.cpp +++ b/src/sys/svc/hasp_telnet.cpp @@ -181,7 +181,7 @@ static inline void telnetProcessCharacter(char ch) #endif -static inline void telnetProcessLine(const char* input) +static void telnetProcessLine(const char* input) { switch(telnetLoginState) { case TELNET_UNAUTHENTICATED: { From 2216cc0ddd0bc724dc059d67390e1c439fadfe35 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Mon, 10 May 2021 12:29:55 +0200 Subject: [PATCH 165/227] Update ini for png and filesystem --- user_setups/linux_sdl/linux_sdl_64bits.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_setups/linux_sdl/linux_sdl_64bits.ini b/user_setups/linux_sdl/linux_sdl_64bits.ini index f900faa1..34017d30 100644 --- a/user_setups/linux_sdl/linux_sdl_64bits.ini +++ b/user_setups/linux_sdl/linux_sdl_64bits.ini @@ -28,6 +28,7 @@ build_flags = -D HASP_USE_GPIO=1 -D HASP_USE_CONFIG=0 ; Standalone application, as library -D HASP_USE_DEBUG=1 + -D HASP_USE_PNGDECODE=1 -D HASP_USE_MQTT=1 -D MQTT_MAX_PACKET_SIZE=2048 -D HASP_ATTRIBUTE_FAST_MEM= @@ -46,8 +47,7 @@ build_flags = ;-D NO_PERSISTENCE -I.pio/libdeps/linux_sdl_64bits/paho/src -I.pio/libdeps/linux_sdl_64bits/ArduinoJson/src - -I lib/ArduinoJson/src - -I lib/lv_fs_if + !python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))" ; ----- Statically linked libraries -------------------- -lSDL2 @@ -61,12 +61,12 @@ lib_deps = https://github.com/eclipse/paho.mqtt.c.git bblanchon/ArduinoJson@^6.17.2 ; Json(l) parser https://github.com/fvanroie/lv_drivers + git+https://github.com/lvgl/lv_lib_png.git lib_ignore = paho AXP192 ArduinoLog - lv_fs_if src_filter = +<*> From a20da57b9b3d4e91cfe5775ffbe0bdfa76234ca9 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 10 May 2021 17:41:48 +0200 Subject: [PATCH 166/227] Add variable windows size for native apps --- src/drv/tft_driver_sdl2.cpp | 2 +- src/hasp_gui.cpp | 12 ++++----- src/main_sdl2.cpp | 34 +++++++++++++++++------- user_setups/win32/windows_sdl_64bits.ini | 1 - 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/drv/tft_driver_sdl2.cpp b/src/drv/tft_driver_sdl2.cpp index 0c8801a1..7023ca7c 100644 --- a/src/drv/tft_driver_sdl2.cpp +++ b/src/drv/tft_driver_sdl2.cpp @@ -49,7 +49,7 @@ void TftSdl::init(int w, int h) /* Add a display * Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/ - monitor_init(MONITOR_HOR_RES, MONITOR_VER_RES); + monitor_init(w, h); // (MONITOR_HOR_RES, MONITOR_VER_RES); monitor_title(haspDevice.get_hostname()); /* Add the mouse as input device diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 4dbee301..3b57ccc7 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -176,8 +176,8 @@ void guiSetup() lv_disp_drv_init(&disp_drv); disp_drv.buffer = &disp_buf; disp_drv.flush_cb = gui_flush_cb; - disp_drv.hor_res = TFT_WIDTH; - disp_drv.ver_res = TFT_HEIGHT; + disp_drv.hor_res = tft_width; + disp_drv.ver_res = tft_height; switch(gui_settings.rotation) { case 1: @@ -185,13 +185,13 @@ void guiSetup() case 5: case 7: // lv_disp_set_rotation(display, LV_DISP_ROT_90); - disp_drv.hor_res = TFT_HEIGHT; - disp_drv.ver_res = TFT_WIDTH; + disp_drv.hor_res = tft_height; + disp_drv.ver_res = tft_width; break; default: // lv_disp_set_rotation(display, LV_DISP_ROT_NONE); - disp_drv.hor_res = TFT_WIDTH; - disp_drv.ver_res = TFT_HEIGHT; + disp_drv.hor_res = tft_width; + disp_drv.ver_res = tft_height; } lv_disp_t* display = lv_disp_drv_register(&disp_drv); (void)display; // unused diff --git a/src/main_sdl2.cpp b/src/main_sdl2.cpp index 78fdf2e1..cb85b61a 100644 --- a/src/main_sdl2.cpp +++ b/src/main_sdl2.cpp @@ -25,7 +25,7 @@ #include "hasp_conf.h" #include "lvgl.h" -#include "app_hal.h" +// #include "app_hal.h" #include "display/monitor.h" #include "hasp_debug.h" @@ -42,6 +42,9 @@ bool isRunning = 1; uint8_t mainLoopCounter = 0; unsigned long mainLastLoopTime = 0; +extern uint16_t tft_width; +extern uint16_t tft_height; + #if defined(WINDOWS) // https://gist.github.com/kingseva/a918ec66079a9475f19642ec31276a21 void BindStdHandlesToConsole() @@ -136,8 +139,8 @@ void setup() #endif mainLastLoopTime = millis() - 1000; // reset loop counter - delay(250); printf("%s %d\n", __FILE__, __LINE__); + // delay(250); } void loop() @@ -237,19 +240,27 @@ int main(int argc, char* argv[]) // Change to preferences dir std::cout << "\nCommand-line arguments:\n"; for(count = 0; count < argc; count++) - std::cout << " argv[" << count << "] " << argv[count] << "\n" << std::endl << std::flush; + std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush; for(count = 0; count < argc; count++) { if(argv[count][0] == '-') { if(strncmp(argv[count], "--help", 6) == 0 || strncmp(argv[count], "-h", 2) == 0) { - std::cout << " argv[" << count << "] " << argv[count] << "\n" << std::endl << std::flush; - fflush(stdout); - exit(0); + showhelp = true; } - if(strncmp(argv[count], "--name", 6) == 0) { - std::cout << " argv[" << count << "] " << argv[count] << "\n" << std::endl << std::flush; + if(strncmp(argv[count], "--width", 7) == 0 || strncmp(argv[count], "-x", 2) == 0) { + int w = atoi(argv[count + 1]); + if(w > 0) tft_width = w; + } + + if(strncmp(argv[count], "--height", 8) == 0 || strncmp(argv[count], "-y", 2) == 0) { + int h = atoi(argv[count + 1]); + if(h > 0) tft_height = h; + } + + if(strncmp(argv[count], "--name", 6) == 0 || strncmp(argv[count], "-n", 2) == 0) { + std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush; fflush(stdout); if(count + 1 < argc) { haspDevice.set_hostname(argv[count + 1]); @@ -264,9 +275,11 @@ int main(int argc, char* argv[]) usage("openHASP"); #if defined(WINDOWS) - WriteConsole(std_out, "bye", 3, NULL, NULL); - + WriteConsole(std_out, "bye\n", 3, NULL, NULL); + std::cout << std::endl << std::flush; + fflush(stdout); FreeConsole(); + exit(0); #endif return 0; } @@ -275,6 +288,7 @@ int main(int argc, char* argv[]) // fflush(stdout); debugPrintHaspHeader(stdout); + LOG_NOTICE(TAG_MAIN, "resolution %d x %d", tft_width, tft_height); LOG_NOTICE(TAG_MAIN, "pre setup"); setup(); diff --git a/user_setups/win32/windows_sdl_64bits.ini b/user_setups/win32/windows_sdl_64bits.ini index b85d97a6..b7b94638 100644 --- a/user_setups/win32/windows_sdl_64bits.ini +++ b/user_setups/win32/windows_sdl_64bits.ini @@ -49,7 +49,6 @@ build_flags = ;-D NO_PERSISTENCE -I.pio/libdeps/windows_sdl_64bits/paho/src -I.pio/libdeps/windows_sdl_64bits/ArduinoJson/src - -I lib/ArduinoJson/src -I lib/lv_fs_if !python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))" -mconsole From e236905f2e0939f0577de38fa1514685c749279d Mon Sep 17 00:00:00 2001 From: Gerardo Castillo <32140109+altersis@users.noreply.github.com> Date: Mon, 10 May 2021 18:54:32 -0400 Subject: [PATCH 167/227] THis is the new Spanish language file --- src/lang/sp_ES.h | 205 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 src/lang/sp_ES.h diff --git a/src/lang/sp_ES.h b/src/lang/sp_ES.h new file mode 100644 index 00000000..1a3265cf --- /dev/null +++ b/src/lang/sp_ES.h @@ -0,0 +1,205 @@ +#ifndef HASP_LANG_EN_US_H +#define HASP_LANG_EN_US_H + +#define D_USERNAME "Usuario:" +#define D_PASSWORD "Contraseña:" +#define D_SSID "Ssid:" +#define D_YES "Si" // New +#define D_NO "No" // New + +#define D_ERROR_OUT_OF_MEMORY "Memory llena" +#define D_ERROR_UNKNOWN "Error desconocido" + +#define D_CONFIG_NOT_CHANGED "No hay cambios en la configuración" +#define D_CONFIG_CHANGED "Configuración cambiada" +#define D_CONFIG_LOADED "Configuración cargada" + +#define D_FILE_LOADING "Cargando %s" +#define D_FILE_LOADED "%s cargado" +#define D_FILE_LOAD_FAILED "No se pudo cargar %s" + +#define D_FILE_SAVING "Guardando %s" +#define D_FILE_SAVED "%s guardado" +#define D_FILE_SAVE_FAILED "No se pudo guardar %s" +#define D_FILE_NOT_FOUND "Archivo no encontrado" // new + +#define D_SERVICE_STARTING "Inicializando..." +#define D_SERVICE_STARTED "Inicializado" +#define D_SERVICE_START_FAILED "No se pudo arrancar" +#define D_SERVICE_STOPPED "Parado" +#define D_SERVICE_DISABLED "Deshabilitado" +#define D_SERVICE_CONNECTED "Conectado" +#define D_SERVICE_DISCONNECTED "Desconectado" + +#define D_SETTING_ENABLED "habilitado" // New +#define D_SETTING_DISABLED "Deshabilitado" // New + +#define D_NETWORK_IP_ADDRESS_RECEIVED "Se recibió la dirección IP: %s" +#define D_NETWORK_ONLINE "en linea" +#define D_NETWORK_OFFLINE "fuera de línea" +#define D_NETWORK_CONNECTION_FAILED "Falló la conexión" + +#define D_MQTT_DEFAULT_NAME "placa_%s" +#define D_MQTT_CONNECTING "Conectando..." +#define D_MQTT_CONNECTED "Conectado al Broker %s con el clientID %s" +#define D_MQTT_NOT_CONNECTED "No hay conexión ???" +#define D_MQTT_DISCONNECTING "Desconectando..." +#define D_MQTT_DISCONNECTED "Desconectado" +#define D_MQTT_RECONNECTING "Desconectado del broker, reconectando..." +#define D_MQTT_NOT_CONFIGURED "No se ha configurado el Broker" +#define D_MQTT_STARTED "Arrancando: %d bytes" +#define D_MQTT_FAILED "Falló:" +#define D_MQTT_INVALID_TOPIC "El mensaje tiene un tópico inválido" +#define D_MQTT_SUBSCRIBED "Subscrito a %s" +#define D_MQTT_NOT_SUBSCRIBED "No se pudo subscribir a %s" +#define D_MQTT_HA_AUTO_DISCOVERY "Registrando auto-descubrimiento en HA" +#define D_MQTT_PAYLOAD_TOO_LONG "Los datos enviados son demasiado largos(%u bytes)" + +#define D_TELNET_CLOSING_CONNECTION "Cerrando sesión de %s" +#define D_TELNET_CLIENT_LOGIN_FROM "Se ha firmado el cliente %s" +#define D_TELNET_CLIENT_CONNECT_FROM "Se ha conectado el cliente %s" +#define D_TELNET_AUTHENTICATION_FAILED "Falló la autorización!" +#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Intento de conexión incorrecta desde %s" +#define D_TELNET_STARTED "Console Telnet arrancada" +#define D_TELNET_FAILED "Falló el arranque de la consola Telnet" +#define D_TELNET_CLIENT_CONNECTED "Cliente conectado" +#define D_TELNET_CLIENT_NOT_CONNECTED "Cliente NO conectado" +#define D_TELNET_CLIENT_REJECTED "Cliente rechazado" + +#define D_HASP_INVALID_PAGE "Página inválida %u" +#define D_HASP_INVALID_LAYER "No se puede borrar una capa del sistema" +#define D_HASP_CHANGE_PAGE "Cambiando a página %u" +#define D_HASP_CLEAR_PAGE "Limpiando página %u" + +#define D_OBJECT_DELETED "Objeto borrado" +#define D_OBJECT_UNKNOWN "Objeto desconocido" +#define D_OBJECT_MISMATCH "Los objetos NO SON IGUALES!" +#define D_OBJECT_LOST "Objeto perdido!" +#define D_OBJECT_CREATE_FAILED "No se pudo crear objeto %u" +#define D_OBJECT_PAGE_UNKNOWN "La página ID %u no está definida" +#define D_OBJECT_EVENT_UNKNOWN "NO se conoce el evento %d " + +#define D_ATTRIBUTE_UNKNOWN "Propiedad %s desconocida" +#define D_ATTRIBUTE_READ_ONLY "%s es solo lectura" +#define D_ATTRIBUTE_PAGE_METHOD_INVALID "No se puede llamar %s en una página" + +#define D_OOBE_SSID_VALIDATED "SSID %s validado" +#define D_OOBE_AUTO_CALIBRATE "Auto calibración hablitada" +#define D_OOBE_CALIBRATED "Ya se ha calibrado" + +#define D_DISPATCH_COMMAND_NOT_FOUND "No se encontró el comando '%s'" +#define D_DISPATCH_INVALID_PAGE "Página inválida %s" +#define D_DISPATCH_REBOOT "Reiniciando microprocesador!" + +#define D_JSON_FAILED "No se pudo analizar JSON:" +#define D_JSONL_FAILED "El análisis del JSONL falló en la línea %u" +#define D_JSONL_SUCCEEDED "JSONL analizado" + +#define D_OTA_CHECK_UPDATE "Buscando actualización en URL: %s" +#define D_OTA_CHECK_COMPLETE "Verificación de actualizacion completa" +#define D_OTA_CHECK_FAILED "Falló la verificación de actualización: %s" +#define D_OTA_UPDATE_FIRMWARE "Actualización de firmware OTA" +#define D_OTA_UPDATE_COMPLETE "Actualización OTA completada" +#define D_OTA_UPDATE_APPLY "Aplicando el nuevo firmware y reinicio" +#define D_OTA_UPDATE_FAILED "La actualización OTA falló" +#define D_OTA_UPDATING_FIRMWARE "Actualizando el firmware..." +#define D_OTA_UPDATING_FILESYSTEM "Actualizando el sistema de archivos..." + +#define D_HTTP_HASP_DESIGN "Diseño de HASP" +#define D_HTTP_INFORMATION "Información" +#define D_HTTP_HTTP_SETTINGS "Ajustes HTTP" +#define D_HTTP_WIFI_SETTINGS "Ajustes Wifi" +#define D_HTTP_MQTT_SETTINGS "Ajustes MQTT" +#define D_HTTP_GPIO_SETTINGS "Ajustes GPIO" +#define D_HTTP_MDNS_SETTINGS "Ajustes mDNS" +#define D_HTTP_TELNET_SETTINGS "Ajustes Telnet" +#define D_HTTP_DEBUG_SETTINGS "Ajustes de depuración" +#define D_HTTP_GUI_SETTINGS "Ajustes de Pantalla" +#define D_HTTP_SAVE_SETTINGS "Guardar configuración" +#define D_HTTP_UPLOAD_FILE "Cargar archivo" +#define D_HTTP_ERASE_DEVICE "Borrar configuración" +#define D_HTTP_ADD_GPIO "Agragar un nuevo pin" +#define D_HTTP_BACK "Atrás" +#define D_HTTP_REFRESH "Refrescar" +#define D_HTTP_PREV_PAGE "Página Previa" +#define D_HTTP_NEXT_PAGE "Siguiente Página" +#define D_HTTP_CALIBRATE "Calibrar" +#define D_HTTP_SCREENSHOT "Imagen de Pantalla" +#define D_HTTP_FILE_BROWSER "Editor de Archivos" +#define D_HTTP_FIRMWARE_UPGRADE "Actualización de firmware" +#define D_HTTP_UPDATE_FIRMWARE "Actualizar firmware" +#define D_HTTP_FACTORY_RESET "Restaurar conf de fábrica" +#define D_HTTP_MAIN_MENU "Menú principal" +#define D_HTTP_REBOOT "Reiniciar" +#define D_HTTP_CONFIGURATION "Configuración" +#define D_HTTP_SENDING_PAGE "Se envió pagina %S a %s" // New +#define D_HTTP_FOOTER "por Francis Van Roie" + +#define D_INFO_VERSION "Versión" +#define D_INFO_BUILD_DATETIME "Fecha de compilación" +#define D_INFO_UPTIME "Tiempo activo" +#define D_INFO_FREE_HEAP "Heap libre" +#define D_INFO_FREE_BLOCK "Bloques libres" +#define D_INFO_DEVICE_MEMORY "Memoria de dispositivo" +#define D_INFO_LVGL_MEMORY "Memoria LVGL" +#define D_INFO_TOTAL_MEMORY "Total" +#define D_INFO_FREE_MEMORY "Libre" +#define D_INFO_FRAGMENTATION "Fragmentación" +#define D_INFO_PSRAM_FREE "PSRam libre" +#define D_INFO_PSRAM_SIZE "Tamaño PSRam " +#define D_INFO_FLASH_SIZE "Tamaño Flash" +#define D_INFO_SKETCH_USED "Memoria programa usada" +#define D_INFO_SKETCH_FREE "Memoria Programa libre" +#define D_INFO_MODULE "Módulo" +#define D_INFO_MODEL "Modelo" +#define D_INFO_FREQUENCY "Frecuencia" +#define D_INFO_CORE_VERSION "Versión del núcleo" +#define D_INFO_RESET_REASON "Razón de ultimo Reset" +#define D_INFO_STATUS "Estado" +#define D_INFO_SERVER "Servidor" +#define D_INFO_USERNAME "Nombre de usuario" +#define D_INFO_CLIENTID "ID de Cliente" +#define D_INFO_CONNECTED "Connectado" +#define D_INFO_DISCONNECTED "Desconectado" +#define D_INFO_RECEIVED "Recivido" +#define D_INFO_PUBLISHED "Publicado" +#define D_INFO_FAILED "Fallado" +#define D_INFO_ETHERNET "Ethernet" +#define D_INFO_WIFI "Wifi" +#define D_INFO_LINK_SPEED "Velocidad de enlace" +#define D_INFO_FULL_DUPLEX "Full Duplex" +#define D_INFO_SSID "SSID" +#define D_INFO_RSSI "Potencia de señal" +#define D_INFO_IP_ADDRESS "Dirección IP" +#define D_INFO_MAC_ADDRESS "Dirección MAC" +#define D_INFO_GATEWAY "Gateway" +#define D_INFO_DNS_SERVER "Servidor DNS" + +#define D_OOBE_MSG "Toque la pantalla para ajustar WiFi o conectarse a un punto de acceso" +#define D_OOBE_SCAN_TO_CONNECT "Scanee para conectar" + +#define D_WIFI_CONNECTING_TO "Connectando a %s" +#define D_WIFI_CONNECTED_TO "Connectado a %s, pidiendo IP..." +#define D_WIFI_RSSI_EXCELLENT "Excellente" +#define D_WIFI_RSSI_GOOD "Buena" +#define D_WIFI_RSSI_FAIR "Pasable" +#define D_WIFI_RSSI_WEAK "Débil" +#define D_WIFI_RSSI_BAD "Muy baka" + +// new +#define D_GPIO_SWITCH "Switch" +#define D_GPIO_BUTTON "Botón" +#define D_GPIO_LED "DEL" +#define D_GPIO_LED_R "Ánimo Red" +#define D_GPIO_LED_G "Ánimo Green" +#define D_GPIO_LED_B "Ánimo Blue" +#define D_GPIO_RELAY "Relé" +#define D_GPIO_PWM "PWM" +#define D_GPIO_DAC "DAC" +#define D_GPIO_SERIAL_DIMMER "Atenuador serial" +#define D_GPIO_UNKNOWN "Desconocido" +#define D_GPIO_PIN "Pin" +#define D_GPIO_GROUP "Grupo" +#define D_GPIO_GROUP_NONE "Ninguno" + +#endif \ No newline at end of file From 16f4c9d3b0781d395c4d2419788bc572dfbd848c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 01:30:31 +0200 Subject: [PATCH 168/227] Remove duplicate D_TELNET_CLIENT_NOT_CONNECTED --- src/lang/en_US.h | 1 - src/lang/fr_FR.h | 204 +++++++++++++++++++++++++++++++++++++++++++++++ src/lang/hu_HU.h | 1 - src/lang/nl_NL.h | 2 +- src/lang/ro_RO.h | 1 - 5 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 src/lang/fr_FR.h diff --git a/src/lang/en_US.h b/src/lang/en_US.h index bc0116f2..838621ef 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -64,7 +64,6 @@ #define D_TELNET_STARTED "Telnet console started" #define D_TELNET_FAILED "Failed to start telnet console" #define D_TELNET_CLIENT_CONNECTED "Client connected" -#define D_TELNET_CLIENT_NOT_CONNECTED "Client NOT connected" #define D_TELNET_CLIENT_REJECTED "Client rejected" #define D_HASP_INVALID_PAGE "Invalid page %u" diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h new file mode 100644 index 00000000..e423e592 --- /dev/null +++ b/src/lang/fr_FR.h @@ -0,0 +1,204 @@ +#ifndef HASP_LANG_EN_US_H +#define HASP_LANG_EN_US_H + +#define D_USERNAME "Utilisateur:" +#define D_PASSWORD "Mot de passe:" +#define D_SSID "Ssid:" +#define D_YES "Oui" +#define D_NO "Non" + +#define D_ERROR_OUT_OF_MEMORY "Mémoire insuffisante " +#define D_ERROR_UNKNOWN "Erreur inconnue" + +#define D_CONFIG_NOT_CHANGED "Paramètres pas modifiés" +#define D_CONFIG_CHANGED "Paramètres modifiés" +#define D_CONFIG_LOADED "Paramètres chargés" + +#define D_FILE_LOADING "Charger %s" +#define D_FILE_LOADED "Chargé %s" +#define D_FILE_LOAD_FAILED "Échec du chargement %s" + +#define D_FILE_SAVING "Enregistrer %s" +#define D_FILE_SAVED "Enregistré %s" +#define D_FILE_SAVE_FAILED "Échec de l'enregistrement %s" +#define D_FILE_NOT_FOUND "Fichier non trouvé" + +#define D_SERVICE_STARTING "Démarer..." +#define D_SERVICE_STARTED "Démaré" +#define D_SERVICE_START_FAILED "Échec du démarrage" +#define D_SERVICE_STOPPED "Arrêté" +#define D_SERVICE_DISABLED "Désactivé" +#define D_SERVICE_CONNECTED "Connecté" +#define D_SERVICE_DISCONNECTED "Débranché" + +#define D_SETTING_ENABLED "Activé" +#define D_SETTING_DISABLED "Désactivé" + +#define D_NETWORK_IP_ADDRESS_RECEIVED "Adresse IP reçue %s" +#define D_NETWORK_ONLINE "en ligne" +#define D_NETWORK_OFFLINE "déconnecté" +#define D_NETWORK_CONNECTION_FAILED "Échec de la connexion " + +#define D_MQTT_DEFAULT_NAME "plaque_%s" +#define D_MQTT_CONNECTING "Connexion..." +#define D_MQTT_CONNECTED "Connecté au broker %s avec ID client %s" +#define D_MQTT_NOT_CONNECTED "Pas connecté ???" +#define D_MQTT_DISCONNECTING "Déconnexion..." +#define D_MQTT_DISCONNECTED "Débranché" +#define D_MQTT_RECONNECTING "Déconnecté du broker, reconnexion..." +#define D_MQTT_NOT_CONFIGURED "Broker non configuré" +#define D_MQTT_STARTED "Démarré: %d octets " +#define D_MQTT_FAILED "Manqué:" +#define D_MQTT_INVALID_TOPIC "Message avec sujet non valide " +#define D_MQTT_SUBSCRIBED "Abonné à %s" +#define D_MQTT_NOT_SUBSCRIBED "Échec de s'abonner à %s" +#define D_MQTT_HA_AUTO_DISCOVERY "Enregistrer la détection automatique HA" +#define D_MQTT_PAYLOAD_TOO_LONG "Charge utile trop long (%u octets) " + +#define D_TELNET_CLOSING_CONNECTION "Clôture de la session %s" +#define D_TELNET_CLIENT_LOGIN_FROM "Connexion client depuis %s" +#define D_TELNET_CLIENT_CONNECT_FROM "Client connecté depuis %s" +#define D_TELNET_CLIENT_NOT_CONNECTED "Client NON connecté" +#define D_TELNET_AUTHENTICATION_FAILED "Échec de l'autorisation!" +#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Tentative incorrecte de %s" +#define D_TELNET_STARTED "Console Telnet démarré" +#define D_TELNET_FAILED "Échec du démarrage de la console telnet" +#define D_TELNET_CLIENT_CONNECTED "Client connecté" +#define D_TELNET_CLIENT_REJECTED "Client rejeté" + +#define D_HASP_INVALID_PAGE "Page non valide %u" +#define D_HASP_INVALID_LAYER "Impossible d'effacer la couche système" +#define D_HASP_CHANGE_PAGE "Changement de page %u" +#define D_HASP_CLEAR_PAGE "Effacement de la page %u" + +#define D_OBJECT_DELETED "Objet supprimé" +#define D_OBJECT_UNKNOWN "Objet inconnu" +#define D_OBJECT_MISMATCH "Objets ne correspondent PAS!" +#define D_OBJECT_LOST "Objet perdu!" +#define D_OBJECT_CREATE_FAILED "Échec de la création d'objet %u" +#define D_OBJECT_PAGE_UNKNOWN "ID de page %u non défini" +#define D_OBJECT_EVENT_UNKNOWN "Inconnu Event %d" + +#define D_ATTRIBUTE_UNKNOWN "Unknown property %s" +#define D_ATTRIBUTE_READ_ONLY "%s is read-only" +#define D_ATTRIBUTE_PAGE_METHOD_INVALID "Unable to call %s on a page" + +#define D_OOBE_SSID_VALIDATED "SSID %s validated" +#define D_OOBE_AUTO_CALIBRATE "Auto calibrate enabled" +#define D_OOBE_CALIBRATED "Already calibrated" + +#define D_DISPATCH_COMMAND_NOT_FOUND "Command '%s' not found" +#define D_DISPATCH_INVALID_PAGE "Invalid page %s" +#define D_DISPATCH_REBOOT "Rebooting the MCU now!" + +#define D_JSON_FAILED "JSON parsing failed:" +#define D_JSONL_FAILED "JSONL parsing failed at line %u" +#define D_JSONL_SUCCEEDED "Jsonl fully parsed" + +#define D_OTA_CHECK_UPDATE "Checking updates URL: %s" +#define D_OTA_CHECK_COMPLETE "Update check complete" +#define D_OTA_CHECK_FAILED "Update check failed: %s" +#define D_OTA_UPDATE_FIRMWARE "OTA Firmware Update" +#define D_OTA_UPDATE_COMPLETE "OTA Update complete" +#define D_OTA_UPDATE_APPLY "Applying Firmware & Reboot" +#define D_OTA_UPDATE_FAILED "OTA Update failed" +#define D_OTA_UPDATING_FIRMWARE "Updating firmware..." +#define D_OTA_UPDATING_FILESYSTEM "Updating filesystem..." + +#define D_HTTP_HASP_DESIGN "Conception HASP" +#define D_HTTP_INFORMATION "Information" +#define D_HTTP_HTTP_SETTINGS "Paramètres HTTP" +#define D_HTTP_WIFI_SETTINGS "Paramètres Wifi" +#define D_HTTP_MQTT_SETTINGS "Paramètres MQTT" +#define D_HTTP_GPIO_SETTINGS "Paramètres GPIO" +#define D_HTTP_MDNS_SETTINGS "Paramètres mDNS" +#define D_HTTP_TELNET_SETTINGS "Paramètres Telnet" +#define D_HTTP_DEBUG_SETTINGS "Paramètres de débogage" +#define D_HTTP_GUI_SETTINGS "Paramètres d'affichage" +#define D_HTTP_SAVE_SETTINGS "Enregistrer les paramètres" +#define D_HTTP_UPLOAD_FILE "Télécharger le fichier" +#define D_HTTP_ERASE_DEVICE "Réinitialiser tous les paramètres" +#define D_HTTP_ADD_GPIO "Ajouter une nouvelle épingles" +#define D_HTTP_BACK "Retour" +#define D_HTTP_REFRESH "Actualiser" +#define D_HTTP_PREV_PAGE "Page précédente" +#define D_HTTP_NEXT_PAGE "Page suivante" +#define D_HTTP_CALIBRATE "Calibrer" +#define D_HTTP_SCREENSHOT "Capture d'écran" +#define D_HTTP_FILE_BROWSER "Éditeur de fichiers" +#define D_HTTP_FIRMWARE_UPGRADE "Mise à jour du micrologiciel" +#define D_HTTP_UPDATE_FIRMWARE "Mettre à jour le micrologiciel" +#define D_HTTP_FACTORY_RESET "Paramètres d'usine" +#define D_HTTP_MAIN_MENU "Menu principal" +#define D_HTTP_REBOOT "Redémarrer" +#define D_HTTP_CONFIGURATION "Configuration" +#define D_HTTP_SENDING_PAGE "La page %S a été envoyée à %s" +#define D_HTTP_FOOTER "par Francis Van Roie" + +#define D_INFO_VERSION "Version" +#define D_INFO_BUILD_DATETIME "Date/heure de compilation" +#define D_INFO_UPTIME "Disponibilité" +#define D_INFO_FREE_HEAP "Tas libre" +#define D_INFO_FREE_BLOCK "Blocage libre" +#define D_INFO_DEVICE_MEMORY "Mémoire de l'appareil" +#define D_INFO_LVGL_MEMORY "Mémoire LVGL" +#define D_INFO_TOTAL_MEMORY "Total" +#define D_INFO_FREE_MEMORY "Libre" +#define D_INFO_FRAGMENTATION "Fragmentation" +#define D_INFO_PSRAM_FREE "PSRam libre" +#define D_INFO_PSRAM_SIZE "Taille PSRam" +#define D_INFO_FLASH_SIZE "Taille du flash" +#define D_INFO_SKETCH_USED "Taille utilisée du programme" +#define D_INFO_SKETCH_FREE "Taille libre du programme" +#define D_INFO_MODULE "Module" +#define D_INFO_MODEL "Modèle" +#define D_INFO_FREQUENCY "Fréquence" +#define D_INFO_CORE_VERSION "Version principale" +#define D_INFO_RESET_REASON "Raison de la réinitialisation" +#define D_INFO_STATUS "Statut" +#define D_INFO_SERVER "Serveur" +#define D_INFO_USERNAME "Nom d'utilisateur" +#define D_INFO_CLIENTID "ID client" +#define D_INFO_CONNECTED "Connecté" +#define D_INFO_DISCONNECTED "Déconnecté" +#define D_INFO_RECEIVED "Reçu" +#define D_INFO_PUBLISHED "Publié" +#define D_INFO_FAILED "Échec" +#define D_INFO_ETHERNET "Ethernet" +#define D_INFO_WIFI "Wifi" +#define D_INFO_LINK_SPEED "Vitesse de liaison" +#define D_INFO_FULL_DUPLEX "Duplex intégral" +#define D_INFO_SSID "SSID" +#define D_INFO_RSSI "Force du signal" +#define D_INFO_IP_ADDRESS "Adresse IP" +#define D_INFO_MAC_ADDRESS "Adresse MAC" +#define D_INFO_GATEWAY "Passerelle" +#define D_INFO_DNS_SERVER "Serveur DNS" + +#define D_OOBE_MSG "Touchez l'écran pour configurer le WiFi ou branchez ce point d'accès:" +#define D_OOBE_SCAN_TO_CONNECT "Scanner pour se connecter" + +#define D_WIFI_CONNECTING_TO "Connexion à %s" +#define D_WIFI_CONNECTED_TO "Connecté à %s, demande d'IP..." +#define D_WIFI_RSSI_EXCELLENT "Excellent" +#define D_WIFI_RSSI_GOOD "Bon" +#define D_WIFI_RSSI_FAIR "Juste" +#define D_WIFI_RSSI_WEAK "Faible" +#define D_WIFI_RSSI_BAD "Très mauvais" + +#define D_GPIO_SWITCH "Interrupteur" +#define D_GPIO_BUTTON "Bouton" +#define D_GPIO_LED "Led" +#define D_GPIO_LED_R "Humeur Rouge" +#define D_GPIO_LED_G "Humeur Vert" +#define D_GPIO_LED_B "Humeur Bleu" +#define D_GPIO_RELAY "Relaiss" +#define D_GPIO_PWM "PWM" +#define D_GPIO_DAC "DAC" +#define D_GPIO_SERIAL_DIMMER "Gradateur Série" +#define D_GPIO_UNKNOWN "Inconnu" +#define D_GPIO_PIN "Pin" +#define D_GPIO_GROUP "Groupe" +#define D_GPIO_GROUP_NONE "Aucun" + +#endif \ No newline at end of file diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index 835fa205..e0463bd8 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -64,7 +64,6 @@ #define D_TELNET_STARTED "Telnet konzol elindítva" #define D_TELNET_FAILED "Telnet konzol elindítása meghiúsult" #define D_TELNET_CLIENT_CONNECTED "Kliens csatlakozva" -#define D_TELNET_CLIENT_NOT_CONNECTED "Kliens NEM csatlakozik" #define D_TELNET_CLIENT_REJECTED "Kliens elutasítva" #define D_HASP_INVALID_PAGE "Érvénytelen oldal: %u" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index b55e6596..f358f1b9 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -58,12 +58,12 @@ #define D_TELNET_CLOSING_CONNECTION "Sessie sluiten van %s" #define D_TELNET_CLIENT_LOGIN_FROM "Client aangemeld van %s" #define D_TELNET_CLIENT_CONNECT_FROM "Client verbonden van %s" +#define D_TELNET_CLIENT_NOT_CONNECTED "Client NIET verbonden" #define D_TELNET_AUTHENTICATION_FAILED "Autorisatie mislukt!" #define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Aanmelding van %s mislukt" #define D_TELNET_STARTED "Telnet console gestart" #define D_TELNET_FAILED "Telnet console starten is mislukt" #define D_TELNET_CLIENT_CONNECTED "Client verbonden" -#define D_TELNET_CLIENT_NOT_CONNECTED "Client NIET verbonden" #define D_TELNET_CLIENT_REJECTED "Client geweigerd" #define D_HASP_INVALID_PAGE "Ongeldige pagina %u" diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 2795f3a9..bb5c4196 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -64,7 +64,6 @@ #define D_TELNET_STARTED "Consola Telnet pornită" #define D_TELNET_FAILED "Nu s-a putut porni consola Telnet" #define D_TELNET_CLIENT_CONNECTED "Client conectat" -#define D_TELNET_CLIENT_NOT_CONNECTED "Client NU este conectat" #define D_TELNET_CLIENT_REJECTED "Client respins" #define D_HASP_INVALID_PAGE "Pagina invalidă: %u" From 637668d9b1d1e8f47d1b3ca9c50f29da379bf090 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 01:31:55 +0200 Subject: [PATCH 169/227] Add usedBytes and totalBytes --- src/hasp_filesystem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hasp_filesystem.cpp b/src/hasp_filesystem.cpp index 78a1101a..ceff1646 100644 --- a/src/hasp_filesystem.cpp +++ b/src/hasp_filesystem.cpp @@ -65,6 +65,8 @@ void filesystemInfo() Serial.print("Max path lenght: "); // Serial.println(SPIFFS.maxPathLength()); #endif + + Log.verbose(TAG_FILE, "Partition size: total: %d, used: %d", HASP_FS.totalBytes(), HASP_FS.usedBytes()); } void filesystemList() From 64eeb49a7890cd8077c50ea9e7dace742c384cec Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 01:32:29 +0200 Subject: [PATCH 170/227] Add moodlight brightness --- src/hasp/hasp_dispatch.cpp | 21 ++++++--------------- src/sys/gpio/hasp_gpio.cpp | 24 +++++++++++++++++++++++- src/sys/gpio/hasp_gpio.h | 2 +- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 1ecd1541..06269767 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -42,12 +42,7 @@ uint32_t dispatchLastMillis = -3000000; // force discovery uint8_t nCommands = 0; haspCommand_t commands[20]; -struct moodlight_t -{ - uint8_t power; - uint8_t r, g, b; -}; -moodlight_t moodlight; +moodlight_t moodlight = {.brightness = 255}; static void dispatch_config(const char* topic, const char* payload); // void dispatch_group_value(uint8_t groupid, int16_t state, lv_obj_t * obj); @@ -705,6 +700,7 @@ void dispatch_moodlight(const char* topic, const char* payload) if(!json["r"].isNull()) moodlight.r = json["r"].as(); if(!json["g"].isNull()) moodlight.g = json["g"].as(); if(!json["b"].isNull()) moodlight.b = json["b"].as(); + if(!json["brightness"].isNull()) moodlight.brightness = json["brightness"].as(); if(!json[F("color")].isNull()) { if(!json[F("color")]["r"].isNull()) { @@ -725,10 +721,7 @@ void dispatch_moodlight(const char* topic, const char* payload) } #if HASP_USE_GPIO > 0 - if(moodlight.power) - gpio_set_moodlight(moodlight.r, moodlight.g, moodlight.b); - else - gpio_set_moodlight(0, 0, 0); + gpio_set_moodlight(moodlight); #endif } } @@ -740,8 +733,8 @@ void dispatch_moodlight(const char* topic, const char* payload) snprintf_P( // buffer, sizeof(buffer), // PSTR("{\"state\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%u,\"g\":%u,\"b\":%u}"), - buffer, sizeof(buffer), PSTR("{\"state\":\"%s\",\"color\":{\"r\":%u,\"g\":%u,\"b\":%u}}"), - moodlight.power ? "ON" : "OFF", moodlight.r, moodlight.g, moodlight.b); + buffer, sizeof(buffer), PSTR("{\"state\":\"%s\",\"color\":{\"r\":%u,\"g\":%u,\"b\":%u,\"brightness\":%u}}"), + moodlight.power ? "ON" : "OFF", moodlight.r, moodlight.g, moodlight.b, moodlight.brightness); dispatch_state_subtopic(out_topic, buffer); } @@ -1000,9 +993,7 @@ void dispatchSetup() } IRAM_ATTR void dispatchLoop() -{ - lv_task_handler(); // process animations -} +{} #if 1 || ARDUINO void dispatchEverySecond() diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index b613ca50..c10c09cd 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -575,8 +575,20 @@ bool gpio_set_pin_value(uint8_t pin, int32_t val) } // Updates the RGB pins directly, rgb are already normalized values -void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b) +void gpio_set_moodlight(moodlight_t& moodlight) { + uint8_t r = 0; + uint8_t g = 0; + uint8_t b = 0; + + if(moodlight.power && moodlight.brightness) { + r = (moodlight.r * moodlight.brightness + 127) / 255; + g = (moodlight.g * moodlight.brightness + 127) / 255; + b = (moodlight.b * moodlight.brightness + 127) / 255; + } else { + moodlight.power = 0; + } + // RGBXX https://stackoverflow.com/questions/39949331/how-to-calculate-rgbaw-amber-white-from-rgb-for-leds for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { @@ -591,6 +603,16 @@ void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b) break; } } + + for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { + switch(gpioConfig[i].type) { + case HASP_GPIO_LED_B: + case HASP_GPIO_LED_G: + case HASP_GPIO_LED_R: + LOG_VERBOSE(TAG_GPIO, F(D_BULLET D_GPIO_PIN " %d => %d"), gpioConfig[i].pin, gpioConfig[i].val); + break; + } + } } bool gpioIsSystemPin(uint8_t gpio) diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index 62ec3beb..10519c6e 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -31,7 +31,7 @@ void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, i // void gpio_set_gpio_state(uint8_t pin, uint16_t state); bool gpio_get_value(uint8_t pin, uint16_t& val); bool gpio_set_pin_value(uint8_t pin, int32_t val); -void gpio_set_moodlight(uint8_t r, uint8_t g, uint8_t b); +void gpio_set_moodlight(moodlight_t& moodlight); void gpio_discovery(JsonArray& relay, JsonArray& led); From 5a847f0da2f6c8db3183e9096abf98fdc762556c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 01:33:39 +0200 Subject: [PATCH 171/227] Code cleanup --- src/hasp/hasp.cpp | 6 +++--- src/hasp/hasp_object.cpp | 5 +++-- src/hasp_gui.cpp | 2 ++ src/log/hasp_debug.cpp | 20 +------------------- src/main_arduino copy.cpp | 2 +- src/main_arduino.cpp | 9 +++++---- 6 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 78aca9e2..e40acd88 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -363,8 +363,8 @@ void haspSetup(void) if(haspFonts[3] == nullptr) haspFonts[3] = LV_THEME_DEFAULT_FONT_TITLE; // haspFonts[0] = lv_font_load("E:/font_1.fnt"); - // haspFonts[2] = lv_font_load("E:/font_2.fnt"); - // haspFonts[3] = lv_font_load("E:/font_3.fnt"); + // haspFonts[2] = lv_font_load("E:/font_2.fnt"); + // haspFonts[3] = lv_font_load("E:/font_3.fnt"); /* ********** Theme Initializations ********** */ if(haspThemeId == 8) haspThemeId = 1; // update old HASP id @@ -461,7 +461,7 @@ void haspSetup(void) hasp_init(); hasp_load_json(); - haspPages.set(haspStartPage, LV_SCR_LOAD_ANIM_NONE); + haspPages.set(haspStartPage, LV_SCR_LOAD_ANIM_FADE_ON); } /********************** diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index e443f15d..fd204496 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -249,7 +249,8 @@ static int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) std::string v; for(JsonPair keyValue : doc) { - LOG_VERBOSE(TAG_HASP, F(D_BULLET "%s=%s"), keyValue.key().c_str(), keyValue.value().as().c_str()); + // LOG_VERBOSE(TAG_HASP, F(D_BULLET "%s=%s"), keyValue.key().c_str(), + // keyValue.value().as().c_str()); v = keyValue.value().as(); hasp_process_obj_attribute(obj, keyValue.key().c_str(), keyValue.value().as().c_str(), true); i++; @@ -259,7 +260,7 @@ static int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) v.reserve(64); for(JsonPair keyValue : doc) { - LOG_DEBUG(TAG_HASP, F(D_BULLET "%s=%s"), keyValue.key().c_str(), keyValue.value().as().c_str()); + // LOG_DEBUG(TAG_HASP, F(D_BULLET "%s=%s"), keyValue.key().c_str(), keyValue.value().as().c_str()); v = keyValue.value().as(); hasp_process_obj_attribute(obj, keyValue.key().c_str(), keyValue.value().as().c_str(), true); i++; diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 3b57ccc7..87df5e69 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -298,6 +298,8 @@ void guiSetup() IRAM_ATTR void guiLoop(void) { + lv_task_handler(); // process animations + #if defined(STM32F4xx) // tick.update(); #endif diff --git a/src/log/hasp_debug.cpp b/src/log/hasp_debug.cpp index 3e41b88b..3208e9b1 100644 --- a/src/log/hasp_debug.cpp +++ b/src/log/hasp_debug.cpp @@ -319,25 +319,7 @@ void debugSetup(JsonObject settings) } IRAM_ATTR void debugLoop(void) -{ - /* int16_t keypress; - do { - switch(keypress = debugConsole.readKey()) { - - case ConsoleInput::KEY_PAGE_UP: - dispatch_page_next(LV_SCR_LOAD_ANIM_NONE); - break; - - case ConsoleInput::KEY_PAGE_DOWN: - dispatch_page_prev(LV_SCR_LOAD_ANIM_NONE); - break; - - case(ConsoleInput::KEY_FN)...(ConsoleInput::KEY_FN + 12): - dispatch_set_page(keypress - ConsoleInput::KEY_FN, LV_SCR_LOAD_ANIM_NONE); - break; - } - } while(keypress != 0); */ -} +{} void printLocalTime() { diff --git a/src/main_arduino copy.cpp b/src/main_arduino copy.cpp index 0e2b192d..eef0a3f5 100644 --- a/src/main_arduino copy.cpp +++ b/src/main_arduino copy.cpp @@ -104,7 +104,7 @@ void setup() #endif mainLastLoopTime = millis() - 1000; // reset loop counter - delay(250); + delay(20); guiStart(); } diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index dbbe961c..d8d2f800 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -115,7 +115,7 @@ void setup() IRAM_ATTR void loop() { guiLoop(); - haspLoop(); + // haspLoop(); networkLoop(); #if HASP_USE_GPIO > 0 @@ -126,10 +126,10 @@ IRAM_ATTR void loop() mqttLoop(); #endif // MQTT - // debugLoop(); haspDevice.loop(); #if HASP_USE_CONSOLE > 0 + // debugLoop(); consoleLoop(); #endif @@ -137,8 +137,8 @@ IRAM_ATTR void loop() if(millis() - mainLastLoopTime >= 1000) { /* Runs Every Second */ - haspEverySecond(); // sleep timer - debugEverySecond(); // statusupdate + haspEverySecond(); // sleep timer & statusupdate + // debugEverySecond(); /* Runs Every 5 Seconds */ if(mainLoopCounter == 0 || mainLoopCounter == 5) { @@ -165,6 +165,7 @@ IRAM_ATTR void loop() } else { mainLoopCounter++; } + mainLastLoopTime += 1000; } From da9edfa8faa5e54bca70b575b4b96746fdc63195 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 01:33:54 +0200 Subject: [PATCH 172/227] Add moodlight brightness --- src/hasp/hasp_dispatch.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index 73c63e0e..0b635afb 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -11,6 +11,13 @@ struct dispatch_conf_t uint16_t teleperiod; }; +struct moodlight_t +{ + uint8_t brightness; + uint8_t power; + uint8_t r, g, b; +}; + enum hasp_event_t { // even = released, odd = pressed HASP_EVENT_OFF = 0, HASP_EVENT_ON = 1, From 2f5d75b556f06d52b28f0da65a10b5317e86c67c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 01:34:17 +0200 Subject: [PATCH 173/227] Set LV_MEM_SIZE to 48 kB --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 755e97ff..ea509b82 100644 --- a/platformio.ini +++ b/platformio.ini @@ -115,7 +115,7 @@ build_flags = -D HASP_CONSOLE_BUFFER=256 ; maximum length of a console/telnet command -D NO_GLOBAL_HTTPUPDATE ; dont instantiate httpUpdate ; -- lvgl build options ----------------------------- - -D LV_MEM_SIZE=61440U ; 60kB lvgl memory + -D LV_MEM_SIZE=49152U ; 48 kB lvgl memory -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR ;-D LV_FS_PC_PATH="//littlefs" ; this needs to match the vfs mount pount -D LODEPNG_NO_COMPILE_ALLOCATORS ; use PSram functions From 1b42dd4a6b7de7a704fe1584862f16faa57367be Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 02:26:03 +0200 Subject: [PATCH 174/227] Add translations for file size units and decimal point/comma --- src/dev/esp32/esp32.cpp | 2 +- src/hasp/hasp_parser.cpp | 18 +++++++++--------- src/lang/en_US.h | 7 ++++++- src/lang/{sp_ES.h => es_ES.h} | 13 +++++++++---- src/lang/fr_FR.h | 7 ++++++- src/lang/hu_HU.h | 7 ++++++- src/lang/nl_NL.h | 9 +++++++-- src/lang/ro_RO.h | 7 ++++++- 8 files changed, 50 insertions(+), 20 deletions(-) rename src/lang/{sp_ES.h => es_ES.h} (95%) diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp index c3e5dc0c..db5752f0 100644 --- a/src/dev/esp32/esp32.cpp +++ b/src/dev/esp32/esp32.cpp @@ -264,7 +264,7 @@ void Esp32Device::get_info(JsonDocument& doc) /* ESP Stats */ buffer = String(get_cpu_frequency()); buffer += F("MHz"); - info[F(D_INFO_MODULE)] = get_chip_model(); // 10ms + info[F(D_INFO_MODEL)] = get_chip_model(); // 10ms info[F(D_INFO_FREQUENCY)] = buffer; info[F(D_INFO_CORE_VERSION)] = get_core_version(); diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp index 16d9c849..a1f7057e 100644 --- a/src/hasp/hasp_parser.cpp +++ b/src/hasp/hasp_parser.cpp @@ -171,18 +171,18 @@ bool Parser::is_only_digits(const char* s) int Parser::format_bytes(size_t filesize, char* buf, size_t len) { - if(filesize < 1024) return snprintf_P(buf, len, PSTR("%d B"), filesize); + if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%d " D_FILE_SIZE_BYTES), filesize); + filesize = filesize * 10; - char labels[] = "kMGT"; - filesize = filesize * 10 / 1024; // multiply by 10 for 1 decimal place - int unit = 0; + filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 10 for 1 decimal place + if(filesize < D_FILE_SIZE_DIVIDER * 10) + return snprintf_P(buf, len, PSTR(D_FILE_SIZE_DECIMAL " " D_FILE_SIZE_KILOBYTES), filesize / 10, filesize % 10); - while(filesize >= 10240 && unit < (sizeof(labels) - 1)) { // it is multiplied by 10 - unit++; - filesize = filesize / 1024; - } + filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 10 for 1 decimal place + if(filesize < D_FILE_SIZE_DIVIDER * 10) + return snprintf_P(buf, len, PSTR(D_FILE_SIZE_DECIMAL " " D_FILE_SIZE_MEGABYTES), filesize / 10, filesize % 10); - return snprintf_P(buf, len, PSTR("%d.%d %ciB"), filesize / 10, filesize % 10, labels[unit]); + return snprintf_P(buf, len, PSTR(D_FILE_SIZE_DECIMAL " " D_FILE_SIZE_GIGABYTES), filesize / 10, filesize % 10); } uint8_t Parser::get_action_id(const char* action) diff --git a/src/lang/en_US.h b/src/lang/en_US.h index 838621ef..6ef6b58a 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -17,11 +17,16 @@ #define D_FILE_LOADING "Loading %s" #define D_FILE_LOADED "Loaded %s" #define D_FILE_LOAD_FAILED "Failed to load %s" - #define D_FILE_SAVING "Saving %s" #define D_FILE_SAVED "Saved %s" #define D_FILE_SAVE_FAILED "Failed to save %s" #define D_FILE_NOT_FOUND "File not found" // new +#define D_FILE_SIZE_BYTES "bytes" // new +#define D_FILE_SIZE_KILOBYTES "KiB" // new +#define D_FILE_SIZE_MEGABYTES "MiB" // new +#define D_FILE_SIZE_GIGABYTES "GiB" // new +#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes +#define F_FILE_SIZE_DECIMAL "%d.%d" // new, decimal comma or point #define D_SERVICE_STARTING "Starting..." #define D_SERVICE_STARTED "Started" diff --git a/src/lang/sp_ES.h b/src/lang/es_ES.h similarity index 95% rename from src/lang/sp_ES.h rename to src/lang/es_ES.h index 1a3265cf..358dd4bb 100644 --- a/src/lang/sp_ES.h +++ b/src/lang/es_ES.h @@ -5,7 +5,7 @@ #define D_PASSWORD "Contraseña:" #define D_SSID "Ssid:" #define D_YES "Si" // New -#define D_NO "No" // New +#define D_NO "No" // New #define D_ERROR_OUT_OF_MEMORY "Memory llena" #define D_ERROR_UNKNOWN "Error desconocido" @@ -17,11 +17,16 @@ #define D_FILE_LOADING "Cargando %s" #define D_FILE_LOADED "%s cargado" #define D_FILE_LOAD_FAILED "No se pudo cargar %s" - #define D_FILE_SAVING "Guardando %s" #define D_FILE_SAVED "%s guardado" #define D_FILE_SAVE_FAILED "No se pudo guardar %s" -#define D_FILE_NOT_FOUND "Archivo no encontrado" // new +#define D_FILE_NOT_FOUND "Archivo no encontrado" +#define D_FILE_SIZE_BYTES "bytes" // new +#define D_FILE_SIZE_KILOBYTES "KiB" // new +#define D_FILE_SIZE_MEGABYTES "MiB" // new +#define D_FILE_SIZE_GIGABYTES "GiB" // new +#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes +#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point #define D_SERVICE_STARTING "Inicializando..." #define D_SERVICE_STARTED "Inicializado" @@ -31,7 +36,7 @@ #define D_SERVICE_CONNECTED "Conectado" #define D_SERVICE_DISCONNECTED "Desconectado" -#define D_SETTING_ENABLED "habilitado" // New +#define D_SETTING_ENABLED "habilitado" // New #define D_SETTING_DISABLED "Deshabilitado" // New #define D_NETWORK_IP_ADDRESS_RECEIVED "Se recibió la dirección IP: %s" diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h index e423e592..c00903e1 100644 --- a/src/lang/fr_FR.h +++ b/src/lang/fr_FR.h @@ -17,11 +17,16 @@ #define D_FILE_LOADING "Charger %s" #define D_FILE_LOADED "Chargé %s" #define D_FILE_LOAD_FAILED "Échec du chargement %s" - #define D_FILE_SAVING "Enregistrer %s" #define D_FILE_SAVED "Enregistré %s" #define D_FILE_SAVE_FAILED "Échec de l'enregistrement %s" #define D_FILE_NOT_FOUND "Fichier non trouvé" +#define D_FILE_SIZE_BYTES "octets" +#define D_FILE_SIZE_KILOBYTES "Kio" +#define D_FILE_SIZE_MEGABYTES "Mio" +#define D_FILE_SIZE_GIGABYTES "Gio" +#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes +#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point #define D_SERVICE_STARTING "Démarer..." #define D_SERVICE_STARTED "Démaré" diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index e0463bd8..2c923436 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -18,10 +18,15 @@ #define D_FILE_LOADED "%s betöltve" #define D_FILE_LOAD_FAILED "%s betöltése nem sikerült" #define D_FILE_NOT_FOUND "File not found" // new - #define D_FILE_SAVING "%s mentése" #define D_FILE_SAVED "%s mentve" #define D_FILE_SAVE_FAILED "%s mentése meghiúsult" +#define D_FILE_SIZE_BYTES "bytes" // new +#define D_FILE_SIZE_KILOBYTES "KiB" // new +#define D_FILE_SIZE_MEGABYTES "MiB" // new +#define D_FILE_SIZE_GIGABYTES "GiB" // new +#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes +#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point #define D_SERVICE_STARTING "Indítás..." #define D_SERVICE_STARTED "Elindítva" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index f358f1b9..3e25217f 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -17,11 +17,16 @@ #define D_FILE_LOADING "%s laden..." #define D_FILE_LOADED "%s geladen" #define D_FILE_LOAD_FAILED "%s laden mislukt" - #define D_FILE_SAVING "%s bewaren..." #define D_FILE_SAVED "%s bewaard" #define D_FILE_SAVE_FAILED "%s bewaren mislukt" -#define D_FILE_NOT_FOUND "Bestand niet gevonden" // new +#define D_FILE_NOT_FOUND "Bestand niet gevonden" +#define D_FILE_SIZE_BYTES "bytes" +#define D_FILE_SIZE_KILOBYTES "KiB" +#define D_FILE_SIZE_MEGABYTES "MiB" +#define D_FILE_SIZE_GIGABYTES "GiB" +#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes +#define F_FILE_SIZE_DECIMAL "%d,%d" // decimal comma or point #define D_SETTING_ENABLED "Ingeschakeld" #define D_SETTING_DISABLED "Uitgeschakeld" diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index bb5c4196..122f9028 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -17,11 +17,16 @@ #define D_FILE_LOADING "Se încarcă %s" #define D_FILE_LOADED "S-a încărcat %s" #define D_FILE_LOAD_FAILED "Încărcarea %s a eșuat" - #define D_FILE_SAVING "Se salvează %s" #define D_FILE_SAVED "S-a salvat %s" #define D_FILE_SAVE_FAILED "Salvarea %s a eșuat" #define D_FILE_NOT_FOUND "File not found" // new +#define D_FILE_SIZE_BYTES "bytes" // new +#define D_FILE_SIZE_KILOBYTES "KiB" // new +#define D_FILE_SIZE_MEGABYTES "MiB" // new +#define D_FILE_SIZE_GIGABYTES "GiB" // new +#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes +#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point #define D_SETTING_ENABLED "Activ" #define D_SETTING_DISABLED "Inactiv" From 74149bbdc53098fba5e20862e444da63efe728ba Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 18:42:51 +0200 Subject: [PATCH 175/227] Strings for file sizes --- src/hasp/hasp_parser.cpp | 8 +++++--- src/lang/en_US.h | 2 +- src/lang/es_ES.h | 6 +++--- src/lang/fr_FR.h | 8 ++++---- src/lang/hu_HU.h | 2 +- src/lang/nl_NL.h | 8 ++++---- src/lang/ro_RO.h | 2 +- 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp index a1f7057e..036ecc23 100644 --- a/src/hasp/hasp_parser.cpp +++ b/src/hasp/hasp_parser.cpp @@ -176,13 +176,15 @@ int Parser::format_bytes(size_t filesize, char* buf, size_t len) filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 10 for 1 decimal place if(filesize < D_FILE_SIZE_DIVIDER * 10) - return snprintf_P(buf, len, PSTR(D_FILE_SIZE_DECIMAL " " D_FILE_SIZE_KILOBYTES), filesize / 10, filesize % 10); + return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%d " D_FILE_SIZE_KILOBYTES), filesize / 10, + filesize % 10); filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 10 for 1 decimal place if(filesize < D_FILE_SIZE_DIVIDER * 10) - return snprintf_P(buf, len, PSTR(D_FILE_SIZE_DECIMAL " " D_FILE_SIZE_MEGABYTES), filesize / 10, filesize % 10); + return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%d " D_FILE_SIZE_MEGABYTES), filesize / 10, + filesize % 10); - return snprintf_P(buf, len, PSTR(D_FILE_SIZE_DECIMAL " " D_FILE_SIZE_GIGABYTES), filesize / 10, filesize % 10); + return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%d " D_FILE_SIZE_GIGABYTES), filesize / 10, filesize % 10); } uint8_t Parser::get_action_id(const char* action) diff --git a/src/lang/en_US.h b/src/lang/en_US.h index 6ef6b58a..c132e4d3 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -26,7 +26,7 @@ #define D_FILE_SIZE_MEGABYTES "MiB" // new #define D_FILE_SIZE_GIGABYTES "GiB" // new #define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes -#define F_FILE_SIZE_DECIMAL "%d.%d" // new, decimal comma or point +#define D_DECIMAL_POINT "." // new, decimal comma or point #define D_SERVICE_STARTING "Starting..." #define D_SERVICE_STARTED "Started" diff --git a/src/lang/es_ES.h b/src/lang/es_ES.h index 358dd4bb..448b8cca 100644 --- a/src/lang/es_ES.h +++ b/src/lang/es_ES.h @@ -1,5 +1,5 @@ -#ifndef HASP_LANG_EN_US_H -#define HASP_LANG_EN_US_H +#ifndef HASP_LANG_ES_ES_H +#define HASP_LANG_ES_ES_H #define D_USERNAME "Usuario:" #define D_PASSWORD "Contraseña:" @@ -26,7 +26,7 @@ #define D_FILE_SIZE_MEGABYTES "MiB" // new #define D_FILE_SIZE_GIGABYTES "GiB" // new #define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes -#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point +#define D_DECIMAL_POINT "," // new, decimal comma or point #define D_SERVICE_STARTING "Inicializando..." #define D_SERVICE_STARTED "Inicializado" diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h index c00903e1..53f69044 100644 --- a/src/lang/fr_FR.h +++ b/src/lang/fr_FR.h @@ -1,5 +1,5 @@ -#ifndef HASP_LANG_EN_US_H -#define HASP_LANG_EN_US_H +#ifndef HASP_LANG_FR_FR_H +#define HASP_LANG_FR_FR_H #define D_USERNAME "Utilisateur:" #define D_PASSWORD "Mot de passe:" @@ -25,8 +25,8 @@ #define D_FILE_SIZE_KILOBYTES "Kio" #define D_FILE_SIZE_MEGABYTES "Mio" #define D_FILE_SIZE_GIGABYTES "Gio" -#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes -#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point +#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes +#define D_DECIMAL_POINT "," // new, decimal comma or point #define D_SERVICE_STARTING "Démarer..." #define D_SERVICE_STARTED "Démaré" diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index 2c923436..5ef4d125 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -26,7 +26,7 @@ #define D_FILE_SIZE_MEGABYTES "MiB" // new #define D_FILE_SIZE_GIGABYTES "GiB" // new #define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes -#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point +#define D_DECIMAL_POINT "," // new, decimal comma or point #define D_SERVICE_STARTING "Indítás..." #define D_SERVICE_STARTED "Elindítva" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index 3e25217f..5d800e6b 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -1,5 +1,5 @@ -#ifndef HASP_LANG_EN_US_H -#define HASP_LANG_EN_US_H +#ifndef HASP_LANG_NL_NL_H +#define HASP_LANG_NL_NL_H #define D_USERNAME "Gebruikersnaam:" #define D_PASSWORD "Wachtwoord:" @@ -25,8 +25,8 @@ #define D_FILE_SIZE_KILOBYTES "KiB" #define D_FILE_SIZE_MEGABYTES "MiB" #define D_FILE_SIZE_GIGABYTES "GiB" -#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes -#define F_FILE_SIZE_DECIMAL "%d,%d" // decimal comma or point +#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes +#define D_DECIMAL_POINT "," // decimal comma or point #define D_SETTING_ENABLED "Ingeschakeld" #define D_SETTING_DISABLED "Uitgeschakeld" diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 122f9028..4da987e7 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -26,7 +26,7 @@ #define D_FILE_SIZE_MEGABYTES "MiB" // new #define D_FILE_SIZE_GIGABYTES "GiB" // new #define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes -#define F_FILE_SIZE_DECIMAL "%d,%d" // new, decimal comma or point +#define D_DECIMAL_POINT "," // new, decimal comma or point #define D_SETTING_ENABLED "Activ" #define D_SETTING_DISABLED "Inactiv" From 2bd650ec4f6c857d82bab3855a978523be2ea3e3 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 20:46:57 +0200 Subject: [PATCH 176/227] Create regional files for Portuguese --- src/lang/pt_BR.h | 16 ++++ src/lang/pt_PT.h | 209 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 src/lang/pt_BR.h create mode 100644 src/lang/pt_PT.h diff --git a/src/lang/pt_BR.h b/src/lang/pt_BR.h new file mode 100644 index 00000000..61d297ee --- /dev/null +++ b/src/lang/pt_BR.h @@ -0,0 +1,16 @@ +#ifndef HASP_LANG_PT_BR_H +#define HASP_LANG_PT_BR_H + +#include "pt_PT.h" // Common language file + +// Overrides +#undef D_USERNAME +#define D_USERNAME "Usuário:" + +#undef D_PASSWORD +#define D_PASSWORD "Senha:" + +#undef D_NETWORK_CONNECTION_FAILED +#define D_NETWORK_CONNECTION_FAILED "Falhou a conexão" + +#endif \ No newline at end of file diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h new file mode 100644 index 00000000..18b5c3a2 --- /dev/null +++ b/src/lang/pt_PT.h @@ -0,0 +1,209 @@ +#ifndef HASP_LANG_PT_PT_H +#define HASP_LANG_PT_PT_H + +#define D_USERNAME "Utilizador:" +#define D_PASSWORD "Palavra-passe:" +#define D_SSID "Ssid:" +#define D_YES "Sim" +#define D_NO "Não" + +#define D_ERROR_OUT_OF_MEMORY "Memória Cheia" +#define D_ERROR_UNKNOWN "Erro desconhecido" + +#define D_CONFIG_NOT_CHANGED "Não existe mudanças na configuração" +#define D_CONFIG_CHANGED "Configuração alterada" +#define D_CONFIG_LOADED "Configuração carregada" + +#define D_FILE_LOADING "A carregar %s" +#define D_FILE_LOADED "%s carregado" +#define D_FILE_LOAD_FAILED "Não foi possível carregar %s" +#define D_FILE_SAVING "A guardar %s" +#define D_FILE_SAVED "%s guardado" +#define D_FILE_SAVE_FAILED "Não foi possível guardar %s" +#define D_FILE_NOT_FOUND "Ficheiro não encontrado" +#define D_FILE_SIZE_BYTES "bytes" // new +#define D_FILE_SIZE_KILOBYTES "KiB" // new +#define D_FILE_SIZE_MEGABYTES "MiB" // new +#define D_FILE_SIZE_GIGABYTES "GiB" // new +#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes +#define D_DECIMAL_POINT "." // new, decimal comma or point + +#define D_SERVICE_STARTING "A inicializar..." +#define D_SERVICE_STARTED "Iniciado" +#define D_SERVICE_START_FAILED "Não foi possível iniciar" +#define D_SERVICE_STOPPED "Parado" +#define D_SERVICE_DISABLED "Desativado" +#define D_SERVICE_CONNECTED "Conetado" +#define D_SERVICE_DISCONNECTED "Desconetado" + +#define D_SETTING_ENABLED "Ativado" +#define D_SETTING_DISABLED "Desativado" + +#define D_NETWORK_IP_ADDRESS_RECEIVED "Foi recebido no endereço IP: %s" +#define D_NETWORK_ONLINE "Online" +#define D_NETWORK_OFFLINE "Offline" +#define D_NETWORK_CONNECTION_FAILED "Falhou a ligação" + +#define D_MQTT_DEFAULT_NAME "placa_%s" +#define D_MQTT_CONNECTING "A conetar..." +#define D_MQTT_CONNECTED "Ligado no Broker %s com clientID %s" +#define D_MQTT_NOT_CONNECTED "Não há conexão ???" +#define D_MQTT_DISCONNECTING "A desconetar..." +#define D_MQTT_DISCONNECTED "Desconetado" +#define D_MQTT_RECONNECTING "Desconetado do broker, a reconetar..." +#define D_MQTT_NOT_CONFIGURED "O Broker não foi configurado" +#define D_MQTT_STARTED "A iniciar: %d bytes" +#define D_MQTT_FAILED "Falhou:" +#define D_MQTT_INVALID_TOPIC "A mensagem tem um tópico inválido" +#define D_MQTT_SUBSCRIBED "Subscrito a %s" +#define D_MQTT_NOT_SUBSCRIBED "Não foi possível subscrever %s" +#define D_MQTT_HA_AUTO_DISCOVERY "A registar auto-descoberta no HA" +#define D_MQTT_PAYLOAD_TOO_LONG "Os dados são demasiado grandes(%u bytes)" + +#define D_TELNET_CLOSING_CONNECTION "A fechar a conexão de %s" +#define D_TELNET_CLIENT_LOGIN_FROM "Foi feito login ao cliente %s" +#define D_TELNET_CLIENT_CONNECT_FROM "Foi conetado ao cliente %s" +#define D_TELNET_AUTHENTICATION_FAILED "Falhou a autorização!" +#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Tentativa de conexão incorreta desde %s" +#define D_TELNET_STARTED "Console Telnet iniciada" +#define D_TELNET_FAILED "Falhou início da consola Telnet" +#define D_TELNET_CLIENT_CONNECTED "Cliente conetado" +#define D_TELNET_CLIENT_NOT_CONNECTED "Cliente não conetado" +#define D_TELNET_CLIENT_REJECTED "Cliente rejeitado" + +#define D_HASP_INVALID_PAGE "Página inválida %u" +#define D_HASP_INVALID_LAYER "Não foi possível eliminar a camada do sistema" +#define D_HASP_CHANGE_PAGE "A alterar a página %u" +#define D_HASP_CLEAR_PAGE "A limpar página %u" + +#define D_OBJECT_DELETED "Objeto eliminado" +#define D_OBJECT_UNKNOWN "Objeto desconhecido" +#define D_OBJECT_MISMATCH "Os objetos não são iguais!" +#define D_OBJECT_LOST "Objeto perdido!" +#define D_OBJECT_CREATE_FAILED "Não foi possível criar o objeto %u" +#define D_OBJECT_PAGE_UNKNOWN "A página ID %u não está definida" +#define D_OBJECT_EVENT_UNKNOWN "Não se conhece o evento %d " + +#define D_ATTRIBUTE_UNKNOWN "Propiedade %s desconhecida" +#define D_ATTRIBUTE_READ_ONLY "%s é de leitura apenas" +#define D_ATTRIBUTE_PAGE_METHOD_INVALID "Não foi possível chamar %s numa página" + +#define D_OOBE_SSID_VALIDATED "SSID %s validado" +#define D_OOBE_AUTO_CALIBRATE "Auto calibração ativada" +#define D_OOBE_CALIBRATED "já se foi calibrado" + +#define D_DISPATCH_COMMAND_NOT_FOUND "Não se encontrou o comando '%s'" +#define D_DISPATCH_INVALID_PAGE "Página inválida %s" +#define D_DISPATCH_REBOOT "A reiniciar dispositivo!" + +#define D_JSON_FAILED "Não foi possível analisar o JSON:" +#define D_JSONL_FAILED "A análise do JSONL falhou na linha %u" +#define D_JSONL_SUCCEEDED "JSONL analisado" + +#define D_OTA_CHECK_UPDATE "A procurar a atualização do URL: %s" +#define D_OTA_CHECK_COMPLETE "Verificação de atualização completa" +#define D_OTA_CHECK_FAILED "Falhou a verificação de atualização: %s" +#define D_OTA_UPDATE_FIRMWARE "Atualização de firmware OTA" +#define D_OTA_UPDATE_COMPLETE "Atualização OTA completa" +#define D_OTA_UPDATE_APPLY "A aplicar o novo firmware e reiniciar" +#define D_OTA_UPDATE_FAILED "A atualização OTA falhou" +#define D_OTA_UPDATING_FIRMWARE "A atualizar o firmware..." +#define D_OTA_UPDATING_FILESYSTEM "A atualizar o sistema de ficheiros..." + +#define D_HTTP_HASP_DESIGN "Design do HASP" +#define D_HTTP_INFORMATION "Informação" +#define D_HTTP_HTTP_SETTINGS "Configuração HTTP" +#define D_HTTP_WIFI_SETTINGS "Configuração Wifi" +#define D_HTTP_MQTT_SETTINGS "Configuração MQTT" +#define D_HTTP_GPIO_SETTINGS "Configuração GPIO" +#define D_HTTP_MDNS_SETTINGS "Configuração mDNS" +#define D_HTTP_TELNET_SETTINGS "Configuração Telnet" +#define D_HTTP_DEBUG_SETTINGS "Configuração do debug" +#define D_HTTP_GUI_SETTINGS "Configuração da GUI" +#define D_HTTP_SAVE_SETTINGS "Guardar Configuração" +#define D_HTTP_UPLOAD_FILE "Carregar ficheiro" +#define D_HTTP_ERASE_DEVICE "Eliminar Configuração" +#define D_HTTP_ADD_GPIO "Adicionar novo pino" +#define D_HTTP_BACK "Atrás" +#define D_HTTP_REFRESH "Atualizar" +#define D_HTTP_PREV_PAGE "Página Anterior" +#define D_HTTP_NEXT_PAGE "Página Seguinte" +#define D_HTTP_CALIBRATE "Calibrar" +#define D_HTTP_SCREENSHOT "Screenshot" +#define D_HTTP_FILE_BROWSER "Editor de ficheiros" +#define D_HTTP_FIRMWARE_UPGRADE "Atualização do firmware" +#define D_HTTP_UPDATE_FIRMWARE "Atualizar o firmware" +#define D_HTTP_FACTORY_RESET "Restauração de fábrica" +#define D_HTTP_MAIN_MENU "Menu Principal" +#define D_HTTP_REBOOT "Reiniciar" +#define D_HTTP_CONFIGURATION "Configuração" +#define D_HTTP_SENDING_PAGE "Foi enviado página %S a %s" +#define D_HTTP_FOOTER "por Francis Van Roie" + +#define D_INFO_VERSION "Versão" +#define D_INFO_BUILD_DATETIME "Data de compilação" +#define D_INFO_UPTIME "Tempo ativo" +#define D_INFO_FREE_HEAP "Heap livre" +#define D_INFO_FREE_BLOCK "Blocos livres" +#define D_INFO_DEVICE_MEMORY "Memória do dispositivo" +#define D_INFO_LVGL_MEMORY "Memória LVGL" +#define D_INFO_TOTAL_MEMORY "Total" +#define D_INFO_FREE_MEMORY "Livre" +#define D_INFO_FRAGMENTATION "Fragmentação" +#define D_INFO_PSRAM_FREE "PSRam livre" +#define D_INFO_PSRAM_SIZE "Tamanho PSRam " +#define D_INFO_FLASH_SIZE "Tamanho Flash" +#define D_INFO_SKETCH_USED "Memória programa usada" +#define D_INFO_SKETCH_FREE "Memória Programa livre" +#define D_INFO_MODULE "Módulo" +#define D_INFO_MODEL "Modelo" +#define D_INFO_FREQUENCY "Frequência" +#define D_INFO_CORE_VERSION "Versão do núcleo" +#define D_INFO_RESET_REASON "Razão do último Reset" +#define D_INFO_STATUS "Estado" +#define D_INFO_SERVER "Servidor" +#define D_INFO_USERNAME "Nome do usuário" +#define D_INFO_CLIENTID "ID do Cliente" +#define D_INFO_CONNECTED "Conetado" +#define D_INFO_DISCONNECTED "Desconetado" +#define D_INFO_RECEIVED "Recebido" +#define D_INFO_PUBLISHED "Publicado" +#define D_INFO_FAILED "Falhado" +#define D_INFO_ETHERNET "Ethernet" +#define D_INFO_WIFI "Wifi" +#define D_INFO_LINK_SPEED "Link Speed" +#define D_INFO_FULL_DUPLEX "Full Duplex" +#define D_INFO_SSID "SSID" +#define D_INFO_RSSI "Potência do sinal" +#define D_INFO_IP_ADDRESS "Endereço IP" +#define D_INFO_MAC_ADDRESS "Endereço MAC" +#define D_INFO_GATEWAY "Gateway" +#define D_INFO_DNS_SERVER "Servidor DNS" + +#define D_OOBE_MSG "Toque no ecrã para configurar WiFi ou para se conetar a um access point" +#define D_OOBE_SCAN_TO_CONNECT "A fazer scan para conetar" + +#define D_WIFI_CONNECTING_TO "A conetar a %s" +#define D_WIFI_CONNECTED_TO "A conetar a %s, a pedir IP..." +#define D_WIFI_RSSI_EXCELLENT "Excelente" +#define D_WIFI_RSSI_GOOD "Bom" +#define D_WIFI_RSSI_FAIR "Decente" +#define D_WIFI_RSSI_WEAK "Fraco" +#define D_WIFI_RSSI_BAD "Muito baixo" + +#define D_GPIO_SWITCH "Interruptor" +#define D_GPIO_BUTTON "Botão" +#define D_GPIO_LED "LED" +#define D_GPIO_LED_R "LED Red" +#define D_GPIO_LED_G "LED Green" +#define D_GPIO_LED_B "LED Blue" +#define D_GPIO_RELAY "Relé" +#define D_GPIO_PWM "PWM" +#define D_GPIO_DAC "DAC" +#define D_GPIO_SERIAL_DIMMER "Dimmer serial" +#define D_GPIO_UNKNOWN "Desconhecido" +#define D_GPIO_PIN "Pin" +#define D_GPIO_GROUP "Grupo" +#define D_GPIO_GROUP_NONE "Ninguém" + +#endif \ No newline at end of file From 718d0bfeccf90598ebeab095ccc94b574017eae3 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 22:18:12 +0200 Subject: [PATCH 177/227] Add AceButton pointer to gpio struct --- src/sys/gpio/hasp_gpio.cpp | 118 ++++++++++++++++++++----------------- src/sys/gpio/hasp_gpio.h | 8 +++ 2 files changed, 73 insertions(+), 53 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index c10c09cd..b7065fad 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -13,16 +13,22 @@ #endif #ifdef ARDUINO + #include "AceButton.h" using namespace ace_button; static AceButton* button[HASP_NUM_INPUTS]; +ButtonConfig buttonConfig; // Clicks, double-clicks and long presses +ButtonConfig switchConfig; // Clicks only + #else + #define HIGH 1 #define LOW 0 #define NUM_DIGITAL_PINS 40 #define digitalWrite(x, y) #define analogWrite(x, y) -#endif + +#endif // ARDUINO #define SCALE_8BIT_TO_12BIT(x) x << 4 | x >> 4 #define SCALE_8BIT_TO_10BIT(x) x << 2 | x >> 6 @@ -118,25 +124,31 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but void aceButtonSetup(void) { - ButtonConfig* buttonConfig = ButtonConfig::getSystemButtonConfig(); - buttonConfig->setEventHandler(gpio_event_handler); - - // Features - // buttonConfig->setFeature(ButtonConfig::kFeatureClick); - // buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); - // buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress); - // buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick); - // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); - + // Button Features + buttonConfig.setEventHandler(gpio_event_handler); + buttonConfig.setFeature(ButtonConfig::kFeatureClick); + buttonConfig.clearFeature(ButtonConfig::kFeatureDoubleClick); + buttonConfig.setFeature(ButtonConfig::kFeatureLongPress); + // buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); + buttonConfig.clearFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses + buttonConfig.setFeature(ButtonConfig::kFeatureSuppressAfterClick); + buttonConfig.setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); // Delays - buttonConfig->setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME); + buttonConfig.setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + buttonConfig.setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + buttonConfig.setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + buttonConfig.setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME); + + // Switch Features + switchConfig.setEventHandler(gpio_event_handler); + switchConfig.setFeature(ButtonConfig::kFeatureClick); + switchConfig.clearFeature(ButtonConfig::kFeatureLongPress); + switchConfig.clearFeature(ButtonConfig::kFeatureRepeatPress); + switchConfig.clearFeature(ButtonConfig::kFeatureDoubleClick); + switchConfig.setClickDelay(100); // decrease click delay from default 200 ms } -void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index) +/* void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index) { uint8_t i; for(i = 0; i < HASP_NUM_INPUTS; i++) { @@ -145,20 +157,20 @@ void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8 LOG_TRACE(TAG_GPIO, F("Creating Button%d on pin %d (index %d) mode %d default %d"), i, pin, index, input_mode, default_state); - button[i] = new AceButton(pin, default_state, index); + button[i] = new AceButton(&buttonConfig, pin, default_state, index); if(button[i]) { // pinMode(pin, input_mode); - ButtonConfig* buttonConfig = button[i]->getButtonConfig(); - buttonConfig->setEventHandler(gpio_event_handler); - buttonConfig->setFeature(ButtonConfig::kFeatureClick); - buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick); - buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); - // buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); - buttonConfig->clearFeature( - ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses - buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick); + // ButtonConfig* buttonConfig = button[i]->getButtonConfig(); + // buttonConfig->setEventHandler(gpio_event_handler); + // buttonConfig->setFeature(ButtonConfig::kFeatureClick); + // buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick); + // buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); + // // buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); + // buttonConfig->clearFeature( + // ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses + // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick); LOG_INFO(TAG_GPIO, F("Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index, input_mode, default_state); @@ -180,28 +192,32 @@ void gpioAddSwitch(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8 LOG_TRACE(TAG_GPIO, F("Creating Switch%d on pin %d (index %d) mode %d default %d"), i, pin, index, input_mode, default_state); - button[i] = new AceButton(pin, default_state, index); + button[i] = new AceButton(&switchConfig, pin, default_state, index); if(button[i]) { // pinMode(pin, input_mode); - ButtonConfig* buttonConfig = button[i]->getButtonConfig(); - buttonConfig->setEventHandler(gpio_event_handler); - buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAll); - - LOG_INFO(TAG_GPIO, F("Button%d switch on pin %d (index %d) mode %d default %d"), i, pin, index, - input_mode, default_state); + LOG_INFO(TAG_GPIO, F("Switch%d on pin %d (index %d) mode %d default %d"), i, pin, index, input_mode, + default_state); gpioUsedInputCount = i + 1; return; } } } - LOG_ERROR(TAG_GPIO, F("Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin, + LOG_ERROR(TAG_GPIO, F("Failed to create Switch%d pin %d (index %d). All %d slots available are in use!"), i, pin, index, HASP_NUM_INPUTS); -} +}*/ -void gpio_setup_pin(hasp_gpio_config_t* gpio) +// Can be called ad-hoc to change a setup +static void gpio_setup_pin(uint8_t index) { + hasp_gpio_config_t* gpio = &gpioConfig[index]; + + if(gpioIsSystemPin(gpio->pin)) { + LOG_WARNING(TAG_GPIO, F("Invalid pin %d"), gpio->pin); + return; + } + uint8_t input_mode; switch(gpio->gpio_function) { case OUTPUT: @@ -219,22 +235,15 @@ void gpio_setup_pin(hasp_gpio_config_t* gpio) input_mode = INPUT_PULLUP; } - if(gpioIsSystemPin(gpio->pin)) { - LOG_WARNING(TAG_GPIO, F("Invalid pin %d"), gpio->pin); - return; - } - - gpio->max = 255; + gpio->max = 255; + ButtonConfig* config = &buttonConfig; // Ddefault pushbutton switch(gpio->type) { case HASP_GPIO_SWITCH: - gpioAddSwitch(gpio->pin, input_mode, HIGH, gpioUsedInputCount); - pinMode(gpio->pin, INPUT_PULLUP); - gpio->max = 0; - break; - + config = &switchConfig; case HASP_GPIO_BUTTON: - gpioAddButton(gpio->pin, input_mode, HIGH, gpioUsedInputCount); + if(gpio->btn) delete gpio->btn; + gpio->btn = new AceButton(config, gpio->pin, HIGH, index); pinMode(gpio->pin, INPUT_PULLUP); gpio->max = 0; break; @@ -270,7 +279,8 @@ void gpio_setup_pin(hasp_gpio_config_t* gpio) case HASP_GPIO_SERIAL_DIMMER: { const char command[9] = "\xEF\x01\x4D\xA3"; // Start Lanbon Dimmer #if defined(ARDUINO_ARCH_ESP32) - Serial1.begin(115200UL, SERIAL_8N1, UART_PIN_NO_CHANGE, gpio->pin, true, 2000); + Serial1.begin(115200UL, SERIAL_8N1, UART_PIN_NO_CHANGE, gpio->pin, true, + 2000); // true = EU, false = AU Serial1.flush(); delay(20); Serial1.print(" "); @@ -328,7 +338,7 @@ void gpioSetup() aceButtonSetup(); for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { - gpio_setup_pin(&gpioConfig[i]); + gpio_setup_pin(i); } LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTED)); @@ -337,12 +347,13 @@ void gpioSetup() IRAM_ATTR void gpioLoop(void) { // Should be called every 4-5ms or faster, for the default debouncing time of ~20ms. - for(uint8_t i = 0; i < gpioUsedInputCount; i++) { - if(button[i]) button[i]->check(); + for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { + if(gpioConfig[i].btn) gpioConfig[i].btn->check(); } } #else + void gpioSetup(void) { gpioSavePinConfig(0, 3, HASP_GPIO_RELAY, 0, -1); @@ -352,6 +363,7 @@ void gpioSetup(void) } IRAM_ATTR void gpioLoop(void) {} + #endif // ARDUINO /* ********************************* State Setters *************************************** */ diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index 10519c6e..fcf3e3b1 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -6,6 +6,11 @@ #include "hasplib.h" +#ifdef ARDUINO +#include "AceButton.h" +using namespace ace_button; +#endif + #ifdef __cplusplus extern "C" { #endif @@ -20,6 +25,9 @@ struct hasp_gpio_config_t uint8_t type; // switch, button, ... uint16_t val; uint16_t max; +#ifdef ARDUINO + AceButton* btn; +#endif }; void gpioSetup(void); From b023cfcec64a18e436a231cbafb9fb6c05edab24 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 22:22:48 +0200 Subject: [PATCH 178/227] Update Portuguese --- src/lang/pt_PT.h | 95 ++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h index 18b5c3a2..d81b023e 100644 --- a/src/lang/pt_PT.h +++ b/src/lang/pt_PT.h @@ -3,20 +3,21 @@ #define D_USERNAME "Utilizador:" #define D_PASSWORD "Palavra-passe:" -#define D_SSID "Ssid:" +#define D_SSID "SSID:" #define D_YES "Sim" #define D_NO "Não" #define D_ERROR_OUT_OF_MEMORY "Memória Cheia" #define D_ERROR_UNKNOWN "Erro desconhecido" -#define D_CONFIG_NOT_CHANGED "Não existe mudanças na configuração" +#define D_CONFIG_NOT_CHANGED "Sem alterações na configuração" #define D_CONFIG_CHANGED "Configuração alterada" #define D_CONFIG_LOADED "Configuração carregada" #define D_FILE_LOADING "A carregar %s" #define D_FILE_LOADED "%s carregado" #define D_FILE_LOAD_FAILED "Não foi possível carregar %s" + #define D_FILE_SAVING "A guardar %s" #define D_FILE_SAVED "%s guardado" #define D_FILE_SAVE_FAILED "Não foi possível guardar %s" @@ -33,24 +34,24 @@ #define D_SERVICE_START_FAILED "Não foi possível iniciar" #define D_SERVICE_STOPPED "Parado" #define D_SERVICE_DISABLED "Desativado" -#define D_SERVICE_CONNECTED "Conetado" -#define D_SERVICE_DISCONNECTED "Desconetado" +#define D_SERVICE_CONNECTED "Ligado" +#define D_SERVICE_DISCONNECTED "Desligado" #define D_SETTING_ENABLED "Ativado" #define D_SETTING_DISABLED "Desativado" -#define D_NETWORK_IP_ADDRESS_RECEIVED "Foi recebido no endereço IP: %s" +#define D_NETWORK_IP_ADDRESS_RECEIVED "Foi atribuído endereço IP: %s" #define D_NETWORK_ONLINE "Online" #define D_NETWORK_OFFLINE "Offline" #define D_NETWORK_CONNECTION_FAILED "Falhou a ligação" #define D_MQTT_DEFAULT_NAME "placa_%s" -#define D_MQTT_CONNECTING "A conetar..." -#define D_MQTT_CONNECTED "Ligado no Broker %s com clientID %s" -#define D_MQTT_NOT_CONNECTED "Não há conexão ???" -#define D_MQTT_DISCONNECTING "A desconetar..." -#define D_MQTT_DISCONNECTED "Desconetado" -#define D_MQTT_RECONNECTING "Desconetado do broker, a reconetar..." +#define D_MQTT_CONNECTING "A ligar..." +#define D_MQTT_CONNECTED "Ligado ao broker %s com clientID %s" +#define D_MQTT_NOT_CONNECTED "Não há ligação ???" +#define D_MQTT_DISCONNECTING "A desligar..." +#define D_MQTT_DISCONNECTED "Desligado" +#define D_MQTT_RECONNECTING "Desligado do broker, a religar..." #define D_MQTT_NOT_CONFIGURED "O Broker não foi configurado" #define D_MQTT_STARTED "A iniciar: %d bytes" #define D_MQTT_FAILED "Falhou:" @@ -60,19 +61,19 @@ #define D_MQTT_HA_AUTO_DISCOVERY "A registar auto-descoberta no HA" #define D_MQTT_PAYLOAD_TOO_LONG "Os dados são demasiado grandes(%u bytes)" -#define D_TELNET_CLOSING_CONNECTION "A fechar a conexão de %s" +#define D_TELNET_CLOSING_CONNECTION "A fechar a ligação de %s" #define D_TELNET_CLIENT_LOGIN_FROM "Foi feito login ao cliente %s" -#define D_TELNET_CLIENT_CONNECT_FROM "Foi conetado ao cliente %s" +#define D_TELNET_CLIENT_CONNECT_FROM "Foi conectado ao cliente %s" #define D_TELNET_AUTHENTICATION_FAILED "Falhou a autorização!" -#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Tentativa de conexão incorreta desde %s" -#define D_TELNET_STARTED "Console Telnet iniciada" -#define D_TELNET_FAILED "Falhou início da consola Telnet" -#define D_TELNET_CLIENT_CONNECTED "Cliente conetado" -#define D_TELNET_CLIENT_NOT_CONNECTED "Cliente não conetado" +#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Tentativa de ligação incorreta desde %s" +#define D_TELNET_STARTED "Consola inicializada" +#define D_TELNET_FAILED "Falhou inicialização da consola" +#define D_TELNET_CLIENT_CONNECTED "Cliente ligado" +#define D_TELNET_CLIENT_NOT_CONNECTED "Cliente não ligado" #define D_TELNET_CLIENT_REJECTED "Cliente rejeitado" #define D_HASP_INVALID_PAGE "Página inválida %u" -#define D_HASP_INVALID_LAYER "Não foi possível eliminar a camada do sistema" +#define D_HASP_INVALID_LAYER "Não foi possível eliminar a camada de sistema" #define D_HASP_CHANGE_PAGE "A alterar a página %u" #define D_HASP_CLEAR_PAGE "A limpar página %u" @@ -84,13 +85,13 @@ #define D_OBJECT_PAGE_UNKNOWN "A página ID %u não está definida" #define D_OBJECT_EVENT_UNKNOWN "Não se conhece o evento %d " -#define D_ATTRIBUTE_UNKNOWN "Propiedade %s desconhecida" +#define D_ATTRIBUTE_UNKNOWN "Propriedade %s desconhecida" #define D_ATTRIBUTE_READ_ONLY "%s é de leitura apenas" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "Não foi possível chamar %s numa página" -#define D_OOBE_SSID_VALIDATED "SSID %s validado" +#define D_OOBE_SSID_VALIDATED "SSID %s válido" #define D_OOBE_AUTO_CALIBRATE "Auto calibração ativada" -#define D_OOBE_CALIBRATED "já se foi calibrado" +#define D_OOBE_CALIBRATED "já foi calibrado" #define D_DISPATCH_COMMAND_NOT_FOUND "Não se encontrou o comando '%s'" #define D_DISPATCH_INVALID_PAGE "Página inválida %s" @@ -100,9 +101,9 @@ #define D_JSONL_FAILED "A análise do JSONL falhou na linha %u" #define D_JSONL_SUCCEEDED "JSONL analisado" -#define D_OTA_CHECK_UPDATE "A procurar a atualização do URL: %s" -#define D_OTA_CHECK_COMPLETE "Verificação de atualização completa" -#define D_OTA_CHECK_FAILED "Falhou a verificação de atualização: %s" +#define D_OTA_CHECK_UPDATE "A procurar por atualização no URL: %s" +#define D_OTA_CHECK_COMPLETE "Verificação da atualização completa" +#define D_OTA_CHECK_FAILED "Falhou a verificação da atualização: %s" #define D_OTA_UPDATE_FIRMWARE "Atualização de firmware OTA" #define D_OTA_UPDATE_COMPLETE "Atualização OTA completa" #define D_OTA_UPDATE_APPLY "A aplicar o novo firmware e reiniciar" @@ -112,19 +113,19 @@ #define D_HTTP_HASP_DESIGN "Design do HASP" #define D_HTTP_INFORMATION "Informação" -#define D_HTTP_HTTP_SETTINGS "Configuração HTTP" -#define D_HTTP_WIFI_SETTINGS "Configuração Wifi" -#define D_HTTP_MQTT_SETTINGS "Configuração MQTT" -#define D_HTTP_GPIO_SETTINGS "Configuração GPIO" -#define D_HTTP_MDNS_SETTINGS "Configuração mDNS" -#define D_HTTP_TELNET_SETTINGS "Configuração Telnet" -#define D_HTTP_DEBUG_SETTINGS "Configuração do debug" -#define D_HTTP_GUI_SETTINGS "Configuração da GUI" +#define D_HTTP_HTTP_SETTINGS "Configurar HTTP" +#define D_HTTP_WIFI_SETTINGS "Configurar Wifi" +#define D_HTTP_MQTT_SETTINGS "Configurar MQTT" +#define D_HTTP_GPIO_SETTINGS "Configurar GPIO" +#define D_HTTP_MDNS_SETTINGS "Configurar mDNS" +#define D_HTTP_TELNET_SETTINGS "Configurar Telnet" +#define D_HTTP_DEBUG_SETTINGS "Configurar debug" +#define D_HTTP_GUI_SETTINGS "Configurar GUI" #define D_HTTP_SAVE_SETTINGS "Guardar Configuração" #define D_HTTP_UPLOAD_FILE "Carregar ficheiro" #define D_HTTP_ERASE_DEVICE "Eliminar Configuração" #define D_HTTP_ADD_GPIO "Adicionar novo pino" -#define D_HTTP_BACK "Atrás" +#define D_HTTP_BACK "Retroceder" #define D_HTTP_REFRESH "Atualizar" #define D_HTTP_PREV_PAGE "Página Anterior" #define D_HTTP_NEXT_PAGE "Página Seguinte" @@ -133,7 +134,7 @@ #define D_HTTP_FILE_BROWSER "Editor de ficheiros" #define D_HTTP_FIRMWARE_UPGRADE "Atualização do firmware" #define D_HTTP_UPDATE_FIRMWARE "Atualizar o firmware" -#define D_HTTP_FACTORY_RESET "Restauração de fábrica" +#define D_HTTP_FACTORY_RESET "Repor configuração de fábrica" #define D_HTTP_MAIN_MENU "Menu Principal" #define D_HTTP_REBOOT "Reiniciar" #define D_HTTP_CONFIGURATION "Configuração" @@ -141,7 +142,7 @@ #define D_HTTP_FOOTER "por Francis Van Roie" #define D_INFO_VERSION "Versão" -#define D_INFO_BUILD_DATETIME "Data de compilação" +#define D_INFO_BUILD_DATETIME "Compilado a" #define D_INFO_UPTIME "Tempo ativo" #define D_INFO_FREE_HEAP "Heap livre" #define D_INFO_FREE_BLOCK "Blocos livres" @@ -154,21 +155,21 @@ #define D_INFO_PSRAM_SIZE "Tamanho PSRam " #define D_INFO_FLASH_SIZE "Tamanho Flash" #define D_INFO_SKETCH_USED "Memória programa usada" -#define D_INFO_SKETCH_FREE "Memória Programa livre" +#define D_INFO_SKETCH_FREE "Memória programa livre" #define D_INFO_MODULE "Módulo" #define D_INFO_MODEL "Modelo" #define D_INFO_FREQUENCY "Frequência" -#define D_INFO_CORE_VERSION "Versão do núcleo" +#define D_INFO_CORE_VERSION "Versão do core" #define D_INFO_RESET_REASON "Razão do último Reset" #define D_INFO_STATUS "Estado" #define D_INFO_SERVER "Servidor" -#define D_INFO_USERNAME "Nome do usuário" +#define D_INFO_USERNAME "Nome do utilizador" #define D_INFO_CLIENTID "ID do Cliente" -#define D_INFO_CONNECTED "Conetado" -#define D_INFO_DISCONNECTED "Desconetado" +#define D_INFO_CONNECTED "Ligado" +#define D_INFO_DISCONNECTED "Desligado" #define D_INFO_RECEIVED "Recebido" #define D_INFO_PUBLISHED "Publicado" -#define D_INFO_FAILED "Falhado" +#define D_INFO_FAILED "Em falha" #define D_INFO_ETHERNET "Ethernet" #define D_INFO_WIFI "Wifi" #define D_INFO_LINK_SPEED "Link Speed" @@ -180,11 +181,11 @@ #define D_INFO_GATEWAY "Gateway" #define D_INFO_DNS_SERVER "Servidor DNS" -#define D_OOBE_MSG "Toque no ecrã para configurar WiFi ou para se conetar a um access point" -#define D_OOBE_SCAN_TO_CONNECT "A fazer scan para conetar" +#define D_OOBE_MSG "Toque no ecrã para configurar WiFi ou para se ligar a um access point" +#define D_OOBE_SCAN_TO_CONNECT "Procurar rede" -#define D_WIFI_CONNECTING_TO "A conetar a %s" -#define D_WIFI_CONNECTED_TO "A conetar a %s, a pedir IP..." +#define D_WIFI_CONNECTING_TO "A ligar a %s" +#define D_WIFI_CONNECTED_TO "Ligado a %s, a pedir IP..." #define D_WIFI_RSSI_EXCELLENT "Excelente" #define D_WIFI_RSSI_GOOD "Bom" #define D_WIFI_RSSI_FAIR "Decente" @@ -204,6 +205,6 @@ #define D_GPIO_UNKNOWN "Desconhecido" #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Grupo" -#define D_GPIO_GROUP_NONE "Ninguém" +#define D_GPIO_GROUP_NONE "Nenhum" #endif \ No newline at end of file From 9a19ddc7474316ec17f0112b8373cbff2280d186 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 11 May 2021 23:14:52 +0200 Subject: [PATCH 179/227] Fix filesystemInfo for ESP8266 --- src/hasp_filesystem.cpp | 52 ++++------------------------------------- 1 file changed, 4 insertions(+), 48 deletions(-) diff --git a/src/hasp_filesystem.cpp b/src/hasp_filesystem.cpp index ceff1646..1d640a01 100644 --- a/src/hasp_filesystem.cpp +++ b/src/hasp_filesystem.cpp @@ -14,59 +14,15 @@ void filesystemInfo() { // Get all information of your SPIFFS -#if 0 +#ifdef ESP8266 FSInfo fs_info; HASP_FS.info(fs_info); - - Serial.println("File system info."); - - Serial.print("Total space: "); - Serial.print(fs_info.totalBytes); - Serial.println("byte"); - - Serial.print("Total space used: "); - Serial.print(fs_info.usedBytes); - Serial.println("byte"); - - Serial.print("Block size: "); - Serial.print(fs_info.blockSize); - Serial.println("byte"); - - Serial.print("Page size: "); - Serial.print(fs_info.totalBytes); - Serial.println("byte"); - - Serial.print("Max open files: "); - Serial.println(fs_info.maxOpenFiles); - - Serial.print("Max path lenght: "); - Serial.println(fs_info.maxPathLength); - Serial.println("File sistem info."); - - Serial.print("Total space: "); - Serial.print(SPIFFS.totalBytes()); - Serial.println("byte"); - - Serial.print("Total space used: "); - Serial.print(SPIFFS.usedBytes()); - Serial.println("byte"); - - Serial.print("Block size: "); - // Serial.print(SPIFFS); - Serial.println("byte"); - - Serial.print("Page size: "); - Serial.print(SPIFFS.totalBytes()); - Serial.println("byte"); - - Serial.print("Max open files: "); - // Serial.println(SPIFFS.maxOpenFiles()); - - Serial.print("Max path lenght: "); - // Serial.println(SPIFFS.maxPathLength()); + Log.verbose(TAG_FILE, "Partition size: total: %d, used: %d", fs_info.totalBytes, fs_info.usedBytes); #endif +#ifdef ESP32 Log.verbose(TAG_FILE, "Partition size: total: %d, used: %d", HASP_FS.totalBytes(), HASP_FS.usedBytes()); +#endif } void filesystemList() From 5961ce87de3fbf5f3447b195028c4d2fc77a25b1 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 12 May 2021 04:24:57 +0200 Subject: [PATCH 180/227] Add D_GPIO_TOUCH --- src/lang/en_US.h | 1 + src/lang/es_ES.h | 1 + src/lang/fr_FR.h | 3 ++- src/lang/hu_HU.h | 1 + src/lang/nl_NL.h | 1 + src/lang/pt_PT.h | 1 + src/lang/ro_RO.h | 1 + 7 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lang/en_US.h b/src/lang/en_US.h index c132e4d3..aea5c2c1 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -194,6 +194,7 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Button" +#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Mood Red" #define D_GPIO_LED_G "Mood Green" diff --git a/src/lang/es_ES.h b/src/lang/es_ES.h index 448b8cca..d668352a 100644 --- a/src/lang/es_ES.h +++ b/src/lang/es_ES.h @@ -194,6 +194,7 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Botón" +#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw #define D_GPIO_LED "DEL" #define D_GPIO_LED_R "Ánimo Red" #define D_GPIO_LED_G "Ánimo Green" diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h index 53f69044..515e334a 100644 --- a/src/lang/fr_FR.h +++ b/src/lang/fr_FR.h @@ -193,11 +193,12 @@ #define D_GPIO_SWITCH "Interrupteur" #define D_GPIO_BUTTON "Bouton" +#define D_GPIO_TOUCH "Touche Capacitive" #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Humeur Rouge" #define D_GPIO_LED_G "Humeur Vert" #define D_GPIO_LED_B "Humeur Bleu" -#define D_GPIO_RELAY "Relaiss" +#define D_GPIO_RELAY "Relais" #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Gradateur Série" diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index 5ef4d125..76c33600 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -194,6 +194,7 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Button" +#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Mood Red" #define D_GPIO_LED_G "Mood Green" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index 5d800e6b..c23a50b3 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -193,6 +193,7 @@ #define D_GPIO_SWITCH "Schakelaar" #define D_GPIO_BUTTON "Drukknop" +#define D_GPIO_TOUCH "Aanraakknop" #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Sfeer Rood" #define D_GPIO_LED_G "Sfeer Groen" diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h index d81b023e..2ef1a498 100644 --- a/src/lang/pt_PT.h +++ b/src/lang/pt_PT.h @@ -194,6 +194,7 @@ #define D_GPIO_SWITCH "Interruptor" #define D_GPIO_BUTTON "Botão" +#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw #define D_GPIO_LED "LED" #define D_GPIO_LED_R "LED Red" #define D_GPIO_LED_G "LED Green" diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 4da987e7..4d75a2dd 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -194,6 +194,7 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Button" +#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Mood Red" #define D_GPIO_LED_G "Mood Green" From 7b03c0ae83122e5d4bf82df24592ee15189f4922 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 12 May 2021 04:29:05 +0200 Subject: [PATCH 181/227] Use hasp_update_value_t to dispatch normalized value updates --- src/hasp/hasp_dispatch.cpp | 47 ++------ src/hasp/hasp_dispatch.h | 2 +- src/hasp/hasp_event.cpp | 36 ++++-- src/hasp/hasp_object.cpp | 60 +++++----- src/hasp/hasp_object.h | 11 +- src/sys/gpio/hasp_gpio.cpp | 235 +++++++++++++++---------------------- src/sys/gpio/hasp_gpio.h | 6 +- 7 files changed, 168 insertions(+), 229 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 214b3053..fb18eec8 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -429,47 +429,20 @@ void dispatch_config(const char* topic, const char* payload) #endif // HASP_USE_CONFIG /********************************************** Output States ******************************************/ -/* -static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const char* payload) + +void dispatch_normalized_group_values(hasp_update_value_t& value) { + if(value.group == 0) return; -}*/ - -// void dispatch_group_onoff(uint8_t groupid, uint16_t eventid, lv_obj_t * obj) -// { -// if((eventid == HASP_EVENT_LONG) || (eventid == HASP_EVENT_HOLD)) return; // don't send repeat events - -// if(groupid >= 0) { -// bool state = Parser::get_event_state(eventid); -// gpio_set_group_onoff(groupid, state); -// object_set_normalized_group_value(groupid, eventid, obj); -// } - -// char payload[8]; -// Parser::get_event_name(eventid, payload, sizeof(payload)); -// // dispatch_output_group_state(groupid, payload); -// } - -// void dispatch_group_value(uint8_t groupid, int16_t state, lv_obj_t * obj) -// { -// if(groupid >= 0) { -// gpio_set_group_value(groupid, state); -// object_set_normalized_group_value(groupid, state, obj); -// } - -// char payload[8]; -// // dispatch_output_group_state(groupid, payload); -// } - -void dispatch_normalized_group_values(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max) -{ - if(groupid == 0) return; - - LOG_VERBOSE(TAG_MSGR, F("GROUP %d value %d (%d-%d)"), groupid, val, min, max); + LOG_VERBOSE(TAG_MSGR, F("GROUP %d value %d (%d-%d)"), value.group, value.val, value.min, value.max); #if HASP_USE_GPIO > 0 - gpio_set_normalized_group_values(groupid, val, min, max); // Update GPIO states + gpio_set_normalized_group_values(value); // Update GPIO states first +#endif + object_set_normalized_group_values(value); // Update onsreen objects except originating obj + +#if HASP_USE_GPIO > 0 + gpio_output_group_values(value.group); // Output new gpio values #endif - object_set_normalized_group_values(groupid, obj, val, min, max); // Update onsreen objects } /********************************************** Native Commands ****************************************/ diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index f17d85ad..b6173d0f 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -71,7 +71,7 @@ void dispatch_wakeup(const char*, const char*); void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid); void dispatch_output_pin_value(uint8_t pin, uint16_t val); -void dispatch_normalized_group_values(uint8_t groupid, lv_obj_t* obj, int16_t val, int16_t min, int16_t max); +void dispatch_normalized_group_values(hasp_update_value_t& value); void dispatch_state_subtopic(const char* subtopic, const char* payload); diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index a81f026e..21343c68 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -239,6 +239,18 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16 // ##################### Event Handlers ######################################################## +static inline void event_update_group(uint8_t group, lv_obj_t* obj, int32_t val, int32_t min, int32_t max) +{ + hasp_update_value_t value = { + .min = min, + .max = max, + .val = val, + .obj = obj, + .group = group, + }; + dispatch_normalized_group_values(value); +} + #if HASP_USE_GPIO > 0 void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) { @@ -448,8 +460,8 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) // Update group objects and gpios on release if(last_value_sent == HASP_EVENT_UP || last_value_sent == HASP_EVENT_RELEASE) { - dispatch_normalized_group_values(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent), - HASP_EVENT_OFF, HASP_EVENT_ON); + event_update_group(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent), HASP_EVENT_OFF, + HASP_EVENT_ON); } } @@ -491,8 +503,8 @@ void toggle_event_handler(lv_obj_t* obj, lv_event_t event) event_object_val_event(obj, hasp_event_id, last_value_sent); // Update group objects and gpios on release - if(last_value_sent == HASP_EVENT_UP) { - dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON); + if(obj->user_data.groupid && hasp_event_id == HASP_EVENT_UP) { + event_update_group(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON); } } @@ -558,9 +570,9 @@ void selector_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = val; event_object_selection_changed(obj, hasp_event_id, val, buffer); - if(max > 0) // max a cannot be 0, its the divider + if(obj->user_data.groupid && max > 0) // max a cannot be 0, its the divider if(hasp_event_id == HASP_EVENT_UP || hasp_event_id == LV_EVENT_VALUE_CHANGED) { - dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, 0, max); + event_update_group(obj->user_data.groupid, obj, last_value_sent, 0, max); } // set the property @@ -599,7 +611,7 @@ void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) // if(max > 0) // max a cannot be 0, its the divider // if(hasp_event_id == HASP_EVENT_UP || hasp_event_id == LV_EVENT_VALUE_CHANGED) { - // dispatch_normalized_group_values(obj->user_data.groupid, obj, last_value_sent, 0, max); + // event_update_group(obj->user_data.groupid, obj, last_value_sent, 0, max); // } } @@ -632,7 +644,7 @@ void msgbox_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = val; event_object_selection_changed(obj, hasp_event_id, val, buffer); - // if(max > 0) dispatch_normalized_group_values(obj->user_data.groupid, obj, val, 0, max); + // if(max > 0) event_update_group(obj->user_data.groupid, obj, val, 0, max); } /** @@ -671,8 +683,8 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = val; event_object_val_event(obj, hasp_event_id, val); - if(hasp_event_id == HASP_EVENT_CHANGED && min != max) - dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); + if(obj->user_data.groupid && hasp_event_id == HASP_EVENT_CHANGED && min != max) + event_update_group(obj->user_data.groupid, obj, val, min, max); } /** @@ -704,7 +716,7 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); event_send_object_data(obj, data); - // dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); + // event_update_group(obj->user_data.groupid, obj, val, min, max); } void calendar_event_handler(lv_obj_t* obj, lv_event_t event) @@ -736,5 +748,5 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event) eventname, date->day, date->year, date->month, date->day); event_send_object_data(obj, data); - // dispatch_normalized_group_values(obj->user_data.groupid, obj, val, min, max); + // event_update_group(obj->user_data.groupid, obj, val, min, max); } \ No newline at end of file diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index fd204496..5da3790f 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -165,48 +165,42 @@ void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload) // ##################### State Changers ######################################################## -void object_set_group_values(lv_obj_t* parent, uint8_t groupid, int16_t intval) +// Recursive function that goes over all objects only ONCE +void object_set_group_values(lv_obj_t* parent, hasp_update_value_t& value) { - if(groupid == 0 || parent == nullptr) return; + if(parent == nullptr) return; - lv_obj_t* child; - child = lv_obj_get_child(parent, NULL); - while(child) { - /* child found, update it */ - if(groupid == child->user_data.groupid) hasp_process_obj_attribute_val(child, NULL, intval, intval, true); + // Update object if it's in the same group + if(value.group == parent->user_data.groupid && value.obj != parent) + hasp_process_obj_attribute_val(parent, NULL, value.val, !!value.val, true); - /* update grandchildren */ - object_set_group_values(child, groupid, intval); - - /* check tabs */ - if(obj_check_type(child, LV_HASP_TABVIEW)) { - //#if LVGL_VERSION_MAJOR == 7 - uint16_t tabcount = lv_tabview_get_tab_count(child); - for(uint16_t i = 0; i < tabcount; i++) { - lv_obj_t* tab = lv_tabview_get_tab(child, i); - LOG_VERBOSE(TAG_HASP, F("Found tab %i"), i); - if(tab->user_data.groupid && groupid == tab->user_data.groupid) - hasp_process_obj_attribute_val(tab, NULL, intval, intval, true); /* tab found, update it */ - - /* check grandchildren */ - object_set_group_values(tab, groupid, intval); - } - //#endif + /* check tabs */ + if(obj_get_type(parent) == LV_HASP_TABVIEW) { + uint16_t tabcount = lv_tabview_get_tab_count(parent); + for(uint16_t i = 0; i < tabcount; i++) { + lv_obj_t* tab = lv_tabview_get_tab(parent, i); + object_set_group_values(tab, value); + } + } else { + lv_obj_t* child; + child = lv_obj_get_child(parent, NULL); + while(child) { + object_set_group_values(child, value); + child = lv_obj_get_child(parent, child); } - - /* try next sibling */ - child = lv_obj_get_child(parent, child); } } -// Recursive function that goes over all objects only ONCE -void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max) +// SHOULD only by called from DISPATCH +void object_set_normalized_group_values(hasp_update_value_t& value) { - if(groupid == 0) return; - if(min == max) return; + if(value.group == 0 || value.min == value.max) return; - for(uint8_t page = 0; page < HASP_NUM_PAGES; page++) { - object_set_group_values(haspPages.get_obj(page), groupid, val); + uint8_t page = haspPages.get(); + object_set_group_values(haspPages.get_obj(page), value); // Update visible objects first + + for(uint8_t i = 0; i < HASP_NUM_PAGES; i++) { + if(i != page) object_set_group_values(haspPages.get_obj(i), value); // uint8_t startid = 1; // for(uint8_t objid = startid; objid < 20; objid++) { // lv_obj_t* obj = hasp_find_obj_from_parent_id(get_page_obj(page), objid); diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index 35095330..0295f4a4 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -20,6 +20,15 @@ typedef struct uint16_t interval; } hasp_task_user_data_t; +typedef struct +{ + int32_t min; + int32_t max; + int32_t val; + lv_obj_t* obj; + uint8_t group; +} hasp_update_value_t; + enum lv_hasp_obj_type_t { /* Containers */ LV_HASP_SCREEN = 1, @@ -81,7 +90,7 @@ void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload); void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, const char* payload, bool update); -void object_set_normalized_group_values(uint8_t groupid, lv_obj_t* src_obj, int16_t val, int16_t min, int16_t max); +void object_set_normalized_group_values(hasp_update_value_t& value); #define HASP_OBJ_BAR 1971 #define HASP_OBJ_BTN 3164 diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index b7065fad..6a96d7a1 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -16,10 +16,8 @@ #include "AceButton.h" using namespace ace_button; -static AceButton* button[HASP_NUM_INPUTS]; ButtonConfig buttonConfig; // Clicks, double-clicks and long presses ButtonConfig switchConfig; // Clicks only - #else #define HIGH 1 @@ -33,38 +31,52 @@ ButtonConfig switchConfig; // Clicks only #define SCALE_8BIT_TO_12BIT(x) x << 4 | x >> 4 #define SCALE_8BIT_TO_10BIT(x) x << 2 | x >> 6 -uint8_t gpioUsedInputCount = 0; - // An array of button pins, led pins, and the led states. Cannot be const // because ledState is mutable. hasp_gpio_config_t gpioConfig[HASP_NUM_GPIO_CONFIG] = { // {2, 8, INPUT, LOW}, {3, 9, OUTPUT, LOW}, {4, 10, INPUT, HIGH}, {5, 11, OUTPUT, LOW}, {6, 12, INPUT, LOW}, }; +static inline void gpio_update_group(uint8_t group, lv_obj_t* obj, int32_t val, int32_t min, int32_t max) +{ + hasp_update_value_t value = { + .min = min, + .max = max, + .val = val, + .obj = obj, + .group = group, + }; + dispatch_normalized_group_values(value); +} + #if defined(ARDUINO_ARCH_ESP32) #include "driver/uart.h" #include -class TouchConfig : public ButtonConfig { - public: - TouchConfig(); +volatile bool touchdetected = false; + +void gotTouch() +{ + touchdetected = true; +} + +// Overrides the readButton function on ESP32 +class CapacitiveConfig : public ButtonConfig { protected: // Number of iterations to sample the capacitive switch. Higher number // provides better smoothing but increases the time taken for a single read. - static const uint8_t kSamples = 10; + // static const uint8_t kSamples = 10; // The threshold value which is considered to be a "touch" on the switch. - static const long kTouchThreshold = 70; + static const long kTouchThreshold = 32; int readButton(uint8_t pin) override { - // long total = mSensor.capacitiveSensor(kSamples); - return (touchRead(pin) > kTouchThreshold) ? LOW : HIGH; + return touchdetected ? HIGH : LOW; // HIGH = not touched } }; - -TouchConfig touchConfig(); +CapacitiveConfig touchConfig; // Capacitive touch #endif void gpio_log_serial_dimmer(const char* command) @@ -88,7 +100,8 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but } else { eventid = HASP_EVENT_DOWN; } - state = true; + state = true; + touchdetected = false; break; case 2: // AceButton::kEventClicked: eventid = HASP_EVENT_UP; @@ -116,8 +129,10 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but } event_gpio_input(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid); - if(eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG - dispatch_normalized_group_values(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON); + + // update objects and gpios in this group + if(gpioConfig[btnid].group && eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG + gpio_update_group(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON); } /* ********************************* GPIO Setup *************************************** */ @@ -129,11 +144,11 @@ void aceButtonSetup(void) buttonConfig.setFeature(ButtonConfig::kFeatureClick); buttonConfig.clearFeature(ButtonConfig::kFeatureDoubleClick); buttonConfig.setFeature(ButtonConfig::kFeatureLongPress); - // buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); + // buttonConfig.clearFeature(ButtonConfig::kFeatureRepeatPress); buttonConfig.clearFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses buttonConfig.setFeature(ButtonConfig::kFeatureSuppressAfterClick); - buttonConfig.setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); // Delays + buttonConfig.setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); buttonConfig.setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); buttonConfig.setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); buttonConfig.setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); @@ -146,68 +161,25 @@ void aceButtonSetup(void) switchConfig.clearFeature(ButtonConfig::kFeatureRepeatPress); switchConfig.clearFeature(ButtonConfig::kFeatureDoubleClick); switchConfig.setClickDelay(100); // decrease click delay from default 200 ms + +#if defined(ARDUINO_ARCH_ESP32) + // Capacitive Touch Features + touchConfig.setEventHandler(gpio_event_handler); + touchConfig.setFeature(ButtonConfig::kFeatureClick); + touchConfig.clearFeature(ButtonConfig::kFeatureDoubleClick); + touchConfig.setFeature(ButtonConfig::kFeatureLongPress); + // touchConfig.clearFeature(ButtonConfig::kFeatureRepeatPress); + touchConfig.clearFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses + touchConfig.setFeature(ButtonConfig::kFeatureSuppressAfterClick); + // Delays + touchConfig.setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + touchConfig.setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + touchConfig.setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + touchConfig.setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + touchConfig.setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME); +#endif } -/* void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index) -{ - uint8_t i; - for(i = 0; i < HASP_NUM_INPUTS; i++) { - - if(!button[i]) { - LOG_TRACE(TAG_GPIO, F("Creating Button%d on pin %d (index %d) mode %d default %d"), i, pin, index, - input_mode, default_state); - - button[i] = new AceButton(&buttonConfig, pin, default_state, index); - - if(button[i]) { - // pinMode(pin, input_mode); - - // ButtonConfig* buttonConfig = button[i]->getButtonConfig(); - // buttonConfig->setEventHandler(gpio_event_handler); - // buttonConfig->setFeature(ButtonConfig::kFeatureClick); - // buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick); - // buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); - // // buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); - // buttonConfig->clearFeature( - // ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses - // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick); - - LOG_INFO(TAG_GPIO, F("Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index, - input_mode, default_state); - gpioUsedInputCount = i + 1; - return; - } - } - } - LOG_ERROR(TAG_GPIO, F("Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin, - index, HASP_NUM_INPUTS); -} - -void gpioAddSwitch(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index) -{ - uint8_t i; - for(i = 0; i < HASP_NUM_INPUTS; i++) { - - if(!button[i]) { - LOG_TRACE(TAG_GPIO, F("Creating Switch%d on pin %d (index %d) mode %d default %d"), i, pin, index, - input_mode, default_state); - - button[i] = new AceButton(&switchConfig, pin, default_state, index); - - if(button[i]) { - // pinMode(pin, input_mode); - - LOG_INFO(TAG_GPIO, F("Switch%d on pin %d (index %d) mode %d default %d"), i, pin, index, input_mode, - default_state); - gpioUsedInputCount = i + 1; - return; - } - } - } - LOG_ERROR(TAG_GPIO, F("Failed to create Switch%d pin %d (index %d). All %d slots available are in use!"), i, pin, - index, HASP_NUM_INPUTS); -}*/ - // Can be called ad-hoc to change a setup static void gpio_setup_pin(uint8_t index) { @@ -240,13 +212,23 @@ static void gpio_setup_pin(uint8_t index) switch(gpio->type) { case HASP_GPIO_SWITCH: - config = &switchConfig; - case HASP_GPIO_BUTTON: if(gpio->btn) delete gpio->btn; - gpio->btn = new AceButton(config, gpio->pin, HIGH, index); + gpio->btn = new AceButton(&switchConfig, gpio->pin, HIGH, index); pinMode(gpio->pin, INPUT_PULLUP); gpio->max = 0; break; + case HASP_GPIO_BUTTON: + if(gpio->btn) delete gpio->btn; + gpio->btn = new AceButton(&buttonConfig, gpio->pin, HIGH, index); + pinMode(gpio->pin, INPUT_PULLUP); + gpio->max = 0; + break; + case HASP_GPIO_TOUCH: + if(gpio->btn) delete gpio->btn; + gpio->btn = new AceButton(&touchConfig, gpio->pin, HIGH, index); + gpio->max = 0; + // touchAttachInterrupt(gpio->pin, gotTouch, 33); + break; case HASP_GPIO_RELAY: pinMode(gpio->pin, OUTPUT); @@ -300,37 +282,6 @@ static void gpio_setup_pin(uint8_t index) LOG_VERBOSE(TAG_GPIO, F(D_BULLET "Configured pin %d"), gpio->pin); } -void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index) -{ - uint8_t i; - for(i = 0; i < HASP_NUM_INPUTS; i++) { - - if(!button[i]) { - button[i] = new AceButton(pin, default_state, index); - - if(button[i]) { - pinMode(pin, input_mode); - - ButtonConfig* buttonConfig = button[i]->getButtonConfig(); - buttonConfig->setEventHandler(gpio_event_handler); - buttonConfig->setFeature(ButtonConfig::kFeatureClick); - buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick); - buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); - buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); - buttonConfig->clearFeature( - ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses - - LOG_INFO(TAG_GPIO, F("Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index, - input_mode, default_state); - gpioUsedInputCount = i + 1; - return; - } - } - } - LOG_ERROR(TAG_GPIO, F("Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin, - index, HASP_NUM_INPUTS); -} - void gpioSetup() { LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTING)); @@ -462,7 +413,7 @@ bool gpio_get_pin_config(uint8_t pin, hasp_gpio_config_t** gpio) return false; } -// Update the actual value of one pin +// Update the actual value of one pin, does NOT update group members // The value must be normalized first static bool gpio_set_output_value(hasp_gpio_config_t* gpio, uint16_t val) { @@ -492,7 +443,7 @@ static bool gpio_set_output_value(hasp_gpio_config_t* gpio, uint16_t val) // Update the normalized value of one pin void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int32_t val, int32_t min, int32_t max) { - if(min != 0 || max != gpio->max) { + if(min != 0 || max != gpio->max) { // do we need to recalculate? if(min == max) { LOG_ERROR(TAG_GPIO, F("Invalid value range")); return; @@ -511,51 +462,48 @@ void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int32_t val, int32_t mi break; default: - return; + return; // invalid output type } } - gpio_set_output_value(gpio, val); // normalized + gpio_set_output_value(gpio, val); // recalculated } -/* void gpio_set_normalized_group_values(uint8_t groupid, int16_t val, int16_t min, int16_t max) +static inline bool gpio_is_input(hasp_gpio_config_t* gpio) { - if(min == max) { - LOG_ERROR(TAG_GPIO, F("Invalid value range")); - return; - } + return gpio->type == HASP_GPIO_BUTTON || gpio->type == HASP_GPIO_SWITCH || gpio->type == HASP_GPIO_TOUCH; +} - // bool state = Parser::get_event_state(eventid); - for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { - if(gpioConfig[i].group == groupid) { - gpio_set_normalized_value(&gpioConfig[i], val, min, max); - } - } -} */ +static inline bool gpio_is_output(hasp_gpio_config_t* gpio) +{ + return (gpio->type != HASP_GPIO_FREE) && !gpio_is_input(gpio); +} // Dispatch all group member values void gpio_output_group_values(uint8_t group) { for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { hasp_gpio_config_t* gpio = &gpioConfig[k]; - if(gpio->group == group && gpio->type != HASP_GPIO_BUTTON && - gpio->type != HASP_GPIO_SWITCH && // group members that are outputs - gpioConfigInUse(k)) + if(gpio->group == group && gpio_is_output(gpio)) // group members that are outputs dispatch_output_pin_value(gpioConfig[k].pin, gpioConfig[k].val); } } +// SHOULD only by called from DISPATCH // Update the normalized value of all group members -void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, int32_t max) +// Does not procude logging output +void gpio_set_normalized_group_values(hasp_update_value_t& value) { // Set all pins first, minimizes delays for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { hasp_gpio_config_t* gpio = &gpioConfig[k]; - if(gpio->group == group && gpioConfigInUse(k)) // group members that are outputs - gpio_set_normalized_value(gpio, val, min, max); + if(gpio->group == value.group && gpioConfigInUse(k)) // group members that are outputs + gpio_set_normalized_value(gpio, value.val, value.min, value.max); } - gpio_output_group_values(group); - object_set_normalized_group_values(group, NULL, val, min, max); // Update onsreen objects + // Log the changed output values + // gpio_output_group_values(value.group); + + // object_set_normalized_group_values(group, NULL, val, min, max); // Update onsreen objects } // Update the value of an output pin and its group members @@ -563,22 +511,23 @@ bool gpio_set_pin_value(uint8_t pin, int32_t val) { hasp_gpio_config_t* gpio = NULL; - if(!gpio_get_pin_config(pin, &gpio) || !gpio || gpio->type == HASP_GPIO_FREE) { + if(!gpio_get_pin_config(pin, &gpio) || !gpio) { LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); return false; - } else if(gpio->type == HASP_GPIO_BUTTON || gpio->type == HASP_GPIO_SWITCH) { - LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is an input"), pin); + } else if(gpio_is_output(gpio)) { + LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d can not be set"), pin); if(gpio->group) gpio_output_group_values(gpio->group); return false; } if(gpio->group) { - gpio_set_normalized_group_values(gpio->group, val, 0, gpio->max); // Set all pins in the group - LOG_VERBOSE(TAG_GPIO, F("Group %d - Pin %d = %d"), gpio->group, gpio->pin, gpio->val); + // update objects and gpios in this group + gpio_update_group(gpio->group, NULL, gpio->val, 0, gpio->max); } else { - gpio_set_output_value(gpio, val); // update this gpio value only + // update this gpio value only + gpio_set_output_value(gpio, val); dispatch_output_pin_value(gpio->pin, gpio->val); LOG_VERBOSE(TAG_GPIO, F("No Group - Pin %d = %d"), gpio->pin, gpio->val); } @@ -625,6 +574,8 @@ void gpio_set_moodlight(moodlight_t& moodlight) break; } } + + // TODO: Update objects when the Mood Color Pin is in a group } bool gpioIsSystemPin(uint8_t gpio) diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index fcf3e3b1..571eaa91 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -34,9 +34,9 @@ void gpioSetup(void); IRAM_ATTR void gpioLoop(void); void gpioEvery5Seconds(void); -// void gpio_set_group_onoff(uint8_t groupid, bool ison); -void gpio_set_normalized_group_values(uint8_t group, int32_t val, int32_t min, int32_t max); -// void gpio_set_gpio_state(uint8_t pin, uint16_t state); +void gpio_set_normalized_group_values(hasp_update_value_t& value); +void gpio_output_group_values(uint8_t group); + bool gpio_get_value(uint8_t pin, uint16_t& val); bool gpio_set_pin_value(uint8_t pin, int32_t val); void gpio_set_moodlight(moodlight_t& moodlight); From 2f2d24954f9b7dafd2fafddad06cce2211f04838 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 12 May 2021 04:29:20 +0200 Subject: [PATCH 182/227] Add HASP_GPIO_TOUCH --- src/sys/svc/hasp_http.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 68c44f3f..64139f74 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1555,6 +1555,9 @@ void webHandleGpioConfig() case HASP_GPIO_BUTTON: httpMessage += F(D_GPIO_BUTTON); break; + case HASP_GPIO_TOUCH: + httpMessage += F(D_GPIO_TOUCH); + break; case HASP_GPIO_LED: httpMessage += F(D_GPIO_LED); break; @@ -1666,6 +1669,9 @@ void webHandleGpioOptions() selected = (conf.type == HASP_GPIO_BUTTON); httpMessage += getOption(HASP_GPIO_BUTTON, F(D_GPIO_BUTTON), selected); + selected = (conf.type == HASP_GPIO_TOUCH); + httpMessage += getOption(HASP_GPIO_TOUCH, F(D_GPIO_TOUCH), selected); + selected = (conf.type == HASP_GPIO_LED); httpMessage += getOption(HASP_GPIO_LED, F(D_GPIO_LED), selected); From 81850a52ad201903a1812f1b4222585653acf650 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 12 May 2021 04:29:32 +0200 Subject: [PATCH 183/227] Remove HASP_NUM_INPUTS --- include/hasp_conf.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/hasp_conf.h b/include/hasp_conf.h index ba16d3b4..ac40b629 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -110,10 +110,6 @@ #define HASP_NUM_GPIO_CONFIG 8 #endif -#ifndef HASP_NUM_INPUTS -#define HASP_NUM_INPUTS 4 // Number of ACE Buttons -#endif - // #ifndef HASP_NUM_OUTPUTS // #define HASP_NUM_OUTPUTS 3 // #endif From 6e758a460f3a1ba36af49fa257b87072d61c3727 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 12 May 2021 09:33:56 +0200 Subject: [PATCH 184/227] Reboot using deepsleep --- src/dev/esp32/esp32.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp index db5752f0..d1e0b824 100644 --- a/src/dev/esp32/esp32.cpp +++ b/src/dev/esp32/esp32.cpp @@ -115,7 +115,9 @@ Esp32Device::Esp32Device() void Esp32Device::reboot() { - ESP.restart(); + esp_sleep_enable_timer_wakeup(50 * 1000); + esp_deep_sleep_start(); + // ESP.restart(); } void Esp32Device::show_info() From 8414cd7a7141e2320234509fb698958959d6066f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 13 May 2021 17:36:05 +0200 Subject: [PATCH 185/227] Add ext_click_h and ext_click_v Add my_obj_get_range for setting group values --- src/hasp/hasp_attribute.cpp | 134 ++++++++++++++++++++++++++++++++---- src/hasp/hasp_attribute.h | 4 ++ 2 files changed, 126 insertions(+), 12 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 67e99ff4..ffd6322e 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -1549,6 +1549,100 @@ static bool attr_anim_time(lv_obj_t* obj, const char* attr, uint16_t val, bool u return false; } +bool my_obj_get_range(lv_obj_t* obj, int32_t& min, int32_t& max) +{ + min = 0; + max = 1; + + switch(obj_get_type(obj)) { + case LV_HASP_BUTTON: + if(!lv_btn_get_checkable(obj)) { + return false; // not checkable + } + case LV_HASP_CHECKBOX: + case LV_HASP_SWITCH: + // default min=0 and max=1 + break; + + case LV_HASP_LED: + min = 0; + max = 255; + break; + + case LV_HASP_LMETER: + min = lv_linemeter_get_min_value(obj); + max = lv_linemeter_get_max_value(obj); + break; + + case LV_HASP_SLIDER: + min = lv_slider_get_min_value(obj); + max = lv_slider_get_max_value(obj); + break; + + case LV_HASP_GAUGE: + min = lv_gauge_get_min_value(obj); + max = lv_gauge_get_max_value(obj); + break; + + case LV_HASP_ARC: + min = lv_arc_get_min_value(obj); + max = lv_arc_get_max_value(obj); + break; + + case LV_HASP_BAR: + min = lv_bar_get_min_value(obj); + max = lv_bar_get_max_value(obj); + break; + + case LV_HASP_TABVIEW: + min = 0; + max = lv_tabview_get_tab_count(obj) - 1; + if(max == 0) return false; // only one tab available + break; + + case LV_HASP_CHART: + min = my_chart_get_min_value(obj); + max = my_chart_get_max_value(obj); + break; + + case LV_HASP_DROPDOWN: + case LV_HASP_ROLLER: + return false; // not supported yet + + default: + return false; + } + return true; +} + +bool attribute_set_normalized_value(lv_obj_t* obj, hasp_update_value_t& value) +{ + if(value.min == value.max) return false; // would cause divide by zero error + + int32_t min; + int32_t max; + if(!my_obj_get_range(obj, min, max)) return false; // range could not be determined + + // Limit the value between min and max, adjust if power = 0 + int16_t val; + if(value.power == 0 || value.val <= value.min) { + val = value.min; + } else if(value.val >= value.max) { + val = value.max; + } else { + val = value.val; + } + + if(min == 0 && max == 1) { + val = val != value.min; // Toggles are set to 0 when val = min, otherwise 1 + } else { + val = map(val, value.min, value.max, min, max); + } + + hasp_process_obj_attribute_val(obj, NULL, val, !!val, true); + return true; +} + bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool boolval, bool update) { if(obj_check_type(obj, LV_HASP_BUTTON)) { @@ -1602,9 +1696,13 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co int16_t val = atoi(payload); int32_t val32 = strtol(payload, nullptr, DEC); + int32_t min; + int32_t max; + if(!my_obj_get_range(obj, min, max)) return false; + if(obj_check_type(obj, LV_HASP_SLIDER)) { - int16_t min = lv_slider_get_min_value(obj); - int16_t max = lv_slider_get_max_value(obj); + // int16_t min = lv_slider_get_min_value(obj); + // int16_t max = lv_slider_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_slider_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1612,8 +1710,8 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_GAUGE)) { - int32_t min = lv_gauge_get_min_value(obj); - int32_t max = lv_gauge_get_max_value(obj); + // int32_t min = lv_gauge_get_min_value(obj); + // int32_t max = lv_gauge_get_max_value(obj); if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max update ? lv_gauge_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1621,8 +1719,8 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_ARC)) { - int16_t min = lv_arc_get_min_value(obj); - int16_t max = lv_arc_get_max_value(obj); + // int16_t min = lv_arc_get_min_value(obj); + // int16_t max = lv_arc_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_arc_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1630,8 +1728,8 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_BAR)) { - int16_t min = lv_bar_get_min_value(obj); - int16_t max = lv_bar_get_max_value(obj); + // int16_t min = lv_bar_get_min_value(obj); + // int16_t max = lv_bar_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_bar_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1639,8 +1737,8 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_LMETER)) { - int32_t min = lv_linemeter_get_min_value(obj); - int32_t max = lv_linemeter_get_max_value(obj); + // int32_t min = lv_linemeter_get_min_value(obj); + // int32_t max = lv_linemeter_get_max_value(obj); if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max update ? lv_linemeter_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1648,8 +1746,8 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_CHART)) { - int16_t min = my_chart_get_min_value(obj); - int16_t max = my_chart_get_max_value(obj); + // int16_t min = my_chart_get_min_value(obj); + // int16_t max = my_chart_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_chart_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1799,6 +1897,18 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p update ? lv_obj_set_click(obj, Parser::is_true(payload)) : attr_out_int(obj, attr, lv_obj_get_click(obj)); return; // attribute_found + case ATTR_EXT_CLICK_H: + update ? lv_obj_set_ext_click_area(obj, val, val, lv_obj_get_ext_click_pad_top(obj), + lv_obj_get_ext_click_pad_bottom(obj)) + : attr_out_int(obj, attr, lv_obj_get_ext_click_pad_left(obj)); + return; + + case ATTR_EXT_CLICK_V: + update ? lv_obj_set_ext_click_area(obj, lv_obj_get_ext_click_pad_left(obj), + lv_obj_get_ext_click_pad_right(obj), val, val) + : attr_out_int(obj, attr, lv_obj_get_ext_click_pad_top(obj)); + return; + case ATTR_ENABLED: if(update) if(Parser::is_true(payload)) diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index 1fd211df..56cc7b43 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -20,6 +20,8 @@ void line_clear_points(lv_obj_t* obj); void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update); bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool booval, bool update); +bool attribute_set_normalized_value(lv_obj_t* obj, hasp_update_value_t& value); + void attr_out_str(lv_obj_t* obj, const char* attribute, const char* data); void attr_out_int(lv_obj_t* obj, const char* attribute, int32_t val); void attr_out_color(lv_obj_t* obj, const char* attribute, lv_color_t color); @@ -306,6 +308,8 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_TEXT 53869 #define ATTR_SRC 4964 #define ATTR_ID 6715 +#define ATTR_EXT_CLICK_H 46643 +#define ATTR_EXT_CLICK_V 46657 #define ATTR_ANIM_TIME 59451 #define ATTR_ANIM_SPEED 281 From 8755f78b4af37d9dc31c51ff7192a9b950cb2ed9 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 05:20:12 +0200 Subject: [PATCH 186/227] Add LV_ATTRIBUTE_TASK_HANDLER --- include/lv_conf_v7.h | 2 ++ platformio.ini | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index 2782c1e6..c89700e0 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -237,7 +237,9 @@ typedef void* lv_img_decoder_user_data_t; #define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to `lv_task_handler` function */ +#ifndef LV_ATTRIBUTE_TASK_HANDLER #define LV_ATTRIBUTE_TASK_HANDLER +#endif /* With size optimization (-Os) the compiler might not align data to * 4 or 8 byte boundary. This alignment will be explicitly applied where needed. diff --git a/platformio.ini b/platformio.ini index ea509b82..d7889b52 100644 --- a/platformio.ini +++ b/platformio.ini @@ -117,6 +117,7 @@ build_flags = ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=49152U ; 48 kB lvgl memory -D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR + -D LV_ATTRIBUTE_TASK_HANDLER=IRAM_ATTR ;-D LV_FS_PC_PATH="//littlefs" ; this needs to match the vfs mount pount -D LODEPNG_NO_COMPILE_ALLOCATORS ; use PSram functions ; -- ArduinoJson build options ---------------------------- @@ -195,6 +196,7 @@ build_flags= ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=12288U ; 12kB lvgl memory -D LV_ATTRIBUTE_FAST_MEM= + -D LV_ATTRIBUTE_TASK_HANDLER=IRAM_ATTR ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments -D ARDUINOJSON_ENABLE_STD_STRING=1 ; for std::string From 55961c5b4fb10d415eb0e6ed5ca7518a8a567c86 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 05:23:59 +0200 Subject: [PATCH 187/227] Speedup loop --- src/mqtt/hasp_mqtt_pubsubclient.cpp | 3 +- src/sys/svc/hasp_telnet.cpp | 72 ++++++++++++++++++----------- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index 229e02be..93da72f6 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -342,7 +342,8 @@ void mqttSetup() IRAM_ATTR void mqttLoop(void) { - if(mqttEnabled) mqttClient.loop(); + // if(mqttEnabled) + mqttClient.loop(); } void mqttEvery5Seconds(bool networkIsConnected) diff --git a/src/sys/svc/hasp_telnet.cpp b/src/sys/svc/hasp_telnet.cpp index 647395ad..4001dd3a 100644 --- a/src/sys/svc/hasp_telnet.cpp +++ b/src/sys/svc/hasp_telnet.cpp @@ -44,8 +44,8 @@ void telnetClientDisconnect() LOG_TRACE(TAG_TELN, F(D_TELNET_CLOSING_CONNECTION), telnetClient.remoteIP().toString().c_str()); telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginAttempt = 0; // Initial attempt - // delete telnetConsole; - // telnetConsole = NULL; + delete telnetConsole; + telnetConsole = NULL; telnetClient.stop(); } @@ -215,11 +215,16 @@ static void telnetProcessLine(const char* input) break; } default: - if(strcasecmp_P(input, PSTR("exit")) == 0) { + if(strcasecmp_P(input, PSTR("exit")) == 0 || strcasecmp_P(input, PSTR("quit")) == 0 || + strcasecmp_P(input, PSTR("bye")) == 0) { telnetClientDisconnect(); } else if(strcasecmp_P(input, PSTR("logoff")) == 0) { - telnetClient.println(F("\r\n" D_USERNAME " ")); - telnetLoginState = TELNET_UNAUTHENTICATED; + if(strcmp(input, http_config.password) == 0) { + telnetClient.println(F("\r\n" D_USERNAME " ")); + telnetLoginState = TELNET_UNAUTHENTICATED; + } else { + telnetClientDisconnect(); + } } else { dispatch_text_line(input); } @@ -245,15 +250,16 @@ void telnetSetup() telnetServer->setNoDelay(true); telnetServer->begin(); - telnetConsole = new ConsoleInput(&telnetClient, HASP_CONSOLE_BUFFER); - if(telnetConsole != NULL) { - telnetConsole->setLineCallback(telnetProcessLine); - LOG_INFO(TAG_TELN, F(D_TELNET_STARTED)); - return; - } + // telnetConsole = new ConsoleInput(&telnetClient, HASP_CONSOLE_BUFFER); + // if(telnetConsole != NULL) { + // telnetConsole->setLineCallback(telnetProcessLine); + // LOG_INFO(TAG_TELN, F(D_TELNET_STARTED)); + // return; + // } + LOG_INFO(TAG_TELN, F(D_TELNET_STARTED)); + } else { + LOG_ERROR(TAG_TELN, F(D_TELNET_FAILED)); } - - LOG_ERROR(TAG_TELN, F(D_TELNET_FAILED)); #endif } } @@ -290,6 +296,31 @@ IRAM_ATTR void telnetLoop() } } #else + + /* Active Client: Process user input */ + if(telnetClient.connected()) { + if(telnetConsole) { + int16_t keypress = telnetConsole->readKey(); + } else { + telnetConsole = new ConsoleInput(&telnetClient, HASP_CONSOLE_BUFFER); + if(telnetConsole) { + telnetConsole->setLineCallback(telnetProcessLine); + } else { + telnetClientDisconnect(); + LOG_ERROR(TAG_TELN, F(D_TELNET_FAILED)); + } + } + } + +#endif +} + +void telnetEverySecond(void) +{ + if(!telnetClient.connected() && telnetLoginState != TELNET_UNAUTHENTICATED) { + telnetClientDisconnect(); // active client disconnected + } + if(telnetServer && telnetServer->hasClient()) { // a new client has connected if(!telnetClient.connected()) { // nobody is already connected telnetAcceptClient(); // allow the new client @@ -297,22 +328,7 @@ IRAM_ATTR void telnetLoop() LOG_WARNING(TAG_TELN, F(D_TELNET_CLIENT_REJECTED)); telnetServer->available().stop(); // already have a client, block new connections } - } else { - if(!telnetClient.connected() && telnetLoginState != TELNET_UNAUTHENTICATED) { - telnetClientDisconnect(); // active client disconnected - } else { - - /* Active Client: Process user input */ - if(telnetConsole && telnetClient.connected()) { - int16_t keypress = telnetConsole->readKey(); - switch(keypress) { - case ConsoleInput::KEY_PAUSE: - break; - } - } - } } -#endif } #if HASP_USE_CONFIG > 0 From 46505290bff950c8c5e6a30437411f5798b593e7 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 11:53:55 +0200 Subject: [PATCH 188/227] Update tavern tests --- test/test_colors.tavern.yaml | 49 ++++++++++-------- test/test_mqtt.tavern.yaml | 10 +++- test/test_obj.tavern.yaml | 2 +- test/test_range.tavern.yaml | 91 +++++++++++++++++++++++++++++++++ test/test_spinner.tavern.yaml | 87 +++++++++++++++++++++++++++++++ test/test_value_str.tavern.yaml | 8 +-- 6 files changed, 220 insertions(+), 27 deletions(-) create mode 100644 test/test_range.tavern.yaml create mode 100644 test/test_spinner.tavern.yaml diff --git a/test/test_colors.tavern.yaml b/test/test_colors.tavern.yaml index 32e07ac0..167ccfc5 100644 --- a/test/test_colors.tavern.yaml +++ b/test/test_colors.tavern.yaml @@ -2,6 +2,34 @@ --- test_name: Obj Standard Properties +includes: + - !include config.yaml + +paho-mqtt: + client: + transport: tcp + client_id: tavern-tester + connect: + host: "{host}" + port: !int "{port:d}" + timeout: 3 + auth: + username: "{username}" + password: "{password}" + +stages: + - name: Page 1 + mqtt_publish: + topic: hasp/{plate}/command + payload: "page 1" + mqtt_response: + topic: hasp/{plate}/state/page + payload: "1" + timeout: 1 + +--- +test_name: Obj Standard Properties + includes: - !include config.yaml @@ -77,27 +105,15 @@ marks: - btn stages: - - name: Page 1 - mqtt_publish: - topic: hasp/{plate}/command - payload: "page 1" - mqtt_response: - topic: hasp/{plate}/state/page - payload: "1" - timeout: 1 - delay_after: 0 - - name: Set bg_color mqtt_publish: topic: hasp/{plate}/command payload: "p[1].b[0].bg_color={color}" - delay_after: 0.02 - name: Clear page mqtt_publish: topic: hasp/{plate}/command/clearpage payload: "" - delay_after: 0.02 - name: Create object mqtt_publish: @@ -105,17 +121,12 @@ stages: json: obj: "{obj}" id: 1 - txt: "{color}" - r: !int "{r:d}" - g: !int "{g:d}" - b: !int "{b:d}" - delay_after: 0.02 + text: "{color}" - name: Set bg_color mqtt_publish: topic: hasp/{plate}/command payload: "p[1].b[0].bg_color={rgb565}" - delay_after: 0.02 - name: Test named COLOR mqtt_publish: @@ -134,7 +145,6 @@ stages: mqtt_publish: topic: hasp/{plate}/command payload: "p[1].b[1].text_color=123" - delay_after: 0.02 - name: Test hex COLOR mqtt_publish: @@ -153,7 +163,6 @@ stages: mqtt_publish: topic: hasp/{plate}/command payload: "p[1].b[1].text_color=529" - delay_after: 0.02 - name: Test rgb565 COLOR mqtt_publish: diff --git a/test/test_mqtt.tavern.yaml b/test/test_mqtt.tavern.yaml index c0aa526a..b5e43aab 100644 --- a/test/test_mqtt.tavern.yaml +++ b/test/test_mqtt.tavern.yaml @@ -1,6 +1,6 @@ # test_page.tavern.yaml --- -test_name: Page command +test_name: Obj Standard Properties includes: - !include config.yaml @@ -77,7 +77,10 @@ paho-mqtt: connect: host: "{host}" port: !int "{port:d}" - timeout: 1 + timeout: 3 + auth: + username: "{username}" + password: "{password}" stages: - name: Test reboot command @@ -104,6 +107,9 @@ paho-mqtt: host: "{host}" port: !int "{port:d}" timeout: 3 + auth: + username: "{username}" + password: "{password}" stages: - name: Test idle diff --git a/test/test_obj.tavern.yaml b/test/test_obj.tavern.yaml index 8f2cd522..e3a4a5bf 100644 --- a/test/test_obj.tavern.yaml +++ b/test/test_obj.tavern.yaml @@ -34,7 +34,7 @@ marks: - switch - bar - arc - - led + # - led # has a shadow bug - obj - lmeter - dropdown diff --git a/test/test_range.tavern.yaml b/test/test_range.tavern.yaml new file mode 100644 index 00000000..6b74ba5c --- /dev/null +++ b/test/test_range.tavern.yaml @@ -0,0 +1,91 @@ +# test_page.tavern.yaml +--- +test_name: Obj Standard Properties + +includes: + - !include config.yaml + +paho-mqtt: + client: + transport: tcp + client_id: tavern-tester + connect: + host: "{host}" + port: !int "{port:d}" + timeout: 3 + auth: + username: "{username}" + password: "{password}" + +marks: + - parametrize: + key: obj + vals: + - arc + - bar + - slider + - gauge + - lmeter + - parametrize: + key: + - min + - max + - val + vals: + - [-1000, 10000, 90] + - [128, 512, 256] + - [-15, 0, -5] + +stages: + - name: Page 1 + mqtt_publish: + topic: hasp/{plate}/command + payload: "page 1" + mqtt_response: + topic: hasp/{plate}/state/page + payload: "1" + timeout: 1 + + - name: Clear page + mqtt_publish: + topic: hasp/{plate}/command/clearpage + payload: "" + + - name: Create object + mqtt_publish: + topic: hasp/{plate}/command/jsonl + json: + obj: "{obj}" + id: 1 + x: 128 + y: 128 + + - name: Test min + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.min={min}","p1b1.min"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + min: !int "{min:d}" + timeout: 1 + + - name: Test max + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.max={max}","p1b1.max"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + max: !int "{max:d}" + timeout: 1 + + - name: Test val + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.val={val}","p1b1.val"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + val: !int "{val:d}" + timeout: 1 diff --git a/test/test_spinner.tavern.yaml b/test/test_spinner.tavern.yaml new file mode 100644 index 00000000..d2ad657d --- /dev/null +++ b/test/test_spinner.tavern.yaml @@ -0,0 +1,87 @@ +# test_page.tavern.yaml +--- +test_name: Obj Standard Properties + +includes: + - !include config.yaml + +paho-mqtt: + client: + transport: tcp + client_id: tavern-tester + connect: + host: "{host}" + port: !int "{port:d}" + timeout: 3 + auth: + username: "{username}" + password: "{password}" + +marks: + - parametrize: + key: obj + vals: + - spinner + - parametrize: + key: + - speed + - direction + - angle + vals: + - [1000, 0, 90] + - [2000, 1, 120] + - [1500, 0, 30] + +stages: + - name: Page 1 + mqtt_publish: + topic: hasp/{plate}/command + payload: "page 1" + mqtt_response: + topic: hasp/{plate}/state/page + payload: "1" + timeout: 1 + + - name: Clear page + mqtt_publish: + topic: hasp/{plate}/command/clearpage + payload: "" + + - name: Create object + mqtt_publish: + topic: hasp/{plate}/command/jsonl + json: + obj: "{obj}" + id: 1 + x: 128 + y: 128 + + - name: Test speed + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.speed={speed}","p1b1.speed"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + speed: !int "{speed:d}" + timeout: 1 + + - name: Test direction + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.direction={direction}","p1b1.direction"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + direction: !int "{direction:d}" + timeout: 1 + + - name: Test angle + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.angle={angle}","p1b1.angle"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + angle: !int "{angle:d}" + timeout: 1 diff --git a/test/test_value_str.tavern.yaml b/test/test_value_str.tavern.yaml index ec85b53d..e151c496 100644 --- a/test/test_value_str.tavern.yaml +++ b/test/test_value_str.tavern.yaml @@ -98,13 +98,13 @@ stages: - name: Set value_str mqtt_publish: - topic: "hasp/{plate}/command/p[1].b[1].value_str" - payload: "{str1}{str2}" + topic: "hasp/{plate}/command" + payload: "p1b1.value_str={str1}{str2}" delay_after: 0 - name: Get value_str mqtt_publish: - topic: hasp/{plate}/command - payload: "p[1].b[1].value_str" + topic: hasp/{plate}/command/p1b1.value_str + payload: "" mqtt_response: topic: hasp/{plate}/state/p1b1 json: From e77a1d14d352ddf946668eb6465246dcf834cdfa Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 11:58:07 +0200 Subject: [PATCH 189/227] Update config.yaml template --- .gitignore | 1 + test/config.yaml | 2 +- test/config_template.yaml | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/config_template.yaml diff --git a/.gitignore b/.gitignore index a8cd17da..3c2f15da 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ include/user_config_override.h src/user_config_override.h user_config_override.h platformio_override.ini +test/config.yaml user_setups/active/* build_output/* build_output/firmware/*.bin diff --git a/test/config.yaml b/test/config.yaml index 8e75a5fc..5a232814 100644 --- a/test/config.yaml +++ b/test/config.yaml @@ -8,4 +8,4 @@ variables: username: hasp password: hasp port: 1883 - plate: plate35 + plate: plate01 diff --git a/test/config_template.yaml b/test/config_template.yaml new file mode 100644 index 00000000..fd0dfab2 --- /dev/null +++ b/test/config_template.yaml @@ -0,0 +1,12 @@ +# Copy and rename this file to config.yaml +# Enter the connection details for the mqtt test server +--- +name: Common test information +description: Connection information for MQTT Client + +variables: + host: + port: 1883 + username: + password: + plate: From d42749703e70adcc35320ccd8d6d56feb6eb14e5 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:35:20 +0200 Subject: [PATCH 190/227] Add power pulse counter --- src/dev/esp32/lanbonl8.cpp | 86 +++++++++++++++++++++++++++++++++++++- src/dev/esp32/lanbonl8.h | 3 ++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/dev/esp32/lanbonl8.cpp b/src/dev/esp32/lanbonl8.cpp index f2f50ad9..215779ce 100644 --- a/src/dev/esp32/lanbonl8.cpp +++ b/src/dev/esp32/lanbonl8.cpp @@ -8,13 +8,32 @@ #include "Arduino.h" #include "dev/esp32/esp32.h" +#include "driver/pcnt.h" // Pulse count driver #include "driver/adc.h" #include "esp_adc_cal.h" #include "hasp_conf.h" #include "hasp_debug.h" -#define BACKLIGHT_CHANNEL 0 +#define BACKLIGHT_CHANNEL 15 + +// https://esp32.com/viewtopic.php?t=14660 +#define PCNT_FREQ_UNIT PCNT_UNIT_0 // Pulse Count Unit 0 +#define PCNT_H_LIM_VAL 10000 // upper limit of counting max. 32767, write +1 to overflow counter, when reached +#define PCNT_L_LIM_VAL -10000 // lower limit of counting max. 32767, write +1 to overflow counter, when reached +#define PCNT_INPUT_SIG_IO 35 // Pulse Input GPIO +#define PCNT_INPUT_CTRL_IO 36 // Pulse Control GPIO +#define PCNT_FILTER_VAL 300 // filter (damping, inertia) value for avoiding glitches in the count, max. 1023 +#define MEASURED_WATTS 1580 +#define MEASURED_PULSES_PER_SECOND 281 +// Per second + +int16_t PulseCounter = 0; // pulse counter, max. value is 32535 +int OverflowCounter = 0; // pulse counter overflow counter +uint32_t totalPulses; + +pcnt_isr_handle_t user_isr_handle = NULL; // interrupt handler - not used +hw_timer_t* timer = NULL; // Instancia do timer #define REF_VOLTAGE 1100 esp_adc_cal_characteristics_t* adc_chars = @@ -51,8 +70,49 @@ static void print_char_val_type(esp_adc_cal_value_t val_type) } } +//------------------------------------------------------------------------------------ +void IRAM_ATTR energy_pulse_counter_overflow(void* arg) +{ // Interrupt for overflow of pulse counter + OverflowCounter = OverflowCounter + 1; // increase overflow counter + PCNT.int_clr.val = BIT(PCNT_FREQ_UNIT); // clean overflow flag + pcnt_counter_clear(PCNT_FREQ_UNIT); // zero and reset of pulse counter unit +} + +//------------------------------------------------------------ +void energy_pulse_counter_init() +{ + pcnt_config_t pcntFreqConfig = {}; // initialise pulse counter + pcntFreqConfig.pulse_gpio_num = PCNT_INPUT_SIG_IO; // pin assignment for pulse counter + pcntFreqConfig.ctrl_gpio_num = PCNT_INPUT_CTRL_IO; // pin assignment for control + pcntFreqConfig.channel = PCNT_CHANNEL_0; // select channel 0 of pulse counter unit 0 + pcntFreqConfig.unit = PCNT_FREQ_UNIT; // select ESP32 pulse counter unit 0 + pcntFreqConfig.pos_mode = PCNT_COUNT_INC; // count rising edges (=change from low to high logical level) as pulses + pcntFreqConfig.neg_mode = PCNT_COUNT_DIS; // Conta na subida do pulso + pcntFreqConfig.lctrl_mode = PCNT_MODE_REVERSE; + pcntFreqConfig.hctrl_mode = PCNT_MODE_KEEP, + pcntFreqConfig.counter_h_lim = PCNT_H_LIM_VAL; // set upper limit of counting + pcntFreqConfig.counter_l_lim = PCNT_L_LIM_VAL; // set lower limit of counting + + pcnt_unit_config(&pcntFreqConfig); // configure rigisters of the pulse counter + + pcnt_counter_pause(PCNT_FREQ_UNIT); // pause puls counter unit + pcnt_counter_clear(PCNT_FREQ_UNIT); // zero and reset of pulse counter unit + + pcnt_event_enable(PCNT_FREQ_UNIT, PCNT_EVT_H_LIM); // enable event for interrupt on reaching upper limit of counting + pcnt_isr_register(energy_pulse_counter_overflow, NULL, 0, + &user_isr_handle); // configure register overflow interrupt handler + pcnt_intr_enable(PCNT_FREQ_UNIT); // enable overflow interrupt + + pcnt_set_filter_value(PCNT_FREQ_UNIT, PCNT_FILTER_VAL); // set damping, inertia + pcnt_filter_enable(PCNT_FREQ_UNIT); // enable counter glitch filter (damping) + + pcnt_counter_resume(PCNT_FREQ_UNIT); // resume counting on pulse counter unit +} + void LanbonL8::init() { + energy_pulse_counter_init(); + // Check if Two Point or Vref are burned into eFuse check_efuse(); @@ -64,6 +124,30 @@ void LanbonL8::init() print_char_val_type(val_type); } +void LanbonL8::loop_5s() +{ // function for reading pulse counter (for timer) + pcnt_get_counter_value(PCNT_FREQ_UNIT, &PulseCounter); // get pulse counter value - maximum value is 16 bits + uint32_t newPulses = OverflowCounter * 10000 + PulseCounter; + uint32_t delta = newPulses - totalPulses; + totalPulses = newPulses; + int16_t watt_10 = DEC / 5 * delta * MEASURED_WATTS / MEASURED_PULSES_PER_SECOND; + int16_t kwh_10 = DEC * totalPulses * MEASURED_WATTS / MEASURED_PULSES_PER_SECOND / 3600 / 1000; + LOG_VERBOSE(TAG_DEV, F("Pulse Counter %d.%d W / %d / %d.%d kWh"), watt_10 / DEC, watt_10 % DEC, totalPulses, + kwh_10 / DEC, kwh_10 % DEC); +} + +//------------------------------------------------------------ +void Read_Reset_PCNT() +{ // function for reading pulse counter (for timer) + pcnt_get_counter_value(PCNT_FREQ_UNIT, &PulseCounter); // get pulse counter value - maximum value is 16 bits + + // resetting counter as if example, delet for application in PiedPiperS + OverflowCounter = 0; // set overflow counter to zero + pcnt_counter_clear(PCNT_FREQ_UNIT); // zero and reset of pulse counter unit + // conterOK = true; // not in use, copy from example code + // ######################################## +} + } // namespace dev dev::LanbonL8 haspDevice; diff --git a/src/dev/esp32/lanbonl8.h b/src/dev/esp32/lanbonl8.h index f32e1fa4..b4e205cd 100644 --- a/src/dev/esp32/lanbonl8.h +++ b/src/dev/esp32/lanbonl8.h @@ -8,11 +8,14 @@ #if defined(LANBONL8) +void Read_PCNT(); + namespace dev { class LanbonL8 : public Esp32Device { public: void init(); + void loop_5s(); }; } // namespace dev From 859a111d9e9c59f07427fc80bf3f61d975a64e8b Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:39:10 +0200 Subject: [PATCH 191/227] Rework gpios --- src/sys/gpio/hasp_gpio.cpp | 293 ++++++++++++++++++++++--------------- src/sys/gpio/hasp_gpio.h | 132 ++++++++++------- 2 files changed, 255 insertions(+), 170 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 6a96d7a1..89493d84 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -13,8 +13,8 @@ #endif #ifdef ARDUINO - #include "AceButton.h" + using namespace ace_button; ButtonConfig buttonConfig; // Clicks, double-clicks and long presses ButtonConfig switchConfig; // Clicks only @@ -36,16 +36,11 @@ ButtonConfig switchConfig; // Clicks only hasp_gpio_config_t gpioConfig[HASP_NUM_GPIO_CONFIG] = { // {2, 8, INPUT, LOW}, {3, 9, OUTPUT, LOW}, {4, 10, INPUT, HIGH}, {5, 11, OUTPUT, LOW}, {6, 12, INPUT, LOW}, }; +uint8_t pwm_channel = 1; // Backlight has 0 -static inline void gpio_update_group(uint8_t group, lv_obj_t* obj, int32_t val, int32_t min, int32_t max) +static inline void gpio_update_group(uint8_t group, lv_obj_t* obj, bool power, int32_t val, int32_t min, int32_t max) { - hasp_update_value_t value = { - .min = min, - .max = max, - .val = val, - .obj = obj, - .group = group, - }; + hasp_update_value_t value = {.obj = obj, .group = group, .min = min, .max = max, .val = val, .power = power}; dispatch_normalized_group_values(value); } @@ -53,7 +48,8 @@ static inline void gpio_update_group(uint8_t group, lv_obj_t* obj, int32_t val, #include "driver/uart.h" #include -volatile bool touchdetected = false; +volatile bool touchdetected = false; +RTC_DATA_ATTR int recordCounter = 0; void gotTouch() { @@ -95,7 +91,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but bool state = false; switch(eventType) { case AceButton::kEventPressed: - if(gpioConfig[btnid].type == HASP_GPIO_SWITCH) { + if(gpioConfig[btnid].type != hasp_gpio_type_t::BUTTON) { eventid = HASP_EVENT_ON; } else { eventid = HASP_EVENT_DOWN; @@ -118,7 +114,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but // state = true; // do not repeat DOWN + LONG + HOLD // break; case AceButton::kEventReleased: - if(gpioConfig[btnid].type == HASP_GPIO_SWITCH) { + if(gpioConfig[btnid].type != hasp_gpio_type_t::BUTTON) { eventid = HASP_EVENT_OFF; } else { eventid = HASP_EVENT_RELEASE; @@ -128,11 +124,11 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but eventid = HASP_EVENT_LOST; } - event_gpio_input(gpioConfig[btnid].pin, gpioConfig[btnid].group, eventid); + event_gpio_input(gpioConfig[btnid].pin, eventid); // update objects and gpios in this group if(gpioConfig[btnid].group && eventid != HASP_EVENT_LONG) // do not repeat DOWN + LONG - gpio_update_group(gpioConfig[btnid].group, NULL, state, HASP_EVENT_OFF, HASP_EVENT_ON); + gpio_update_group(gpioConfig[btnid].group, NULL, gpioConfig[btnid].power, state, HASP_EVENT_OFF, HASP_EVENT_ON); } /* ********************************* GPIO Setup *************************************** */ @@ -191,64 +187,75 @@ static void gpio_setup_pin(uint8_t index) } uint8_t input_mode; + bool default_state = gpio->inverted ? LOW : HIGH; // default pullup switch(gpio->gpio_function) { - case OUTPUT: + case hasp_gpio_function_t::OUTPUT_PIN: input_mode = OUTPUT; break; - case INPUT: + case hasp_gpio_function_t::EXTERNAL_PULLDOWN: + default_state = !default_state; // not pullup + case hasp_gpio_function_t::EXTERNAL_PULLUP: input_mode = INPUT; break; #ifndef ARDUINO_ARCH_ESP8266 - case INPUT_PULLDOWN: - input_mode = INPUT_PULLDOWN; + case hasp_gpio_function_t::INTERNAL_PULLDOWN: + default_state = !default_state; // not pullup + input_mode = INPUT_PULLDOWN; break; #endif + case hasp_gpio_function_t::INTERNAL_PULLUP: default: input_mode = INPUT_PULLUP; } - gpio->max = 255; - ButtonConfig* config = &buttonConfig; // Ddefault pushbutton - + gpio->power = 1; // on by default, value is set to 0 + gpio->max = 255; switch(gpio->type) { - case HASP_GPIO_SWITCH: + case hasp_gpio_type_t::SWITCH: + case hasp_gpio_type_t::BATTERY... hasp_gpio_type_t::WINDOW: if(gpio->btn) delete gpio->btn; - gpio->btn = new AceButton(&switchConfig, gpio->pin, HIGH, index); + gpio->btn = new AceButton(&switchConfig, gpio->pin, default_state, index); pinMode(gpio->pin, INPUT_PULLUP); gpio->max = 0; break; - case HASP_GPIO_BUTTON: + case hasp_gpio_type_t::BUTTON: if(gpio->btn) delete gpio->btn; - gpio->btn = new AceButton(&buttonConfig, gpio->pin, HIGH, index); + gpio->btn = new AceButton(&buttonConfig, gpio->pin, default_state, index); pinMode(gpio->pin, INPUT_PULLUP); gpio->max = 0; break; - case HASP_GPIO_TOUCH: + case hasp_gpio_type_t::TOUCH: if(gpio->btn) delete gpio->btn; gpio->btn = new AceButton(&touchConfig, gpio->pin, HIGH, index); gpio->max = 0; // touchAttachInterrupt(gpio->pin, gotTouch, 33); break; - case HASP_GPIO_RELAY: + case hasp_gpio_type_t::POWER_RELAY: + case hasp_gpio_type_t::LIGHT_RELAY: pinMode(gpio->pin, OUTPUT); gpio->max = 1; // on-off break; - case HASP_GPIO_PWM: + case hasp_gpio_type_t::PWM: gpio->max = 4095; - case HASP_GPIO_ALL_LEDS: - // case HASP_GPIO_BACKLIGHT: + case hasp_gpio_type_t::LED... hasp_gpio_type_t::LED_W: + // case hasp_gpio_type_t::BACKLIGHT: pinMode(gpio->pin, OUTPUT); #if defined(ARDUINO_ARCH_ESP32) - // configure LED PWM functionalitites - ledcSetup(gpio->group, 20000, 12); - // attach the channel to the GPIO to be controlled - ledcAttachPin(gpio->pin, gpio->group); + if(pwm_channel < 16) { + // configure LED PWM functionalitites + ledcSetup(pwm_channel, 20000, 12); + // attach the channel to the GPIO to be controlled + ledcAttachPin(gpio->pin, pwm_channel); + gpio->channel = pwm_channel++; + } else { + LOG_ERROR(TAG_GPIO, F("Too many PWM channels defined")); + } #endif break; - case HASP_GPIO_DAC: + case hasp_gpio_type_t::DAC: #if defined(ARDUINO_ARCH_ESP32) gpio_num_t pin; if(dac_pad_get_io_num(DAC_CHANNEL_1, &pin) == ESP_OK) @@ -258,11 +265,13 @@ static void gpio_setup_pin(uint8_t index) #endif break; - case HASP_GPIO_SERIAL_DIMMER: { + case hasp_gpio_type_t::SERIAL_DIMMER: + case hasp_gpio_type_t::SERIAL_DIMMER_AU: + case hasp_gpio_type_t::SERIAL_DIMMER_EU: { const char command[9] = "\xEF\x01\x4D\xA3"; // Start Lanbon Dimmer #if defined(ARDUINO_ARCH_ESP32) - Serial1.begin(115200UL, SERIAL_8N1, UART_PIN_NO_CHANGE, gpio->pin, true, - 2000); // true = EU, false = AU + Serial1.begin(115200UL, SERIAL_8N1, UART_PIN_NO_CHANGE, gpio->pin, + gpio->type == hasp_gpio_type_t::SERIAL_DIMMER_EU); // true = EU, false = AU Serial1.flush(); delay(20); Serial1.print(" "); @@ -273,7 +282,7 @@ static void gpio_setup_pin(uint8_t index) break; } - case HASP_GPIO_FREE: + case hasp_gpio_type_t::FREE: return; default: @@ -285,6 +294,7 @@ static void gpio_setup_pin(uint8_t index) void gpioSetup() { LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTING)); + LOG_WARNING(TAG_GPIO, F("Reboot counter %d"), recordCounter++); aceButtonSetup(); @@ -307,23 +317,55 @@ IRAM_ATTR void gpioLoop(void) void gpioSetup(void) { - gpioSavePinConfig(0, 3, HASP_GPIO_RELAY, 0, -1); - gpioSavePinConfig(1, 4, HASP_GPIO_RELAY, 0, -1); - gpioSavePinConfig(2, 13, HASP_GPIO_LED, 0, -1); - gpioSavePinConfig(3, 14, HASP_GPIO_DAC, 0, -1); + gpioSavePinConfig(0, 3, hasp_gpio_type_t::RELAY, 0, -1, false); + gpioSavePinConfig(1, 4, hasp_gpio_type_t::RELAY, 0, -1, false); + gpioSavePinConfig(2, 13, hasp_gpio_type_t::LED, 0, -1, false); + gpioSavePinConfig(3, 14, hasp_gpio_type_t::DAC, 0, -1, false); } IRAM_ATTR void gpioLoop(void) {} #endif // ARDUINO +static inline bool gpio_is_input(hasp_gpio_config_t* gpio) +{ + return (gpio->type != hasp_gpio_type_t::USER) && (gpio->type >= 0x80); +} + +static inline bool gpio_is_output(hasp_gpio_config_t* gpio) +{ + return (gpio->type > hasp_gpio_type_t::USED) && (gpio->type < 0x80); +} + /* ********************************* State Setters *************************************** */ -bool gpio_get_value(uint8_t pin, uint16_t& val) +bool gpio_get_pin_state(uint8_t pin, bool& power, int32_t& val) +{ + for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { + if(gpioConfig[i].pin == pin && gpio_is_output(&gpioConfig[i])) { + power = gpioConfig[i].power; + val = gpioConfig[i].val; + return true; + } + } + return false; +} + +void gpio_output_state(hasp_gpio_config_t* gpio) +{ + char payload[32]; + char topic[12]; + snprintf_P(topic, sizeof(topic), PSTR("output%d"), gpio->pin); + snprintf_P(payload, sizeof(payload), PSTR("{\"state\":%d,\"val\":%d}"), gpio->power, gpio->val); + + dispatch_state_subtopic(topic, payload); +} + +bool gpio_output_pin_state(uint8_t pin) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { if(gpioConfig[i].pin == pin && gpioConfigInUse(i)) { - val = gpioConfig[i].val; + gpio_output_state(&gpioConfig[i]); return true; } } @@ -348,10 +390,11 @@ static inline bool gpio_set_analog_value(hasp_gpio_config_t* gpio) else if(gpio->max == 4095) val = gpio->val; + if(!gpio->power) val = 0; if(gpio->inverted) val = 4095 - val; - ledcWrite(gpio->group, val); // 12 bits - return true; // sent + ledcWrite(gpio->channel, val); // 12 bits + return true; // sent #elif defined(ARDUINO_ARCH_ESP8266) @@ -360,6 +403,7 @@ static inline bool gpio_set_analog_value(hasp_gpio_config_t* gpio) else if(gpio->max == 4095) val = gpio->val >> 2; + if(!gpio->power) val = 0; if(gpio->inverted) val = 1023 - val; analogWrite(gpio->pin, val); // 10 bits @@ -372,8 +416,13 @@ static inline bool gpio_set_analog_value(hasp_gpio_config_t* gpio) static inline bool gpio_set_serial_dimmer(hasp_gpio_config_t* gpio) { + uint16_t val = gpio_limit(gpio->val, 0, 255); + + if(!gpio->power) val = 0; + if(gpio->inverted) val = 255 - val; + char command[5] = "\xEF\x02\x00\xED"; - command[2] = (uint8_t)map(gpio->val, 0, 255, 0, 100); + command[2] = (uint8_t)map(val, 0, 255, 0, 100); command[3] ^= command[2]; #if defined(ARDUINO_ARCH_ESP32) @@ -389,7 +438,12 @@ static inline bool gpio_set_serial_dimmer(hasp_gpio_config_t* gpio) static inline bool gpio_set_dac_value(hasp_gpio_config_t* gpio) { #ifdef ARDUINO_ARCH_ESP32 + uint16_t val = gpio_limit(gpio->val, 0, 255); gpio_num_t pin; + + if(!gpio->power) val = 0; + if(gpio->inverted) val = 255 - val; + if(dac_pad_get_io_num(DAC_CHANNEL_1, &pin) == ESP_OK && gpio->pin == pin) dac_output_voltage(DAC_CHANNEL_1, gpio->val); else if(dac_pad_get_io_num(DAC_CHANNEL_2, &pin) == ESP_OK && gpio->pin == pin) @@ -415,23 +469,30 @@ bool gpio_get_pin_config(uint8_t pin, hasp_gpio_config_t** gpio) // Update the actual value of one pin, does NOT update group members // The value must be normalized first -static bool gpio_set_output_value(hasp_gpio_config_t* gpio, uint16_t val) +static bool gpio_set_output_value(hasp_gpio_config_t* gpio, bool power, uint16_t val) { - gpio->val = gpio_limit(val, 0, gpio->max); + // if val is 0, then set power to 0 + gpio->power = val == 0 ? 0 : power; + + // Only update the current value if power set to 1, otherwise retain previous value + if(power) gpio->val = gpio_limit(val, 0, gpio->max); switch(gpio->type) { - case HASP_GPIO_RELAY: - digitalWrite(gpio->pin, gpio->inverted ? !gpio->val : gpio->val); + case hasp_gpio_type_t::POWER_RELAY: + case hasp_gpio_type_t::LIGHT_RELAY: + digitalWrite(gpio->pin, power ? (gpio->inverted ? !gpio->val : gpio->val) : 0); return true; - case HASP_GPIO_ALL_LEDS: - case HASP_GPIO_PWM: + case hasp_gpio_type_t::LED... hasp_gpio_type_t::LED_W: + case hasp_gpio_type_t::PWM: return gpio_set_analog_value(gpio); - case HASP_GPIO_DAC: + case hasp_gpio_type_t::DAC: return gpio_set_dac_value(gpio); - case HASP_GPIO_SERIAL_DIMMER: + case hasp_gpio_type_t::SERIAL_DIMMER: + case hasp_gpio_type_t::SERIAL_DIMMER_AU: + case hasp_gpio_type_t::SERIAL_DIMMER_EU: return gpio_set_serial_dimmer(gpio); default: @@ -441,41 +502,37 @@ static bool gpio_set_output_value(hasp_gpio_config_t* gpio, uint16_t val) } // Update the normalized value of one pin -void gpio_set_normalized_value(hasp_gpio_config_t* gpio, int32_t val, int32_t min, int32_t max) +static void gpio_set_normalized_value(hasp_gpio_config_t* gpio, hasp_update_value_t& value) { - if(min != 0 || max != gpio->max) { // do we need to recalculate? - if(min == max) { + int32_t val = value.val; + + if(value.min != 0 || value.max != gpio->max) { // do we need to recalculate? + if(value.min == value.max) { LOG_ERROR(TAG_GPIO, F("Invalid value range")); return; } switch(gpio->type) { - case HASP_GPIO_RELAY: - val = val > min ? HIGH : LOW; + case hasp_gpio_type_t::POWER_RELAY: + case hasp_gpio_type_t::LIGHT_RELAY: + val = val > value.min ? HIGH : LOW; break; - case HASP_GPIO_ALL_LEDS: - case HASP_GPIO_DAC: - case HASP_GPIO_PWM: - case HASP_GPIO_SERIAL_DIMMER: - val = map(val, min, max, 0, gpio->max); + case hasp_gpio_type_t::LED... hasp_gpio_type_t::LED_W: + case hasp_gpio_type_t::DAC: + case hasp_gpio_type_t::PWM: + case hasp_gpio_type_t::SERIAL_DIMMER: + case hasp_gpio_type_t::SERIAL_DIMMER_AU: + case hasp_gpio_type_t::SERIAL_DIMMER_EU: + val = map(val, value.min, value.max, 0, gpio->max); break; default: return; // invalid output type } } - gpio_set_output_value(gpio, val); // recalculated -} -static inline bool gpio_is_input(hasp_gpio_config_t* gpio) -{ - return gpio->type == HASP_GPIO_BUTTON || gpio->type == HASP_GPIO_SWITCH || gpio->type == HASP_GPIO_TOUCH; -} - -static inline bool gpio_is_output(hasp_gpio_config_t* gpio) -{ - return (gpio->type != HASP_GPIO_FREE) && !gpio_is_input(gpio); + gpio_set_output_value(gpio, value.power, val); // recalculated } // Dispatch all group member values @@ -484,7 +541,7 @@ void gpio_output_group_values(uint8_t group) for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { hasp_gpio_config_t* gpio = &gpioConfig[k]; if(gpio->group == group && gpio_is_output(gpio)) // group members that are outputs - dispatch_output_pin_value(gpioConfig[k].pin, gpioConfig[k].val); + gpio_output_state(&gpioConfig[k]); } } @@ -497,7 +554,7 @@ void gpio_set_normalized_group_values(hasp_update_value_t& value) for(uint8_t k = 0; k < HASP_NUM_GPIO_CONFIG; k++) { hasp_gpio_config_t* gpio = &gpioConfig[k]; if(gpio->group == value.group && gpioConfigInUse(k)) // group members that are outputs - gpio_set_normalized_value(gpio, value.val, value.min, value.max); + gpio_set_normalized_value(gpio, value); } // Log the changed output values @@ -507,29 +564,34 @@ void gpio_set_normalized_group_values(hasp_update_value_t& value) } // Update the value of an output pin and its group members -bool gpio_set_pin_value(uint8_t pin, int32_t val) +bool gpio_set_pin_state(uint8_t pin, bool power, int32_t val) { hasp_gpio_config_t* gpio = NULL; if(!gpio_get_pin_config(pin, &gpio) || !gpio) { LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); return false; + } - } else if(gpio_is_output(gpio)) { + if(!gpio_is_output(gpio)) { LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d can not be set"), pin); - if(gpio->group) gpio_output_group_values(gpio->group); return false; } if(gpio->group) { // update objects and gpios in this group - gpio_update_group(gpio->group, NULL, gpio->val, 0, gpio->max); + gpio->power = power; + gpio->val = gpio_limit(val, 0, gpio->max); + gpio_update_group(gpio->group, NULL, gpio->power, gpio->val, 0, gpio->max); } else { // update this gpio value only - gpio_set_output_value(gpio, val); - dispatch_output_pin_value(gpio->pin, gpio->val); - LOG_VERBOSE(TAG_GPIO, F("No Group - Pin %d = %d"), gpio->pin, gpio->val); + if(gpio_set_output_value(gpio, power, val)) { + gpio_output_state(gpio); + LOG_VERBOSE(TAG_GPIO, F("No Group - Pin %d = %d"), gpio->pin, gpio->val); + } else { + return false; + } } return true; // pin found and set @@ -538,38 +600,22 @@ bool gpio_set_pin_value(uint8_t pin, int32_t val) // Updates the RGB pins directly, rgb are already normalized values void gpio_set_moodlight(moodlight_t& moodlight) { - uint8_t r = 0; - uint8_t g = 0; - uint8_t b = 0; - - if(moodlight.power && moodlight.brightness) { - r = (moodlight.r * moodlight.brightness + 127) / 255; - g = (moodlight.g * moodlight.brightness + 127) / 255; - b = (moodlight.b * moodlight.brightness + 127) / 255; - } else { - moodlight.power = 0; - } - // RGBXX https://stackoverflow.com/questions/39949331/how-to-calculate-rgbaw-amber-white-from-rgb-for-leds for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { - case HASP_GPIO_LED_R: - gpio_set_output_value(&gpioConfig[i], r); - break; - case HASP_GPIO_LED_G: - gpio_set_output_value(&gpioConfig[i], g); - break; - case HASP_GPIO_LED_B: - gpio_set_output_value(&gpioConfig[i], b); + case hasp_gpio_type_t::LED_R... hasp_gpio_type_t::LED_W: + uint8_t index = (gpioConfig[i].type - hasp_gpio_type_t::LED_R) / 2; + if(index > 4) continue; + + uint8_t val = (moodlight.rgbww[index] * moodlight.brightness + 127) / 255; + gpio_set_output_value(&gpioConfig[i], moodlight.power, val); break; } } for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { - case HASP_GPIO_LED_B: - case HASP_GPIO_LED_G: - case HASP_GPIO_LED_R: + case hasp_gpio_type_t::LED_R... hasp_gpio_type_t::LED_W: LOG_VERBOSE(TAG_GPIO, F(D_BULLET D_GPIO_PIN " %d => %d"), gpioConfig[i].pin, gpioConfig[i].val); break; } @@ -689,10 +735,10 @@ bool gpioIsSystemPin(uint8_t gpio) return false; } -bool gpioInUse(uint8_t gpio) +bool gpioInUse(uint8_t pin) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { - if((gpioConfig[i].pin == gpio) && gpioConfigInUse(i)) { + if((gpioConfig[i].pin == pin) && gpioConfigInUse(i)) { return true; // pin matches and is in use } } @@ -700,7 +746,7 @@ bool gpioInUse(uint8_t gpio) return false; } -bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc) +bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc, bool inverted) { // TODO: Input validation @@ -713,6 +759,7 @@ bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t gr gpioConfig[config_num].type = type; gpioConfig[config_num].group = group; gpioConfig[config_num].gpio_function = pinfunc; + gpioConfig[config_num].inverted = inverted; LOG_TRACE(TAG_GPIO, F("Saving Pin config #%d pin %d - type %d - group %d - func %d"), config_num, pin, type, group, pinfunc); return true; @@ -724,7 +771,7 @@ bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t gr bool gpioConfigInUse(uint8_t num) { if(num >= HASP_NUM_GPIO_CONFIG) return false; - return gpioConfig[num].type != HASP_GPIO_FREE; + return gpioConfig[num].type != hasp_gpio_type_t::FREE; } int8_t gpioGetFreeConfigId() @@ -746,20 +793,23 @@ void gpio_discovery(JsonArray& relay, JsonArray& led) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { - case HASP_GPIO_RELAY: + case hasp_gpio_type_t::LIGHT_RELAY: + case hasp_gpio_type_t::POWER_RELAY: relay.add(gpioConfig[i].pin); break; - case HASP_GPIO_DAC: - case HASP_GPIO_LED: // Don't include the moodlight - case HASP_GPIO_SERIAL_DIMMER: + case hasp_gpio_type_t::DAC: + case hasp_gpio_type_t::LED: // Don't include the moodlight + case hasp_gpio_type_t::SERIAL_DIMMER: + case hasp_gpio_type_t::SERIAL_DIMMER_AU: + case hasp_gpio_type_t::SERIAL_DIMMER_EU: led.add(gpioConfig[i].pin); break; // pwm.add(gpioConfig[i].pin); break; - case HASP_GPIO_FREE: + case hasp_gpio_type_t::FREE: default: break; } @@ -778,7 +828,7 @@ bool gpioGetConfig(const JsonObject& settings) for(JsonVariant v : array) { if(i < HASP_NUM_GPIO_CONFIG) { uint32_t cur_val = gpioConfig[i].pin | (gpioConfig[i].group << 8) | (gpioConfig[i].type << 16) | - (gpioConfig[i].gpio_function << 24); + (gpioConfig[i].gpio_function << 24) | (gpioConfig[i].inverted << 31); LOG_INFO(TAG_GPIO, F("GPIO CONF: %d: %d <=> %d"), i, cur_val, v.as()); if(cur_val != v.as()) changed = true; @@ -794,7 +844,7 @@ bool gpioGetConfig(const JsonObject& settings) array = settings[FPSTR(FP_GPIO_CONFIG)].to(); // Clear JsonArray for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { uint32_t cur_val = gpioConfig[i].pin | (gpioConfig[i].group << 8) | (gpioConfig[i].type << 16) | - (gpioConfig[i].gpio_function << 24); + (gpioConfig[i].gpio_function << 24) | (gpioConfig[i].inverted << 31); array.add(cur_val); } changed = true; @@ -827,13 +877,14 @@ bool gpioSetConfig(const JsonObject& settings) if(i < HASP_NUM_GPIO_CONFIG) { uint32_t cur_val = gpioConfig[i].pin | (gpioConfig[i].group << 8) | (gpioConfig[i].type << 16) | - (gpioConfig[i].gpio_function << 24); + (gpioConfig[i].gpio_function << 24) | (gpioConfig[i].inverted << 31); if(cur_val != new_val) status = true; gpioConfig[i].pin = new_val & 0xFF; gpioConfig[i].group = new_val >> 8 & 0xFF; gpioConfig[i].type = new_val >> 16 & 0xFF; - gpioConfig[i].gpio_function = new_val >> 24 & 0xFF; + gpioConfig[i].gpio_function = new_val >> 24 & 0x7F; + gpioConfig[i].inverted = new_val >> 31 & 0x1; } i++; } diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index 571eaa91..1665fd3a 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -17,10 +17,11 @@ extern "C" { struct hasp_gpio_config_t { - uint8_t gpio_function : 8; // INPUT, OUTPUT, PULLUP, etc uint8_t pin : 8; // pin number - uint8_t group : 6; // groupid + uint8_t group : 8; // groupid + uint8_t gpio_function : 7; // INPUT, OUTPUT, PULLUP, etc uint8_t inverted : 1; + uint8_t channel : 4; // pwmchannel uint8_t power : 1; uint8_t type; // switch, button, ... uint16_t val; @@ -37,15 +38,17 @@ void gpioEvery5Seconds(void); void gpio_set_normalized_group_values(hasp_update_value_t& value); void gpio_output_group_values(uint8_t group); -bool gpio_get_value(uint8_t pin, uint16_t& val); -bool gpio_set_pin_value(uint8_t pin, int32_t val); +bool gpio_output_pin_state(uint8_t pin); +bool gpio_get_pin_state(uint8_t pin, bool& power, int32_t& val); +bool gpio_set_pin_state(uint8_t pin, bool power, int32_t val); + void gpio_set_moodlight(moodlight_t& moodlight); void gpio_discovery(JsonArray& relay, JsonArray& led); -bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc); +bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc, bool inverted); bool gpioIsSystemPin(uint8_t gpio); -bool gpioInUse(uint8_t gpio); +bool gpioInUse(uint8_t pin); bool gpioConfigInUse(uint8_t num); int8_t gpioGetFreeConfigId(); hasp_gpio_config_t gpioGetPinConfig(uint8_t num); @@ -55,49 +58,80 @@ bool gpioGetConfig(const JsonObject& settings); bool gpioSetConfig(const JsonObject& settings); #endif -#define HASP_GPIO_FREE 0x00 -#define HASP_GPIO_USED 0x01 -#define HASP_GPIO_SWITCH 0x02 // User Inputs -// #define HASP_GPIO_SWITCH_INVERTED 0x03 -#define HASP_GPIO_BUTTON 0x04 -// #define HASP_GPIO_BUTTON_INVERTED 0x05 -#define HASP_GPIO_TOUCH 0x06 -// #define HASP_GPIO_TOUCH_INVERTED 0x07 -#define HASP_GPIO_COUNTER_RISE 0x10 // User Counters -// #define HASP_GPIO_COUNTER_RISE_INVERTED 0x11 -#define HASP_GPIO_COUNTER_FALL 0x12 -// #define HASP_GPIO_COUNTER_FALL_INVERTED 0x13 -#define HASP_GPIO_COUNTER_BOTH 0x14 -// #define HASP_GPIO_COUNTER_BOTH_INVERTED 0x15 -#define HASP_GPIO_RELAY 0x20 // User Outputs -// #define HASP_GPIO_RELAY_INVERTED 0x21 -#define HASP_GPIO_ALL_LEDS 0x22 ... 0x2F -#define HASP_GPIO_LED 0x22 -// #define HASP_GPIO_LED_INVERTED 0x23 -#define HASP_GPIO_LED_R 0x24 -// #define HASP_GPIO_LED_R_INVERTED 0x25 -#define HASP_GPIO_LED_G 0x26 -// #define HASP_GPIO_LED_G_INVERTED 0x27 -#define HASP_GPIO_LED_B 0x28 -// #define HASP_GPIO_LED_B_INVERTED 0x29 -#define HASP_GPIO_LED_W 0x2A -// #define HASP_GPIO_LED_W_INVERTED 0x2B -#define HASP_GPIO_LED_WW 0x2C -// #define HASP_GPIO_LED_WW_INVERTED 0x2D -#define HASP_GPIO_LED_CW 0x2E -// #define HASP_GPIO_LED_CW_INVERTED 0x2F -#define HASP_GPIO_PWM 0x40 -// #define HASP_GPIO_PWM_INVERTED 0x41 -#define HASP_GPIO_DAC 0x50 -// #define HASP_GPIO_DAC_INVERTED 0x51 -#define HASP_GPIO_ADC 0x52 -// #define HASP_GPIO_ADC_INVERTED 0x53 -#define HASP_GPIO_SERIAL_DIMMER 0x60 -#define HASP_GPIO_BUZZER 0x70 -// #define HASP_GPIO_BUZZER_INVERTED 0x71 -#define HASP_GPIO_HAPTIC 0x72 -// #define HASP_GPIO_HAPTIC_INVERTED 0x73 -#define HASP_GPIO_USER 0xFF +enum hasp_gpio_function_t { + OUTPUT_PIN = 1, + INTERNAL_PULLUP = 2, + INTERNAL_PULLDOWN = 3, + EXTERNAL_PULLUP = 4, + EXTERNAL_PULLDOWN = 5 +}; + +enum hasp_gpio_type_t { + FREE = 0x00, + USED = 0x01, + + /* Outputs */ + LED = 0x02, + LED_R = 0x03, + LED_G = 0x04, + LED_B = 0x05, + LED_CW = 0x06, + LED_WW = 0x07, + LED_W = 0x08, + LIGHT_RELAY = 0x0A, + POWER_RELAY = 0x0B, + SHUTTER_RELAY = 0x0C, + SHUTTER_OPEN = 0x1A, + SHUTTER_CLOSE = 0x1B, + BACKLIGHT = 0x20, + PWM = 0x21, + DAC = 0x22, + SERIAL_DIMMER = 0x30, + SERIAL_DIMMER_EU = 0x31, + SERIAL_DIMMER_AU = 0x32, + BUZZER = 0x40, + HAPTIC = 0x41, + + /* Inputs */ + BATTERY = 0xA1, + BATTERY_CHARGING = 0xA2, + COLD = 0xA3, + CONNECTIVITY = 0xA4, + DOOR = 0xA5, + GARAGE_DOOR = 0xA6, + GAS = 0xA7, + HEAT = 0xA8, + LIGHT = 0xA9, + LOCK = 0xAA, + MOISTURE = 0xAB, + MOTION = 0xAC, + OCCUPANCY = 0xAD, + OPENING = 0xAE, + PLUG = 0xAF, + PRESENCE = 0xB0, + PROBLEM = 0xB1, + SAFETY = 0xB2, + SMOKE = 0xB3, + SOUND = 0xB4, + VIBRATION = 0xB5, + WINDOW = 0xB6, + + SWITCH = 0xC0, // Binary Sensors + + BUTTON = 0xF0, + BUTTON_TOGGLE_ON = 0xF1, + BUTTON_TOGGLE_OFF = 0xF2, + BUTTON_TOGGLE_BOTH = 0xF3, + TOUCH = 0xF4, + + ADC = 0xF9, + + COUNTER_RISE = 0xFA, // User Counters + COUNTER_FALL = 0xFB, + COUNTER_BOTH = 0xFC, + + USER = 0xFF +}; #ifdef __cplusplus } /* extern "C" */ From 7e80c81ea12215013ab24473cf2fc786d444850e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:40:02 +0200 Subject: [PATCH 192/227] Separate input and output config pages --- src/sys/svc/hasp_http.cpp | 240 +++++++++++++++++++++++++++++++------- 1 file changed, 197 insertions(+), 43 deletions(-) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 64139f74..466c4f4b 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1516,15 +1516,16 @@ void webHandleGpioConfig() if(webServer.hasArg(PSTR("save"))) { uint8_t id = webServer.arg(F("id")).toInt(); uint8_t pin = webServer.arg(F("pin")).toInt(); - uint8_t type = webServer.arg(F("type")).toInt() + webServer.arg(F("state")).toInt(); + uint8_t type = webServer.arg(F("type")).toInt(); uint8_t group = webServer.arg(F("group")).toInt(); uint8_t pinfunc = webServer.arg(F("func")).toInt(); - gpioSavePinConfig(id, pin, type, group, pinfunc); + bool inverted = webServer.arg(F("state")).toInt(); + gpioSavePinConfig(id, pin, type, group, pinfunc, inverted); } if(webServer.hasArg(PSTR("del"))) { uint8_t id = webServer.arg(F("id")).toInt(); uint8_t pin = webServer.arg(F("pin")).toInt(); - gpioSavePinConfig(id, pin, HASP_GPIO_FREE, 0, 0); + gpioSavePinConfig(id, pin, hasp_gpio_type_t::FREE, 0, 0, false); } { @@ -1546,54 +1547,72 @@ void webHandleGpioConfig() httpMessage += F("

"); // httpMessage += halGpioName(gpio); httpMessage += haspDevice.gpio_name(gpio).c_str(); - httpMessage += F(""); + if(conf.type >= 0x80) { + httpMessage += F(""); switch(conf.type) { - case HASP_GPIO_SWITCH: + case hasp_gpio_type_t::SWITCH: httpMessage += F(D_GPIO_SWITCH); break; - case HASP_GPIO_BUTTON: + case hasp_gpio_type_t::BUTTON: httpMessage += F(D_GPIO_BUTTON); break; - case HASP_GPIO_TOUCH: + case hasp_gpio_type_t::TOUCH: httpMessage += F(D_GPIO_TOUCH); break; - case HASP_GPIO_LED: + case hasp_gpio_type_t::LED: httpMessage += F(D_GPIO_LED); break; - case HASP_GPIO_LED_R: + case hasp_gpio_type_t::LED_R: httpMessage += F(D_GPIO_LED_R); break; - case HASP_GPIO_LED_G: + case hasp_gpio_type_t::LED_G: httpMessage += F(D_GPIO_LED_G); break; - case HASP_GPIO_LED_B: + case hasp_gpio_type_t::LED_B: httpMessage += F(D_GPIO_LED_B); break; - case HASP_GPIO_RELAY: + case hasp_gpio_type_t::LIGHT_RELAY: + httpMessage += F("LIGHT_RELAY"); + break; + case hasp_gpio_type_t::POWER_RELAY: httpMessage += F(D_GPIO_RELAY); break; - case HASP_GPIO_PWM: + case hasp_gpio_type_t::SHUTTER_RELAY: + httpMessage += F("SHUTTER_RELAY"); + break; + case hasp_gpio_type_t::PWM: httpMessage += F(D_GPIO_PWM); break; - case HASP_GPIO_DAC: + case hasp_gpio_type_t::DAC: httpMessage += F(D_GPIO_DAC); break; - case HASP_GPIO_SERIAL_DIMMER: + case hasp_gpio_type_t::SERIAL_DIMMER: httpMessage += F(D_GPIO_SERIAL_DIMMER); break; +#if defined(LANBONL8) + case hasp_gpio_type_t::SERIAL_DIMMER_EU: + httpMessage += F("L8-HD (EU)"); + break; + case hasp_gpio_type_t::SERIAL_DIMMER_AU: + httpMessage += F("L8-HD (AU)"); + break; +#endif default: httpMessage += F(D_GPIO_UNKNOWN); } - httpMessage += F(""); + httpMessage += F(""); httpMessage += conf.group; httpMessage += F(""); httpMessage += (conf.inverted) ? F("Inverted") : F("Normal"); - httpMessage += F("Edit Type

"); @@ -1710,7 +1734,7 @@ void webHandleGpioOptions() } httpMessage += F("

"); - httpMessage += F("

Default State "); httpMessage += getOption(0, F("Normal"), !conf.inverted); httpMessage += getOption(1, F("Inverted"), conf.inverted); httpMessage += F("

"); @@ -1728,6 +1752,134 @@ void webHandleGpioOptions() // if(webServer.hasArg(F("action"))) dispatch_text_line(webServer.arg(F("action")).c_str()); // Security check } + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void webHandleGpioInput() +{ // http://plate01/config/gpio/options + if(!httpIsAuthenticated(F("config/gpio/input"))) return; + { + StaticJsonDocument<256> settings; + guiGetConfig(settings.to()); + + uint8_t config_id = webServer.arg(F("id")).toInt(); + + String httpMessage((char*)0); + httpMessage.reserve(HTTP_PAGE_SIZE); + httpMessage += F("

"); + httpMessage += haspDevice.get_hostname(); + httpMessage += F("


"); + + httpMessage += F(""); + httpMessage += F(""); + + httpMessage += F("

GPIO Options"); + httpMessage += config_id; + httpMessage += F(" Options

"); + + httpMessage += F("

" D_GPIO_PIN "

"); + + bool selected; + httpMessage += F("

Type

"); + + httpMessage += F("

" D_GPIO_GROUP "

"); + + httpMessage += F("

Default State

"); + + httpMessage += F("

Resistor

"); + + httpMessage += + F("

"); + + httpMessage += PSTR("

"); + + webSendPage(haspDevice.get_hostname(), httpMessage.length(), false); + webServer.sendContent(httpMessage); + } + webSendFooter(); + + // if(webServer.hasArg(F("action"))) dispatch_text_line(webServer.arg(F("action")).c_str()); // Security check +} #endif // HASP_USE_GPIO //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2184,6 +2336,7 @@ void httpSetup() #if HASP_USE_GPIO > 0 webServer.on(F("/config/gpio"), webHandleGpioConfig); webServer.on(F("/config/gpio/options"), webHandleGpioOptions); + webServer.on(F("/config/gpio/input"), webHandleGpioInput); #endif webServer.on(F("/saveConfig"), webHandleSaveConfig); webServer.on(F("/resetConfig"), httpHandleResetConfig); @@ -2223,7 +2376,8 @@ void httpReconnect() //////////////////////////////////////////////////////////////////////////////////////////////////// IRAM_ATTR void httpLoop(void) { - if(http_config.enable) webServer.handleClient(); + // if(http_config.enable) + webServer.handleClient(); } //////////////////////////////////////////////////////////////////////////////////////////////////// From 52659803fd8cfce1969f9d2ed478db2014972880 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:42:03 +0200 Subject: [PATCH 193/227] Add clear and spinner attributes. More generic attribute methods --- src/hasp/hasp_attribute.cpp | 307 +++++++++++++++++++----------------- 1 file changed, 161 insertions(+), 146 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index ffd6322e..286d3b2d 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -194,8 +194,28 @@ static uint8_t my_roller_get_visible_row_count(lv_obj_t* roller) return 0; } +// OK - this function is not const in lvgl and doesn't return 0 +static uint16_t my_msgbox_stop_auto_close(const lv_obj_t* obj) +{ + lv_msgbox_stop_auto_close((lv_obj_t*)obj); + return 0; +} + +// OK - this function is not const in lvgl +static bool my_arc_get_adjustable(const lv_obj_t* arc) +{ + return lv_arc_get_adjustable((lv_obj_t*)arc); +} + +// OK - we need to change the event handler too +static void my_arc_set_adjustable(lv_obj_t* arc, bool toggle) +{ + lv_arc_set_adjustable(arc, toggle); + lv_obj_set_event_cb(arc, toggle ? slider_event_handler : generic_event_handler); +} + // OK - this function is missing in lvgl -static inline int16_t my_arc_get_rotation(lv_obj_t* arc) +static inline uint16_t my_arc_get_rotation(lv_obj_t* arc) { lv_arc_ext_t* ext = (lv_arc_ext_t*)lv_obj_get_ext_attr(arc); return ext->rotation_angle; @@ -645,21 +665,10 @@ lv_obj_t* FindButtonLabel(lv_obj_t* btn) { if(btn) { lv_obj_t* label = lv_obj_get_child_back(btn, NULL); -#if 1 if(label) { if(obj_check_type(label, LV_HASP_LABEL)) { return label; } -#else - if(label) { - lv_obj_type_t list; - lv_obj_get_type(label, &list); - const char* objtype = list.type[0]; - - if(obj_check_type(objtype, LV_HASP_LABEL)) { - return label; - } -#endif } else { LOG_ERROR(TAG_ATTR, F("FindButtonLabel NULL Pointer encountered")); @@ -685,6 +694,29 @@ static const char* my_label_get_text(const lv_obj_t* label) return lv_label_get_text(label); // library does not return const } +static void my_label_set_text(lv_obj_t* label, const char* text) +{ + if(text[0] == '%') { + uint16_t hash = Parser::get_sdbm(text); + size_t len = strlen(text); + const char* static_text; + + switch(hash) { + + case 10125: + static_text = haspDevice.get_hostname(); + break; + default: + lv_label_set_text(label, text); + return; + } + + lv_label_set_text_static(label, static_text); + } else { + lv_label_set_text(label, text); + } +} + // OK static const char* my_btn_get_text(const lv_obj_t* obj) { @@ -767,16 +799,17 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch #if(LV_SLIDER_PART_INDIC != LV_SWITCH_PART_INDIC) || (LV_SLIDER_PART_KNOB != LV_SWITCH_PART_KNOB) || \ (LV_SLIDER_PART_BG != LV_SWITCH_PART_BG) || (LV_SLIDER_PART_INDIC != LV_ARC_PART_INDIC) || \ (LV_SLIDER_PART_KNOB != LV_ARC_PART_KNOB) || (LV_SLIDER_PART_BG != LV_ARC_PART_BG) || \ + (LV_SLIDER_PART_INDIC != LV_SPINNER_PART_INDIC) || (LV_SLIDER_PART_BG != LV_SPINNER_PART_BG) || \ (LV_SLIDER_PART_INDIC != LV_BAR_PART_INDIC) || (LV_SLIDER_PART_BG != LV_BAR_PART_BG) -#error "LV_SLIDER, LV_BAR, LV_ARC, LV_SWITCH parts should match!" +#error "LV_SLIDER, LV_BAR, LV_ARC, LV_SPINNER, LV_SWITCH parts should match!" #endif if(obj_check_type(obj, LV_HASP_SLIDER) || obj_check_type(obj, LV_HASP_SWITCH) || obj_check_type(obj, LV_HASP_ARC) || - obj_check_type(obj, LV_HASP_BAR)) { + obj_check_type(obj, LV_HASP_BAR) || obj_check_type(obj, LV_HASP_SPINNER)) { if(index == 1) { part = LV_SLIDER_PART_INDIC; } else if(index == 2) { - if(!obj_check_type(obj, LV_HASP_BAR)) part = LV_SLIDER_PART_KNOB; + if(!obj_check_type(obj, LV_HASP_BAR) && !obj_check_type(obj, LV_HASP_SPINNER)) part = LV_SLIDER_PART_KNOB; } else { part = LV_SLIDER_PART_BG; } @@ -823,6 +856,7 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch void my_tabview_set_text(lv_obj_t* obj, const char* payload) { uint16_t id = lv_tabview_get_tab_act(obj); + if(id < lv_tabview_get_tab_count(obj)) { lv_tabview_set_tab_name(obj, id, (char*)payload); } @@ -831,6 +865,7 @@ void my_tabview_set_text(lv_obj_t* obj, const char* payload) const char* my_tabview_get_text(const lv_obj_t* obj) { uint16_t id = lv_tabview_get_tab_act(obj); + if(id < lv_tabview_get_tab_count(obj)) { return my_tabview_get_tab_name(obj, id); } else { @@ -1277,36 +1312,6 @@ static bool hasp_process_arc_attribute(lv_obj_t* obj, const char* attr, uint16_t case ATTR_TYPE: (update) ? lv_arc_set_type(obj, val % 3) : attr_out_int(obj, attr, lv_arc_get_type(obj)); return true; - - case ATTR_ROTATION: - (update) ? lv_arc_set_rotation(obj, val) : attr_out_int(obj, attr, my_arc_get_rotation(obj)); - return true; - - case ATTR_ADJUSTABLE: - if(update) { - bool toggle = Parser::is_true(payload); - lv_arc_set_adjustable(obj, toggle); - lv_obj_set_event_cb(obj, toggle ? slider_event_handler : generic_event_handler); - } else { - attr_out_int(obj, attr, lv_arc_get_adjustable(obj)); - } - return true; - - case ATTR_START_ANGLE: - (update) ? lv_arc_set_bg_start_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_bg_angle_start(obj)); - return true; - - case ATTR_END_ANGLE: - (update) ? lv_arc_set_bg_end_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_bg_angle_end(obj)); - return true; - - case ATTR_START_ANGLE1: - (update) ? lv_arc_set_start_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_angle_start(obj)); - return true; - - case ATTR_END_ANGLE1: - (update) ? lv_arc_set_end_angle(obj, val) : attr_out_int(obj, attr, lv_arc_get_angle_end(obj)); - return true; } return false; @@ -1466,22 +1471,43 @@ static bool hasp_process_page_attributes(lv_obj_t* obj, const char* attr_p, uint return false; } +template +static inline bool do_attribute(T& list, lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) +{ + uint8_t obj_type = obj_get_type(obj); + int count = sizeof(list) / sizeof(list[0]); + + for(int i = 0; i < count; i++) { + if(obj_type == list[i].obj_type && attr_hash == list[i].hash) { + if(update) + list[i].set(obj, val); + else + val = list[i].get(obj); + return true; + } + } + + return false; +} + static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, const char* payload, bool update) { + uint8_t obj_type = obj_get_type(obj); + hasp_attr_update_char_const_t text[] = { - {LV_HASP_BUTTON, my_btn_set_text, my_btn_get_text}, - {LV_HASP_LABEL, lv_label_set_text, my_label_get_text}, - {LV_HASP_CHECKBOX, lv_checkbox_set_text, lv_checkbox_get_text}, - {LV_HASP_TABVIEW, my_tabview_set_text, my_tabview_get_text}, - {LV_HASP_TAB, my_tab_set_text, my_tab_get_text}, + {LV_HASP_BUTTON, ATTR_TEXT, my_btn_set_text, my_btn_get_text}, + {LV_HASP_LABEL, ATTR_TEXT, my_label_set_text, my_label_get_text}, + {LV_HASP_CHECKBOX, ATTR_TEXT, lv_checkbox_set_text, lv_checkbox_get_text}, + {LV_HASP_TABVIEW, ATTR_TEXT, my_tabview_set_text, my_tabview_get_text}, + {LV_HASP_TAB, ATTR_TEXT, my_tab_set_text, my_tab_get_text}, #if LV_USE_WIN != 0 - {LV_HASP_WINDOW, lv_win_set_title, lv_win_get_title}, + {LV_HASP_WINDOW, ATTR_TEXT, lv_win_set_title, lv_win_get_title}, #endif - {LV_HASP_MSGBOX, lv_msgbox_set_text, lv_msgbox_get_text} + {LV_HASP_MSGBOX, ATTR_TEXT, lv_msgbox_set_text, lv_msgbox_get_text} }; for(int i = 0; i < sizeof(text) / sizeof(text[0]); i++) { - if(obj_check_type(obj, text[i].obj_type)) { + if(obj_type == text[i].obj_type) { if(update) { text[i].set(obj, payload); } else { @@ -1513,43 +1539,65 @@ static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con return false; } -static bool attr_anim_time(lv_obj_t* obj, const char* attr, uint16_t val, bool update) +static bool generic_bool_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { - { // Use anim_time for const lv_obj getters - hasp_attr_update16_const_t anim_time[] = {{LV_HASP_BAR, lv_bar_set_anim_time, lv_bar_get_anim_time}, - {LV_HASP_SWITCH, lv_switch_set_anim_time, lv_switch_get_anim_time}, - {LV_HASP_LIST, lv_list_set_anim_time, lv_list_get_anim_time}, - {LV_HASP_MSGBOX, lv_msgbox_set_anim_time, lv_msgbox_get_anim_time}, - {LV_HASP_PAGE, lv_page_set_anim_time, lv_page_get_anim_time}, - {LV_HASP_ROLLER, lv_roller_set_anim_time, lv_roller_get_anim_time}, - {LV_HASP_TABVIEW, lv_tabview_set_anim_time, lv_tabview_get_anim_time}, - {LV_HASP_WINDOW, lv_win_set_anim_time, lv_win_get_anim_time}}; - - int count = sizeof(anim_time) / sizeof(anim_time[0]); - for(int i = 0; i < count; i++) { - if(obj_check_type(obj, anim_time[i].obj_type)) { - update ? anim_time[i].set(obj, val) : attr_out_int(obj, attr, anim_time[i].get(obj)); - return true; - } - } - } - - { // Re-use anim_time for non-const lv_obj getters - hasp_attr_update16_t anim_time[] = {{LV_HASP_SLIDER, lv_slider_set_anim_time, lv_slider_get_anim_time}, - {LV_HASP_TILEVIEW, lv_tileview_set_anim_time, lv_tileview_get_anim_time}}; - - int count = sizeof(anim_time) / sizeof(anim_time[0]); - for(int i = 0; i < count; i++) { - if(obj_check_type(obj, anim_time[i].obj_type)) { - update ? anim_time[i].set(obj, val) : attr_out_int(obj, attr, anim_time[i].get(obj)); - return true; - } - } + { // bool + hasp_attr_update_bool_const_t list[] = { + {LV_HASP_ARC, ATTR_ADJUSTABLE, my_arc_set_adjustable, my_arc_get_adjustable}, + {LV_HASP_BTNMATRIX, ATTR_ONE_CHECK, lv_btnmatrix_set_one_check, lv_btnmatrix_get_one_check}, + {LV_HASP_IMAGE, ATTR_AUTO_SIZE, lv_img_set_auto_size, lv_img_get_auto_size}}; + if(do_attribute(list, obj, attr_hash, val, update)) return true; } return false; } -bool my_obj_get_range(lv_obj_t* obj, int32_t& min, int32_t& max) +static bool generic_int_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) +{ + { // unint16_t + hasp_attr_update16_const_t list[] = { + {LV_HASP_MSGBOX, ATTR_AUTO_CLOSE, lv_msgbox_start_auto_close, my_msgbox_stop_auto_close}, + {LV_HASP_SPINNER, ATTR_SPEED, lv_spinner_set_spin_time, lv_spinner_get_spin_time}, + {LV_HASP_BAR, ATTR_ANIM_TIME, lv_bar_set_anim_time, lv_bar_get_anim_time}, + {LV_HASP_SWITCH, ATTR_ANIM_TIME, lv_switch_set_anim_time, lv_switch_get_anim_time}, + {LV_HASP_LIST, ATTR_ANIM_TIME, lv_list_set_anim_time, lv_list_get_anim_time}, + {LV_HASP_MSGBOX, ATTR_ANIM_TIME, lv_msgbox_set_anim_time, lv_msgbox_get_anim_time}, + {LV_HASP_PAGE, ATTR_ANIM_TIME, lv_page_set_anim_time, lv_page_get_anim_time}, + {LV_HASP_ROLLER, ATTR_ANIM_TIME, lv_roller_set_anim_time, lv_roller_get_anim_time}, + {LV_HASP_TABVIEW, ATTR_ANIM_TIME, lv_tabview_set_anim_time, lv_tabview_get_anim_time}, + {LV_HASP_WINDOW, ATTR_ANIM_TIME, lv_win_set_anim_time, lv_win_get_anim_time}, + {LV_HASP_LABEL, ATTR_ANIM_SPEED, lv_label_set_anim_speed, lv_label_get_anim_speed}}; + if(do_attribute(list, obj, attr_hash, val, update)) return true; + } + + { // lv_anim_value_t + hasp_attr_update_lv_anim_value_const_t list[] = { + {LV_HASP_SPINNER, ATTR_ANGLE, lv_spinner_set_arc_length, lv_spinner_get_arc_length}}; + if(do_attribute(list, obj, attr_hash, val, update)) return true; + } + + // {LV_HASP_SPINNER, ATTR_THICKNESS, lv_spinner_set_arc_length, lv_spinner_get_arc_length} + + // { // uint8_t + // hasp_attr_update8_const_t list[] = {{LV_HASP_SPINNER, ATTR_DIRECTION, lv_spinner_set_dir, + // lv_spinner_get_dir}}; if(do_attribute(list, obj, attr_hash, val, update)) return true; + // } + + { // unint16_t, but getter is not const + hasp_attr_update16_t list[] = { + {LV_HASP_ARC, ATTR_ROTATION, lv_arc_set_rotation, my_arc_get_rotation}, + {LV_HASP_ARC, ATTR_START_ANGLE, lv_arc_set_bg_start_angle, lv_arc_get_bg_angle_start}, + {LV_HASP_ARC, ATTR_END_ANGLE, lv_arc_set_bg_end_angle, lv_arc_get_bg_angle_end}, + {LV_HASP_ARC, ATTR_START_ANGLE1, lv_arc_set_start_angle, lv_arc_get_angle_start}, + {LV_HASP_ARC, ATTR_END_ANGLE1, lv_arc_set_end_angle, lv_arc_get_angle_end}, + {LV_HASP_SLIDER, ATTR_ANIM_TIME, lv_slider_set_anim_time, lv_slider_get_anim_time}, + {LV_HASP_TILEVIEW, ATTR_ANIM_TIME, lv_tileview_set_anim_time, lv_tileview_get_anim_time}}; + if(do_attribute(list, obj, attr_hash, val, update)) return true; + } + + return false; +} + +static bool my_obj_get_range(lv_obj_t* obj, int32_t& min, int32_t& max) { min = 0; max = 1; @@ -1701,8 +1749,6 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co if(!my_obj_get_range(obj, min, max)) return false; if(obj_check_type(obj, LV_HASP_SLIDER)) { - // int16_t min = lv_slider_get_min_value(obj); - // int16_t max = lv_slider_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_slider_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1710,8 +1756,6 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_GAUGE)) { - // int32_t min = lv_gauge_get_min_value(obj); - // int32_t max = lv_gauge_get_max_value(obj); if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max update ? lv_gauge_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1719,8 +1763,6 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_ARC)) { - // int16_t min = lv_arc_get_min_value(obj); - // int16_t max = lv_arc_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_arc_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1728,8 +1770,6 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_BAR)) { - // int16_t min = lv_bar_get_min_value(obj); - // int16_t max = lv_bar_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_bar_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1737,8 +1777,6 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_LMETER)) { - // int32_t min = lv_linemeter_get_min_value(obj); - // int32_t max = lv_linemeter_get_max_value(obj); if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max update ? lv_linemeter_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1746,8 +1784,6 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co } if(obj_check_type(obj, LV_HASP_CHART)) { - // int16_t min = my_chart_get_min_value(obj); - // int16_t max = my_chart_get_max_value(obj); if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max update ? lv_chart_set_range(obj, set_min ? val : min, set_max ? val : max) : attr_out_int(obj, attr, set_min ? min : max); @@ -1862,19 +1898,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p hasp_process_obj_attribute_text(obj, attr, payload, update); return; // attribute_found - case ATTR_COLOR: - if(obj_check_type(obj, LV_HASP_CPICKER)) { - if(update) { - lv_color32_t c; - if(Parser::haspPayloadToColor(payload, c)) - lv_cpicker_set_color(obj, lv_color_make(c.ch.red, c.ch.green, c.ch.blue)); - } else { - attr_out_color(obj, attr, lv_cpicker_get_color(obj)); - } - return; // attribute_found - } - break; // not found - case ATTR_VAL: if(hasp_process_obj_attribute_val(obj, attr, atoi(payload), Parser::is_true(payload), update)) return; // attribute_found @@ -1924,18 +1947,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p : attr_out_int(obj, attr, obj->user_data.swipeid); return; // attribute_found - case ATTR_ANIM_SPEED: - if(obj_check_type(obj, LV_HASP_LABEL)) { - update ? lv_label_set_anim_speed(obj, (uint16_t)val) - : attr_out_int(obj, attr, lv_label_get_anim_speed(obj)); - return; // attribute_found - } - break; // not found - - case ATTR_ANIM_TIME: - if(attr_anim_time(obj, attr, val, update)) return; // attribute_found - break; - case ATTR_ROWS: switch(obj_get_type(obj)) { case LV_HASP_ROLLER: @@ -2074,17 +2085,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p } break; // not found - case ATTR_ONE_CHECK: - if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { - if(update) { - lv_btnmatrix_set_one_check(obj, Parser::is_true(payload)); - } else { - attr_out_int(obj, attr_p, lv_btnmatrix_get_one_check(obj)); - } - return; // attribute_found - } - break; // not found - case ATTR_BTN_POS: if(obj_check_type(obj, LV_HASP_TABVIEW)) { if(update) { @@ -2105,16 +2105,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p break; // not found // case ATTR_MODAL: - case ATTR_AUTO_CLOSE: - if(obj_check_type(obj, LV_HASP_MSGBOX)) { - if(update) { - lv_msgbox_start_auto_close(obj, val); - } else { - lv_msgbox_stop_auto_close(obj); - } - return; // attribute_found - } - break; // not found case ATTR_RED: // TODO: remove temp RED if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { @@ -2132,6 +2122,10 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p } return; // attribute_found + case ATTR_CLEAR: + lv_obj_clean(obj); + return; // attribute_found + case ATTR_TO_FRONT: if(!lv_obj_get_parent(obj)) { LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attr_p); @@ -2159,9 +2153,6 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p case ATTR_OFFSET_Y: update ? lv_img_set_offset_y(obj, val) : attr_out_int(obj, attr, lv_img_get_offset_y(obj)); return; - case ATTR_AUTO_SIZE: - update ? lv_img_set_auto_size(obj, !!val) : attr_out_int(obj, attr, lv_img_get_auto_size(obj)); - return; case ATTR_SRC: if(update) { lv_img_cache_invalidate_src(lv_img_get_src(obj)); @@ -2208,10 +2199,34 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p } break; // not found + case LV_HASP_CPICKER: + if(attr_hash == ATTR_COLOR) { + if(update) { + lv_color32_t c; + if(Parser::haspPayloadToColor(payload, c)) + lv_cpicker_set_color(obj, lv_color_make(c.ch.red, c.ch.green, c.ch.blue)); + } else { + attr_out_color(obj, attr, lv_cpicker_get_color(obj)); + } + return; // attribute_found + } + break; // not found + default: break; } + if(generic_int_attribute(obj, attr_hash, val, update)) { + if(update) attr_out_int(obj, attr, val); + return; // attribute_found + } + + if(generic_bool_attribute(obj, attr_hash, val, update)) { + bool toggle = Parser::is_true(payload); + if(update) attr_out_int(obj, attr, toggle); + return; // attribute_found + } + { bool result; hasp_local_style_attr(obj, attr, attr_hash, payload, update, result); From 71193fef4d4bf3b09bffacddd0a1e7123954517d Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:43:04 +0200 Subject: [PATCH 194/227] Update group values --- src/hasp/hasp_event.cpp | 45 +++++++++++++++++++---------------------- src/hasp/hasp_event.h | 2 +- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index 21343c68..46df64ae 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -239,32 +239,28 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16 // ##################### Event Handlers ######################################################## -static inline void event_update_group(uint8_t group, lv_obj_t* obj, int32_t val, int32_t min, int32_t max) +static inline void event_update_group(uint8_t group, lv_obj_t* obj, bool power, int32_t val, int32_t min, int32_t max) { - hasp_update_value_t value = { - .min = min, - .max = max, - .val = val, - .obj = obj, - .group = group, - }; + hasp_update_value_t value = {.obj = obj, .group = group, .min = min, .max = max, .val = val, .power = power}; dispatch_normalized_group_values(value); } #if HASP_USE_GPIO > 0 -void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) +void event_gpio_input(uint8_t pin, uint8_t eventid) { - char payload[64]; - char topic[8]; + char payload[32]; + char topic[10]; char eventname[8]; - Parser::get_event_name(eventid, eventname, sizeof(eventname)); - snprintf_P(payload, sizeof(payload), PSTR("{\"pin\":%d,\"group\":%d,\"event\":\"%s\"}"), pin, group, eventname); - memcpy_P(topic, PSTR("input"), 6); + snprintf_P(topic, sizeof(topic), PSTR("input%d"), pin); + if(eventid == HASP_EVENT_ON || eventid == HASP_EVENT_OFF) { + Parser::get_event_name(HASP_EVENT_CHANGED, eventname, sizeof(eventname)); + snprintf_P(payload, sizeof(payload), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, eventid); + } else { + Parser::get_event_name(eventid, eventname, sizeof(eventname)); + snprintf_P(payload, sizeof(payload), PSTR("{\"event\":\"%s\"}"), eventname); + } dispatch_state_subtopic(topic, payload); - - // update outputstates - // dispatch_group_onoff(group, Parser::get_event_state(eventid), NULL); } #endif @@ -459,9 +455,9 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) } // Update group objects and gpios on release - if(last_value_sent == HASP_EVENT_UP || last_value_sent == HASP_EVENT_RELEASE) { - event_update_group(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent), HASP_EVENT_OFF, - HASP_EVENT_ON); + if(last_value_sent != LV_EVENT_LONG_PRESSED || last_value_sent != LV_EVENT_LONG_PRESSED_REPEAT) { + bool state = Parser::get_event_state(last_value_sent); + event_update_group(obj->user_data.groupid, obj, state, state, HASP_EVENT_OFF, HASP_EVENT_ON); } } @@ -504,7 +500,8 @@ void toggle_event_handler(lv_obj_t* obj, lv_event_t event) // Update group objects and gpios on release if(obj->user_data.groupid && hasp_event_id == HASP_EVENT_UP) { - event_update_group(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON); + event_update_group(obj->user_data.groupid, obj, last_value_sent, last_value_sent, HASP_EVENT_OFF, + HASP_EVENT_ON); } } @@ -572,7 +569,7 @@ void selector_event_handler(lv_obj_t* obj, lv_event_t event) if(obj->user_data.groupid && max > 0) // max a cannot be 0, its the divider if(hasp_event_id == HASP_EVENT_UP || hasp_event_id == LV_EVENT_VALUE_CHANGED) { - event_update_group(obj->user_data.groupid, obj, last_value_sent, 0, max); + event_update_group(obj->user_data.groupid, obj, !!last_value_sent, last_value_sent, 0, max); } // set the property @@ -683,8 +680,8 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = val; event_object_val_event(obj, hasp_event_id, val); - if(obj->user_data.groupid && hasp_event_id == HASP_EVENT_CHANGED && min != max) - event_update_group(obj->user_data.groupid, obj, val, min, max); + if(obj->user_data.groupid && (hasp_event_id == HASP_EVENT_CHANGED || hasp_event_id == HASP_EVENT_UP) && min != max) + event_update_group(obj->user_data.groupid, obj, !!val, val, min, max); } /** diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h index 79ebcc8f..517c83ea 100644 --- a/src/hasp/hasp_event.h +++ b/src/hasp/hasp_event.h @@ -28,7 +28,7 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event); #if HASP_USE_GPIO > 0 // GPIO event Handler -void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid); +void event_gpio_input(uint8_t pin, uint8_t eventid); #endif #endif // HASP_EVENT_H \ No newline at end of file From 2d9e73d0ff78b9b284de22e3d87db366d01a0a39 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:44:25 +0200 Subject: [PATCH 195/227] Optimize performance of the main loop --- src/main_arduino.cpp | 74 ++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index d8d2f800..dea795c5 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -3,9 +3,12 @@ #if !(defined(WINDOWS) || defined(POSIX)) -#include -#include "lvgl.h" -#include "hasp_conf.h" // load first +#include "hasplib.h" +#include "hasp_oobe.h" +#include "sys/net/hasp_network.h" +#include "dev/device.h" +#include "drv/hasp_drv_touch.h" +#include "ArduinoLog.h" #if HASP_USE_CONFIG > 0 #include "hasp_debug.h" @@ -16,18 +19,10 @@ #include "hasp_gui.h" #endif -#include "hasp_oobe.h" - -#include "hasp/hasp_dispatch.h" -#include "hasp/hasp.h" - -#include "sys/net/hasp_network.h" - -#include "dev/device.h" - bool isConnected; uint8_t mainLoopCounter = 0; unsigned long mainLastLoopTime = 0; +uint8_t statLoopCounter = 0; void setup() { @@ -116,6 +111,7 @@ IRAM_ATTR void loop() { guiLoop(); // haspLoop(); + networkLoop(); #if HASP_USE_GPIO > 0 @@ -126,53 +122,65 @@ IRAM_ATTR void loop() mqttLoop(); #endif // MQTT - haspDevice.loop(); + // haspDevice.loop(); #if HASP_USE_CONSOLE > 0 // debugLoop(); consoleLoop(); #endif + statLoopCounter++; /* Timer Loop */ if(millis() - mainLastLoopTime >= 1000) { + mainLastLoopTime += 1000; /* Runs Every Second */ haspEverySecond(); // sleep timer & statusupdate + +#if HASP_USE_TELNET > 0 + telnetEverySecond(); +#endif + // debugEverySecond(); - /* Runs Every 5 Seconds */ - if(mainLoopCounter == 0 || mainLoopCounter == 5) { - isConnected = networkEvery5Seconds(); // Check connection + switch(++mainLoopCounter) { + case 1: + haspDevice.loop_5s(); + break; + case 2: #if HASP_USE_HTTP > 0 - // httpEvery5Seconds(); + // httpEvery5Seconds(); #endif + break; + + case 3: +#if HASP_USE_GPIO > 0 + // gpioEvery5Seconds(); +#endif + break; + + case 4: + isConnected = networkEvery5Seconds(); // Check connection #if HASP_USE_MQTT > 0 - mqttEvery5Seconds(isConnected); + mqttEvery5Seconds(isConnected); #endif + break; -#if HASP_USE_GPIO > 0 - // gpioEvery5Seconds(); -#endif - - haspDevice.loop_5s(); + case 5: + mainLoopCounter = 0; + if(statLoopCounter) + LOG_VERBOSE(TAG_MAIN, F("%d millis per loop, %d counted"), 5000 / statLoopCounter, statLoopCounter); + statLoopCounter = 0; + break; } - - /* Reset loop counter every 10 seconds */ - if(mainLoopCounter >= 9) { - mainLoopCounter = 0; - } else { - mainLoopCounter++; - } - - mainLastLoopTime += 1000; } #ifdef ARDUINO_ARCH_ESP8266 delay(2); // ms #else - delay(5); // ms + delay(2); // ms // delay((lv_task_get_idle() >> 5) + 3); // 2..5 ms #endif } From b59207e1b678cc8a5a716d04fd8ec950e8f3af36 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:44:56 +0200 Subject: [PATCH 196/227] Code cleanup --- src/hasp/hasp_object.cpp | 20 +++----------------- src/hasp/hasp_object.h | 5 +++-- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 5da3790f..1f06d8ff 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -171,8 +171,9 @@ void object_set_group_values(lv_obj_t* parent, hasp_update_value_t& value) if(parent == nullptr) return; // Update object if it's in the same group - if(value.group == parent->user_data.groupid && value.obj != parent) - hasp_process_obj_attribute_val(parent, NULL, value.val, !!value.val, true); + if(value.group == parent->user_data.groupid && value.obj != parent) { + attribute_set_normalized_value(parent, value); + } /* check tabs */ if(obj_get_type(parent) == LV_HASP_TABVIEW) { @@ -201,21 +202,6 @@ void object_set_normalized_group_values(hasp_update_value_t& value) for(uint8_t i = 0; i < HASP_NUM_PAGES; i++) { if(i != page) object_set_group_values(haspPages.get_obj(i), value); - // uint8_t startid = 1; - // for(uint8_t objid = startid; objid < 20; objid++) { - // lv_obj_t* obj = hasp_find_obj_from_parent_id(get_page_obj(page), objid); - // if(obj && obj != src_obj && obj->user_data.groupid == groupid) { // skip source object, if set - // LOG_VERBOSE(TAG_HASP, F("Found p%db%d in group %d"), page, objid, groupid); - // lv_obj_set_state(obj, val > 0 ? LV_STATE_PRESSED | LV_STATE_CHECKED : LV_STATE_DEFAULT); - // switch(obj->user_data.objid) { - // case HASP_OBJ_ARC: - // case HASP_OBJ_SLIDER: - // case HASP_OBJ_CHECKBOX: - // hasp_process_obj_attribute_val(); - // default: - // } - // } - // } } } diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index 0295f4a4..4b4f15d8 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -22,11 +22,12 @@ typedef struct typedef struct { + lv_obj_t* obj; + uint8_t group; int32_t min; int32_t max; int32_t val; - lv_obj_t* obj; - uint8_t group; + bool power; } hasp_update_value_t; enum lv_hasp_obj_type_t { From a73984aefa4fdfe6c485c13681a14c3dd870f9d1 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:45:25 +0200 Subject: [PATCH 197/227] Add types for generic attribute lists --- src/hasp/hasp_attribute.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index 56cc7b43..5b6f6e3b 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -30,16 +30,42 @@ void attr_out_color(lv_obj_t* obj, const char* attribute, lv_color_t color); } /* extern "C" */ #endif +struct hasp_attr_update_bool_const_t +{ + lv_hasp_obj_type_t obj_type; + uint16_t hash; + void (*set)(lv_obj_t*, bool); + bool (*get)(const lv_obj_t*); +}; + struct hasp_attr_update16_const_t { lv_hasp_obj_type_t obj_type; + uint16_t hash; void (*set)(lv_obj_t*, uint16_t); uint16_t (*get)(const lv_obj_t*); }; +struct hasp_attr_update_lv_anim_value_const_t +{ + lv_hasp_obj_type_t obj_type; + uint16_t hash; + void (*set)(lv_obj_t*, lv_anim_value_t); + lv_anim_value_t (*get)(const lv_obj_t*); +}; + +struct hasp_attr_update8_const_t +{ + lv_hasp_obj_type_t obj_type; + uint16_t hash; + void (*set)(lv_obj_t*, uint8_t); + uint8_t (*get)(const lv_obj_t*); +}; + struct hasp_attr_update16_t { lv_hasp_obj_type_t obj_type; + uint16_t hash; void (*set)(lv_obj_t*, uint16_t); uint16_t (*get)(lv_obj_t*); }; @@ -47,6 +73,7 @@ struct hasp_attr_update16_t struct hasp_attr_update_char_const_t { lv_hasp_obj_type_t obj_type; + uint16_t hash; void (*set)(lv_obj_t*, const char*); const char* (*get)(const lv_obj_t*); }; @@ -315,6 +342,7 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) // methods #define ATTR_DELETE 50027 +#define ATTR_CLEAR 1069 #define ATTR_TO_FRONT 44741 #define ATTR_TO_BACK 24555 @@ -358,6 +386,12 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_OFFSET_Y 65389 #define ATTR_AUTO_SIZE 63729 +// Spinner +#define ATTR_SPEED 14375 +#define ATTR_THICKNESS 24180 +//#define ATTR_ARC_LENGTH 755 - use ATTR_ANGLE +// #define ATTR_DIRECTION 32415 - see Dropdown + /* hasp user data */ #define ATTR_ACTION 42102 #define ATTR_TRANSITION 10933 From a89fc857c19d5d58a5a43610d889d3331852dad0 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:45:49 +0200 Subject: [PATCH 198/227] Add test/config.yaml --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3c2f15da..3177d26d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ include/user_config_override.h src/user_config_override.h user_config_override.h platformio_override.ini -test/config.yaml user_setups/active/* build_output/* build_output/firmware/*.bin @@ -32,3 +31,5 @@ src/custom/* .vscode/c_cpp_properties.json .vscode/launch.json *.bak + +test/config.yaml From 5f711fc0cef3b60b8eb43561fa8427888d5b5a44 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:46:04 +0200 Subject: [PATCH 199/227] Update tavern tests --- test/test_value_str.tavern.yaml | 38 +++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/test/test_value_str.tavern.yaml b/test/test_value_str.tavern.yaml index e151c496..4bf8a25f 100644 --- a/test/test_value_str.tavern.yaml +++ b/test/test_value_str.tavern.yaml @@ -2,6 +2,35 @@ --- test_name: Obj Standard Properties +includes: + - !include config.yaml + +paho-mqtt: + client: + transport: tcp + client_id: tavern-tester + connect: + host: "{host}" + port: !int "{port:d}" + timeout: 3 + auth: + username: "{username}" + password: "{password}" + +stages: + - name: Page 1 + mqtt_publish: + topic: hasp/{plate}/command + payload: "page 1" + mqtt_response: + topic: hasp/{plate}/state/page + payload: "1" + timeout: 1 + delay_after: 0 + +--- +test_name: Obj Standard Properties + includes: - !include config.yaml @@ -74,15 +103,10 @@ marks: - "" stages: - - name: Page 1 + - name: Clear Page mqtt_publish: topic: hasp/{plate}/command - payload: "page 1" - mqtt_response: - topic: hasp/{plate}/state/page - payload: "1" - timeout: 1 - delay_after: 0 + payload: "clearpage 1" - name: Create object mqtt_publish: From 882ccaf79ca81fdc090ede9f888aaef27186720b Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 12:46:59 +0200 Subject: [PATCH 200/227] Update gpio and group dispatcher --- src/hasp/hasp_dispatch.cpp | 95 ++++++++++++++++++++++++-------------- src/hasp/hasp_dispatch.h | 9 +++- 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index fb18eec8..52b01299 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -100,16 +100,6 @@ void dispatch_json_error(uint8_t tag, DeserializationError& jsonError) LOG_ERROR(tag, F(D_JSON_FAILED " %s"), jsonError.c_str()); } -void dispatch_output_pin_value(uint8_t pin, uint16_t val) -{ - char payload[32]; - char topic[12]; - snprintf_P(topic, sizeof(topic), PSTR("output%d"), pin); - snprintf_P(payload, sizeof(payload), PSTR("%d"), val); - - dispatch_state_subtopic(topic, payload); -} - // p[x].b[y].attr=value static inline bool dispatch_parse_button_attribute(const char* topic_p, const char* payload, bool update) { @@ -164,28 +154,63 @@ static void dispatch_gpio(const char* topic, const char* payload) { #if HASP_USE_GPIO > 0 - if(Parser::is_only_digits(topic)) { - int16_t val; - uint8_t pin; + if(!Parser::is_only_digits(topic)) { + LOG_WARNING(TAG_MSGR, F("Invalid pin %s"), topic); + return; + } - pin = atoi(topic); - if(strlen(payload) > 0) { + uint8_t pin = atoi(topic); - val = atoi(payload); - if(val == 0) val = Parser::is_true(payload); + if(strlen(payload) > 0) { - gpio_set_pin_value(pin, val); + size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 128; + DynamicJsonDocument json(maxsize); + + // Note: Deserialization needs to be (const char *) so the objects WILL be copied + // this uses more memory but otherwise the mqtt receive buffer can get overwritten by the send buffer !! + DeserializationError jsonError = deserializeJson(json, payload); + json.shrinkToFit(); + + if(jsonError) { // Couldn't parse incoming JSON command + dispatch_json_error(TAG_MSGR, jsonError); } else { - uint16_t val; - if(gpio_get_value(pin, val)) { - dispatch_output_pin_value(pin, val); + // Save the current state + int32_t state_value; + bool power_state; + bool updated = false; + + if(!gpio_get_pin_state(pin, power_state, state_value)) { + LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d can not be set"), pin); + return; + } + + JsonVariant state = json[F("state")]; + JsonVariant value = json[F("val")]; + + // Check if the state needs to change + if(!state.isNull() && power_state != state.as()) { + power_state = state.as(); + updated = true; + } + + if(!value.isNull() && state_value != value.as()) { + state_value = value.as(); + updated = true; + } + + // Set new state + if(updated && gpio_set_pin_state(pin, power_state, state_value)) { + return; // value was set and state output already } else { - LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); + // output the new state to the log } } - } else { - LOG_WARNING(TAG_MSGR, F("Invalid pin %s"), topic); + } + + // just output this pin + if(!gpio_output_pin_state(pin)) { + LOG_WARNING(TAG_GPIO, F(D_BULLET "Pin %d is not configured"), pin); } #endif @@ -434,12 +459,12 @@ void dispatch_normalized_group_values(hasp_update_value_t& value) { if(value.group == 0) return; - LOG_VERBOSE(TAG_MSGR, F("GROUP %d value %d (%d-%d)"), value.group, value.val, value.min, value.max); #if HASP_USE_GPIO > 0 gpio_set_normalized_group_values(value); // Update GPIO states first #endif object_set_normalized_group_values(value); // Update onsreen objects except originating obj + LOG_VERBOSE(TAG_MSGR, F("GROUP %d value %d (%d-%d)"), value.group, value.val, value.min, value.max); #if HASP_USE_GPIO > 0 gpio_output_group_values(value.group); // Output new gpio values #endif @@ -655,7 +680,7 @@ void dispatch_moodlight(const char* topic, const char* payload) // Set the current state if(strlen(payload) != 0) { - size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 512; + size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 128; DynamicJsonDocument json(maxsize); // Note: Deserialization needs to be (const char *) so the objects WILL be copied @@ -670,20 +695,20 @@ void dispatch_moodlight(const char* topic, const char* payload) if(!json[F("state")].isNull()) moodlight.power = Parser::is_true(json[F("state")].as().c_str()); - if(!json["r"].isNull()) moodlight.r = json["r"].as(); - if(!json["g"].isNull()) moodlight.g = json["g"].as(); - if(!json["b"].isNull()) moodlight.b = json["b"].as(); + if(!json["r"].isNull()) moodlight.rgbww[0] = json["r"].as(); + if(!json["g"].isNull()) moodlight.rgbww[1] = json["g"].as(); + if(!json["b"].isNull()) moodlight.rgbww[2] = json["b"].as(); if(!json["brightness"].isNull()) moodlight.brightness = json["brightness"].as(); if(!json[F("color")].isNull()) { if(!json[F("color")]["r"].isNull()) { - moodlight.r = json[F("color")]["r"].as(); + moodlight.rgbww[0] = json[F("color")]["r"].as(); } if(!json[F("color")]["g"].isNull()) { - moodlight.g = json[F("color")]["g"].as(); + moodlight.rgbww[1] = json[F("color")]["g"].as(); } if(!json[F("color")]["b"].isNull()) { - moodlight.b = json[F("color")]["b"].as(); + moodlight.rgbww[2] = json[F("color")]["b"].as(); } // lv_color32_t color; // if(Parser::haspPayloadToColor(json[F("color")].as(), color)) { @@ -707,7 +732,8 @@ void dispatch_moodlight(const char* topic, const char* payload) // buffer, sizeof(buffer), // PSTR("{\"state\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%u,\"g\":%u,\"b\":%u}"), buffer, sizeof(buffer), PSTR("{\"state\":\"%s\",\"color\":{\"r\":%u,\"g\":%u,\"b\":%u,\"brightness\":%u}}"), - moodlight.power ? "ON" : "OFF", moodlight.r, moodlight.g, moodlight.b, moodlight.brightness); + moodlight.power ? "ON" : "OFF", moodlight.rgbww[0], moodlight.rgbww[1], moodlight.rgbww[2], + moodlight.brightness); dispatch_state_subtopic(out_topic, buffer); } @@ -971,7 +997,8 @@ IRAM_ATTR void dispatchLoop() #if 1 || ARDUINO void dispatchEverySecond() { - if(dispatch_setings.teleperiod > 0 && (millis() - dispatchLastMillis) >= dispatch_setings.teleperiod * 1000) { + if(mqttIsConnected() && dispatch_setings.teleperiod > 0 && + (millis() - dispatchLastMillis) >= dispatch_setings.teleperiod * 1000) { dispatchLastMillis += dispatch_setings.teleperiod * 1000; dispatch_statusupdate(NULL, NULL); dispatch_send_discovery(NULL, NULL); diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index b6173d0f..fb51d558 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -15,7 +15,7 @@ struct moodlight_t { uint8_t brightness; uint8_t power; - uint8_t r, g, b; + uint8_t rgbww[5]; }; enum hasp_event_t { // even = released, odd = pressed @@ -29,6 +29,12 @@ enum hasp_event_t { // even = released, odd = pressed HASP_EVENT_LOST = 7, HASP_EVENT_DOUBLE = 8, + HASP_EVENT_OPEN = 10, + HASP_EVENT_OPENING = 11, + HASP_EVENT_CLOSED = 12, + HASP_EVENT_CLOSING = 13, + HASP_EVENT_STOP = 14, + HASP_EVENT_CHANGED = 32 }; @@ -69,7 +75,6 @@ void dispatch_calibrate(const char*, const char*); void dispatch_wakeup(const char*, const char*); void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid); -void dispatch_output_pin_value(uint8_t pin, uint16_t val); void dispatch_normalized_group_values(hasp_update_value_t& value); From 09b8fa72a72750385b800f86b01b66b79fd5f90e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 13:33:49 +0200 Subject: [PATCH 201/227] Fix esp8266 compile errors --- platformio.ini | 2 +- src/sys/gpio/hasp_gpio.cpp | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/platformio.ini b/platformio.ini index d7889b52..a15bf3f5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -196,7 +196,7 @@ build_flags= ; -- lvgl build options ----------------------------- -D LV_MEM_SIZE=12288U ; 12kB lvgl memory -D LV_ATTRIBUTE_FAST_MEM= - -D LV_ATTRIBUTE_TASK_HANDLER=IRAM_ATTR + -D LV_ATTRIBUTE_TASK_HANDLER= ; -- ArduinoJson build options ---------------------------- -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments -D ARDUINOJSON_ENABLE_STD_STRING=1 ; for std::string diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 89493d84..e5dd739a 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -48,8 +48,8 @@ static inline void gpio_update_group(uint8_t group, lv_obj_t* obj, bool power, i #include "driver/uart.h" #include -volatile bool touchdetected = false; -RTC_DATA_ATTR int recordCounter = 0; +volatile bool touchdetected = false; +RTC_DATA_ATTR int rtcRecordCounter = 0; void gotTouch() { @@ -96,8 +96,8 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but } else { eventid = HASP_EVENT_DOWN; } - state = true; - touchdetected = false; + state = true; + // touchdetected = false; break; case 2: // AceButton::kEventClicked: eventid = HASP_EVENT_UP; @@ -224,12 +224,14 @@ static void gpio_setup_pin(uint8_t index) pinMode(gpio->pin, INPUT_PULLUP); gpio->max = 0; break; +#if defined(ARDUINO_ARCH_ESP32) case hasp_gpio_type_t::TOUCH: if(gpio->btn) delete gpio->btn; gpio->btn = new AceButton(&touchConfig, gpio->pin, HIGH, index); gpio->max = 0; // touchAttachInterrupt(gpio->pin, gotTouch, 33); break; +#endif case hasp_gpio_type_t::POWER_RELAY: case hasp_gpio_type_t::LIGHT_RELAY: @@ -294,7 +296,9 @@ static void gpio_setup_pin(uint8_t index) void gpioSetup() { LOG_INFO(TAG_GPIO, F(D_SERVICE_STARTING)); - LOG_WARNING(TAG_GPIO, F("Reboot counter %d"), recordCounter++); +#if defined(ARDUINO_ARCH_ESP32) + LOG_WARNING(TAG_GPIO, F("Reboot counter %d"), rtcRecordCounter++); +#endif aceButtonSetup(); From 8fb8733f0567f62f60bc1a32a5f83f09c68c4a3f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 13:48:29 +0200 Subject: [PATCH 202/227] Fix for fake gpios --- src/sys/gpio/hasp_gpio.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index e5dd739a..38474ff2 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -321,8 +321,8 @@ IRAM_ATTR void gpioLoop(void) void gpioSetup(void) { - gpioSavePinConfig(0, 3, hasp_gpio_type_t::RELAY, 0, -1, false); - gpioSavePinConfig(1, 4, hasp_gpio_type_t::RELAY, 0, -1, false); + gpioSavePinConfig(0, 3, hasp_gpio_type_t::POWER_RELAY, 0, -1, false); + gpioSavePinConfig(1, 4, hasp_gpio_type_t::LIGHT_RELAY, 0, -1, false); gpioSavePinConfig(2, 13, hasp_gpio_type_t::LED, 0, -1, false); gpioSavePinConfig(3, 14, hasp_gpio_type_t::DAC, 0, -1, false); } From 17cdca19dfa94639d5479e56f921fd30ee6112f8 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 15 May 2021 13:49:04 +0200 Subject: [PATCH 203/227] inline object_get_type functions --- src/hasp/hasp_object.cpp | 45 -------------------------------------- src/hasp/hasp_object.h | 47 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 1f06d8ff..8ed80516 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -72,51 +72,6 @@ bool hasp_find_id_from_obj(const lv_obj_t* obj, uint8_t* pageid, uint8_t* objid) return true; } -/** - * Get the object type name of an object - * @param obj an lv_obj_t* of the object to check its type - * @return name of the object type - * @note - */ -const char* obj_get_type_name(const lv_obj_t* obj) -{ - lv_obj_type_t list; - lv_obj_get_type(obj, &list); - const char* objtype = list.type[0]; - return objtype + 3; // skip lv_ -} - -/** - * Check if an lvgl objecttype name corresponds to a given HASP object ID - * @param obj an lv_obj_t* of the object to check its type - * @param haspobjtype the HASP object ID to check against - * @return true or false wether the types match - * @note - */ -bool obj_check_type(const lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) -{ -#if 1 - if(!obj) return false; - return obj->user_data.objid == (uint8_t)haspobjtype; -#else - lv_obj_type_t list; - lv_obj_get_type(obj, &list); - const char* objtype = list.type[0]; - return obj_check_type(objtype, haspobjtype); -#endif -} - -/** - * Get the hasp object type of a given LVGL object - * @param obj an lv_obj_t* of the object to check its type - * @return lv_hasp_obj_type_t - * @note - */ -lv_hasp_obj_type_t obj_get_type(const lv_obj_t* obj) -{ - return (lv_hasp_obj_type_t)obj->user_data.objid; -} - void hasp_object_tree(const lv_obj_t* parent, uint8_t pageid, uint16_t level) { if(parent == nullptr) return; diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index 4b4f15d8..a220acb7 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -82,9 +82,7 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id); lv_obj_t* hasp_find_obj_from_parent_id(lv_obj_t* parent, uint8_t objid); lv_obj_t* hasp_find_obj_from_page_id(uint8_t pageid, uint8_t objid); bool hasp_find_id_from_obj(const lv_obj_t* obj, uint8_t* pageid, uint8_t* objid); -const char* obj_get_type_name(const lv_obj_t* obj); -bool obj_check_type(const lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype); -lv_hasp_obj_type_t obj_get_type(const lv_obj_t* obj); + void hasp_object_tree(const lv_obj_t* parent, uint8_t pageid, uint16_t level); void object_dispatch_state(uint8_t pageid, uint8_t btnid, const char* payload); @@ -93,6 +91,49 @@ void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, con void object_set_normalized_group_values(hasp_update_value_t& value); +/** + * Get the object type name of an object + * @param obj an lv_obj_t* of the object to check its type + * @return name of the object type + * @note + */ +inline const char* obj_get_type_name(const lv_obj_t* obj) +{ + lv_obj_type_t list; + lv_obj_get_type(obj, &list); + const char* objtype = list.type[0]; + return objtype + 3; // skip lv_ +} +/** + * Get the hasp object type of a given LVGL object + * @param obj an lv_obj_t* of the object to check its type + * @return lv_hasp_obj_type_t + * @note + */ +inline lv_hasp_obj_type_t obj_get_type(const lv_obj_t* obj) +{ + return (lv_hasp_obj_type_t)obj->user_data.objid; +} +/** + * Check if an lvgl objecttype name corresponds to a given HASP object ID + * @param obj an lv_obj_t* of the object to check its type + * @param haspobjtype the HASP object ID to check against + * @return true or false wether the types match + * @note + */ +inline bool obj_check_type(const lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) +{ +#if 1 + if(!obj) return false; + return obj->user_data.objid == (uint8_t)haspobjtype; +#else + lv_obj_type_t list; + lv_obj_get_type(obj, &list); + const char* objtype = list.type[0]; + return obj_check_type(objtype, haspobjtype); +#endif +} + #define HASP_OBJ_BAR 1971 #define HASP_OBJ_BTN 3164 #define HASP_OBJ_CPICKER 3313 From ee3c03758087d46c4772f6b7ffa5576fa904ad91 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 21:57:59 +0200 Subject: [PATCH 204/227] Update tests --- test/config.yaml | 2 +- test/test_obj.tavern.yaml | 2 +- test/test_range.tavern.yaml | 2 +- test/test_value_str.tavern.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/config.yaml b/test/config.yaml index 5a232814..c0597b68 100644 --- a/test/config.yaml +++ b/test/config.yaml @@ -8,4 +8,4 @@ variables: username: hasp password: hasp port: 1883 - plate: plate01 + plate: DESKTOP-1T7EDMU diff --git a/test/test_obj.tavern.yaml b/test/test_obj.tavern.yaml index e3a4a5bf..5db08543 100644 --- a/test/test_obj.tavern.yaml +++ b/test/test_obj.tavern.yaml @@ -36,7 +36,7 @@ marks: - arc # - led # has a shadow bug - obj - - lmeter + - linemeter - dropdown - calendar - spinner diff --git a/test/test_range.tavern.yaml b/test/test_range.tavern.yaml index 6b74ba5c..75a2d5c0 100644 --- a/test/test_range.tavern.yaml +++ b/test/test_range.tavern.yaml @@ -25,7 +25,7 @@ marks: - bar - slider - gauge - - lmeter + - linemeter - parametrize: key: - min diff --git a/test/test_value_str.tavern.yaml b/test/test_value_str.tavern.yaml index 4bf8a25f..90c68f1d 100644 --- a/test/test_value_str.tavern.yaml +++ b/test/test_value_str.tavern.yaml @@ -64,7 +64,7 @@ marks: - arc - led - obj - - lmeter + - linemeter - dropdown - spinner - roller From 5f6e0cf45ef62bf525c4b67410861e5a9a161498 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 21:58:23 +0200 Subject: [PATCH 205/227] Add strings for invalid attributes --- src/lang/en_US.h | 4 +++- src/lang/es_ES.h | 2 ++ src/lang/fr_FR.h | 2 ++ src/lang/hu_HU.h | 2 ++ src/lang/nl_NL.h | 2 ++ src/lang/pt_PT.h | 2 ++ src/lang/ro_RO.h | 2 ++ 7 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lang/en_US.h b/src/lang/en_US.h index aea5c2c1..7d009bc4 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -87,6 +87,8 @@ #define D_ATTRIBUTE_UNKNOWN "Unknown property %s" #define D_ATTRIBUTE_READ_ONLY "%s is read-only" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "Unable to call %s on a page" +#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s" +#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s" #define D_OOBE_SSID_VALIDATED "SSID %s validated" #define D_OOBE_AUTO_CALIBRATE "Auto calibrate enabled" @@ -193,7 +195,7 @@ // new #define D_GPIO_SWITCH "Switch" -#define D_GPIO_BUTTON "Button" +#define D_GPIO_BUTTON "Push Button" #define D_GPIO_TOUCH "Capacitive Touch" // Nieuw #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Mood Red" diff --git a/src/lang/es_ES.h b/src/lang/es_ES.h index d668352a..df895a91 100644 --- a/src/lang/es_ES.h +++ b/src/lang/es_ES.h @@ -87,6 +87,8 @@ #define D_ATTRIBUTE_UNKNOWN "Propiedad %s desconocida" #define D_ATTRIBUTE_READ_ONLY "%s es solo lectura" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "No se puede llamar %s en una página" +#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s" // new +#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s" // new #define D_OOBE_SSID_VALIDATED "SSID %s validado" #define D_OOBE_AUTO_CALIBRATE "Auto calibración hablitada" diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h index 515e334a..012b15c6 100644 --- a/src/lang/fr_FR.h +++ b/src/lang/fr_FR.h @@ -87,6 +87,8 @@ #define D_ATTRIBUTE_UNKNOWN "Unknown property %s" #define D_ATTRIBUTE_READ_ONLY "%s is read-only" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "Unable to call %s on a page" +#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s" // new +#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s" // new #define D_OOBE_SSID_VALIDATED "SSID %s validated" #define D_OOBE_AUTO_CALIBRATE "Auto calibrate enabled" diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index 76c33600..bf519e51 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -87,6 +87,8 @@ #define D_ATTRIBUTE_UNKNOWN "Ismeretlen tulajdonság: %s" #define D_ATTRIBUTE_READ_ONLY "%s csak olvasható" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "Nem lehet meghívni %s-t egy oldalon" +#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s" // new +#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s" // new #define D_OOBE_SSID_VALIDATED "%s SSID érvényes" #define D_OOBE_AUTO_CALIBRATE "Automatikus kalibrálás engedélyezve" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index c23a50b3..f6d7fd0d 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -87,6 +87,8 @@ #define D_ATTRIBUTE_UNKNOWN "Onbekend attribuut %s" #define D_ATTRIBUTE_READ_ONLY "%s is alleen-lezen" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "%s is ongeldig voor een pagina" +#define D_ATTRIBUTE_ALIGN_INVALID "Ongeldig align attribuut: %s" // new +#define D_ATTRIBUTE_COLOR_INVALID "Ongeldige kleur: %s" // new #define D_OOBE_SSID_VALIDATED "SSID %s gevalideerd" #define D_OOBE_AUTO_CALIBRATE "Auto calibratie actief" diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h index 2ef1a498..d53cd9eb 100644 --- a/src/lang/pt_PT.h +++ b/src/lang/pt_PT.h @@ -88,6 +88,8 @@ #define D_ATTRIBUTE_UNKNOWN "Propriedade %s desconhecida" #define D_ATTRIBUTE_READ_ONLY "%s é de leitura apenas" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "Não foi possível chamar %s numa página" +#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s" // new +#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s" // new #define D_OOBE_SSID_VALIDATED "SSID %s válido" #define D_OOBE_AUTO_CALIBRATE "Auto calibração ativada" diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 4d75a2dd..1bec0b42 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -87,6 +87,8 @@ #define D_ATTRIBUTE_UNKNOWN "Proprietate necunoscută: %s" #define D_ATTRIBUTE_READ_ONLY "%s este numai în citire" #define D_ATTRIBUTE_PAGE_METHOD_INVALID "Nu se poate apela %s pe o pagină" +#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s" // new +#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s" // new #define D_OOBE_SSID_VALIDATED "SSID %s validat" #define D_OOBE_AUTO_CALIBRATE "Calibrarea automată este activă" From 00962f15384b0ced1d9283a09bdaf8039a10c650 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 21:59:09 +0200 Subject: [PATCH 206/227] Check object type before task run --- src/hasp/hasp_event.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index 46df64ae..20d19cc2 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -75,7 +75,7 @@ void event_timer_calendar(lv_task_t* task) lv_obj_t* obj = NULL; if(data) obj = hasp_find_obj_from_page_id(data->pageid, data->objid); - if(!obj || !data) { + if(!obj || !data || !obj_check_type(obj, LV_HASP_CALENDER)) { if(data) lv_mem_free(data); // the object that the user_data points to is gone lv_task_del(task); // the calendar object for this task was deleted LOG_WARNING(TAG_EVENT, "event_timer_calendar could not find the linked object"); From 830b3acbefd9808b61291368758519c167e93b77 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 21:59:29 +0200 Subject: [PATCH 207/227] Add strcpy_P for native builds --- include/hasp_conf.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hasp_conf.h b/include/hasp_conf.h index ac40b629..8d9aabbc 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -299,6 +299,7 @@ static WiFiSpiClass WiFi; #define memcpy_P memcpy #define strcasecmp_P strcasecmp #define strcmp_P strcmp +#define strcpy_P strcpy #define strstr_P strstr #define halRestartMcu() #define millis SDL_GetTicks From 66bba78b0365a97d772e7f49b114332f10d26332 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 22:00:38 +0200 Subject: [PATCH 208/227] Change lmeter to linemeter --- src/hasp/hasp_object.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hasp/hasp_object.h b/src/hasp/hasp_object.h index a220acb7..14836bb7 100644 --- a/src/hasp/hasp_object.h +++ b/src/hasp/hasp_object.h @@ -54,14 +54,14 @@ enum lv_hasp_obj_type_t { LV_HASP_CPICKER = 20, /* Visualizers */ - LV_HASP_LABEL = 21, - LV_HASP_GAUGE = 22, - LV_HASP_BAR = 23, - LV_HASP_LMETER = 24, - LV_HASP_LED = 25, - LV_HASP_ARC = 26, - LV_HASP_SPINNER = 27, - LV_HASP_CHART = 28, + LV_HASP_LABEL = 21, + LV_HASP_GAUGE = 22, + LV_HASP_BAR = 23, + LV_HASP_LINEMETER = 24, + LV_HASP_LED = 25, + LV_HASP_ARC = 26, + LV_HASP_SPINNER = 27, + LV_HASP_CHART = 28, /* Selectors */ LV_HASP_DROPDOWN = 29, @@ -166,6 +166,7 @@ inline bool obj_check_type(const lv_obj_t* obj, lv_hasp_obj_type_t haspobjtype) #define HASP_OBJ_OBJ 53623 #define HASP_OBJ_OBJMASK 55395 #define HASP_OBJ_LMETER 62749 +#define HASP_OBJ_LINEMETER 55189 #define HASP_OBJ_TABVIEW 63226 #define HASP_OBJ_TAB 7861 #define HASP_OBJ_ARC 64594 From 5dad8b938e4ab447ea20effdab71312329067432 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 22:01:15 +0200 Subject: [PATCH 209/227] Bugfix in led index --- src/sys/gpio/hasp_gpio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 38474ff2..3c5682a1 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -608,7 +608,7 @@ void gpio_set_moodlight(moodlight_t& moodlight) for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { case hasp_gpio_type_t::LED_R... hasp_gpio_type_t::LED_W: - uint8_t index = (gpioConfig[i].type - hasp_gpio_type_t::LED_R) / 2; + uint8_t index = (gpioConfig[i].type - hasp_gpio_type_t::LED_R); if(index > 4) continue; uint8_t val = (moodlight.rgbww[index] * moodlight.brightness + 127) / 255; From 4e33888580cd75eb094a18af53a63c591a40ef8b Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 22:21:19 +0200 Subject: [PATCH 210/227] Add HASP_OBJ_LINEMETER --- src/hasp/hasp_object.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 8ed80516..7daa12bc 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -521,13 +521,14 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) } break; - case LV_HASP_LMETER: + case LV_HASP_LINEMETER: case HASP_OBJ_LMETER: + case HASP_OBJ_LINEMETER: obj = lv_linemeter_create(parent_obj, NULL); if(obj) { lv_linemeter_set_range(obj, 0, 100); lv_obj_set_event_cb(obj, generic_event_handler); - obj->user_data.objid = LV_HASP_LMETER; + obj->user_data.objid = LV_HASP_LINEMETER; } break; From 9dda843e3bbb6350bb68600a6d673bec034d21a5 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 23:54:58 +0200 Subject: [PATCH 211/227] Use ascii characterset for WT32-SC01 --- include/lv_conf_v7.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index c89700e0..04b82f8a 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -349,6 +349,36 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in #if TFT_WIDTH>=320 || TFT_WIDTH>=480 +#ifdef WT32SC01 + +#ifndef HASP_FONT_1 +#define HASP_FONT_1 robotocondensed_regular_16_ascii /* 5% Width */ +#endif +#ifndef HASP_FONT_2 +#define HASP_FONT_2 robotocondensed_regular_24_ascii /* 5% Width */ +#endif +#ifndef HASP_FONT_3 +#define HASP_FONT_3 robotocondensed_regular_32_ascii /* 10% Width */ +#endif +#ifndef HASP_FONT_4 +#define HASP_FONT_4 robotocondensed_regular_48_ascii /* 10% Height */ +#endif + +#ifndef ROBOTOCONDENSED_REGULAR_16_ASCII +#define ROBOTOCONDENSED_REGULAR_16_ASCII 1 +#endif +#ifndef ROBOTOCONDENSED_REGULAR_24_ASCII +#define ROBOTOCONDENSED_REGULAR_24_ASCII 1 +#endif +#ifndef ROBOTOCONDENSED_REGULAR_32_ASCII +#define ROBOTOCONDENSED_REGULAR_32_ASCII 1 +#endif +#ifndef ROBOTOCONDENSED_REGULAR_48_ASCII +#define ROBOTOCONDENSED_REGULAR_48_ASCII 1 +#endif + +#else // not WT32SC01 + #ifndef HASP_FONT_1 #define HASP_FONT_1 robotocondensed_regular_16_latin1 /* 5% Width */ #endif @@ -375,7 +405,9 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in #define ROBOTOCONDENSED_REGULAR_48_LATIN1 1 #endif -#else +#endif // WT32SC01 + +#else // not 320x480 #ifndef HASP_FONT_1 #define HASP_FONT_1 robotocondensed_regular_12_latin1 /* 5% Width */ From b216cc1096eeeea469c8f3b91ca4250d2e43245c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 23:55:34 +0200 Subject: [PATCH 212/227] Rewrite of the attribute parser --- src/hasp/hasp_attribute.cpp | 2113 +++++++++++++----------------- src/hasp/hasp_attribute.h | 58 +- src/hasp/hasp_attribute_helper.h | 512 ++++++++ 3 files changed, 1513 insertions(+), 1170 deletions(-) create mode 100644 src/hasp/hasp_attribute_helper.h diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 286d3b2d..766ab807 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -6,318 +6,11 @@ #endif #include "hasplib.h" +#include "hasp_attribute_helper.h" LV_FONT_DECLARE(unscii_8_icon); extern const char** btnmatrix_default_map; // memory pointer to lvgl default btnmatrix map -#if 0 -static bool attribute_lookup_lv_property(uint16_t hash, uint8_t * prop) -{ - struct prop_hash_map - { - uint16_t hash; - uint8_t prop; - }; - - /* in order of prevalence */ - prop_hash_map props[] = { - {ATTR_PAD_TOP, LV_STYLE_PAD_TOP & LV_STYLE_PROP_ALL}, - {ATTR_BORDER_WIDTH, LV_STYLE_BORDER_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_OUTLINE_WIDTH, LV_STYLE_OUTLINE_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_LETTER_SPACE, LV_STYLE_VALUE_LETTER_SPACE & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_LETTER_SPACE, LV_STYLE_TEXT_LETTER_SPACE & LV_STYLE_PROP_ALL}, - {ATTR_LINE_WIDTH, LV_STYLE_LINE_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_TIME, LV_STYLE_TRANSITION_TIME & LV_STYLE_PROP_ALL}, - {ATTR_SCALE_WIDTH, LV_STYLE_SCALE_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_RADIUS, LV_STYLE_RADIUS & LV_STYLE_PROP_ALL}, - {ATTR_PAD_BOTTOM, LV_STYLE_PAD_BOTTOM & LV_STYLE_PROP_ALL}, - {ATTR_BG_MAIN_STOP, LV_STYLE_BG_MAIN_STOP & LV_STYLE_PROP_ALL}, - {ATTR_BORDER_SIDE, LV_STYLE_BORDER_SIDE & LV_STYLE_PROP_ALL}, - {ATTR_OUTLINE_PAD, LV_STYLE_OUTLINE_PAD & LV_STYLE_PROP_ALL}, - {ATTR_PATTERN_REPEAT, LV_STYLE_PATTERN_REPEAT & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_LINE_SPACE, LV_STYLE_VALUE_LINE_SPACE & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_LINE_SPACE, LV_STYLE_TEXT_LINE_SPACE & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_DELAY, LV_STYLE_TRANSITION_DELAY & LV_STYLE_PROP_ALL}, - {ATTR_SCALE_BORDER_WIDTH, LV_STYLE_SCALE_BORDER_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_CLIP_CORNER, LV_STYLE_CLIP_CORNER & LV_STYLE_PROP_ALL}, - {ATTR_PAD_LEFT, LV_STYLE_PAD_LEFT & LV_STYLE_PROP_ALL}, - {ATTR_BG_GRAD_STOP, LV_STYLE_BG_GRAD_STOP & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_DECOR, LV_STYLE_TEXT_DECOR & LV_STYLE_PROP_ALL}, - {ATTR_LINE_DASH_WIDTH, LV_STYLE_LINE_DASH_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_PROP_1, LV_STYLE_TRANSITION_PROP_1 & LV_STYLE_PROP_ALL}, - {ATTR_SCALE_END_BORDER_WIDTH, LV_STYLE_SCALE_END_BORDER_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_SIZE, LV_STYLE_SIZE & LV_STYLE_PROP_ALL}, - {ATTR_PAD_RIGHT, LV_STYLE_PAD_RIGHT & LV_STYLE_PROP_ALL}, - {ATTR_BG_GRAD_DIR, LV_STYLE_BG_GRAD_DIR & LV_STYLE_PROP_ALL}, - {ATTR_BORDER_POST, LV_STYLE_BORDER_POST & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_OFS_X, LV_STYLE_VALUE_OFS_X & LV_STYLE_PROP_ALL}, - {ATTR_LINE_DASH_GAP, LV_STYLE_LINE_DASH_GAP & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_PROP_2, LV_STYLE_TRANSITION_PROP_2 & LV_STYLE_PROP_ALL}, - {ATTR_SCALE_END_LINE_WIDTH, LV_STYLE_SCALE_END_LINE_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_TRANSFORM_WIDTH, LV_STYLE_TRANSFORM_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_PAD_INNER, LV_STYLE_PAD_INNER & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_OFS_Y, LV_STYLE_VALUE_OFS_Y & LV_STYLE_PROP_ALL}, - {ATTR_LINE_ROUNDED, LV_STYLE_LINE_ROUNDED & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_PROP_3, LV_STYLE_TRANSITION_PROP_3 & LV_STYLE_PROP_ALL}, - {ATTR_TRANSFORM_HEIGHT, LV_STYLE_TRANSFORM_HEIGHT & LV_STYLE_PROP_ALL}, - // {ATTR_MARGIN_TOP, LV_STYLE_MARGIN_TOP & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_ALIGN, LV_STYLE_VALUE_ALIGN & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_PROP_4, LV_STYLE_TRANSITION_PROP_4 & LV_STYLE_PROP_ALL}, - // {ATTR_TRANSFORM_ANGLE, LV_STYLE_TRANSFORM_ANGLE & LV_STYLE_PROP_ALL}, - // {ATTR_MARGIN_BOTTOM, LV_STYLE_MARGIN_BOTTOM & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_PROP_5, LV_STYLE_TRANSITION_PROP_5 & LV_STYLE_PROP_ALL}, - // {ATTR_TRANSFORM_ZOOM, LV_STYLE_TRANSFORM_ZOOM & LV_STYLE_PROP_ALL}, - // {ATTR_MARGIN_LEFT, LV_STYLE_MARGIN_LEFT & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_PROP_6, LV_STYLE_TRANSITION_PROP_6 & LV_STYLE_PROP_ALL}, - // {ATTR_MARGIN_RIGHT, LV_STYLE_MARGIN_RIGHT & LV_STYLE_PROP_ALL}, - {ATTR_BG_COLOR, LV_STYLE_BG_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_BORDER_COLOR, LV_STYLE_BORDER_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_OUTLINE_COLOR, LV_STYLE_OUTLINE_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_PATTERN_RECOLOR, LV_STYLE_PATTERN_RECOLOR & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_COLOR, LV_STYLE_VALUE_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_COLOR, LV_STYLE_TEXT_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_LINE_COLOR, LV_STYLE_LINE_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_IMAGE_RECOLOR, LV_STYLE_IMAGE_RECOLOR & LV_STYLE_PROP_ALL}, - {ATTR_SCALE_GRAD_COLOR, LV_STYLE_SCALE_GRAD_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_BG_GRAD_COLOR, LV_STYLE_BG_GRAD_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_SEL_COLOR, LV_STYLE_TEXT_SEL_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_SCALE_END_COLOR, LV_STYLE_SCALE_END_COLOR & LV_STYLE_PROP_ALL}, - // {ATTR_TEXT_SEL_BG_COLOR, LV_STYLE_TEXT_SEL_BG_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_OPA_SCALE, LV_STYLE_OPA_SCALE & LV_STYLE_PROP_ALL}, - {ATTR_BG_OPA, LV_STYLE_BG_OPA & LV_STYLE_PROP_ALL}, - {ATTR_BORDER_OPA, LV_STYLE_BORDER_OPA & LV_STYLE_PROP_ALL}, - {ATTR_OUTLINE_OPA, LV_STYLE_OUTLINE_OPA & LV_STYLE_PROP_ALL}, - {ATTR_PATTERN_OPA, LV_STYLE_PATTERN_OPA & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_OPA, LV_STYLE_VALUE_OPA & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_OPA, LV_STYLE_TEXT_OPA & LV_STYLE_PROP_ALL}, - {ATTR_LINE_OPA, LV_STYLE_LINE_OPA & LV_STYLE_PROP_ALL}, - {ATTR_IMAGE_OPA, LV_STYLE_IMAGE_OPA & LV_STYLE_PROP_ALL}, - {ATTR_PATTERN_RECOLOR_OPA, LV_STYLE_PATTERN_RECOLOR_OPA & LV_STYLE_PROP_ALL}, - {ATTR_IMAGE_RECOLOR_OPA, LV_STYLE_IMAGE_RECOLOR_OPA & LV_STYLE_PROP_ALL}, - {ATTR_PATTERN_IMAGE, LV_STYLE_PATTERN_IMAGE & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_FONT, LV_STYLE_VALUE_FONT & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_FONT, LV_STYLE_TEXT_FONT & LV_STYLE_PROP_ALL}, - {ATTR_TRANSITION_PATH, LV_STYLE_TRANSITION_PATH & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_STR, LV_STYLE_VALUE_STR & LV_STYLE_PROP_ALL}, - -#if LV_USE_SHADOW - {ATTR_SHADOW_WIDTH, LV_STYLE_SHADOW_WIDTH & LV_STYLE_PROP_ALL}, - {ATTR_SHADOW_OFS_X, LV_STYLE_SHADOW_OFS_X & LV_STYLE_PROP_ALL}, - {ATTR_SHADOW_OFS_Y, LV_STYLE_SHADOW_OFS_Y & LV_STYLE_PROP_ALL}, - {ATTR_SHADOW_SPREAD, LV_STYLE_SHADOW_SPREAD & LV_STYLE_PROP_ALL}, - {ATTR_SHADOW_COLOR, LV_STYLE_SHADOW_COLOR & LV_STYLE_PROP_ALL}, - {ATTR_SHADOW_OPA, LV_STYLE_SHADOW_OPA & LV_STYLE_PROP_ALL}, -#endif - -#if LV_USE_BLEND_MODES && LV_USE_SHADOW - {ATTR_SHADOW_BLEND_MODE, LV_STYLE_SHADOW_BLEND_MODE & LV_STYLE_PROP_ALL}, -#endif - -#if LV_USE_BLEND_MODES - {ATTR_BG_BLEND_MODE, LV_STYLE_BG_BLEND_MODE & LV_STYLE_PROP_ALL}, - {ATTR_PATTERN_BLEND_MODE, LV_STYLE_PATTERN_BLEND_MODE & LV_STYLE_PROP_ALL}, - {ATTR_IMAGE_BLEND_MODE, LV_STYLE_IMAGE_BLEND_MODE & LV_STYLE_PROP_ALL}, - {ATTR_LINE_BLEND_MODE, LV_STYLE_LINE_BLEND_MODE & LV_STYLE_PROP_ALL}, - {ATTR_BORDER_BLEND_MODE, LV_STYLE_BORDER_BLEND_MODE & LV_STYLE_PROP_ALL}, - {ATTR_OUTLINE_BLEND_MODE, LV_STYLE_OUTLINE_BLEND_MODE & LV_STYLE_PROP_ALL}, - {ATTR_VALUE_BLEND_MODE, LV_STYLE_VALUE_BLEND_MODE & LV_STYLE_PROP_ALL}, - {ATTR_TEXT_BLEND_MODE, LV_STYLE_TEXT_BLEND_MODE & LV_STYLE_PROP_ALL}, -#endif - }; - - for(uint32_t i = 0; i < sizeof(props) / sizeof(props[0]); i++) { - if(props[i].hash == hash) { - *prop = props[1].prop; - LOG_WARNING(TAG_ATTR, F("%d found and has propery %d"), hash, props[i].prop); - return true; - } - } - LOG_ERROR(TAG_ATTR, F("%d has no property id"), hash); - return false; -} - -static bool attribute_get_lv_property() -{ - lv_res_t res _lv_style_get_int(const lv_style_t * style, lv_style_property_t prop, void * res); - return res == LV_RES_OK -} - -static bool attribute_set_lv_property() -{ - lv_res_t res _lv_style_get_int(const lv_style_t * style, lv_style_property_t prop, void * res); - return res == LV_RES_OK -} - -static bool attribute_update_lv_property(lv_obj_t * obj, const char * attr_p, uint16_t attr_hash, const char * payload, - bool update) -{ - uint8_t prop; - uint8_t prop_type; - - // convert sdbm hash to lv property number - if(!attribute_lookup_lv_property(attr_hash, &prop)) return false; - - // find the parameter type for this property - prop_type = prop & 0xF; - - if(prop_type < LV_STYLE_ID_COLOR) { - if(update) { - _lv_obj_set_style_local_int(obj, part, prop | (state << LV_STYLE_STATE_POS), atoi(payload)) - } else { - attr_out_str(obj, attr_p, lv_obj_get_style_value_str(obj, part)); - } - } else if(prop_type < LV_STYLE_ID_OPA) { - } else if(prop_type < LV_STYLE_ID_PTR) { - } else { - } -} -#endif - -const char* my_tabview_get_tab_name(const lv_obj_t* tabview, uint16_t id) -{ - if(id >= lv_tabview_get_tab_count(tabview)) return NULL; - - lv_tabview_ext_t* ext = (lv_tabview_ext_t*)lv_obj_get_ext_attr(tabview); - return ext->tab_name_ptr[id]; -} - -// OK - this function is missing in lvgl -static uint8_t my_roller_get_visible_row_count(lv_obj_t* roller) -{ - const lv_font_t* font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG); - lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG); - lv_coord_t h = lv_obj_get_height(roller); - - if((lv_font_get_line_height(font) + line_space) != 0) - return (uint8_t)(h / (lv_font_get_line_height(font) + line_space)); - else - return 0; -} - -// OK - this function is not const in lvgl and doesn't return 0 -static uint16_t my_msgbox_stop_auto_close(const lv_obj_t* obj) -{ - lv_msgbox_stop_auto_close((lv_obj_t*)obj); - return 0; -} - -// OK - this function is not const in lvgl -static bool my_arc_get_adjustable(const lv_obj_t* arc) -{ - return lv_arc_get_adjustable((lv_obj_t*)arc); -} - -// OK - we need to change the event handler too -static void my_arc_set_adjustable(lv_obj_t* arc, bool toggle) -{ - lv_arc_set_adjustable(arc, toggle); - lv_obj_set_event_cb(arc, toggle ? slider_event_handler : generic_event_handler); -} - -// OK - this function is missing in lvgl -static inline uint16_t my_arc_get_rotation(lv_obj_t* arc) -{ - lv_arc_ext_t* ext = (lv_arc_ext_t*)lv_obj_get_ext_attr(arc); - return ext->rotation_angle; -} - -// OK - this function is missing in lvgl -static inline int16_t my_chart_get_min_value(lv_obj_t* chart) -{ - lv_chart_ext_t* ext = (lv_chart_ext_t*)lv_obj_get_ext_attr(chart); - return ext->ymin[LV_CHART_AXIS_PRIMARY_Y]; -} - -// OK - this function is missing in lvgl -static inline int16_t my_chart_get_max_value(lv_obj_t* chart) -{ - lv_chart_ext_t* ext = (lv_chart_ext_t*)lv_obj_get_ext_attr(chart); - return ext->ymax[LV_CHART_AXIS_PRIMARY_Y]; -} - -lv_chart_series_t* my_chart_get_series(lv_obj_t* chart, uint8_t ser_num) -{ - lv_chart_ext_t* ext = (lv_chart_ext_t*)lv_obj_get_ext_attr(chart); - lv_chart_series_t* ser = (lv_chart_series_t*)_lv_ll_get_tail(&ext->series_ll); - while(ser_num > 0 && ser) { - ser = (lv_chart_series_t*)_lv_ll_get_prev(&ext->series_ll, ser); - ser_num--; - } - return ser; -} - -/** - * Set a new value_str for an object. Memory will be allocated to store the text by the object. - * @param obj pointer to a object - * @param text '\0' terminated character string. NULL to refresh with the current text. - */ -void my_obj_set_value_str_text(lv_obj_t* obj, uint8_t part, lv_state_t state, const char* text) -{ - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - - const void* value_str_p = lv_obj_get_style_value_str(obj, part); - lv_obj_invalidate(obj); - - if(text == NULL || text[0] == 0) { - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - lv_obj_set_style_local_value_str(obj, part, state, NULL); - lv_mem_free(value_str_p); - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - return; - } - - LV_ASSERT_STR(text); - - if(value_str_p == NULL) { - /*Get the size of the text*/ - size_t len = strlen(text) + 1; - - /*Allocate space for the new text*/ - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - value_str_p = (char*)lv_mem_alloc(len); - LV_ASSERT_MEM(value_str_p); - if(value_str_p == NULL) return; - - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - strncpy((char*)value_str_p, text, len); - lv_obj_set_style_local_value_str(obj, part, state, (char*)value_str_p); - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - return; - } - - // lv_obj_set_style_local_value_str(obj, part, state, str_p); - - if(value_str_p == text) { - /*If set its own text then reallocate it (maybe its size changed)*/ - LOG_DEBUG(TAG_ATTR, "%s %d", __FILE__, __LINE__); - return; // don't touch the data - - // value_str_p = lv_mem_realloc(value_str_p, strlen(text) + 1); - - // LV_ASSERT_MEM(value_str_p); - // if(value_str_p == NULL) return; - } else { - /*Free the old text*/ - if(value_str_p != NULL) { - // LOG_DEBUG(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - lv_mem_free(value_str_p); - value_str_p = NULL; - // LOG_DEBUG(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - } - - /*Get the size of the text*/ - size_t len = strlen(text) + 1; - - /*Allocate space for the new text*/ - value_str_p = lv_mem_alloc(len); - LV_ASSERT_MEM(value_str_p); - if(value_str_p != NULL) strcpy((char*)value_str_p, text); - lv_obj_set_style_local_value_str(obj, part, state, (char*)value_str_p); - } - - // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); -} - void my_btnmatrix_map_clear(lv_obj_t* obj) { lv_btnmatrix_ext_t* ext = (lv_btnmatrix_ext_t*)lv_obj_get_ext_attr(obj); @@ -349,76 +42,6 @@ void my_msgbox_map_clear(lv_obj_t* obj) if(ext && ext->btnm) my_btnmatrix_map_clear(ext->btnm); // Clear the button map if it exists yet } -/* -static void my_btnmatrix_map_create(lv_obj_t* obj, const char* payload) -{ - // const char** map_p = lv_btnmatrix_get_map_array(obj); - - // Create new map - // Reserve memory for JsonDocument - size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 256; - DynamicJsonDocument map_doc(maxsize); - DeserializationError jsonError = deserializeJson(map_doc, payload); - - if(jsonError) { // Couldn't parse incoming JSON payload - dispatch_json_error(TAG_ATTR, jsonError); - return; - } - - JsonArray arr = map_doc.as(); // Parse payload - - size_t tot_len = sizeof(char*) * (arr.size() + 1); - const char** map_data_str = (const char**)lv_mem_alloc(tot_len); - if(map_data_str == NULL) { - LOG_ERROR(TAG_ATTR, F("Out of memory while creating button map")); - return; - } - memset(map_data_str, 0, tot_len); - - // Create buffer - tot_len = 0; - for(JsonVariant btn : arr) { - // tot_len += btn.as().length() + 1; - tot_len += strlen(btn.as()) + 1; - } - tot_len++; // trailing '\0' - LOG_VERBOSE(TAG_ATTR, F("Array Size = %d, Map Length = %d"), arr.size(), tot_len); - - char* buffer_addr = (char*)lv_mem_alloc(tot_len); - if(buffer_addr == NULL) { - lv_mem_free(map_data_str); - LOG_ERROR(TAG_ATTR, F("Out of memory while creating button map")); - return; - } - memset(buffer_addr, 0, tot_len); // Important, last index needs to be 0 => empty string "" - - // Point of no return, destroy & free the previous map / - LOG_VERBOSE(TAG_ATTR, F("%s %d map addr: %x"), __FILE__, __LINE__, map_data_str); - my_btnmatrix_map_clear(obj); // Free previous map - - // Fill buffer - size_t index = 0; - size_t pos = 0; - LOG_VERBOSE(TAG_ATTR, F("%s %d lbl addr: %x"), __FILE__, __LINE__, buffer_addr); - for(JsonVariant btn : arr) { - // size_t len = btn.as().length() + 1; - size_t len = strlen(btn.as()) + 1; - LOG_VERBOSE(TAG_ATTR, F(D_BULLET "Adding button: %s (%d bytes) %x"), btn.as(), len, - buffer_addr + pos); - // LOG_VERBOSE(TAG_ATTR, F(D_BULLET "Adding button: %s (%d bytes) %x"), btn.as().c_str(), len, - // buffer_addr + pos); - memccpy(buffer_addr + pos, btn.as(), 0, len); // Copy the label text into the buffer - // memccpy(buffer_addr + pos, btn.as().c_str(), 0, len); // Copy the label text into the buffer - map_data_str[index++] = buffer_addr + pos; // save pointer to the label in the array - pos += len; - } - map_data_str[index] = buffer_addr + pos; // save pointer to the last \0 byte - - LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); - lv_btnmatrix_set_map(obj, map_data_str); - LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); -}*/ - // Create new btnmatrix button map from json array const char** my_map_create(const char* payload) { @@ -559,16 +182,6 @@ static void line_set_points(lv_obj_t* obj, const char* payload) // TO DO : free & destroy previous pointlist! } -// OK -static inline lv_color_t haspLogColor(lv_color_t color) -{ - // uint8_t r = (LV_COLOR_GET_R(color) * 263 + 7) >> 5; - // uint8_t g = (LV_COLOR_GET_G(color) * 259 + 3) >> 6; - // uint8_t b = (LV_COLOR_GET_B(color) * 263 + 7) >> 5; - // LOG_VERBOSE(TAG_ATTR,F("Color: R%u G%u B%u"), r, g, b); - return color; -} - static lv_font_t* haspPayloadToFont(const char* payload) { uint8_t var = atoi(payload); @@ -613,26 +226,6 @@ static lv_font_t* haspPayloadToFont(const char* payload) } } -static void gauge_format_10(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) -{ - snprintf(buf, bufsize, PSTR("%d"), value / 10); -} - -static void gauge_format_100(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) -{ - snprintf(buf, bufsize, PSTR("%d"), value / 100); -} - -static void gauge_format_1k(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) -{ - snprintf(buf, bufsize, PSTR("%d"), value / 1000); -} - -static void gauge_format_10k(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) -{ - snprintf(buf, bufsize, PSTR("%d"), value / 10000); -} - static void hasp_process_label_long_mode(lv_obj_t* obj, const char* payload, bool update) { if(update) { @@ -660,93 +253,6 @@ static void hasp_process_label_long_mode(lv_obj_t* obj, const char* payload, boo } } -// OK -lv_obj_t* FindButtonLabel(lv_obj_t* btn) -{ - if(btn) { - lv_obj_t* label = lv_obj_get_child_back(btn, NULL); - if(label) { - if(obj_check_type(label, LV_HASP_LABEL)) { - return label; - } - - } else { - LOG_ERROR(TAG_ATTR, F("FindButtonLabel NULL Pointer encountered")); - } - } else { - LOG_WARNING(TAG_ATTR, F("Button not defined")); - } - return NULL; -} - -// OK -static inline void my_btn_set_text(lv_obj_t* obj, const char* value) -{ - lv_obj_t* label = FindButtonLabel(obj); - if(label) { - lv_label_set_text(label, value); - } -} - -// OK - lvgl does not return a const char * -static const char* my_label_get_text(const lv_obj_t* label) -{ - return lv_label_get_text(label); // library does not return const -} - -static void my_label_set_text(lv_obj_t* label, const char* text) -{ - if(text[0] == '%') { - uint16_t hash = Parser::get_sdbm(text); - size_t len = strlen(text); - const char* static_text; - - switch(hash) { - - case 10125: - static_text = haspDevice.get_hostname(); - break; - default: - lv_label_set_text(label, text); - return; - } - - lv_label_set_text_static(label, static_text); - } else { - lv_label_set_text(label, text); - } -} - -// OK -static const char* my_btn_get_text(const lv_obj_t* obj) -{ - if(!obj) { - LOG_WARNING(TAG_ATTR, F("Button not defined")); - return NULL; - } - - lv_obj_t* label = lv_obj_get_child_back(obj, NULL); - if(label) { -#if 1 - if(obj_check_type(label, LV_HASP_LABEL)) return lv_label_get_text(label); - -#else - lv_obj_type_t list; - lv_obj_get_type(label, &list); - - if(obj_check_type(list.type[0], LV_HASP_LABEL)) { - text = lv_label_get_text(label); - return true; - } -#endif - - } else { - LOG_WARNING(TAG_ATTR, F("my_btn_get_text NULL Pointer encountered")); - } - - return NULL; -} - static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, char* attr_out, uint8_t& part, uint8_t& state) { @@ -847,80 +353,12 @@ static void hasp_attribute_get_part_state(lv_obj_t* obj, const char* attr_in, ch return; } - // if(obj_check_type(obj, LV_HASP_LMETER)) { + // if(obj_check_type(obj, LV_HASP_LINEMETER)) { // state = LV_STATE_DEFAULT; // return; // } } -void my_tabview_set_text(lv_obj_t* obj, const char* payload) -{ - uint16_t id = lv_tabview_get_tab_act(obj); - - if(id < lv_tabview_get_tab_count(obj)) { - lv_tabview_set_tab_name(obj, id, (char*)payload); - } -} - -const char* my_tabview_get_text(const lv_obj_t* obj) -{ - uint16_t id = lv_tabview_get_tab_act(obj); - - if(id < lv_tabview_get_tab_count(obj)) { - return my_tabview_get_tab_name(obj, id); - } else { - return NULL; - } -} - -void my_tab_set_text(lv_obj_t* obj, const char* payload) -{ - lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up - if(!content) return LOG_WARNING(TAG_ATTR, F("content not found")); - - lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up - if(!tabview) return LOG_WARNING(TAG_ATTR, F("Tabview not found")); - - if(!obj_check_type(tabview, LV_HASP_TABVIEW)) - return LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); - - for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { - if(obj == lv_tabview_get_tab(tabview, id)) { - lv_tabview_set_tab_name(tabview, id, (char*)payload); - return; - } - } - LOG_WARNING(TAG_ATTR, F("Tab not found")); -} - -const char* my_tab_get_text(const lv_obj_t* obj) -{ - lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up - if(!content) { - LOG_WARNING(TAG_ATTR, F("content not found")); - return NULL; - } - - lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up - if(!tabview) { - LOG_WARNING(TAG_ATTR, F("Tabview not found")); - return NULL; - } - - if(!obj_check_type(tabview, LV_HASP_TABVIEW)) { - LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); - return NULL; - } - - for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { - if(obj == lv_tabview_get_tab(tabview, id)) { - return my_tabview_get_tab_name(tabview, id); - } - } - LOG_WARNING(TAG_ATTR, F("Tab not found")); - return NULL; -} - /** * Change or Retrieve the value of a local attribute of an object PART * @param obj lv_obj_t*: the object to get/set the attribute @@ -1302,96 +740,87 @@ static void hasp_local_style_attr(lv_obj_t* obj, const char* attr_p, uint16_t at result = false; } -static bool hasp_process_arc_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, - bool update) +static hasp_attribute_type_t hasp_process_arc_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { - uint16_t val = atoi(payload); - // We already know it's a arc object switch(attr_hash) { case ATTR_TYPE: - (update) ? lv_arc_set_type(obj, val % 3) : attr_out_int(obj, attr, lv_arc_get_type(obj)); - return true; + if(update) + lv_arc_set_type(obj, val % 3); + else + val = lv_arc_get_type(obj); + break; + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; } - return false; + return hasp_attribute_type_t::ATTR_TYPE_INT; } -static bool hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, - bool update) +static hasp_attribute_type_t hasp_process_lmeter_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { - uint16_t val = atoi(payload); - // We already know it's a linemeter object uint16_t line_count = lv_linemeter_get_line_count(obj); uint16_t angle = lv_linemeter_get_scale_angle(obj); switch(attr_hash) { case ATTR_TYPE: - (update) ? lv_linemeter_set_mirror(obj, val != 0) : attr_out_int(obj, attr, lv_linemeter_get_mirror(obj)); - return true; - - case ATTR_ROTATION: - (update) ? lv_linemeter_set_angle_offset(obj, val) - : attr_out_int(obj, attr, lv_linemeter_get_angle_offset(obj)); - return true; + if(update) + lv_linemeter_set_mirror(obj, !!val); + else + val = lv_linemeter_get_mirror(obj); + break; case ATTR_LINE_COUNT: - (update) ? lv_linemeter_set_scale(obj, angle, val) : attr_out_int(obj, attr, line_count); - return true; + if(update) + lv_linemeter_set_scale(obj, angle, val); + else + val = line_count; + break; case ATTR_ANGLE: - (update) ? lv_linemeter_set_scale(obj, val, line_count) : attr_out_int(obj, attr, angle); - return true; + if(update) + lv_linemeter_set_scale(obj, val, line_count); + else + val = angle; + break; + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; } - return false; + return hasp_attribute_type_t::ATTR_TYPE_INT; } -static bool hasp_process_dropdown_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, - bool update) +static hasp_attribute_type_t special_attribute_direction(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { - int16_t intval = atoi(payload); - uint16_t val = atoi(payload); + switch(obj_get_type(obj)) { - // We already know it's a gauge object - switch(attr_hash) { - case ATTR_DIRECTION: - (update) ? lv_dropdown_set_dir(obj, intval) : attr_out_int(obj, attr, lv_dropdown_get_dir(obj)); - return true; + case LV_HASP_DROPDOWN: + if(update) + lv_dropdown_set_dir(obj, (lv_dropdown_dir_t)val); + else + val = lv_dropdown_get_dir(obj); + break; - case ATTR_SYMBOL: - (update) ? lv_dropdown_set_symbol(obj, payload) : attr_out_str(obj, attr, lv_dropdown_get_symbol(obj)); - return true; + case LV_HASP_SPINNER: + if(update) + lv_spinner_set_dir(obj, (lv_spinner_dir_t)val); + else + val = lv_spinner_get_dir(obj); + break; - case ATTR_OPEN: - lv_dropdown_open(obj); - return true; - - case ATTR_CLOSE: - lv_dropdown_close(obj); - return true; - - case ATTR_MAX_HEIGHT: - (update) ? lv_dropdown_set_max_height(obj, intval) - : attr_out_int(obj, attr, lv_dropdown_get_max_height(obj)); - return true; - - case ATTR_SHOW_SELECTED: - (update) ? lv_dropdown_set_show_selected(obj, val) - : attr_out_int(obj, attr, lv_dropdown_get_show_selected(obj)); - return true; + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; } - return false; + return hasp_attribute_type_t::ATTR_TYPE_INT; } -static bool hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr, uint16_t attr_hash, const char* payload, - bool update) +static hasp_attribute_type_t hasp_process_gauge_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { // We already know it's a gauge object - int16_t intval = atoi(payload); - uint16_t val = atoi(payload); uint8_t label_count = lv_gauge_get_label_count(obj); uint16_t line_count = lv_gauge_get_line_count(obj); @@ -1399,25 +828,32 @@ static bool hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr, uint16 switch(attr_hash) { case ATTR_CRITICAL_VALUE: - (update) ? lv_gauge_set_critical_value(obj, intval) - : attr_out_int(obj, attr, lv_gauge_get_critical_value(obj)); - return true; // found + if(update) + lv_gauge_set_critical_value(obj, val); + else + val = lv_gauge_get_critical_value(obj); + break; case ATTR_ANGLE: - (update) ? lv_gauge_set_scale(obj, val, line_count, label_count) : attr_out_int(obj, attr, angle); - return true; // found + if(update) + lv_gauge_set_scale(obj, val, line_count, label_count); + else + val = angle; + break; case ATTR_LINE_COUNT: - (update) ? lv_gauge_set_scale(obj, angle, val, label_count) : attr_out_int(obj, attr, line_count); - return true; // found + if(update) + lv_gauge_set_scale(obj, angle, val, label_count); + else + val = line_count; + break; case ATTR_LABEL_COUNT: - (update) ? lv_gauge_set_scale(obj, angle, line_count, val) : attr_out_int(obj, attr, label_count); - return true; // found - - case ATTR_ROTATION: - (update) ? lv_gauge_set_angle_offset(obj, val) : attr_out_int(obj, attr, lv_gauge_get_angle_offset(obj)); - return true; // found + if(update) + lv_gauge_set_scale(obj, angle, line_count, val); + else + val = label_count; + break; case ATTR_FORMAT: if(update) { @@ -1439,36 +875,52 @@ static bool hasp_process_gauge_attribute(lv_obj_t* obj, const char* attr, uint16 lv_gauge_set_formatter_cb(obj, NULL); } } - return true; // found + break; + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; } - return false; + return hasp_attribute_type_t::ATTR_TYPE_INT; } // ##################### Common Attributes ######################################################## -static bool hasp_process_page_attributes(lv_obj_t* obj, const char* attr_p, uint16_t attr_hash, uint8_t val, - bool update) +static hasp_attribute_type_t specific_page_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { + if(!obj_check_type(obj, LV_HASP_PAGE)) return hasp_attribute_type_t::ATTR_NOT_FOUND; + uint8_t pageid; if(haspPages.get_id(obj, &pageid)) { switch(attr_hash) { case ATTR_NEXT: - update ? haspPages.set_next(pageid, val) : attr_out_int(obj, attr_p, haspPages.get_next(pageid)); - return true; + if(update) + haspPages.set_next(pageid, (uint8_t)val); + else + val = haspPages.get_next(pageid); + break; case ATTR_PREV: - update ? haspPages.set_prev(pageid, val) : attr_out_int(obj, attr_p, haspPages.get_prev(pageid)); - return true; + if(update) + haspPages.set_prev(pageid, (uint8_t)val); + else + val = haspPages.get_prev(pageid); + break; + + case ATTR_BACK: + if(update) + haspPages.set_back(pageid, (uint8_t)val); + else + val = haspPages.get_back(pageid); + break; - // case ATTR_BACK: default: - update ? haspPages.set_back(pageid, val) : attr_out_int(obj, attr_p, haspPages.get_back(pageid)); - return true; + return hasp_attribute_type_t::ATTR_NOT_FOUND; } } - return false; + + return hasp_attribute_type_t::ATTR_TYPE_INT; } template @@ -1490,11 +942,105 @@ static inline bool do_attribute(T& list, lv_obj_t* obj, uint16_t attr_hash, int3 return false; } -static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, const char* payload, bool update) +static hasp_attribute_type_t special_attribute_src(lv_obj_t* obj, const char* payload, char** text, bool update) +{ + if(!obj_check_type(obj, LV_HASP_IMAGE)) return ATTR_NOT_FOUND; + + if(update) { + lv_img_cache_invalidate_src(lv_img_get_src(obj)); + lv_img_set_src(obj, payload); + } else { + switch(lv_img_src_get_type(obj)) { + case LV_IMG_SRC_FILE: + *text = (char*)lv_img_get_file_name(obj); + case LV_IMG_SRC_SYMBOL: + *text = (char*)lv_img_get_src(obj); + } + } + return ATTR_TYPE_STR; +} + +static hasp_attribute_type_t attribute_common_align(lv_obj_t* obj, const char* attr, const char* payload, char** text, + bool update) +{ + lv_label_align_t val; + + if(update) { + if(!strcasecmp_P(payload, PSTR("left"))) { + val = LV_LABEL_ALIGN_LEFT; + } else if(!strcasecmp_P(payload, PSTR("right"))) { + val = LV_LABEL_ALIGN_RIGHT; + } else if(!strcasecmp_P(payload, PSTR("center"))) { + val = LV_LABEL_ALIGN_CENTER; + } else if(!strcasecmp_P(payload, PSTR("auto"))) { + val = LV_LABEL_ALIGN_AUTO; + } else { + return ATTR_TYPE_ALIGN_INVALID; + } + } + + switch(obj_get_type(obj)) { + case LV_HASP_BUTTON: { + lv_obj_t* label = FindButtonLabel(obj); + if(label) { + if(update) + lv_label_set_align(label, val); + else + val = lv_label_get_align(label); + } else { + return ATTR_NOT_FOUND; // not found + } + break; + } + case LV_HASP_BTNMATRIX: + if(update) + lv_btnmatrix_set_align(obj, val); + else + val = lv_btnmatrix_get_align(obj); + break; + + case LV_HASP_LABEL: + if(update) + lv_label_set_align(obj, val); + else + val = lv_label_get_align(obj); + break; + + case LV_HASP_ROLLER: + if(update) + lv_roller_set_align(obj, val); + else + val = lv_roller_get_align(obj); + break; + + default: + return ATTR_NOT_FOUND; // not found + } + + // return values + switch(val) { + case LV_LABEL_ALIGN_AUTO: + strcpy_P(*text, PSTR("auto")); + break; + case LV_LABEL_ALIGN_CENTER: + strcpy_P(*text, PSTR("center")); + break; + case LV_LABEL_ALIGN_RIGHT: + strcpy_P(*text, PSTR("right")); + break; + default: + strcpy_P(*text, PSTR("left")); + } + + return ATTR_TYPE_STR; +} + +static hasp_attribute_type_t attribute_common_text(lv_obj_t* obj, const char* attr, const char* payload, char** text, + bool update) { uint8_t obj_type = obj_get_type(obj); - hasp_attr_update_char_const_t text[] = { + hasp_attr_update_char_const_t list[] = { {LV_HASP_BUTTON, ATTR_TEXT, my_btn_set_text, my_btn_get_text}, {LV_HASP_LABEL, ATTR_TEXT, my_label_set_text, my_label_get_text}, {LV_HASP_CHECKBOX, ATTR_TEXT, lv_checkbox_set_text, lv_checkbox_get_text}, @@ -1506,14 +1052,14 @@ static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con {LV_HASP_MSGBOX, ATTR_TEXT, lv_msgbox_set_text, lv_msgbox_get_text} }; - for(int i = 0; i < sizeof(text) / sizeof(text[0]); i++) { - if(obj_type == text[i].obj_type) { - if(update) { - text[i].set(obj, payload); - } else { - attr_out_str(obj, attr, text[i].get(obj)); - } - return true; + for(int i = 0; i < sizeof(list) / sizeof(list[0]); i++) { + if(obj_type == list[i].obj_type) { + if(update) + list[i].set(obj, payload); + else + *text = (char*)list[i].get(obj); + + return hasp_attribute_type_t::ATTR_TYPE_STR; } } @@ -1522,39 +1068,60 @@ static bool hasp_process_obj_attribute_text(lv_obj_t* obj, const char* attr, con // {LV_HASP_ROLLER, set_text_not_implemented, my_roller_get_text}, switch(obj_get_type(obj)) { case LV_HASP_DROPDOWN: { - char buffer[128]; - lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); - attr_out_str(obj, attr, buffer); - return true; - } - case LV_HASP_ROLLER: { - char buffer[128]; - lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); - attr_out_str(obj, attr, buffer); - return true; - } - default: + lv_dropdown_get_selected_str(obj, *text, 128); + if(update) return hasp_attribute_type_t::ATTR_TYPE_STR_READONLY; break; + } + + case LV_HASP_ROLLER: { + lv_roller_get_selected_str(obj, *text, 128); + if(update) return hasp_attribute_type_t::ATTR_TYPE_STR_READONLY; + break; + } + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; } - return false; + + return hasp_attribute_type_t::ATTR_TYPE_STR; } -static bool generic_bool_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) +static hasp_attribute_type_t specific_bool_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { { // bool hasp_attr_update_bool_const_t list[] = { {LV_HASP_ARC, ATTR_ADJUSTABLE, my_arc_set_adjustable, my_arc_get_adjustable}, {LV_HASP_BTNMATRIX, ATTR_ONE_CHECK, lv_btnmatrix_set_one_check, lv_btnmatrix_get_one_check}, {LV_HASP_IMAGE, ATTR_AUTO_SIZE, lv_img_set_auto_size, lv_img_get_auto_size}}; - if(do_attribute(list, obj, attr_hash, val, update)) return true; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_BOOL; } - return false; + + { // bool + hasp_attr_update_bool_t list[] = { + {LV_HASP_DROPDOWN, ATTR_SHOW_SELECTED, lv_dropdown_set_show_selected, lv_dropdown_get_show_selected}}; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_BOOL; + } + + return ATTR_NOT_FOUND; } -static bool generic_int_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) +static hasp_attribute_type_t specific_coord_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) { - { // unint16_t - hasp_attr_update16_const_t list[] = { + { // lv_coord_t + hasp_attr_update_lv_coord_t list[] = { + {LV_HASP_IMAGE, ATTR_OFFSET_X, lv_img_set_offset_x, lv_img_get_offset_x}, + {LV_HASP_IMAGE, ATTR_OFFSET_Y, lv_img_set_offset_y, lv_img_get_offset_y}, + {LV_HASP_DROPDOWN, ATTR_MAX_HEIGHT, lv_dropdown_set_max_height, my_dropdown_get_max_height}}; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_INT; + } + + return ATTR_NOT_FOUND; +} + +static hasp_attribute_type_t specific_int_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) +{ + { // uint16_t + hasp_attr_update_uint16_const_t list[] = { {LV_HASP_MSGBOX, ATTR_AUTO_CLOSE, lv_msgbox_start_auto_close, my_msgbox_stop_auto_close}, {LV_HASP_SPINNER, ATTR_SPEED, lv_spinner_set_spin_time, lv_spinner_get_spin_time}, {LV_HASP_BAR, ATTR_ANIM_TIME, lv_bar_set_anim_time, lv_bar_get_anim_time}, @@ -1566,35 +1133,64 @@ static bool generic_int_attribute(lv_obj_t* obj, uint16_t attr_hash, int32_t& va {LV_HASP_TABVIEW, ATTR_ANIM_TIME, lv_tabview_set_anim_time, lv_tabview_get_anim_time}, {LV_HASP_WINDOW, ATTR_ANIM_TIME, lv_win_set_anim_time, lv_win_get_anim_time}, {LV_HASP_LABEL, ATTR_ANIM_SPEED, lv_label_set_anim_speed, lv_label_get_anim_speed}}; - if(do_attribute(list, obj, attr_hash, val, update)) return true; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_INT; } - { // lv_anim_value_t - hasp_attr_update_lv_anim_value_const_t list[] = { - {LV_HASP_SPINNER, ATTR_ANGLE, lv_spinner_set_arc_length, lv_spinner_get_arc_length}}; - if(do_attribute(list, obj, attr_hash, val, update)) return true; - } - - // {LV_HASP_SPINNER, ATTR_THICKNESS, lv_spinner_set_arc_length, lv_spinner_get_arc_length} - - // { // uint8_t - // hasp_attr_update8_const_t list[] = {{LV_HASP_SPINNER, ATTR_DIRECTION, lv_spinner_set_dir, - // lv_spinner_get_dir}}; if(do_attribute(list, obj, attr_hash, val, update)) return true; - // } - - { // unint16_t, but getter is not const - hasp_attr_update16_t list[] = { + { // uint16_t, but getter is not const + hasp_attr_update_uint16_t list[] = { {LV_HASP_ARC, ATTR_ROTATION, lv_arc_set_rotation, my_arc_get_rotation}, {LV_HASP_ARC, ATTR_START_ANGLE, lv_arc_set_bg_start_angle, lv_arc_get_bg_angle_start}, {LV_HASP_ARC, ATTR_END_ANGLE, lv_arc_set_bg_end_angle, lv_arc_get_bg_angle_end}, {LV_HASP_ARC, ATTR_START_ANGLE1, lv_arc_set_start_angle, lv_arc_get_angle_start}, {LV_HASP_ARC, ATTR_END_ANGLE1, lv_arc_set_end_angle, lv_arc_get_angle_end}, + {LV_HASP_LINEMETER, ATTR_ROTATION, lv_linemeter_set_angle_offset, lv_linemeter_get_angle_offset}, + {LV_HASP_GAUGE, ATTR_ROTATION, lv_gauge_set_angle_offset, lv_gauge_get_angle_offset}, {LV_HASP_SLIDER, ATTR_ANIM_TIME, lv_slider_set_anim_time, lv_slider_get_anim_time}, + {LV_HASP_TABLE, ATTR_COLS, lv_table_set_col_cnt, lv_table_get_col_cnt}, + {LV_HASP_TABLE, ATTR_ROWS, lv_table_set_row_cnt, lv_table_get_row_cnt}, {LV_HASP_TILEVIEW, ATTR_ANIM_TIME, lv_tileview_set_anim_time, lv_tileview_get_anim_time}}; - if(do_attribute(list, obj, attr_hash, val, update)) return true; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_INT; } - return false; + { // lv_anim_value_t + hasp_attr_update_lv_anim_value_const_t list[] = { + {LV_HASP_SPINNER, ATTR_ANGLE, lv_spinner_set_arc_length, lv_spinner_get_arc_length}}; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_INT; + } + + { // int16_t + hasp_attr_update_int16_const_t list[] = { + {LV_HASP_BAR, ATTR_START_VALUE, my_bar_set_start_value, lv_bar_get_start_value}, + {LV_HASP_SLIDER, ATTR_START_VALUE, my_slider_set_left_value, lv_slider_get_left_value}}; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_INT; + } + + { // uint8_t + hasp_attr_update_uint8_const_t list[] = { + {LV_HASP_ROLLER, ATTR_ROWS, lv_roller_set_visible_row_count, my_roller_get_visible_row_count}}; + if(do_attribute(list, obj, attr_hash, val, update)) return ATTR_TYPE_INT; + } + + if(obj_check_type(obj, LV_HASP_TABVIEW)) { + switch(attr_hash) { + case ATTR_COUNT: + val = lv_tabview_get_tab_count(obj); + if(update) + return ATTR_TYPE_INT_READONLY; + else + return ATTR_TYPE_INT; + + case ATTR_BTN_POS: + if(update) { + lv_tabview_set_btns_pos(obj, val); + } else { + val = lv_tabview_get_btns_pos(obj); + } + return ATTR_TYPE_INT; + } + } + + return ATTR_NOT_FOUND; } static bool my_obj_get_range(lv_obj_t* obj, int32_t& min, int32_t& max) @@ -1617,7 +1213,7 @@ static bool my_obj_get_range(lv_obj_t* obj, int32_t& min, int32_t& max) max = 255; break; - case LV_HASP_LMETER: + case LV_HASP_LINEMETER: min = lv_linemeter_get_min_value(obj); max = lv_linemeter_get_max_value(obj); break; @@ -1663,16 +1259,87 @@ static bool my_obj_get_range(lv_obj_t* obj, int32_t& min, int32_t& max) return true; } +static hasp_attribute_type_t attribute_common_val(lv_obj_t* obj, int32_t& val, bool update) +{ + if(obj_check_type(obj, LV_HASP_BUTTON)) { + if(lv_btn_get_checkable(obj)) { + if(update) { + if(val) + lv_obj_add_state(obj, LV_STATE_CHECKED); + else + lv_obj_clear_state(obj, LV_STATE_CHECKED); + } else { + val = lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_CHECKED; + } + } else { + return hasp_attribute_type_t::ATTR_NOT_FOUND; // not checkable + } + } else if(obj_check_type(obj, LV_HASP_CHECKBOX)) { + if(update) + lv_checkbox_set_checked(obj, !!val); + else + val = lv_checkbox_is_checked(obj); + } else if(obj_check_type(obj, LV_HASP_SWITCH)) { + if(update) + !val ? lv_switch_off(obj, LV_ANIM_ON) : lv_switch_on(obj, LV_ANIM_ON); + else + val = lv_switch_get_state(obj); + } else if(obj_check_type(obj, LV_HASP_DROPDOWN)) { + lv_dropdown_set_selected(obj, (uint16_t)val); + } else if(obj_check_type(obj, LV_HASP_LINEMETER)) { + if(update) + lv_linemeter_set_value(obj, val); + else + val = lv_linemeter_get_value(obj); + } else if(obj_check_type(obj, LV_HASP_SLIDER)) { + if(update) + lv_slider_set_value(obj, val, LV_ANIM_ON); + else + val = lv_slider_get_value(obj); + } else if(obj_check_type(obj, LV_HASP_LED)) { + if(update) + lv_led_set_bright(obj, (uint8_t)val); + else + val = lv_led_get_bright(obj); + } else if(obj_check_type(obj, LV_HASP_ARC)) { + if(update) + lv_arc_set_value(obj, val); + else + val = lv_arc_get_value(obj); + } else if(obj_check_type(obj, LV_HASP_GAUGE)) { + if(update) + lv_gauge_set_value(obj, 0, val); + else + val = lv_gauge_get_value(obj, 0); + } else if(obj_check_type(obj, LV_HASP_ROLLER)) { + lv_roller_set_selected(obj, (uint16_t)val, LV_ANIM_ON); + } else if(obj_check_type(obj, LV_HASP_BAR)) { + if(update) + lv_bar_set_value(obj, val, LV_ANIM_ON); + else + val = lv_bar_get_value(obj); + } else if(obj_check_type(obj, LV_HASP_TABVIEW)) { + if(update) + lv_tabview_set_tab_act(obj, val, LV_ANIM_ON); + else + val = lv_tabview_get_tab_act(obj); + } else { + return hasp_attribute_type_t::ATTR_NOT_FOUND; // not found + } + + return hasp_attribute_type_t::ATTR_TYPE_INT; // found +} + bool attribute_set_normalized_value(lv_obj_t* obj, hasp_update_value_t& value) { if(value.min == value.max) return false; // would cause divide by zero error + int32_t val; int32_t min; int32_t max; if(!my_obj_get_range(obj, min, max)) return false; // range could not be determined // Limit the value between min and max, adjust if power = 0 - int16_t val; if(value.power == 0 || value.val <= value.min) { val = value.min; } else if(value.val >= value.max) { @@ -1687,110 +1354,317 @@ bool attribute_set_normalized_value(lv_obj_t* obj, hasp_update_value_t& value) val = map(val, value.min, value.max, min, max); } - hasp_process_obj_attribute_val(obj, NULL, val, !!val, true); + attribute_common_val(obj, val, true); return true; } -bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool boolval, bool update) +static hasp_attribute_type_t attribute_common_range(lv_obj_t* obj, int32_t& val, bool update, bool set_min, + bool set_max) { - if(obj_check_type(obj, LV_HASP_BUTTON)) { - if(lv_btn_get_checkable(obj)) { - if(update) { - if(intval) - lv_obj_add_state(obj, LV_STATE_CHECKED); - else - lv_obj_clear_state(obj, LV_STATE_CHECKED); - } else { - attr_out_int(obj, attr, lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_CHECKED); - } - } else { - return false; // not checkable - } - } else if(obj_check_type(obj, LV_HASP_CHECKBOX)) { - update ? lv_checkbox_set_checked(obj, boolval) : attr_out_int(obj, attr, lv_checkbox_is_checked(obj)); - } else if(obj_check_type(obj, LV_HASP_SWITCH)) { - if(update) - boolval ? lv_switch_on(obj, LV_ANIM_ON) : lv_switch_off(obj, LV_ANIM_ON); - else - attr_out_int(obj, attr, lv_switch_get_state(obj)); - } else if(obj_check_type(obj, LV_HASP_DROPDOWN)) { - lv_dropdown_set_selected(obj, (uint16_t)intval); - } else if(obj_check_type(obj, LV_HASP_LMETER)) { - update ? lv_linemeter_set_value(obj, intval) : attr_out_int(obj, attr, lv_linemeter_get_value(obj)); - } else if(obj_check_type(obj, LV_HASP_SLIDER)) { - update ? lv_slider_set_value(obj, intval, LV_ANIM_ON) : attr_out_int(obj, attr, lv_slider_get_value(obj)); - } else if(obj_check_type(obj, LV_HASP_LED)) { - update ? lv_led_set_bright(obj, (uint8_t)intval) : attr_out_int(obj, attr, lv_led_get_bright(obj)); - } else if(obj_check_type(obj, LV_HASP_ARC)) { - update ? lv_arc_set_value(obj, intval) : attr_out_int(obj, attr, lv_arc_get_value(obj)); - } else if(obj_check_type(obj, LV_HASP_GAUGE)) { - update ? lv_gauge_set_value(obj, 0, intval) : attr_out_int(obj, attr, lv_gauge_get_value(obj, 0)); - } else if(obj_check_type(obj, LV_HASP_ROLLER)) { - lv_roller_set_selected(obj, (uint16_t)intval, LV_ANIM_ON); - } else if(obj_check_type(obj, LV_HASP_BAR)) { - update ? lv_bar_set_value(obj, intval, LV_ANIM_ON) : attr_out_int(obj, attr, lv_bar_get_value(obj)); - } else if(obj_check_type(obj, LV_HASP_TABVIEW)) { - update ? lv_tabview_set_tab_act(obj, intval, LV_ANIM_ON) : attr_out_int(obj, attr, lv_tabview_get_tab_act(obj)); - } else { - return false; - } - - return true; -} - -static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, const char* payload, bool update, - bool set_min, bool set_max) -{ - int16_t val = atoi(payload); - int32_t val32 = strtol(payload, nullptr, DEC); - int32_t min; int32_t max; - if(!my_obj_get_range(obj, min, max)) return false; + if(!my_obj_get_range(obj, min, max)) return hasp_attribute_type_t::ATTR_RANGE_ERROR; - if(obj_check_type(obj, LV_HASP_SLIDER)) { - if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max - update ? lv_slider_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); - return true; + switch(obj_get_type(obj)) { + case LV_HASP_SLIDER: + if(update && (set_min ? val : min) == (set_max ? val : max)) + return hasp_attribute_type_t::ATTR_RANGE_ERROR; // prevent setting min=max + if(update) + lv_slider_set_range(obj, set_min ? val : min, set_max ? val : max); + else + val = set_min ? min : max; + break; + + case LV_HASP_GAUGE: + if(update && (set_min ? val : min) == (set_max ? val : max)) + return hasp_attribute_type_t::ATTR_RANGE_ERROR; // prevent setting min=max + if(update) + lv_gauge_set_range(obj, set_min ? val : min, set_max ? val : max); + else + val = set_min ? min : max; + break; + + case LV_HASP_ARC: + if(update && (set_min ? val : min) == (set_max ? val : max)) + return hasp_attribute_type_t::ATTR_RANGE_ERROR; // prevent setting min=max + if(update) + lv_arc_set_range(obj, set_min ? val : min, set_max ? val : max); + else + val = set_min ? min : max; + break; + + case LV_HASP_BAR: + if(update && (set_min ? val : min) == (set_max ? val : max)) + return hasp_attribute_type_t::ATTR_RANGE_ERROR; // prevent setting min=max + if(update) + lv_bar_set_range(obj, set_min ? val : min, set_max ? val : max); + else + val = set_min ? min : max; + break; + + case LV_HASP_LINEMETER: + if(update && (set_min ? val : min) == (set_max ? val : max)) + return hasp_attribute_type_t::ATTR_RANGE_ERROR; // prevent setting min=max + if(update) + lv_linemeter_set_range(obj, set_min ? val : min, set_max ? val : max); + else + val = set_min ? min : max; + break; + + case LV_HASP_CHART: + if(update && (set_min ? val : min) == (set_max ? val : max)) + return hasp_attribute_type_t::ATTR_RANGE_ERROR; // prevent setting min=max + if(update) + lv_chart_set_range(obj, set_min ? val : min, set_max ? val : max); + else + val = set_min ? min : max; + break; + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; } - if(obj_check_type(obj, LV_HASP_GAUGE)) { - if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max - update ? lv_gauge_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) - : attr_out_int(obj, attr, set_min ? min : max); - return true; + return hasp_attribute_type_t::ATTR_TYPE_INT; +} + +// ##################### Default Attributes ######################################################## + +/** + * Execute the method of an object + * @param obj lv_obj_t*: the object to get/set the attribute + * @param attr_hash uint16_t: the hashed attribute value + * @param attr char*: the attribute name (without leading ".") + * @param payload char*: the parameters for the method + * @note setting a value won't return anything, getting will dispatch the value + */ +static hasp_attribute_type_t attribute_common_method(lv_obj_t* obj, uint16_t attr_hash, const char* attr, + const char* payload) +{ + switch(attr_hash) { + case ATTR_DELETE: + if(!lv_obj_get_parent(obj)) return hasp_attribute_type_t::ATTR_TYPE_METHOD_INVALID_FOR_PAGE; + lv_obj_del_async(obj); + break; + + case ATTR_CLEAR: + lv_obj_clean(obj); + break; + + case ATTR_TO_FRONT: + if(!lv_obj_get_parent(obj)) return hasp_attribute_type_t::ATTR_TYPE_METHOD_INVALID_FOR_PAGE; + lv_obj_move_foreground(obj); + break; + + case ATTR_TO_BACK: + if(!lv_obj_get_parent(obj)) return hasp_attribute_type_t::ATTR_TYPE_METHOD_INVALID_FOR_PAGE; + lv_obj_move_background(obj); + break; + + case ATTR_OPEN: + case ATTR_CLOSE: + if(!obj_check_type(obj, LV_HASP_DROPDOWN)) return hasp_attribute_type_t::ATTR_NOT_FOUND; + if(attr_hash == ATTR_OPEN) + lv_dropdown_open(obj); + else + lv_dropdown_open(obj); + break; + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; // attribute_not found } - if(obj_check_type(obj, LV_HASP_ARC)) { - if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max - update ? lv_arc_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); - return true; + return hasp_attribute_type_t::ATTR_TYPE_METHOD_OK; +} + +/** + * Change or Retrieve the value of the attribute of an object + * @param obj lv_obj_t*: the object to get/set the attribute + * @param attr_hash uint16_t: the hashed attribute to get/set + * @param val uint32_t: the new value of the attribute + * @param update bool: change/set the value if true, dispatch/get value if false + * @note setting a value won't return anything, getting will dispatch the value + */ +static hasp_attribute_type_t attribute_common_int(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) +{ + switch(attr_hash) { + case ATTR_ID: + if(update) + obj->user_data.id = (uint8_t)val; + else + val = obj->user_data.id; + break; // attribute_found + + case ATTR_GROUPID: + if(update) + obj->user_data.groupid = (uint8_t)val; + else + val = obj->user_data.groupid; + break; // attribute_found + + case ATTR_TRANSITION: + if(update) + obj->user_data.transitionid = (uint8_t)val; + else + val = obj->user_data.transitionid; + break; // attribute_found + + case ATTR_OBJID: + val = obj->user_data.objid; + if(update && val != obj->user_data.objid) hasp_attribute_type_t::ATTR_TYPE_INT_READONLY; + break; // attribute_found + + case ATTR_X: + if(update) + lv_obj_set_x(obj, val); + else + val = lv_obj_get_x(obj); + break; // attribute_found + + case ATTR_Y: + if(update) + lv_obj_set_y(obj, val); + else + val = lv_obj_get_y(obj); + break; // attribute_found + + case ATTR_W: + if(update) { + lv_obj_set_width(obj, val); + if(obj_check_type(obj, LV_HASP_CPICKER)) { +#if LVGL_VERSION_MAJOR == 7 + lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC + : LV_CPICKER_TYPE_RECT); +#endif + } + } else { + val = lv_obj_get_width(obj); + } + break; // attribute_found + + case ATTR_H: + if(update) { + lv_obj_set_height(obj, val); + if(obj_check_type(obj, LV_HASP_CPICKER)) { +#if LVGL_VERSION_MAJOR == 7 + lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC + : LV_CPICKER_TYPE_RECT); +#endif + } + } else { + val = lv_obj_get_height(obj); + } + break; // attribute_found + + case ATTR_OPACITY: + if(update) + lv_obj_set_style_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, val); + else + val = lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN); + break; // attribute_found + + case ATTR_EXT_CLICK_H: + if(update) + lv_obj_set_ext_click_area(obj, val, val, lv_obj_get_ext_click_pad_top(obj), + lv_obj_get_ext_click_pad_bottom(obj)); + else + val = lv_obj_get_ext_click_pad_left(obj); + break; // attribute_found + + case ATTR_EXT_CLICK_V: + if(update) + lv_obj_set_ext_click_area(obj, lv_obj_get_ext_click_pad_left(obj), lv_obj_get_ext_click_pad_right(obj), + val, val); + else + val = lv_obj_get_ext_click_pad_top(obj); + break; // attribute_found + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; // attribute_not found } - if(obj_check_type(obj, LV_HASP_BAR)) { - if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max - update ? lv_bar_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); - return true; + return hasp_attribute_type_t::ATTR_TYPE_INT; +} + +/** + * Change or Retrieve the value of the attribute of an object + * @param obj lv_obj_t*: the object to get/set the attribute + * @param attr_hash uint16_t: the hashed attribute to get/set + * @param val uint32_t: the new value of the attribute + * @param update bool: change/set the value if true, dispatch/get value if false + * @note setting a value won't return anything, getting will dispatch the value + */ +static hasp_attribute_type_t attribute_common_bool(lv_obj_t* obj, uint16_t attr_hash, int32_t& val, bool update) +{ + switch(attr_hash) { + case ATTR_VIS: + if(update) + lv_obj_set_hidden(obj, !val); + else + val = !lv_obj_get_hidden(obj); + break; // attribute_found + + case ATTR_HIDDEN: + if(update) + lv_obj_set_hidden(obj, !!val); + else + val = lv_obj_get_hidden(obj); + break; // attribute_found + + case ATTR_CLICK: + if(update) + lv_obj_set_click(obj, !!val); + else + val = lv_obj_get_click(obj); + break; // attribute_found + + case ATTR_ENABLED: + if(update) + if(!!val) + lv_obj_clear_state(obj, LV_STATE_DISABLED); + else + lv_obj_add_state(obj, LV_STATE_DISABLED); + else + val = !(lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_DISABLED); + break; // attribute_found + + case ATTR_SWIPE: + if(update) + obj->user_data.swipeid = (!!val) % 16; + else + val = obj->user_data.swipeid; + break; // attribute_found + + case ATTR_TOGGLE: + switch(obj_get_type(obj)) { + case LV_HASP_BUTTON: + if(update) { + lv_btn_set_checkable(obj, !!val); + lv_obj_set_event_cb(obj, !!val ? toggle_event_handler : generic_event_handler); + } else { + val = lv_btn_get_checkable(obj); + } + break; // attribute_found + case LV_HASP_BTNMATRIX: + if(update) { + if(val) { + lv_btnmatrix_set_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); + } else { + lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); + lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECK_STATE); + } + } else { + val = lv_btn_get_checkable(obj); + } + break; // attribute_found + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; // attribute_not found + } + + default: + return hasp_attribute_type_t::ATTR_NOT_FOUND; // attribute_not found } - if(obj_check_type(obj, LV_HASP_LMETER)) { - if(update && (set_min ? val32 : min) == (set_max ? val32 : max)) return false; // prevent setting min=max - update ? lv_linemeter_set_range(obj, set_min ? val32 : min, set_max ? val32 : max) - : attr_out_int(obj, attr, set_min ? min : max); - return true; - } - - if(obj_check_type(obj, LV_HASP_CHART)) { - if(update && (set_min ? val : min) == (set_max ? val : max)) return false; // prevent setting min=max - update ? lv_chart_set_range(obj, set_min ? val : min, set_max ? val : max) - : attr_out_int(obj, attr, set_min ? min : max); - return true; - } - - return false; + return hasp_attribute_type_t::ATTR_TYPE_BOOL; } // ##################### Default Attributes ######################################################## @@ -1803,195 +1677,12 @@ static bool hasp_process_obj_attribute_range(lv_obj_t* obj, const char* attr, co * @param update bool: change/set the value if true, dispatch/get value if false * @note setting a value won't return anything, getting will dispatch the value */ -void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update) +void old_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update) { - // unsigned long start = millis(); - if(!obj) { - LOG_WARNING(TAG_ATTR, F(D_OBJECT_UNKNOWN)); - return; - } - - char* attr = (char*)attr_p; - // if(*attr == '.') attr++; // strip leading '.' - - uint16_t attr_hash = Parser::get_sdbm(attr); - int32_t val = atoi(payload); + uint16_t attr_hash; /* 16-bit Hash Lookup Table */ switch(attr_hash) { - case ATTR_ID: - update ? (void)(obj->user_data.id = (uint8_t)val) : attr_out_int(obj, attr, obj->user_data.id); - return; // attribute_found - - case ATTR_GROUPID: - update ? (void)(obj->user_data.groupid = (uint8_t)val) : attr_out_int(obj, attr, obj->user_data.groupid); - return; // attribute_found - - case ATTR_ACTION: - update ? (void)(obj->user_data.actionid = Parser::get_action_id(payload)) - : attr_out_int(obj, attr, obj->user_data.actionid); - return; // attribute_found - - case ATTR_TRANSITION: - update ? (void)(obj->user_data.transitionid = (uint8_t)val) - : attr_out_int(obj, attr, obj->user_data.transitionid); - return; // attribute_found - - case ATTR_OBJ: - if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); - attr_out_str(obj, attr, obj_get_type_name(obj)); - return; // attribute_found - - case ATTR_OBJID: - if(update && val != obj->user_data.objid) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); - attr_out_int(obj, attr, obj->user_data.objid); - return; // attribute_found - - case ATTR_X: - update ? lv_obj_set_x(obj, val) : attr_out_int(obj, attr, lv_obj_get_x(obj)); - return; // attribute_found - - case ATTR_Y: - update ? lv_obj_set_y(obj, val) : attr_out_int(obj, attr, lv_obj_get_y(obj)); - return; // attribute_found - - case ATTR_W: - if(update) { - lv_obj_set_width(obj, val); - if(obj_check_type(obj, LV_HASP_CPICKER)) { -#if LVGL_VERSION_MAJOR == 7 - lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC - : LV_CPICKER_TYPE_RECT); -#endif - } - } else { - attr_out_int(obj, attr, lv_obj_get_width(obj)); - } - return; // attribute_found - - case ATTR_H: - if(update) { - lv_obj_set_height(obj, val); - if(obj_check_type(obj, LV_HASP_CPICKER)) { -#if LVGL_VERSION_MAJOR == 7 - lv_cpicker_set_type(obj, lv_obj_get_width(obj) == lv_obj_get_height(obj) ? LV_CPICKER_TYPE_DISC - : LV_CPICKER_TYPE_RECT); -#endif - } - } else { - attr_out_int(obj, attr, lv_obj_get_height(obj)); - } - return; // attribute_found - - case ATTR_VIS: - update ? lv_obj_set_hidden(obj, !Parser::is_true(payload)) - : attr_out_int(obj, attr, !lv_obj_get_hidden(obj)); - return; // attribute_found - - case ATTR_HIDDEN: - update ? lv_obj_set_hidden(obj, Parser::is_true(payload)) : attr_out_int(obj, attr, lv_obj_get_hidden(obj)); - return; // attribute_found - - case ATTR_TXT: // TODO: remove - LOG_WARNING(TAG_HASP, F("txt property is obsolete, use text instead")); - case ATTR_TEXT: - hasp_process_obj_attribute_text(obj, attr, payload, update); - return; // attribute_found - - case ATTR_VAL: - if(hasp_process_obj_attribute_val(obj, attr, atoi(payload), Parser::is_true(payload), update)) - return; // attribute_found - break; // not found - - case ATTR_MIN: - if(hasp_process_obj_attribute_range(obj, attr, payload, update, true, false)) return; // attribute_found - break; - - case ATTR_MAX: - if(hasp_process_obj_attribute_range(obj, attr, payload, update, false, true)) return; // attribute_found - break; - - case ATTR_OPACITY: - update ? lv_obj_set_style_local_opa_scale(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, val) - : attr_out_int(obj, attr, lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN)); - return; // attribute_found - - case ATTR_CLICK: - update ? lv_obj_set_click(obj, Parser::is_true(payload)) : attr_out_int(obj, attr, lv_obj_get_click(obj)); - return; // attribute_found - - case ATTR_EXT_CLICK_H: - update ? lv_obj_set_ext_click_area(obj, val, val, lv_obj_get_ext_click_pad_top(obj), - lv_obj_get_ext_click_pad_bottom(obj)) - : attr_out_int(obj, attr, lv_obj_get_ext_click_pad_left(obj)); - return; - - case ATTR_EXT_CLICK_V: - update ? lv_obj_set_ext_click_area(obj, lv_obj_get_ext_click_pad_left(obj), - lv_obj_get_ext_click_pad_right(obj), val, val) - : attr_out_int(obj, attr, lv_obj_get_ext_click_pad_top(obj)); - return; - - case ATTR_ENABLED: - if(update) - if(Parser::is_true(payload)) - lv_obj_clear_state(obj, LV_STATE_DISABLED); - else - lv_obj_add_state(obj, LV_STATE_DISABLED); - else - attr_out_int(obj, attr, !(lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_DISABLED)); - break; // attribute_found - - case ATTR_SWIPE: - update ? (void)(obj->user_data.swipeid = Parser::is_true(payload) % 16) - : attr_out_int(obj, attr, obj->user_data.swipeid); - return; // attribute_found - - case ATTR_ROWS: - switch(obj_get_type(obj)) { - case LV_HASP_ROLLER: - update ? lv_roller_set_visible_row_count(obj, (uint8_t)val) - : attr_out_int(obj, attr, my_roller_get_visible_row_count(obj)); - return; // attribute_found - case LV_HASP_TABLE: - update ? lv_table_set_row_cnt(obj, (uint8_t)val) - : attr_out_int(obj, attr, lv_table_get_row_cnt(obj)); - return; // attribute_found - default: - break; // not found - } - break; // not found - - case ATTR_COLS: - if(obj_check_type(obj, LV_HASP_TABLE)) { - update ? lv_table_set_col_cnt(obj, (uint8_t)val) : attr_out_int(obj, attr, lv_table_get_col_cnt(obj)); - return; // attribute_found - } - break; // not found - - case ATTR_ALIGN: - switch(obj_get_type(obj)) { - case LV_HASP_BUTTON: { - lv_obj_t* label = FindButtonLabel(obj); - if(label) { - update ? lv_label_set_align(label, val) : attr_out_int(obj, attr, lv_label_get_align(label)); - return; // attribute_found - } - break; // not found - } - case LV_HASP_BTNMATRIX: - update ? lv_btnmatrix_set_align(obj, val) : attr_out_int(obj, attr, lv_btnmatrix_get_align(obj)); - return; // attribute_found - case LV_HASP_LABEL: - update ? lv_label_set_align(obj, val) : attr_out_int(obj, attr, lv_label_get_align(obj)); - return; // attribute_found - case LV_HASP_ROLLER: - update ? lv_roller_set_align(obj, val) : attr_out_int(obj, attr, lv_roller_get_align(obj)); - return; // attribute_found - default: - break; // not found - } - break; // not found case ATTR_MODE: switch(obj_get_type(obj)) { @@ -2012,36 +1703,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p (lv_roller_mode_t)Parser::is_true(payload)); } else { lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); - attr_out_int(obj, attr, ext->mode); - } - return; // attribute_found - default: - break; // not found - } - break; // not found - - case ATTR_TOGGLE: - switch(obj_get_type(obj)) { - case LV_HASP_BUTTON: - if(update) { - bool toggle = Parser::is_true(payload); - lv_btn_set_checkable(obj, toggle); - lv_obj_set_event_cb(obj, toggle ? toggle_event_handler : generic_event_handler); - } else { - attr_out_int(obj, attr, lv_btn_get_checkable(obj)); - } - return; // attribute_found - case LV_HASP_BTNMATRIX: - if(update) { - bool toggle = Parser::is_true(payload); - if(toggle) { - lv_btnmatrix_set_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); - } else { - lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECKABLE); - lv_btnmatrix_clear_btn_ctrl_all(obj, LV_BTNMATRIX_CTRL_CHECK_STATE); - } - } else { - attr_out_int(obj, attr, lv_btn_get_checkable(obj)); + attr_out_int(obj, attr_p, ext->mode); } return; // attribute_found default: @@ -2055,7 +1717,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p if(update) { lv_dropdown_set_options(obj, payload); } else { - attr_out_str(obj, attr, lv_dropdown_get_options(obj)); + attr_out_str(obj, attr_p, lv_dropdown_get_options(obj)); } return; // attribute_found case LV_HASP_ROLLER: @@ -2063,7 +1725,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p lv_roller_ext_t* ext = (lv_roller_ext_t*)lv_obj_get_ext_attr(obj); lv_roller_set_options(obj, payload, ext->mode); } else { - attr_out_str(obj, attr, lv_roller_get_options(obj)); + attr_out_str(obj, attr_p, lv_roller_get_options(obj)); } return; // attribute_found case LV_HASP_BTNMATRIX: @@ -2085,152 +1747,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p } break; // not found - case ATTR_BTN_POS: - if(obj_check_type(obj, LV_HASP_TABVIEW)) { - if(update) { - lv_tabview_set_btns_pos(obj, val); - } else { - attr_out_int(obj, attr_p, lv_tabview_get_btns_pos(obj)); - } - return; // attribute_found - } - break; // not found - - case ATTR_COUNT: - if(obj_check_type(obj, LV_HASP_TABVIEW)) { - if(update) LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attr_p); - attr_out_int(obj, attr_p, lv_tabview_get_tab_count(obj)); - return; // attribute_found - } - break; // not found - // case ATTR_MODAL: - - case ATTR_RED: // TODO: remove temp RED - if(obj_check_type(obj, LV_HASP_BTNMATRIX)) { - my_btnmatrix_map_clear(obj); // TODO : remove this test property - return; // attribute_found - } - break; // not found - - /* ***** Methods ***** */ - case ATTR_DELETE: - if(!lv_obj_get_parent(obj)) { - LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attr_p); - } else { - lv_obj_del_async(obj); - } - return; // attribute_found - - case ATTR_CLEAR: - lv_obj_clean(obj); - return; // attribute_found - - case ATTR_TO_FRONT: - if(!lv_obj_get_parent(obj)) { - LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attr_p); - } else { - lv_obj_move_foreground(obj); - } - return; // attribute_found - - case ATTR_TO_BACK: - if(!lv_obj_get_parent(obj)) { - LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attr_p); - } else { - lv_obj_move_background(obj); - } - return; // attribute_found - } - - // Properties by object type - switch(obj_get_type(obj)) { - case LV_HASP_IMAGE: - switch(attr_hash) { - case ATTR_OFFSET_X: - update ? lv_img_set_offset_x(obj, val) : attr_out_int(obj, attr, lv_img_get_offset_x(obj)); - return; - case ATTR_OFFSET_Y: - update ? lv_img_set_offset_y(obj, val) : attr_out_int(obj, attr, lv_img_get_offset_y(obj)); - return; - case ATTR_SRC: - if(update) { - lv_img_cache_invalidate_src(lv_img_get_src(obj)); - lv_img_set_src(obj, payload); - } else { - switch(lv_img_src_get_type(obj)) { - case LV_IMG_SRC_FILE: - return attr_out_str(obj, attr, lv_img_get_file_name(obj)); - case LV_IMG_SRC_SYMBOL: - return attr_out_str(obj, attr, (char*)lv_img_get_src(obj)); - } - } - return; // attribute_found - } - break; // not found - - case LV_HASP_PAGE: - if(hasp_process_page_attributes(obj, attr_p, attr_hash, val, update)) { - return; // attribute_found - } - break; // not found - - case LV_HASP_DROPDOWN: - if(hasp_process_dropdown_attribute(obj, attr_p, attr_hash, payload, update)) { - return; // attribute_found - } - break; // not found - - case LV_HASP_ARC: - if(hasp_process_arc_attribute(obj, attr_p, attr_hash, payload, update)) { - return; // attribute_found - } - break; // not found - - case LV_HASP_GAUGE: - if(hasp_process_gauge_attribute(obj, attr_p, attr_hash, payload, update)) { - return; // attribute_found - } - break; // not found - - case LV_HASP_LMETER: - if(hasp_process_lmeter_attribute(obj, attr_p, attr_hash, payload, update)) { - return; // attribute_found - } - break; // not found - - case LV_HASP_CPICKER: - if(attr_hash == ATTR_COLOR) { - if(update) { - lv_color32_t c; - if(Parser::haspPayloadToColor(payload, c)) - lv_cpicker_set_color(obj, lv_color_make(c.ch.red, c.ch.green, c.ch.blue)); - } else { - attr_out_color(obj, attr, lv_cpicker_get_color(obj)); - } - return; // attribute_found - } - break; // not found - - default: - break; - } - - if(generic_int_attribute(obj, attr_hash, val, update)) { - if(update) attr_out_int(obj, attr, val); - return; // attribute_found - } - - if(generic_bool_attribute(obj, attr_hash, val, update)) { - bool toggle = Parser::is_true(payload); - if(update) attr_out_int(obj, attr, toggle); - return; // attribute_found - } - - { - bool result; - hasp_local_style_attr(obj, attr, attr_hash, payload, update, result); - if(result) return; // attribute_found } LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN " (%d)"), attr_p, attr_hash); @@ -2249,15 +1766,9 @@ void attr_out_str(lv_obj_t* obj, const char* attribute, const char* data) else doc[attribute].set(nullptr); - // size_t size = measureJson(doc); // strlen(data) + strlen(attribute); - // if(size < MQTT_MAX_PACKET_SIZE) { char payload[MQTT_MAX_PACKET_SIZE]; serializeJson(doc, payload, MQTT_MAX_PACKET_SIZE); object_dispatch_state(pageid, objid, payload); - - // } else { - // LOG_ERROR(TAG_ATTR, F(D_MQTT_PAYLOAD_TOO_LONG), (uint32_t)size); - // } } void attr_out_int(lv_obj_t* obj, const char* attribute, int32_t val) @@ -2265,14 +1776,28 @@ void attr_out_int(lv_obj_t* obj, const char* attribute, int32_t val) uint8_t pageid; uint8_t objid; - if(hasp_find_id_from_obj(obj, &pageid, &objid)) { - if(!attribute) return; + if(!attribute || !hasp_find_id_from_obj(obj, &pageid, &objid)) return; - char payload[64 + strlen(attribute)]; - snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":%d}"), attribute, val); + char payload[64 + strlen(attribute)]; + snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":%d}"), attribute, val); - object_dispatch_state(pageid, objid, payload); - } + object_dispatch_state(pageid, objid, payload); +} + +void attr_out_bool(lv_obj_t* obj, const char* attribute, bool val) +{ + uint8_t pageid; + uint8_t objid; + + if(!attribute || !hasp_find_id_from_obj(obj, &pageid, &objid)) return; + + char payload[16 + strlen(attribute)]; + if(val) + snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":true}"), attribute); + else + snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":false}"), attribute); + + object_dispatch_state(pageid, objid, payload); } void attr_out_color(lv_obj_t* obj, const char* attribute, lv_color_t color) @@ -2280,15 +1805,269 @@ void attr_out_color(lv_obj_t* obj, const char* attribute, lv_color_t color) uint8_t pageid; uint8_t objid; - if(hasp_find_id_from_obj(obj, &pageid, &objid)) { - if(!attribute) return; + if(!attribute || !hasp_find_id_from_obj(obj, &pageid, &objid)) return; - char payload[64 + strlen(attribute)]; - lv_color32_t c32; - c32.full = lv_color_to32(color); + char payload[64 + strlen(attribute)]; + lv_color32_t c32; + c32.full = lv_color_to32(color); - snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), attribute, - c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); - object_dispatch_state(pageid, objid, payload); + snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), attribute, + c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); + object_dispatch_state(pageid, objid, payload); +} + +/** + * Change or Retrieve the value of the attribute of an object + * @param obj lv_obj_t*: the object to get/set the attribute + * @param attribute char*: the attribute name (with or without leading ".") + * @param payload char*: the new value of the attribute + * @param update bool: change/set the value if true, dispatch/get value if false + * @note setting a value won't return anything, getting will dispatch the value + */ +void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char* payload, bool update) +{ + // unsigned long start = millis(); + if(!obj) return; + + lv_color_t color; + int32_t val; + char temp_buffer[128] = ""; // buffer to hold return strings + char* text = &temp_buffer[0]; // pointer to temp_buffer + hasp_attribute_type_t ret; // the return code determines the attribute return value type + uint16_t attr_hash = Parser::get_sdbm(attribute); + + switch(attr_hash) { + case ATTR_GROUPID: + case ATTR_ID: + case ATTR_TRANSITION: + case ATTR_OBJID: + case ATTR_X: + case ATTR_Y: + case ATTR_H: + case ATTR_W: + case ATTR_OPACITY: + case ATTR_EXT_CLICK_H: + case ATTR_EXT_CLICK_V: + val = strtol(payload, nullptr, DEC); + ret = attribute_common_int(obj, attr_hash, val, update); + break; + + case ATTR_VIS: + case ATTR_HIDDEN: + case ATTR_TOGGLE: + case ATTR_CLICK: + case ATTR_SWIPE: + case ATTR_ENABLED: + val = Parser::is_true(payload); + ret = attribute_common_bool(obj, attr_hash, val, update); + break; + + case ATTR_MIN: + val = strtol(payload, nullptr, DEC); + ret = attribute_common_range(obj, val, update, true, false); + break; + + case ATTR_MAX: + val = strtol(payload, nullptr, DEC); + ret = attribute_common_range(obj, val, update, false, true); + break; + + case ATTR_VAL: + val = strtol(payload, nullptr, DEC); + ret = attribute_common_val(obj, val, update); + break; + + case ATTR_TXT: // TODO: remove + LOG_WARNING(TAG_HASP, F("txt property is obsolete, use text instead")); + case ATTR_TEXT: + ret = attribute_common_text(obj, attribute, payload, &text, update); + break; + + case ATTR_ALIGN: + ret = attribute_common_align(obj, attribute, payload, &text, update); + break; + + case ATTR_OBJ: + text = (char*)obj_get_type_name(obj); + if(update) + ret = ATTR_TYPE_STR_READONLY; + else + ret = ATTR_TYPE_STR; + break; + + // case ATTR_MODE: + // case ATTR_OPTIONS: + // case ATTR_BTN_POS: + + case ATTR_ACTION: + if(update) + obj->user_data.actionid = Parser::get_action_id(payload); + else + val = obj->user_data.actionid; + ret = ATTR_TYPE_INT; + break; + + // case ATTR_SYMBOL: + // (update) ? lv_dropdown_set_symbol(obj, payload) : attr_out_str(obj, attr, + // lv_dropdown_get_symbol(obj)); return true; + + case ATTR_DELETE: + case ATTR_CLEAR: + case ATTR_TO_FRONT: + case ATTR_TO_BACK: + case ATTR_OPEN: + case ATTR_CLOSE: + ret = attribute_common_method(obj, attr_hash, attribute, payload); + break; + + case ATTR_COLS: + case ATTR_ROWS: + case ATTR_AUTO_CLOSE: + case ATTR_SPEED: + case ATTR_ANIM_TIME: + case ATTR_ANIM_SPEED: + case ATTR_ANGLE: + case ATTR_ROTATION: + case ATTR_START_VALUE: + case ATTR_START_ANGLE: + case ATTR_END_ANGLE: + case ATTR_START_ANGLE1: + case ATTR_END_ANGLE1: + case ATTR_COUNT: + case ATTR_BTN_POS: + val = strtol(payload, nullptr, DEC); + ret = specific_int_attribute(obj, attr_hash, val, update); + break; + + case ATTR_OFFSET_X: + case ATTR_OFFSET_Y: + case ATTR_MAX_HEIGHT: + val = strtol(payload, nullptr, DEC); + ret = specific_coord_attribute(obj, attr_hash, val, update); + break; + + case ATTR_ADJUSTABLE: + case ATTR_ONE_CHECK: + case ATTR_AUTO_SIZE: + case ATTR_SHOW_SELECTED: + val = Parser::is_true(payload); + ret = specific_bool_attribute(obj, attr_hash, val, update); + break; + + case ATTR_NEXT: + case ATTR_PREV: + case ATTR_BACK: + val = strtol(payload, nullptr, DEC); + ret = specific_page_attribute(obj, attr_hash, val, update); + break; + + case ATTR_DIRECTION: + val = strtol(payload, nullptr, DEC); + ret = special_attribute_direction(obj, attr_hash, val, update); + break; + + case ATTR_SRC: + ret = special_attribute_src(obj, payload, &text, update); + break; + + default: { + bool result; + hasp_local_style_attr(obj, attribute, attr_hash, payload, update, result); + if(result) { + ret = ATTR_TYPE_METHOD_OK; + } else { + ret = ATTR_NOT_FOUND; + } + } } -} \ No newline at end of file + + if(ret == ATTR_NOT_FOUND) { + switch(obj_get_type(obj)) { // Properties by object type + + case LV_HASP_ARC: + val = strtol(payload, nullptr, DEC); + ret = hasp_process_arc_attribute(obj, attr_hash, val, update); + break; + + case LV_HASP_GAUGE: + val = strtol(payload, nullptr, DEC); + ret = hasp_process_gauge_attribute(obj, attr_hash, val, update); + break; + + case LV_HASP_LINEMETER: + val = strtol(payload, nullptr, DEC); + ret = hasp_process_lmeter_attribute(obj, attr_hash, val, update); + break; + + case LV_HASP_CPICKER: + if(attr_hash == ATTR_COLOR) { + if(update) { + lv_color32_t c; + if(Parser::haspPayloadToColor(payload, c)) + lv_cpicker_set_color(obj, lv_color_make(c.ch.red, c.ch.green, c.ch.blue)); + } else { + color = lv_cpicker_get_color(obj); + } + ret = ATTR_TYPE_COLOR; + } + break; + + default: + break; // not found + } + } + + // Positive return codes have returned a value, negative are warnings + if(update && ret > 0) return; // done + + // Output the returned value or warning + switch(ret) { + case ATTR_NOT_FOUND: + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_UNKNOWN " (%d)"), attribute, attr_hash); + break; + + case ATTR_TYPE_INT_READONLY: + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attribute); + case ATTR_TYPE_INT: + attr_out_int(obj, attribute, val); + break; + + case ATTR_TYPE_BOOL_READONLY: + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attribute); + case ATTR_TYPE_BOOL: + attr_out_bool(obj, attribute, val); + break; + + case ATTR_TYPE_STR_READONLY: + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_READ_ONLY), attribute); + case ATTR_TYPE_STR: + attr_out_str(obj, attribute, text); + break; + + case ATTR_TYPE_COLOR_INVALID: + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_ALIGN_INVALID), payload); + break; + + case ATTR_TYPE_COLOR: + attr_out_color(obj, attribute, color); + break; + + case ATTR_TYPE_ALIGN_INVALID: + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_ALIGN_INVALID), payload); + break; + + case ATTR_TYPE_ALIGN: + case ATTR_TYPE_DIRECTION_CLOCK: + case ATTR_TYPE_DIRECTION_XY: + attr_out_int(obj, attribute, val); + break; + + case ATTR_TYPE_METHOD_INVALID_FOR_PAGE: + LOG_ERROR(TAG_ATTR, F(D_ATTRIBUTE_PAGE_METHOD_INVALID), attribute); + case ATTR_TYPE_METHOD_OK: + break; + + default: + LOG_ERROR(TAG_ATTR, F(D_ERROR_UNKNOWN " (%d)"), ret); + } +} diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index 5b6f6e3b..0e8db12a 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -18,7 +18,6 @@ void my_msgbox_map_clear(lv_obj_t* obj); void line_clear_points(lv_obj_t* obj); void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* payload, bool update); -bool hasp_process_obj_attribute_val(lv_obj_t* obj, const char* attr, int16_t intval, bool booval, bool update); bool attribute_set_normalized_value(lv_obj_t* obj, hasp_update_value_t& value); @@ -30,6 +29,26 @@ void attr_out_color(lv_obj_t* obj, const char* attribute, lv_color_t color); } /* extern "C" */ #endif +typedef enum { + ATTR_RANGE_ERROR = -9, + ATTR_TYPE_METHOD_INVALID_FOR_PAGE = -8, + ATTR_TYPE_ALIGN_INVALID = -5, + ATTR_TYPE_COLOR_INVALID = -4, + ATTR_TYPE_STR_READONLY = -3, + ATTR_TYPE_BOOL_READONLY = -2, + ATTR_TYPE_INT_READONLY = -1, + ATTR_NOT_FOUND = 0, + ATTR_TYPE_INT, + ATTR_TYPE_BOOL, + ATTR_TYPE_STR, + ATTR_TYPE_COLOR, + ATTR_TYPE_ALIGN, + ATTR_TYPE_DIRECTION_XY, + ATTR_TYPE_DIRECTION_CLOCK, + ATTR_TYPE_METHOD_OK, + +} hasp_attribute_type_t; + struct hasp_attr_update_bool_const_t { lv_hasp_obj_type_t obj_type; @@ -38,7 +57,7 @@ struct hasp_attr_update_bool_const_t bool (*get)(const lv_obj_t*); }; -struct hasp_attr_update16_const_t +struct hasp_attr_update_uint16_const_t { lv_hasp_obj_type_t obj_type; uint16_t hash; @@ -54,6 +73,22 @@ struct hasp_attr_update_lv_anim_value_const_t lv_anim_value_t (*get)(const lv_obj_t*); }; +struct hasp_attr_update_int16_const_t +{ + lv_hasp_obj_type_t obj_type; + uint16_t hash; + void (*set)(lv_obj_t*, int16_t); + int16_t (*get)(const lv_obj_t*); +}; + +struct hasp_attr_update_uint8_const_t +{ + lv_hasp_obj_type_t obj_type; + uint16_t hash; + void (*set)(lv_obj_t*, uint8_t); + uint8_t (*get)(const lv_obj_t*); +}; + struct hasp_attr_update8_const_t { lv_hasp_obj_type_t obj_type; @@ -62,7 +97,7 @@ struct hasp_attr_update8_const_t uint8_t (*get)(const lv_obj_t*); }; -struct hasp_attr_update16_t +struct hasp_attr_update_uint16_t { lv_hasp_obj_type_t obj_type; uint16_t hash; @@ -70,6 +105,22 @@ struct hasp_attr_update16_t uint16_t (*get)(lv_obj_t*); }; +struct hasp_attr_update_bool_t +{ + lv_hasp_obj_type_t obj_type; + uint16_t hash; + void (*set)(lv_obj_t*, bool); + bool (*get)(lv_obj_t*); +}; + +struct hasp_attr_update_lv_coord_t +{ + lv_hasp_obj_type_t obj_type; + uint16_t hash; + void (*set)(lv_obj_t*, lv_coord_t); + lv_coord_t (*get)(lv_obj_t*); +}; + struct hasp_attr_update_char_const_t { lv_hasp_obj_type_t obj_type; @@ -339,6 +390,7 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_EXT_CLICK_V 46657 #define ATTR_ANIM_TIME 59451 #define ATTR_ANIM_SPEED 281 +#define ATTR_START_VALUE 11828 // methods #define ATTR_DELETE 50027 diff --git a/src/hasp/hasp_attribute_helper.h b/src/hasp/hasp_attribute_helper.h new file mode 100644 index 00000000..15379023 --- /dev/null +++ b/src/hasp/hasp_attribute_helper.h @@ -0,0 +1,512 @@ +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#include "hasplib.h" + +const char* my_tabview_get_tab_name(const lv_obj_t* tabview, uint16_t id) +{ + if(id >= lv_tabview_get_tab_count(tabview)) return NULL; + + lv_tabview_ext_t* ext = (lv_tabview_ext_t*)lv_obj_get_ext_attr(tabview); + return ext->tab_name_ptr[id]; +} + +// OK - this function is missing in lvgl +static uint8_t my_roller_get_visible_row_count(const lv_obj_t* roller) +{ + const lv_font_t* font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG); + lv_style_int_t line_space = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_BG); + lv_coord_t h = lv_obj_get_height(roller); + + if((lv_font_get_line_height(font) + line_space) != 0) + return (uint8_t)(h / (lv_font_get_line_height(font) + line_space)); + else + return 0; +} + +// OK - this function is not const in lvgl and doesn't return 0 +static uint16_t my_msgbox_stop_auto_close(const lv_obj_t* obj) +{ + lv_msgbox_stop_auto_close((lv_obj_t*)obj); + return 0; +} + +// OK - this function is not const in lvgl +static bool my_arc_get_adjustable(const lv_obj_t* arc) +{ + return lv_arc_get_adjustable((lv_obj_t*)arc); +} + +// OK - we need to change the event handler too +static void my_arc_set_adjustable(lv_obj_t* arc, bool toggle) +{ + lv_arc_set_adjustable(arc, toggle); + lv_obj_set_event_cb(arc, toggle ? slider_event_handler : generic_event_handler); +} + +// OK - this function is missing in lvgl +static inline uint16_t my_arc_get_rotation(lv_obj_t* arc) +{ + lv_arc_ext_t* ext = (lv_arc_ext_t*)lv_obj_get_ext_attr(arc); + return ext->rotation_angle; +} + +// OK - this function is missing in lvgl +static inline int16_t my_chart_get_min_value(lv_obj_t* chart) +{ + lv_chart_ext_t* ext = (lv_chart_ext_t*)lv_obj_get_ext_attr(chart); + return ext->ymin[LV_CHART_AXIS_PRIMARY_Y]; +} + +// OK - this function is missing in lvgl +static inline int16_t my_chart_get_max_value(lv_obj_t* chart) +{ + lv_chart_ext_t* ext = (lv_chart_ext_t*)lv_obj_get_ext_attr(chart); + return ext->ymax[LV_CHART_AXIS_PRIMARY_Y]; +} + +lv_chart_series_t* my_chart_get_series(lv_obj_t* chart, uint8_t ser_num) +{ + lv_chart_ext_t* ext = (lv_chart_ext_t*)lv_obj_get_ext_attr(chart); + lv_chart_series_t* ser = (lv_chart_series_t*)_lv_ll_get_tail(&ext->series_ll); + while(ser_num > 0 && ser) { + ser = (lv_chart_series_t*)_lv_ll_get_prev(&ext->series_ll, ser); + ser_num--; + } + return ser; +} + +// OK +static inline lv_color_t haspLogColor(lv_color_t color) +{ + // uint8_t r = (LV_COLOR_GET_R(color) * 263 + 7) >> 5; + // uint8_t g = (LV_COLOR_GET_G(color) * 259 + 3) >> 6; + // uint8_t b = (LV_COLOR_GET_B(color) * 263 + 7) >> 5; + // LOG_VERBOSE(TAG_ATTR,F("Color: R%u G%u B%u"), r, g, b); + return color; +} + +void my_bar_set_start_value(lv_obj_t* bar, int16_t start_value) +{ + lv_bar_set_start_value(bar, start_value, true); +} + +void my_slider_set_left_value(lv_obj_t* bar, int16_t start_value) +{ + lv_slider_set_left_value(bar, start_value, true); +} + +lv_coord_t my_dropdown_get_max_height(lv_obj_t* obj) +{ + return lv_dropdown_get_max_height(obj); +} + +// OK +lv_obj_t* FindButtonLabel(lv_obj_t* btn) +{ + if(btn) { + lv_obj_t* label = lv_obj_get_child_back(btn, NULL); + if(label) { + if(obj_check_type(label, LV_HASP_LABEL)) { + return label; + } + + } else { + LOG_ERROR(TAG_ATTR, F("FindButtonLabel NULL Pointer encountered")); + } + } else { + LOG_WARNING(TAG_ATTR, F("Button not defined")); + } + return NULL; +} + +// OK +static inline void my_btn_set_text(lv_obj_t* obj, const char* value) +{ + lv_obj_t* label = FindButtonLabel(obj); + if(label) { + lv_label_set_text(label, value); + } +} + +// OK - lvgl does not return a const char * +static const char* my_label_get_text(const lv_obj_t* label) +{ + return lv_label_get_text(label); // library does not return const +} + +static void my_label_set_text(lv_obj_t* label, const char* text) +{ + if(text[0] == '%') { + uint16_t hash = Parser::get_sdbm(text); + size_t len = strlen(text); + const char* static_text; + + switch(hash) { + + case 10125: + static_text = haspDevice.get_hostname(); + break; + default: + lv_label_set_text(label, text); + return; + } + + lv_label_set_text_static(label, static_text); + } else { + lv_label_set_text(label, text); + } +} + +// OK +static const char* my_btn_get_text(const lv_obj_t* obj) +{ + if(!obj) { + LOG_WARNING(TAG_ATTR, F("Button not defined")); + return NULL; + } + + lv_obj_t* label = lv_obj_get_child_back(obj, NULL); + if(label) { +#if 1 + if(obj_check_type(label, LV_HASP_LABEL)) return lv_label_get_text(label); + +#else + lv_obj_type_t list; + lv_obj_get_type(label, &list); + + if(obj_check_type(list.type[0], LV_HASP_LABEL)) { + text = lv_label_get_text(label); + return true; + } +#endif + + } else { + LOG_WARNING(TAG_ATTR, F("my_btn_get_text NULL Pointer encountered")); + } + + return NULL; +} + +/** + * Set a new value_str for an object. Memory will be allocated to store the text by the object. + * @param obj pointer to a object + * @param text '\0' terminated character string. NULL to refresh with the current text. + */ +void my_obj_set_value_str_text(lv_obj_t* obj, uint8_t part, lv_state_t state, const char* text) +{ + // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + + const void* value_str_p = lv_obj_get_style_value_str(obj, part); + lv_obj_invalidate(obj); + + if(text == NULL || text[0] == 0) { + // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + lv_obj_set_style_local_value_str(obj, part, state, NULL); + lv_mem_free(value_str_p); + // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + return; + } + + LV_ASSERT_STR(text); + + if(value_str_p == NULL) { + /*Get the size of the text*/ + size_t len = strlen(text) + 1; + + /*Allocate space for the new text*/ + // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + value_str_p = (char*)lv_mem_alloc(len); + LV_ASSERT_MEM(value_str_p); + if(value_str_p == NULL) return; + + // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + strncpy((char*)value_str_p, text, len); + lv_obj_set_style_local_value_str(obj, part, state, (char*)value_str_p); + // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + return; + } + + // lv_obj_set_style_local_value_str(obj, part, state, str_p); + + if(value_str_p == text) { + /*If set its own text then reallocate it (maybe its size changed)*/ + LOG_DEBUG(TAG_ATTR, "%s %d", __FILE__, __LINE__); + return; // don't touch the data + + // value_str_p = lv_mem_realloc(value_str_p, strlen(text) + 1); + + // LV_ASSERT_MEM(value_str_p); + // if(value_str_p == NULL) return; + } else { + /*Free the old text*/ + if(value_str_p != NULL) { + // LOG_DEBUG(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + lv_mem_free(value_str_p); + value_str_p = NULL; + // LOG_DEBUG(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); + } + + /*Get the size of the text*/ + size_t len = strlen(text) + 1; + + /*Allocate space for the new text*/ + value_str_p = lv_mem_alloc(len); + LV_ASSERT_MEM(value_str_p); + if(value_str_p != NULL) strcpy((char*)value_str_p, text); + lv_obj_set_style_local_value_str(obj, part, state, (char*)value_str_p); + } + + // LOG_VERBOSE(TAG_ATTR, F("%s %d"), __FILE__, __LINE__); +} + +void my_tabview_set_text(lv_obj_t* obj, const char* payload) +{ + uint16_t id = lv_tabview_get_tab_act(obj); + + if(id < lv_tabview_get_tab_count(obj)) { + lv_tabview_set_tab_name(obj, id, (char*)payload); + } +} + +const char* my_tabview_get_text(const lv_obj_t* obj) +{ + uint16_t id = lv_tabview_get_tab_act(obj); + + if(id < lv_tabview_get_tab_count(obj)) { + return my_tabview_get_tab_name(obj, id); + } else { + return NULL; + } +} + +void my_tab_set_text(lv_obj_t* obj, const char* payload) +{ + lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up + if(!content) return LOG_WARNING(TAG_ATTR, F("content not found")); + + lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up + if(!tabview) return LOG_WARNING(TAG_ATTR, F("Tabview not found")); + + if(!obj_check_type(tabview, LV_HASP_TABVIEW)) + return LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); + + for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { + if(obj == lv_tabview_get_tab(tabview, id)) { + lv_tabview_set_tab_name(tabview, id, (char*)payload); + return; + } + } + LOG_WARNING(TAG_ATTR, F("Tab not found")); +} + +const char* my_tab_get_text(const lv_obj_t* obj) +{ + lv_obj_t* content = lv_obj_get_parent(obj->parent); // 2 levels up + if(!content) { + LOG_WARNING(TAG_ATTR, F("content not found")); + return NULL; + } + + lv_obj_t* tabview = lv_obj_get_parent(content); // 3rd level up + if(!tabview) { + LOG_WARNING(TAG_ATTR, F("Tabview not found")); + return NULL; + } + + if(!obj_check_type(tabview, LV_HASP_TABVIEW)) { + LOG_WARNING(TAG_ATTR, F("LV_HASP_TABVIEW not found %d"), obj_get_type(tabview)); + return NULL; + } + + for(uint16_t id = 0; id < lv_tabview_get_tab_count(tabview); id++) { + if(obj == lv_tabview_get_tab(tabview, id)) { + return my_tabview_get_tab_name(tabview, id); + } + } + LOG_WARNING(TAG_ATTR, F("Tab not found")); + return NULL; +} + +static void gauge_format_10(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) +{ + snprintf(buf, bufsize, PSTR("%d"), value / 10); +} + +static void gauge_format_100(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) +{ + snprintf(buf, bufsize, PSTR("%d"), value / 100); +} + +static void gauge_format_1k(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) +{ + snprintf(buf, bufsize, PSTR("%d"), value / 1000); +} + +static void gauge_format_10k(lv_obj_t* gauge, char* buf, int bufsize, int32_t value) +{ + snprintf(buf, bufsize, PSTR("%d"), value / 10000); +} + +#if 0 +static bool attribute_lookup_lv_property(uint16_t hash, uint8_t * prop) +{ + struct prop_hash_map + { + uint16_t hash; + uint8_t prop; + }; + + /* in order of prevalence */ + prop_hash_map props[] = { + {ATTR_PAD_TOP, LV_STYLE_PAD_TOP & LV_STYLE_PROP_ALL}, + {ATTR_BORDER_WIDTH, LV_STYLE_BORDER_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_OUTLINE_WIDTH, LV_STYLE_OUTLINE_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_LETTER_SPACE, LV_STYLE_VALUE_LETTER_SPACE & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_LETTER_SPACE, LV_STYLE_TEXT_LETTER_SPACE & LV_STYLE_PROP_ALL}, + {ATTR_LINE_WIDTH, LV_STYLE_LINE_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_TIME, LV_STYLE_TRANSITION_TIME & LV_STYLE_PROP_ALL}, + {ATTR_SCALE_WIDTH, LV_STYLE_SCALE_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_RADIUS, LV_STYLE_RADIUS & LV_STYLE_PROP_ALL}, + {ATTR_PAD_BOTTOM, LV_STYLE_PAD_BOTTOM & LV_STYLE_PROP_ALL}, + {ATTR_BG_MAIN_STOP, LV_STYLE_BG_MAIN_STOP & LV_STYLE_PROP_ALL}, + {ATTR_BORDER_SIDE, LV_STYLE_BORDER_SIDE & LV_STYLE_PROP_ALL}, + {ATTR_OUTLINE_PAD, LV_STYLE_OUTLINE_PAD & LV_STYLE_PROP_ALL}, + {ATTR_PATTERN_REPEAT, LV_STYLE_PATTERN_REPEAT & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_LINE_SPACE, LV_STYLE_VALUE_LINE_SPACE & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_LINE_SPACE, LV_STYLE_TEXT_LINE_SPACE & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_DELAY, LV_STYLE_TRANSITION_DELAY & LV_STYLE_PROP_ALL}, + {ATTR_SCALE_BORDER_WIDTH, LV_STYLE_SCALE_BORDER_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_CLIP_CORNER, LV_STYLE_CLIP_CORNER & LV_STYLE_PROP_ALL}, + {ATTR_PAD_LEFT, LV_STYLE_PAD_LEFT & LV_STYLE_PROP_ALL}, + {ATTR_BG_GRAD_STOP, LV_STYLE_BG_GRAD_STOP & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_DECOR, LV_STYLE_TEXT_DECOR & LV_STYLE_PROP_ALL}, + {ATTR_LINE_DASH_WIDTH, LV_STYLE_LINE_DASH_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_PROP_1, LV_STYLE_TRANSITION_PROP_1 & LV_STYLE_PROP_ALL}, + {ATTR_SCALE_END_BORDER_WIDTH, LV_STYLE_SCALE_END_BORDER_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_SIZE, LV_STYLE_SIZE & LV_STYLE_PROP_ALL}, + {ATTR_PAD_RIGHT, LV_STYLE_PAD_RIGHT & LV_STYLE_PROP_ALL}, + {ATTR_BG_GRAD_DIR, LV_STYLE_BG_GRAD_DIR & LV_STYLE_PROP_ALL}, + {ATTR_BORDER_POST, LV_STYLE_BORDER_POST & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_OFS_X, LV_STYLE_VALUE_OFS_X & LV_STYLE_PROP_ALL}, + {ATTR_LINE_DASH_GAP, LV_STYLE_LINE_DASH_GAP & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_PROP_2, LV_STYLE_TRANSITION_PROP_2 & LV_STYLE_PROP_ALL}, + {ATTR_SCALE_END_LINE_WIDTH, LV_STYLE_SCALE_END_LINE_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_TRANSFORM_WIDTH, LV_STYLE_TRANSFORM_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_PAD_INNER, LV_STYLE_PAD_INNER & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_OFS_Y, LV_STYLE_VALUE_OFS_Y & LV_STYLE_PROP_ALL}, + {ATTR_LINE_ROUNDED, LV_STYLE_LINE_ROUNDED & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_PROP_3, LV_STYLE_TRANSITION_PROP_3 & LV_STYLE_PROP_ALL}, + {ATTR_TRANSFORM_HEIGHT, LV_STYLE_TRANSFORM_HEIGHT & LV_STYLE_PROP_ALL}, + // {ATTR_MARGIN_TOP, LV_STYLE_MARGIN_TOP & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_ALIGN, LV_STYLE_VALUE_ALIGN & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_PROP_4, LV_STYLE_TRANSITION_PROP_4 & LV_STYLE_PROP_ALL}, + // {ATTR_TRANSFORM_ANGLE, LV_STYLE_TRANSFORM_ANGLE & LV_STYLE_PROP_ALL}, + // {ATTR_MARGIN_BOTTOM, LV_STYLE_MARGIN_BOTTOM & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_PROP_5, LV_STYLE_TRANSITION_PROP_5 & LV_STYLE_PROP_ALL}, + // {ATTR_TRANSFORM_ZOOM, LV_STYLE_TRANSFORM_ZOOM & LV_STYLE_PROP_ALL}, + // {ATTR_MARGIN_LEFT, LV_STYLE_MARGIN_LEFT & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_PROP_6, LV_STYLE_TRANSITION_PROP_6 & LV_STYLE_PROP_ALL}, + // {ATTR_MARGIN_RIGHT, LV_STYLE_MARGIN_RIGHT & LV_STYLE_PROP_ALL}, + {ATTR_BG_COLOR, LV_STYLE_BG_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_BORDER_COLOR, LV_STYLE_BORDER_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_OUTLINE_COLOR, LV_STYLE_OUTLINE_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_PATTERN_RECOLOR, LV_STYLE_PATTERN_RECOLOR & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_COLOR, LV_STYLE_VALUE_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_COLOR, LV_STYLE_TEXT_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_LINE_COLOR, LV_STYLE_LINE_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_IMAGE_RECOLOR, LV_STYLE_IMAGE_RECOLOR & LV_STYLE_PROP_ALL}, + {ATTR_SCALE_GRAD_COLOR, LV_STYLE_SCALE_GRAD_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_BG_GRAD_COLOR, LV_STYLE_BG_GRAD_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_SEL_COLOR, LV_STYLE_TEXT_SEL_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_SCALE_END_COLOR, LV_STYLE_SCALE_END_COLOR & LV_STYLE_PROP_ALL}, + // {ATTR_TEXT_SEL_BG_COLOR, LV_STYLE_TEXT_SEL_BG_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_OPA_SCALE, LV_STYLE_OPA_SCALE & LV_STYLE_PROP_ALL}, + {ATTR_BG_OPA, LV_STYLE_BG_OPA & LV_STYLE_PROP_ALL}, + {ATTR_BORDER_OPA, LV_STYLE_BORDER_OPA & LV_STYLE_PROP_ALL}, + {ATTR_OUTLINE_OPA, LV_STYLE_OUTLINE_OPA & LV_STYLE_PROP_ALL}, + {ATTR_PATTERN_OPA, LV_STYLE_PATTERN_OPA & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_OPA, LV_STYLE_VALUE_OPA & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_OPA, LV_STYLE_TEXT_OPA & LV_STYLE_PROP_ALL}, + {ATTR_LINE_OPA, LV_STYLE_LINE_OPA & LV_STYLE_PROP_ALL}, + {ATTR_IMAGE_OPA, LV_STYLE_IMAGE_OPA & LV_STYLE_PROP_ALL}, + {ATTR_PATTERN_RECOLOR_OPA, LV_STYLE_PATTERN_RECOLOR_OPA & LV_STYLE_PROP_ALL}, + {ATTR_IMAGE_RECOLOR_OPA, LV_STYLE_IMAGE_RECOLOR_OPA & LV_STYLE_PROP_ALL}, + {ATTR_PATTERN_IMAGE, LV_STYLE_PATTERN_IMAGE & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_FONT, LV_STYLE_VALUE_FONT & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_FONT, LV_STYLE_TEXT_FONT & LV_STYLE_PROP_ALL}, + {ATTR_TRANSITION_PATH, LV_STYLE_TRANSITION_PATH & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_STR, LV_STYLE_VALUE_STR & LV_STYLE_PROP_ALL}, + +#if LV_USE_SHADOW + {ATTR_SHADOW_WIDTH, LV_STYLE_SHADOW_WIDTH & LV_STYLE_PROP_ALL}, + {ATTR_SHADOW_OFS_X, LV_STYLE_SHADOW_OFS_X & LV_STYLE_PROP_ALL}, + {ATTR_SHADOW_OFS_Y, LV_STYLE_SHADOW_OFS_Y & LV_STYLE_PROP_ALL}, + {ATTR_SHADOW_SPREAD, LV_STYLE_SHADOW_SPREAD & LV_STYLE_PROP_ALL}, + {ATTR_SHADOW_COLOR, LV_STYLE_SHADOW_COLOR & LV_STYLE_PROP_ALL}, + {ATTR_SHADOW_OPA, LV_STYLE_SHADOW_OPA & LV_STYLE_PROP_ALL}, +#endif + +#if LV_USE_BLEND_MODES && LV_USE_SHADOW + {ATTR_SHADOW_BLEND_MODE, LV_STYLE_SHADOW_BLEND_MODE & LV_STYLE_PROP_ALL}, +#endif + +#if LV_USE_BLEND_MODES + {ATTR_BG_BLEND_MODE, LV_STYLE_BG_BLEND_MODE & LV_STYLE_PROP_ALL}, + {ATTR_PATTERN_BLEND_MODE, LV_STYLE_PATTERN_BLEND_MODE & LV_STYLE_PROP_ALL}, + {ATTR_IMAGE_BLEND_MODE, LV_STYLE_IMAGE_BLEND_MODE & LV_STYLE_PROP_ALL}, + {ATTR_LINE_BLEND_MODE, LV_STYLE_LINE_BLEND_MODE & LV_STYLE_PROP_ALL}, + {ATTR_BORDER_BLEND_MODE, LV_STYLE_BORDER_BLEND_MODE & LV_STYLE_PROP_ALL}, + {ATTR_OUTLINE_BLEND_MODE, LV_STYLE_OUTLINE_BLEND_MODE & LV_STYLE_PROP_ALL}, + {ATTR_VALUE_BLEND_MODE, LV_STYLE_VALUE_BLEND_MODE & LV_STYLE_PROP_ALL}, + {ATTR_TEXT_BLEND_MODE, LV_STYLE_TEXT_BLEND_MODE & LV_STYLE_PROP_ALL}, +#endif + }; + + for(uint32_t i = 0; i < sizeof(props) / sizeof(props[0]); i++) { + if(props[i].hash == hash) { + *prop = props[1].prop; + LOG_WARNING(TAG_ATTR, F("%d found and has propery %d"), hash, props[i].prop); + return true; + } + } + LOG_ERROR(TAG_ATTR, F("%d has no property id"), hash); + return false; +} + +static bool attribute_get_lv_property() +{ + lv_res_t res _lv_style_get_int(const lv_style_t * style, lv_style_property_t prop, void * res); + return res == LV_RES_OK +} + +static bool attribute_set_lv_property() +{ + lv_res_t res _lv_style_get_int(const lv_style_t * style, lv_style_property_t prop, void * res); + return res == LV_RES_OK +} + +static bool attribute_update_lv_property(lv_obj_t * obj, const char * attr_p, uint16_t attr_hash, const char * payload, + bool update) +{ + uint8_t prop; + uint8_t prop_type; + + // convert sdbm hash to lv property number + if(!attribute_lookup_lv_property(attr_hash, &prop)) return false; + + // find the parameter type for this property + prop_type = prop & 0xF; + + if(prop_type < LV_STYLE_ID_COLOR) { + if(update) { + _lv_obj_set_style_local_int(obj, part, prop | (state << LV_STYLE_STATE_POS), atoi(payload)) + } else { + attr_out_str(obj, attr_p, lv_obj_get_style_value_str(obj, part)); + } + } else if(prop_type < LV_STYLE_ID_OPA) { + } else if(prop_type < LV_STYLE_ID_PTR) { + } else { + } +} +#endif From 67542199a8dc9feca7d3dbbbbfd028592ff4a13f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 16 May 2021 23:56:21 +0200 Subject: [PATCH 213/227] Add generic_event_handler to spinner --- src/hasp/hasp_object.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 7daa12bc..ee87d9d9 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -175,7 +175,7 @@ void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, con // ##################### Object Creator ######################################################## // Called from hasp_new_object only to process all attributes -static int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) +static inline int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc) { int i = 0; #if defined(WINDOWS) || defined(POSIX) @@ -415,14 +415,7 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) obj = lv_tabview_create(parent_obj, LV_DIR_TOP, 100); // No event handler for tabs if(obj) { - lv_obj_t* tab; - tab = lv_tabview_add_tab(obj, "tab 1"); - // lv_obj_set_user_data(tab, id + 1); - tab = lv_tabview_add_tab(obj, "tab 2"); - // lv_obj_set_user_data(tab, id + 2); - tab = lv_tabview_add_tab(obj, "tab 3"); - // lv_obj_set_user_data(tab, id + 3); - + lv_obj_set_event_cb(obj, selector_event_handler); obj->user_data.objid = LV_HASP_TABVIEW; } break; @@ -484,10 +477,13 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) case LV_HASP_SPINNER: case HASP_OBJ_SPINNER: obj = lv_spinner_create(parent_obj, NULL); - if(obj) obj->user_data.objid = LV_HASP_SPINNER; + if(obj) { + obj->user_data.objid = LV_HASP_SPINNER; + lv_obj_set_event_cb(obj, generic_event_handler); + } break; - #endif + /* ----- Range Objects ------ */ case LV_HASP_SLIDER: case HASP_OBJ_SLIDER: @@ -522,7 +518,7 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id) break; case LV_HASP_LINEMETER: - case HASP_OBJ_LMETER: + case HASP_OBJ_LMETER: // obsolete case HASP_OBJ_LINEMETER: obj = lv_linemeter_create(parent_obj, NULL); if(obj) { From 6879cf12f5623feaa792d3e4990558bb5528efb8 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 17 May 2021 14:14:46 +0200 Subject: [PATCH 214/227] Update tests --- test/config.yaml | 2 +- test/test_checkbox.tavern.yaml | 293 +++++++++++++++++++++++++++++++++ test/test_led.tavern.yaml | 288 ++++++++++++++++++++++++++++++++ test/test_obj.tavern.yaml | 4 +- test/test_switch.tavern.yaml | 288 ++++++++++++++++++++++++++++++++ 5 files changed, 872 insertions(+), 3 deletions(-) create mode 100644 test/test_checkbox.tavern.yaml create mode 100644 test/test_led.tavern.yaml create mode 100644 test/test_switch.tavern.yaml diff --git a/test/config.yaml b/test/config.yaml index c0597b68..801002f1 100644 --- a/test/config.yaml +++ b/test/config.yaml @@ -8,4 +8,4 @@ variables: username: hasp password: hasp port: 1883 - plate: DESKTOP-1T7EDMU + plate: ubuntu-desktop-20-04 diff --git a/test/test_checkbox.tavern.yaml b/test/test_checkbox.tavern.yaml new file mode 100644 index 00000000..dc721221 --- /dev/null +++ b/test/test_checkbox.tavern.yaml @@ -0,0 +1,293 @@ +# test_page.tavern.yaml +--- +test_name: Obj Standard Properties + +includes: + - !include config.yaml + +paho-mqtt: + client: + transport: tcp + client_id: tavern-tester + connect: + host: "{host}" + port: !int "{port:d}" + timeout: 3 + auth: + username: "{username}" + password: "{password}" + +marks: + - parametrize: + key: obj + vals: + - checkbox + - parametrize: + key: + - hidden + - hidden_inv + - x + - y + - w + - h + - radius + - opacity + - str1 + - str2 + vals: + - [1, 0, 120, 121, 122, 123, 0, 255, "I'm sorry.", "louie"] + - [1, 0, -10, -10, 256, 257, 1, 64, "louie", " The cat stretched."] + - [ + 0, + 1, + 1024, + 1025, + 1026, + 1027, + 5, + 0, + "The pipe began to rust while new.", + "", + ] + - [ + 0, + 1, + 80, + 81, + 82, + 83, + 32535, + 192, + "", + " Oak is strong and also gives shade.", + ] + +stages: + - name: Page 1 + mqtt_publish: + topic: hasp/{plate}/command + payload: "page 1" + mqtt_response: + topic: hasp/{plate}/state/page + payload: "1" + timeout: 1 + delay_after: 0 + + - name: Clear page + mqtt_publish: + topic: hasp/{plate}/command/clearpage + payload: "" + delay_after: 0.2 + + - name: Create object + mqtt_publish: + topic: hasp/{plate}/command/jsonl + json: + obj: "{obj}" + id: 1 + x: 128 + y: 128 + delay_after: 0 + + - name: Test x + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.x={x}","p1b1.x"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + x: !int "{x:d}" + timeout: 1 + + - name: Test y + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.y={y}","p1b1.y"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + y: !int "{y:d}" + timeout: 1 + + # - name: Test w + # mqtt_publish: + # topic: hasp/{plate}/command/json + # payload: '["p1b1.w={w}","p1b1.w"]' + # mqtt_response: + # topic: hasp/{plate}/state/p1b1 + # json: + # w: !int "{w:d}" + # timeout: 1 + + # - name: Test h + # mqtt_publish: + # topic: hasp/{plate}/command/json + # payload: '["p1b1.h={h}","p1b1.h"]' + # delay_after: 0 + # mqtt_response: + # topic: hasp/{plate}/state/p1b1 + # json: + # h: !int "{h:d}" + # timeout: 1 + + - name: Test enabled + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.enabled={hidden}","p1b1.enabled"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + enabled: !int "{hidden:d}" + timeout: 1 + + - name: Test click + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.click={hidden}","p1b1.click"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + click: !int "{hidden:d}" + timeout: 1 + + - name: Test swipe + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.swipe={hidden_inv}","p1b1.swipe"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + swipe: !int "{hidden_inv:d}" + timeout: 1 + + - name: Set vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis={hidden}" + delay_after: 0 + - name: Get hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + hidden: !int "{hidden_inv:d}" + timeout: 1 + - name: Get vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + vis: !int "{hidden:d}" + timeout: 1 + + - name: Set hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden={hidden}" + delay_after: 0 + - name: Get hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + hidden: !int "{hidden:d}" + timeout: 1 + + - name: Get vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + vis: !int "{hidden_inv:d}" + timeout: 1 + + - name: Test opacity + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.opacity={opacity}","p1b1.opacity"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + opacity: !int "{opacity:d}" + timeout: 1 + + - name: Test radius + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.radius={radius}","p1b1.radius"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + radius: !int "{radius:d}" + timeout: 1 + + - name: Set value_str + mqtt_publish: + topic: "hasp/{plate}/command/p1b1.value_str" + payload: "{str1}{str2}" + delay_after: 0.05 + - name: Get value_str + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.value_str" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + value_str: "{str1}{str2}" + timeout: 1 + + - name: Get obj type + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.obj" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + obj: "{obj}" + timeout: 1 + + - name: Test groupid + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.groupid={hidden}","p1b1.groupid"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + groupid: !int "{hidden:d}" + timeout: 1 + + - name: Test val + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.val={hidden}","p1b1.val"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + val: !int "{hidden:d}" + timeout: 1 + + - name: Set text + mqtt_publish: + topic: "hasp/{plate}/command/p1b1.text" + payload: "{str1}{str2}" + delay_after: 0.05 + - name: Get text + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.text" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + text: "{str1}{str2}" + timeout: 1 diff --git a/test/test_led.tavern.yaml b/test/test_led.tavern.yaml new file mode 100644 index 00000000..578e21be --- /dev/null +++ b/test/test_led.tavern.yaml @@ -0,0 +1,288 @@ +# test_page.tavern.yaml +--- +test_name: Obj Standard Properties + +includes: + - !include config.yaml + +paho-mqtt: + client: + transport: tcp + client_id: tavern-tester + connect: + host: "{host}" + port: !int "{port:d}" + timeout: 3 + auth: + username: "{username}" + password: "{password}" + +marks: + - parametrize: + key: obj + vals: + - led + - parametrize: + key: + - hidden + - hidden_inv + - x + - y + - w + - h + - radius + - opacity + - str1 + - str2 + vals: + - [1, 0, 120, 121, 122, 123, 0, 255, "I'm sorry.", "louie"] + - [1, 0, -10, -10, 256, 257, 1, 64, "louie", " The cat stretched."] + - [ + 0, + 1, + 1024, + 1025, + 1026, + 1027, + 5, + 0, + "The pipe began to rust while new.", + "", + ] + - [ + 0, + 1, + 80, + 81, + 82, + 83, + 32535, + 192, + "", + " Oak is strong and also gives shade.", + ] + +stages: + - name: Page 1 + mqtt_publish: + topic: hasp/{plate}/command + payload: "page 1" + mqtt_response: + topic: hasp/{plate}/state/page + payload: "1" + timeout: 1 + delay_after: 0 + + - name: Clear page + mqtt_publish: + topic: hasp/{plate}/command/clearpage + payload: "" + delay_after: 0.2 + + - name: Create object + mqtt_publish: + topic: hasp/{plate}/command/jsonl + json: + obj: "{obj}" + id: 1 + x: 128 + y: 128 + delay_after: 0 + + - name: Test x + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.x={x}","p1b1.x"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + x: !int "{x:d}" + timeout: 1 + + - name: Test y + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.y={y}","p1b1.y"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + y: !int "{y:d}" + timeout: 1 + + - name: Test w + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.w={w}","p1b1.w"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + w: !int "{w:d}" + timeout: 1 + + - name: Test h + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.h={h}","p1b1.h"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + h: !int "{h:d}" + timeout: 1 + + - name: Test enabled + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.enabled={hidden}","p1b1.enabled"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + enabled: !int "{hidden:d}" + timeout: 1 + + - name: Test click + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.click={hidden}","p1b1.click"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + click: !int "{hidden:d}" + timeout: 1 + + - name: Test swipe + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.swipe={hidden_inv}","p1b1.swipe"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + swipe: !int "{hidden_inv:d}" + timeout: 1 + + - name: Set vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis={hidden}" + delay_after: 0 + - name: Get hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + hidden: !int "{hidden_inv:d}" + timeout: 1 + - name: Get vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + vis: !int "{hidden:d}" + timeout: 1 + + - name: Set hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden={hidden}" + delay_after: 0 + - name: Get hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + hidden: !int "{hidden:d}" + timeout: 1 + + - name: Get vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + vis: !int "{hidden_inv:d}" + timeout: 1 + + - name: Test opacity + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.opacity={opacity}","p1b1.opacity"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + opacity: !int "{opacity:d}" + timeout: 1 + + - name: Test radius + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.radius={radius}","p1b1.radius"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + radius: !int "{radius:d}" + timeout: 1 + + - name: Test radius2 + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.radius2={radius}","p1b1.radius2"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + radius2: !int "{radius:d}" + timeout: 1 + + - name: Set value_str + mqtt_publish: + topic: "hasp/{plate}/command/p1b1.value_str" + payload: "{str1}{str2}" + delay_after: 0.05 + - name: Get value_str + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.value_str" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + value_str: "{str1}{str2}" + timeout: 1 + + - name: Get obj type + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.obj" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + obj: "{obj}" + timeout: 1 + + - name: Test groupid + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.groupid={hidden}","p1b1.groupid"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + groupid: !int "{hidden:d}" + timeout: 1 + + - name: Test val + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.val={opacity}","p1b1.val"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + val: !int "{opacity:d}" + timeout: 1 diff --git a/test/test_obj.tavern.yaml b/test/test_obj.tavern.yaml index 5db08543..4ad63f7f 100644 --- a/test/test_obj.tavern.yaml +++ b/test/test_obj.tavern.yaml @@ -30,8 +30,8 @@ marks: - btn - label - slider - - checkbox - - switch + #- checkbox + #- switch - bar - arc # - led # has a shadow bug diff --git a/test/test_switch.tavern.yaml b/test/test_switch.tavern.yaml new file mode 100644 index 00000000..6d142de2 --- /dev/null +++ b/test/test_switch.tavern.yaml @@ -0,0 +1,288 @@ +# test_page.tavern.yaml +--- +test_name: Obj Standard Properties + +includes: + - !include config.yaml + +paho-mqtt: + client: + transport: tcp + client_id: tavern-tester + connect: + host: "{host}" + port: !int "{port:d}" + timeout: 3 + auth: + username: "{username}" + password: "{password}" + +marks: + - parametrize: + key: obj + vals: + - switch + - parametrize: + key: + - hidden + - hidden_inv + - x + - y + - w + - h + - radius + - opacity + - str1 + - str2 + vals: + - [1, 0, 120, 121, 122, 123, 0, 255, "I'm sorry.", "louie"] + - [1, 0, -10, -10, 256, 257, 1, 64, "louie", " The cat stretched."] + - [ + 0, + 1, + 1024, + 1025, + 1026, + 1027, + 5, + 0, + "The pipe began to rust while new.", + "", + ] + - [ + 0, + 1, + 80, + 81, + 82, + 83, + 32535, + 192, + "", + " Oak is strong and also gives shade.", + ] + +stages: + - name: Page 1 + mqtt_publish: + topic: hasp/{plate}/command + payload: "page 1" + mqtt_response: + topic: hasp/{plate}/state/page + payload: "1" + timeout: 1 + delay_after: 0 + + - name: Clear page + mqtt_publish: + topic: hasp/{plate}/command/clearpage + payload: "" + delay_after: 0.2 + + - name: Create object + mqtt_publish: + topic: hasp/{plate}/command/jsonl + json: + obj: "{obj}" + id: 1 + x: 128 + y: 128 + delay_after: 0 + + - name: Test x + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.x={x}","p1b1.x"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + x: !int "{x:d}" + timeout: 1 + + - name: Test y + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.y={y}","p1b1.y"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + y: !int "{y:d}" + timeout: 1 + + - name: Test w + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.w={w}","p1b1.w"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + w: !int "{w:d}" + timeout: 1 + + - name: Test h + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.h={h}","p1b1.h"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + h: !int "{h:d}" + timeout: 1 + + - name: Test enabled + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.enabled={hidden}","p1b1.enabled"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + enabled: !int "{hidden:d}" + timeout: 1 + + - name: Test click + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.click={hidden}","p1b1.click"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + click: !int "{hidden:d}" + timeout: 1 + + - name: Test swipe + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.swipe={hidden_inv}","p1b1.swipe"]' + delay_after: 0 + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + swipe: !int "{hidden_inv:d}" + timeout: 1 + + - name: Set vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis={hidden}" + delay_after: 0 + - name: Get hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + hidden: !int "{hidden_inv:d}" + timeout: 1 + - name: Get vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + vis: !int "{hidden:d}" + timeout: 1 + + - name: Set hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden={hidden}" + delay_after: 0 + - name: Get hidden + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.hidden" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + hidden: !int "{hidden:d}" + timeout: 1 + + - name: Get vis + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.vis" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + vis: !int "{hidden_inv:d}" + timeout: 1 + + - name: Test opacity + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.opacity={opacity}","p1b1.opacity"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + opacity: !int "{opacity:d}" + timeout: 1 + + - name: Test radius + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.radius={radius}","p1b1.radius"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + radius: !int "{radius:d}" + timeout: 1 + + - name: Test radius2 + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.radius2={radius}","p1b1.radius2"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + radius2: !int "{radius:d}" + timeout: 1 + + - name: Set value_str + mqtt_publish: + topic: "hasp/{plate}/command/p1b1.value_str" + payload: "{str1}{str2}" + delay_after: 0.05 + - name: Get value_str + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.value_str" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + value_str: "{str1}{str2}" + timeout: 1 + + - name: Get obj type + mqtt_publish: + topic: hasp/{plate}/command + payload: "p1b1.obj" + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + obj: "{obj}" + timeout: 1 + + - name: Test groupid + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.groupid={hidden}","p1b1.groupid"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + groupid: !int "{hidden:d}" + timeout: 1 + + - name: Test val + mqtt_publish: + topic: hasp/{plate}/command/json + payload: '["p1b1.val={hidden}","p1b1.val"]' + mqtt_response: + topic: hasp/{plate}/state/p1b1 + json: + val: !int "{hidden:d}" + timeout: 1 From 2fa975f21c735dac378dbbfe298ec95d3d560fea Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 00:16:13 +0200 Subject: [PATCH 215/227] Update discovery and device classes for binary_input --- src/hasp/hasp_dispatch.cpp | 29 ++++++------ src/sys/gpio/hasp_gpio.cpp | 91 ++++++++++++++++++++++++++++++++++++-- src/sys/gpio/hasp_gpio.h | 33 +++++++++----- 3 files changed, 124 insertions(+), 29 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 52b01299..e8f50378 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -481,7 +481,7 @@ void dispatch_screenshot(const char*, const char* filename) memcpy_P(tempfile, PSTR("/screenshot.bmp"), sizeof(tempfile)); guiTakeScreenshot(tempfile); } else if(strlen(filename) > 31 || filename[0] != '/') { // Invalid filename - LOG_WARNING(TAG_MSGR, "Invalid filename %s", filename); + LOG_WARNING(TAG_MSGR, F("D_FILE_SAVE_FAILED"), filename); } else { // Valid filename guiTakeScreenshot(filename); } @@ -803,24 +803,27 @@ void dispatch_send_discovery(const char*, const char*) { #if HASP_USE_MQTT > 0 - StaticJsonDocument<512> doc; - char data[512]; - haspGetVersion(data, sizeof(data)); + StaticJsonDocument<1024> doc; - doc[F("node")] = haspDevice.get_hostname(); - doc[F("model")] = haspDevice.get_model(); - doc[F("manufacturer")] = F(D_MANUFACTURER); - doc[F("hwid")] = haspDevice.get_hardware_id(); - doc[F("version")] = data; - doc[F("numPages")] = haspPages.count(); + doc[F("node")] = haspDevice.get_hostname(); + doc[F("mdl")] = haspDevice.get_model(); + doc[F("mf")] = F(D_MANUFACTURER); + doc[F("hwid")] = haspDevice.get_hardware_id(); + doc[F("pages")] = haspPages.count(); - JsonArray relay = doc.createNestedArray(F("relay")); - JsonArray led = doc.createNestedArray(F("led")); + JsonObject input = doc.createNestedObject(F("input")); + JsonArray relay = doc.createNestedArray(F("power")); + JsonArray led = doc.createNestedArray(F("light")); + JsonArray dimmer = doc.createNestedArray(F("dim")); #if HASP_USE_GPIO > 0 - gpio_discovery(relay, led); + gpio_discovery(input, relay, led, dimmer); #endif + char data[1024]; + haspGetVersion(data, sizeof(data)); + doc[F("sw")] = data; + size_t len = serializeJson(doc, data); switch(mqtt_send_discovery(data, len)) { case MQTT_ERR_OK: diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp index 3c5682a1..921a3e60 100644 --- a/src/sys/gpio/hasp_gpio.cpp +++ b/src/sys/gpio/hasp_gpio.cpp @@ -793,11 +793,16 @@ hasp_gpio_config_t gpioGetPinConfig(uint8_t num) return gpioConfig[num]; } -void gpio_discovery(JsonArray& relay, JsonArray& led) +void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonArray& dimmer) { + char description[20]; + for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { switch(gpioConfig[i].type) { case hasp_gpio_type_t::LIGHT_RELAY: + light.add(gpioConfig[i].pin); + break; + case hasp_gpio_type_t::POWER_RELAY: relay.add(gpioConfig[i].pin); break; @@ -807,16 +812,94 @@ void gpio_discovery(JsonArray& relay, JsonArray& led) case hasp_gpio_type_t::SERIAL_DIMMER: case hasp_gpio_type_t::SERIAL_DIMMER_AU: case hasp_gpio_type_t::SERIAL_DIMMER_EU: - led.add(gpioConfig[i].pin); + dimmer.add(gpioConfig[i].pin); break; - // pwm.add(gpioConfig[i].pin); + case SWITCH: + strcpy_P(description, PSTR("none")); + break; + case BATTERY: + strcpy_P(description, PSTR("battery")); + break; + case BATTERY_CHARGING: + strcpy_P(description, PSTR("battery_charging")); + break; + case COLD: + strcpy_P(description, PSTR("cold")); + break; + case CONNECTIVITY: + strcpy_P(description, PSTR("connectivity")); + break; + case DOOR: + strcpy_P(description, PSTR("door")); + break; + case GARAGE_DOOR: + strcpy_P(description, PSTR("garage_door")); + break; + case GAS: + strcpy_P(description, PSTR("gas")); + break; + case HEAT: + strcpy_P(description, PSTR("heat")); + break; + case LIGHT: + strcpy_P(description, PSTR("light")); + break; + case LOCK: + strcpy_P(description, PSTR("lock")); + break; + case MOISTURE: + strcpy_P(description, PSTR("moisture")); + break; + case MOTION: + strcpy_P(description, PSTR("motion")); + break; + case MOVING: + strcpy_P(description, PSTR("moving")); + break; + case OCCUPANCY: + strcpy_P(description, PSTR("occupancy")); + break; + case OPENING: + strcpy_P(description, PSTR("opening")); + break; + case PLUG: + strcpy_P(description, PSTR("plug")); + break; + case POWER: + strcpy_P(description, PSTR("power")); + break; + case PRESENCE: + strcpy_P(description, PSTR("presence")); + break; + case PROBLEM: + strcpy_P(description, PSTR("problem")); + break; + case SAFETY: + strcpy_P(description, PSTR("safety")); + break; + case SMOKE: + strcpy_P(description, PSTR("smoke")); + break; + case SOUND: + strcpy_P(description, PSTR("sound")); + break; + case VIBRATION: + strcpy_P(description, PSTR("vibration")); + break; + case WINDOW: + strcpy_P(description, PSTR("window")); break; - case hasp_gpio_type_t::FREE: default: break; } + + if(gpioConfig[i].type >= hasp_gpio_type_t::SWITCH && gpioConfig[i].type <= hasp_gpio_type_t::WINDOW) { + JsonArray arr = input[description]; + if(arr.isNull()) arr = input.createNestedArray(description); + arr.add(gpioConfig[i].pin); + } } }; diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h index 1665fd3a..7de0bf98 100644 --- a/src/sys/gpio/hasp_gpio.h +++ b/src/sys/gpio/hasp_gpio.h @@ -44,7 +44,7 @@ bool gpio_set_pin_state(uint8_t pin, bool power, int32_t val); void gpio_set_moodlight(moodlight_t& moodlight); -void gpio_discovery(JsonArray& relay, JsonArray& led); +void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonArray& dimmer); bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc, bool inverted); bool gpioIsSystemPin(uint8_t gpio); @@ -93,6 +93,7 @@ enum hasp_gpio_type_t { HAPTIC = 0x41, /* Inputs */ + SWITCH = 0xA0, // Binary Sensors BATTERY = 0xA1, BATTERY_CHARGING = 0xA2, COLD = 0xA3, @@ -105,18 +106,26 @@ enum hasp_gpio_type_t { LOCK = 0xAA, MOISTURE = 0xAB, MOTION = 0xAC, - OCCUPANCY = 0xAD, - OPENING = 0xAE, - PLUG = 0xAF, - PRESENCE = 0xB0, - PROBLEM = 0xB1, - SAFETY = 0xB2, - SMOKE = 0xB3, - SOUND = 0xB4, - VIBRATION = 0xB5, - WINDOW = 0xB6, + MOVING = 0xAD, + OCCUPANCY = 0xAE, + OPENING = 0xAF, + PLUG = 0xB0, + POWER = 0xB1, + PRESENCE = 0xB2, + PROBLEM = 0xB3, + SAFETY = 0xB4, + SMOKE = 0xB5, + SOUND = 0xB6, + VIBRATION = 0xB7, + WINDOW = 0xB8, - SWITCH = 0xC0, // Binary Sensors + AWNING = 0xB9, + BLIND = 0xBA, + CURTAIN = 0xBB, + DAMPER = 0xBC, + GATE = 0xBD, + SHADE = 0xBE, + SHUTTER = 0xBF, BUTTON = 0xF0, BUTTON_TOGGLE_ON = 0xF1, From 968a78f3a3c68f7ffd87a4805fca348bcabcd368 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 00:16:33 +0200 Subject: [PATCH 216/227] Set LV_LED_BRIGHT_MIN=0 --- include/lv_conf_v7.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index 04b82f8a..8c2acb9d 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -746,6 +746,7 @@ typedef struct { /*LED (dependencies: -)*/ #define LV_USE_LED 1 +#define LV_LED_BRIGHT_MIN 0 /*Line (dependencies: -*/ #define LV_USE_LINE 1 From b926e984e31644295104f1b8ce752991ec2557a0 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 00:16:51 +0200 Subject: [PATCH 217/227] Check hasp_local_style_attr last --- src/hasp/hasp_attribute.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 766ab807..258af713 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -1971,13 +1971,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char break; default: { - bool result; - hasp_local_style_attr(obj, attribute, attr_hash, payload, update, result); - if(result) { - ret = ATTR_TYPE_METHOD_OK; - } else { - ret = ATTR_NOT_FOUND; - } + break; // not found } } @@ -2017,6 +2011,16 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char } } + if(ret == ATTR_NOT_FOUND) { + bool result; + hasp_local_style_attr(obj, attribute, attr_hash, payload, update, result); + if(result) { + ret = ATTR_TYPE_METHOD_OK; + } else { + ret = ATTR_NOT_FOUND; + } + } + // Positive return codes have returned a value, negative are warnings if(update && ret > 0) return; // done From 5c17df8cf2837e555e296372fb4c8a57e6b8be96 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 00:17:11 +0200 Subject: [PATCH 218/227] Use separate input/output buttons --- src/sys/svc/hasp_http.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 466c4f4b..9b9b45db 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1625,10 +1625,15 @@ void webHandleGpioConfig() httpMessage += F("
"); if(configCount < HASP_NUM_GPIO_CONFIG) { + httpMessage += F("

"); + httpMessage += F("

"); + httpMessage += F("

"); httpMessage += F("

"); + httpMessage += F("'>

"); } add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); From af9e45645ecaa3112657c7d9ba9aa13df7db5890 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 02:30:25 +0200 Subject: [PATCH 219/227] Add translations --- src/lang/en_US.h | 7 +++- src/lang/es_ES.h | 7 +++- src/lang/fr_FR.h | 5 ++- src/lang/hu_HU.h | 7 +++- src/lang/lang.h | 1 + src/lang/nl_NL.h | 5 ++- src/lang/pt_PT.h | 7 +++- src/lang/ro_RO.h | 7 +++- src/sys/svc/hasp_http.cpp | 85 +++++++++++---------------------------- 9 files changed, 57 insertions(+), 74 deletions(-) diff --git a/src/lang/en_US.h b/src/lang/en_US.h index 7d009bc4..38df2de4 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -196,12 +196,13 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Push Button" -#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw +#define D_GPIO_TOUCH "Capacitive Touch" // new #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Mood Red" #define D_GPIO_LED_G "Mood Green" #define D_GPIO_LED_B "Mood Blue" -#define D_GPIO_RELAY "Relay" +#define D_GPIO_POWER_RELAY "Power Relay" // new +#define D_GPIO_LIGHT_RELAY "Light Relay" // new #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Serial Dimmer" @@ -209,5 +210,7 @@ #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Group" #define D_GPIO_GROUP_NONE "None" +#define D_GPIO_STATE_NORMAL "Normal" // new +#define D_GPIO_STATE_INVERTED "Inverted" // new #endif \ No newline at end of file diff --git a/src/lang/es_ES.h b/src/lang/es_ES.h index df895a91..adc2b0b9 100644 --- a/src/lang/es_ES.h +++ b/src/lang/es_ES.h @@ -196,12 +196,13 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Botón" -#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw +#define D_GPIO_TOUCH "Capacitive Touch" // new #define D_GPIO_LED "DEL" #define D_GPIO_LED_R "Ánimo Red" #define D_GPIO_LED_G "Ánimo Green" #define D_GPIO_LED_B "Ánimo Blue" -#define D_GPIO_RELAY "Relé" +#define D_GPIO_POWER_RELAY "Power Relé" // new +#define D_GPIO_LIGHT_RELAY "Light Relé" // new #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Atenuador serial" @@ -209,5 +210,7 @@ #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Grupo" #define D_GPIO_GROUP_NONE "Ninguno" +#define D_GPIO_STATE_NORMAL "Normal" // new +#define D_GPIO_STATE_INVERTED "Inverted" // new #endif \ No newline at end of file diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h index 012b15c6..749e4a6d 100644 --- a/src/lang/fr_FR.h +++ b/src/lang/fr_FR.h @@ -200,7 +200,8 @@ #define D_GPIO_LED_R "Humeur Rouge" #define D_GPIO_LED_G "Humeur Vert" #define D_GPIO_LED_B "Humeur Bleu" -#define D_GPIO_RELAY "Relais" +#define D_GPIO_POWER_RELAY "Relais Electrique" +#define D_GPIO_LIGHT_RELAY "Relais de Lumière" #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Gradateur Série" @@ -208,5 +209,7 @@ #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Groupe" #define D_GPIO_GROUP_NONE "Aucun" +#define D_GPIO_STATE_NORMAL "Normal" +#define D_GPIO_STATE_INVERTED "Inverse" #endif \ No newline at end of file diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h index bf519e51..cd4fb20e 100644 --- a/src/lang/hu_HU.h +++ b/src/lang/hu_HU.h @@ -196,12 +196,13 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Button" -#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw +#define D_GPIO_TOUCH "Capacitive Touch" // new #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Mood Red" #define D_GPIO_LED_G "Mood Green" #define D_GPIO_LED_B "Mood Blue" -#define D_GPIO_RELAY "Relay" +#define D_GPIO_POWER_RELAY "Power Relay" // new +#define D_GPIO_LIGHT_RELAY "Light Relay" // new #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Serial Dimmer" @@ -209,5 +210,7 @@ #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Group" #define D_GPIO_GROUP_NONE "None" +#define D_GPIO_STATE_NORMAL "Normal" // new +#define D_GPIO_STATE_INVERTED "Inverted" // new #endif diff --git a/src/lang/lang.h b/src/lang/lang.h index 7be7e779..20411ecd 100644 --- a/src/lang/lang.h +++ b/src/lang/lang.h @@ -14,6 +14,7 @@ #define D_PASSWORD_MASK "********" #define D_BULLET " * " #define D_MANUFACTURER "openHASP" +#define D_BACK_ICON "↩ " #define D_TIMESTAMP "%H:%M:%S" // Used when reference time is set from NTP #define D_TIME_MILLIS "%8d" // Used when no reference clock could be set diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index f6d7fd0d..12a600cd 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -200,7 +200,8 @@ #define D_GPIO_LED_R "Sfeer Rood" #define D_GPIO_LED_G "Sfeer Groen" #define D_GPIO_LED_B "Sfeer Blauw" -#define D_GPIO_RELAY "Relay" +#define D_GPIO_POWER_RELAY "Stroomrelais" +#define D_GPIO_LIGHT_RELAY "Licht Relais" #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Seriële Dimmer" @@ -208,5 +209,7 @@ #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Groep" #define D_GPIO_GROUP_NONE "Geen" +#define D_GPIO_STATE_NORMAL "Normaal" +#define D_GPIO_STATE_INVERTED "Geïnverteerd" #endif \ No newline at end of file diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h index d53cd9eb..95375b30 100644 --- a/src/lang/pt_PT.h +++ b/src/lang/pt_PT.h @@ -196,12 +196,13 @@ #define D_GPIO_SWITCH "Interruptor" #define D_GPIO_BUTTON "Botão" -#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw +#define D_GPIO_TOUCH "Capacitive Touch" // new #define D_GPIO_LED "LED" #define D_GPIO_LED_R "LED Red" #define D_GPIO_LED_G "LED Green" #define D_GPIO_LED_B "LED Blue" -#define D_GPIO_RELAY "Relé" +#define D_GPIO_POWER_RELAY "Power Relé" // new +#define D_GPIO_LIGHT_RELAY "Light Relé" // new #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Dimmer serial" @@ -209,5 +210,7 @@ #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Grupo" #define D_GPIO_GROUP_NONE "Nenhum" +#define D_GPIO_STATE_NORMAL "Normal" // new +#define D_GPIO_STATE_INVERTED "Inverted" // new #endif \ No newline at end of file diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h index 1bec0b42..abb91b15 100644 --- a/src/lang/ro_RO.h +++ b/src/lang/ro_RO.h @@ -196,12 +196,13 @@ // new #define D_GPIO_SWITCH "Switch" #define D_GPIO_BUTTON "Button" -#define D_GPIO_TOUCH "Capacitive Touch" // Nieuw +#define D_GPIO_TOUCH "Capacitive Touch" // new #define D_GPIO_LED "Led" #define D_GPIO_LED_R "Mood Red" #define D_GPIO_LED_G "Mood Green" #define D_GPIO_LED_B "Mood Blue" -#define D_GPIO_RELAY "Relay" +#define D_GPIO_POWER_RELAY "Power Relay" // new +#define D_GPIO_LIGHT_RELAY "Light Relay" // new #define D_GPIO_PWM "PWM" #define D_GPIO_DAC "DAC" #define D_GPIO_SERIAL_DIMMER "Serial Dimmer" @@ -209,5 +210,7 @@ #define D_GPIO_PIN "Pin" #define D_GPIO_GROUP "Group" #define D_GPIO_GROUP_NONE "None" +#define D_GPIO_STATE_NORMAL "Normal" // new +#define D_GPIO_STATE_INVERTED "Inverted" // new #endif diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 9b9b45db..cac82c5f 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1210,20 +1210,13 @@ void webHandleConfig() httpMessage += F("
"); #if HASP_USE_WIFI > 0 - httpMessage += F("

"); + add_form_button(httpMessage, F(D_HTTP_WIFI_SETTINGS), F("/config/wifi"), F("")); #endif - #if HASP_USE_MQTT > 0 - httpMessage += F("

"); + add_form_button(httpMessage, F(D_HTTP_MQTT_SETTINGS), F("/config/mqtt"), F("")); #endif - - httpMessage += F("

"); - - httpMessage += F("

"); + add_form_button(httpMessage, F(D_HTTP_HTTP_SETTINGS), F("/config/http"), F("")); + add_form_button(httpMessage, F(D_HTTP_GUI_SETTINGS), F("/config/gui"), F("")); // httpMessage += // F("

"); - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += PSTR("

"); - + add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"), F("")); webSendPage(haspDevice.get_hostname(), httpMessage.length(), false); webServer.sendContent(httpMessage); } @@ -1381,12 +1370,9 @@ void webHandleGuiConfig() #if TOUCH_DRIVER == 2046 && defined(TOUCH_CS) add_form_button(httpMessage, F(D_HTTP_CALIBRATE), F("/config/gui"), F("name='cal' value='1'")); - -// httpMessage += PSTR("

"); #endif - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); + add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"), F("")); webSendPage(haspDevice.get_hostname(), httpMessage.length(), false); webServer.sendContent(httpMessage); } @@ -1424,10 +1410,7 @@ void webHandleWifiConfig() #if HASP_USE_WIFI > 0 && !defined(STM32F4xx) if(WiFi.getMode() == WIFI_STA) { - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += PSTR("

"); + add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"), F("")); } #endif @@ -1452,29 +1435,6 @@ void webHandleHttpConfig() StaticJsonDocument<256> settings; httpGetConfig(settings.to()); - // String httpMessage((char *)0); - // httpMessage.reserve(HTTP_PAGE_SIZE); - // httpMessage += F("

"); - // httpMessage += haspDevice.get_hostname(); - // httpMessage += F("


"); - - // httpMessage += F("
"); - // httpMessage += F("Web Username (optional)
Web Password (optional)

"); - - // httpMessage += PSTR("

"); - char httpMessage[HTTP_PAGE_SIZE]; size_t len = snprintf_P( @@ -1578,10 +1538,10 @@ void webHandleGpioConfig() httpMessage += F(D_GPIO_LED_B); break; case hasp_gpio_type_t::LIGHT_RELAY: - httpMessage += F("LIGHT_RELAY"); + httpMessage += F(D_GPIO_LIGHT_RELAY); break; case hasp_gpio_type_t::POWER_RELAY: - httpMessage += F(D_GPIO_RELAY); + httpMessage += F(D_GPIO_POWER_RELAY); break; case hasp_gpio_type_t::SHUTTER_RELAY: httpMessage += F("SHUTTER_RELAY"); @@ -1592,10 +1552,11 @@ void webHandleGpioConfig() case hasp_gpio_type_t::DAC: httpMessage += F(D_GPIO_DAC); break; - case hasp_gpio_type_t::SERIAL_DIMMER: - httpMessage += F(D_GPIO_SERIAL_DIMMER); - break; + #if defined(LANBONL8) + // case hasp_gpio_type_t::SERIAL_DIMMER: + // httpMessage += F(D_GPIO_SERIAL_DIMMER); + // break; case hasp_gpio_type_t::SERIAL_DIMMER_EU: httpMessage += F("L8-HD (EU)"); break; @@ -1610,7 +1571,7 @@ void webHandleGpioConfig() httpMessage += F("
"); httpMessage += conf.group; httpMessage += F(""); - httpMessage += (conf.inverted) ? F("Inverted") : F("Normal"); + httpMessage += (conf.inverted) ? F(D_GPIO_STATE_INVERTED) : F(D_GPIO_STATE_NORMAL); httpMessage += ("

"); } - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); + add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"), F("")); // httpMessage += F("

"); @@ -1700,10 +1661,10 @@ void webHandleGpioOptions() httpMessage += getOption(hasp_gpio_type_t::LED_B, F(D_GPIO_LED_B), selected); selected = (conf.type == hasp_gpio_type_t::LIGHT_RELAY); - httpMessage += getOption(hasp_gpio_type_t::LIGHT_RELAY, F("Light Relay"), selected); + httpMessage += getOption(hasp_gpio_type_t::LIGHT_RELAY, F(D_GPIO_LIGHT_RELAY), selected); selected = (conf.type == hasp_gpio_type_t::POWER_RELAY); - httpMessage += getOption(hasp_gpio_type_t::POWER_RELAY, F(D_GPIO_RELAY), selected); + httpMessage += getOption(hasp_gpio_type_t::POWER_RELAY, F(D_GPIO_POWER_RELAY), selected); selected = (conf.type == hasp_gpio_type_t::SHUTTER_RELAY); httpMessage += getOption(hasp_gpio_type_t::SHUTTER_RELAY, F("Shutter Relay"), selected); @@ -1711,8 +1672,8 @@ void webHandleGpioOptions() selected = (conf.type == hasp_gpio_type_t::DAC); httpMessage += getOption(hasp_gpio_type_t::DAC, F(D_GPIO_DAC), selected); - selected = (conf.type == hasp_gpio_type_t::SERIAL_DIMMER); - httpMessage += getOption(hasp_gpio_type_t::SERIAL_DIMMER, F(D_GPIO_SERIAL_DIMMER), selected); + // selected = (conf.type == hasp_gpio_type_t::SERIAL_DIMMER); + // httpMessage += getOption(hasp_gpio_type_t::SERIAL_DIMMER, F(D_GPIO_SERIAL_DIMMER), selected); #if defined(LANBONL8) selected = (conf.type == hasp_gpio_type_t::SERIAL_DIMMER_AU); @@ -1740,8 +1701,8 @@ void webHandleGpioOptions() httpMessage += F("

"); httpMessage += F("

Value

"); httpMessage += @@ -1942,7 +1903,7 @@ void webHandleDebugConfig() httpMessage += F("

"); - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); + add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"), F("")); // httpMessage += PSTR("

"); @@ -2209,7 +2170,7 @@ void httpHandleResetConfig() add_button(httpMessage, F(D_HTTP_ERASE_DEVICE), F("name='confirm' value='yes'")); close_form(httpMessage); - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); + add_form_button(httpMessage, F(D_BACK_ICON D_HTTP_CONFIGURATION), F("/config"), F("")); } webSendPage(haspDevice.get_hostname(), httpMessage.length(), resetConfirmed); From 798cf8bd5e53221b62266f23c01e15c116dde292 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 04:19:26 +0200 Subject: [PATCH 220/227] Replace haspGetVersion() with haspDevice.get_version() --- src/dev/device.cpp | 22 +++++++++++++++++++++- src/dev/device.h | 17 ++++++++++------- src/dev/esp32/esp32.cpp | 10 +--------- src/dev/esp32/esp32.h | 3 --- src/hasp/hasp.cpp | 11 +++++------ src/hasp/hasp.h | 2 +- src/hasp/hasp_dispatch.cpp | 9 ++++----- src/hasp_debug.cpp | 7 ++----- src/mqtt/hasp_mqtt_ha.cpp | 5 +---- src/sys/svc/hasp_http.cpp | 16 ++++------------ src/sys/svc/hasp_mdns.cpp | 3 +-- src/sys/svc/hasp_slave.cpp | 5 ++--- 12 files changed, 52 insertions(+), 58 deletions(-) diff --git a/src/dev/device.cpp b/src/dev/device.cpp index cfb21a77..6d1d449b 100644 --- a/src/dev/device.cpp +++ b/src/dev/device.cpp @@ -16,4 +16,24 @@ const char* BaseDevice::get_model() return PIOENV; #endif } -} \ No newline at end of file + +const char* BaseDevice::get_version() +{ +#ifdef HASP_MODEL + return (QUOTE(HASP_VER_MAJ) "." QUOTE(HASP_VER_MIN) "." QUOTE(HASP_VER_REV)); +#else + return PIOENV; +#endif +} + +const char* BaseDevice::get_hostname() +{ + return _hostname; //.c_str(); +} + +void BaseDevice::set_hostname(const char* hostname) +{ + strncpy(_hostname, hostname, STR_LEN_HOSTNAME); +} + +} // namespace dev \ No newline at end of file diff --git a/src/dev/device.h b/src/dev/device.h index 61b8d01c..6e644513 100644 --- a/src/dev/device.h +++ b/src/dev/device.h @@ -20,6 +20,8 @@ #include "ArduinoJson.h" +#define STR_LEN_HOSTNAME 64 + namespace dev { class BaseDevice { @@ -29,13 +31,9 @@ class BaseDevice { virtual void reboot() {} - virtual const char* get_hostname() - { - return ""; - } - virtual void set_hostname(const char*) - {} - virtual const char* get_core_version() + const char* get_hostname(); + void set_hostname(const char*); + const char* get_core_version() { return ""; } @@ -44,6 +42,7 @@ class BaseDevice { return ""; } virtual const char* get_model(); + virtual const char* get_version(); virtual const char* get_hardware_id() { return ""; @@ -100,6 +99,10 @@ class BaseDevice { snprintf(buffer, sizeof(buffer), "%d", pin); return buffer; } + + private: + // std::string _hostname; + char _hostname[STR_LEN_HOSTNAME]; }; } // namespace dev diff --git a/src/dev/esp32/esp32.cpp b/src/dev/esp32/esp32.cpp index d1e0b824..6fcdc0a2 100644 --- a/src/dev/esp32/esp32.cpp +++ b/src/dev/esp32/esp32.cpp @@ -97,7 +97,7 @@ static void halGetResetInfo(String& resetReason) Esp32Device::Esp32Device() { - _hostname = MQTT_NODENAME; + BaseDevice::set_hostname(MQTT_NODENAME); _backlight_invert = (TFT_BACKLIGHT_ON == LOW); _backlight_power = 1; _backlight_level = 255; @@ -129,14 +129,6 @@ void Esp32Device::show_info() if(_sketch_size == 0) _sketch_size = ESP.getSketchSize(); // slow: takes ~1 second } -const char* Esp32Device::get_hostname() -{ - return _hostname.c_str(); -} -void Esp32Device::set_hostname(const char* hostname) -{ - _hostname = hostname; -} const char* Esp32Device::get_core_version() { return esp_get_idf_version(); // == ESP.getSdkVersion(); diff --git a/src/dev/esp32/esp32.h b/src/dev/esp32/esp32.h index cb217599..38bf9db2 100644 --- a/src/dev/esp32/esp32.h +++ b/src/dev/esp32/esp32.h @@ -19,8 +19,6 @@ class Esp32Device : public BaseDevice { void reboot() override; void show_info() override; - const char* get_hostname(); - void set_hostname(const char*); const char* get_core_version(); const char* get_chip_model(); const char* get_hardware_id(); @@ -40,7 +38,6 @@ class Esp32Device : public BaseDevice { bool is_system_pin(uint8_t pin) override; private: - std::string _hostname; std::string _hardware_id; uint32_t _sketch_size; // cached because function is slow diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index e40acd88..848d9dd6 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -534,10 +534,10 @@ void hasp_background(uint16_t pageid, uint16_t imageid) /////////////////////////////////////////////////////////////////////////////////////////////////////////// -void haspGetVersion(char* version, size_t len) -{ - snprintf_P(version, len, PSTR("%u.%u.%u"), HASP_VER_MAJ, HASP_VER_MIN, HASP_VER_REV); -} +// void haspGetVersion(char* version, size_t len) +// { +// snprintf_P(version, len, PSTR("%u.%u.%u"), HASP_VER_MAJ, HASP_VER_MIN, HASP_VER_REV); +// } void haspClearPage(uint16_t pageid) { @@ -577,8 +577,7 @@ void hasp_get_info(JsonDocument& doc) char size_buf[32]; JsonObject info = doc.createNestedObject(F(D_MANUFACTURER)); - haspGetVersion(size_buf, sizeof(size_buf)); - info[F(D_INFO_VERSION)] = size_buf; + info[F(D_INFO_VERSION)] = haspDevice.get_version(); buffer = __DATE__; buffer += (" "); diff --git a/src/hasp/hasp.h b/src/hasp/hasp.h index 0db81f9f..632d615f 100644 --- a/src/hasp/hasp.h +++ b/src/hasp/hasp.h @@ -50,7 +50,7 @@ void haspEverySecond(void); void haspReconnect(void); void haspDisconnect(void); -void haspGetVersion(char* version, size_t len); +// void haspGetVersion(char* version, size_t len); // void haspBackground(uint16_t pageid, uint16_t imageid); // void haspNewObject(const JsonObject & config, uint8_t & saved_page_id); diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index e8f50378..cbb92472 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -810,6 +810,7 @@ void dispatch_send_discovery(const char*, const char*) doc[F("mf")] = F(D_MANUFACTURER); doc[F("hwid")] = haspDevice.get_hardware_id(); doc[F("pages")] = haspPages.count(); + doc[F("sw")] = haspDevice.get_version(); JsonObject input = doc.createNestedObject(F("input")); JsonArray relay = doc.createNestedArray(F("power")); @@ -821,10 +822,8 @@ void dispatch_send_discovery(const char*, const char*) #endif char data[1024]; - haspGetVersion(data, sizeof(data)); - doc[F("sw")] = data; - size_t len = serializeJson(doc, data); + switch(mqtt_send_discovery(data, len)) { case MQTT_ERR_OK: LOG_TRACE(TAG_MQTT_PUB, F(MQTT_TOPIC_DISCOVERY " => %s"), data); @@ -854,9 +853,9 @@ void dispatch_statusupdate(const char*, const char*) char buffer[128]; hasp_get_sleep_state(topic); - haspGetVersion(buffer, sizeof(buffer)); snprintf_P(data, sizeof(data), PSTR("{\"node\":\"%s\",\"idle\":\"%s\",\"version\":\"%s\",\"uptime\":%lu,"), - haspDevice.get_hostname(), topic, buffer, long(millis() / 1000)); // \"status\":\"available\", + haspDevice.get_hostname(), topic, haspDevice.get_version(), + long(millis() / 1000)); // \"status\":\"available\", #if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0 network_get_statusupdate(buffer, sizeof(buffer)); diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 1fbc44a8..699a02fc 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -177,9 +177,6 @@ void debugLvglLogEvent(lv_log_level_t level, const char* file, uint32_t line, co // Send the HASP header and version to the output device specified void debugPrintHaspHeader(Print* output) { - char buffer[16]; - haspGetVersion(buffer, sizeof(buffer)); - #ifdef ARDUINO if(debugAnsiCodes) output->print(TERM_COLOR_YELLOW); output->println(); @@ -190,7 +187,7 @@ void debugPrintHaspHeader(Print* output) " |__|__|__|__|_____|__|\r\n" " Home Automation Switch Plate\r\n" " Open Hardware edition v")); - output->println(buffer); + output->println(haspDevice.get_version()); output->println(); #else if(debugAnsiCodes) debug_print(output, TERM_COLOR_YELLOW); @@ -201,7 +198,7 @@ void debugPrintHaspHeader(Print* output) " |__|__|__|__|_____|__|\r\n" " Home Automation Switch Plate\r\n" " Open Hardware edition v")); - debug_print(output, buffer); + debug_print(output, haspDevice.get_version()); debug_newline(output); debug_newline(output); #endif diff --git a/src/mqtt/hasp_mqtt_ha.cpp b/src/mqtt/hasp_mqtt_ha.cpp index a4adbd41..190105f8 100644 --- a/src/mqtt/hasp_mqtt_ha.cpp +++ b/src/mqtt/hasp_mqtt_ha.cpp @@ -75,10 +75,7 @@ void mqtt_ha_add_device_ids(JsonDocument& doc) ids.add(haspDevice.get_hostname()); ids.add(HASP_MAC_ADDRESS_STR); - char buffer[32]; - haspGetVersion(buffer, sizeof(buffer)); - device[F("sw")] = buffer; - + device[F("sw")] = haspDevice.get_version(); device[FPSTR(FP_MQTT_HA_NAME)] = haspDevice.get_hostname(); device[FPSTR(FP_MQTT_HA_MODEL)] = F(PIOENV); device[FPSTR(FP_MQTT_HA_MANUFACTURER)] = F(D_MANUFACTURER); diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index cac82c5f..136d912f 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -250,16 +250,13 @@ bool httpIsAuthenticated(const __FlashStringHelper* notused) void webSendFooter() { - char buffer[16]; - haspGetVersion(buffer, sizeof(buffer)); - #if defined(STM32F4xx) webServer.sendContent(HTTP_END); - webServer.sendContent(buffer); + webServer.sendContent(haspDevice.get_version()); webServer.sendContent(HTTP_FOOTER); #else webServer.sendContent_P(HTTP_END); - webServer.sendContent(buffer); + webServer.sendContent(haspDevice.get_version()); webServer.sendContent_P(HTTP_FOOTER); #endif } @@ -279,10 +276,9 @@ void webSendPage(const char* nodename, uint32_t httpdatalength, bool gohome = fa { { char buffer[64]; - haspGetVersion(buffer, sizeof(buffer)); /* Calculate Content Length upfront */ - uint32_t contentLength = strlen(buffer); // version length + uint32_t contentLength = strlen(haspDevice.get_version()); // version length contentLength += sizeof(HTTP_DOCTYPE) - 1; contentLength += sizeof(HTTP_HEADER) - 1 - 2 + strlen(nodename); // -2 for %s contentLength += sizeof(HTTP_SCRIPT) - 1; @@ -624,11 +620,7 @@ void webHandleInfo() /* HASP Stats */ httpMessage += F("HASP Version: "); - { - char version[32]; - haspGetVersion(version, sizeof(version)); - httpMessage += version; - } + httpMessage += haspDevice.get_version(); httpMessage += F("
Build DateTime: "); httpMessage += __DATE__; httpMessage += F(" "); diff --git a/src/sys/svc/hasp_mdns.cpp b/src/sys/svc/hasp_mdns.cpp index 464db38d..35761d98 100644 --- a/src/sys/svc/hasp_mdns.cpp +++ b/src/sys/svc/hasp_mdns.cpp @@ -60,8 +60,7 @@ void mdnsStart() MDNS.addService(service, proto, 80); strcpy_P(key, PSTR("app_version")); - haspGetVersion(value, sizeof(value)); - MDNS.addServiceTxt(service, proto, key, value); + MDNS.addServiceTxt(service, proto, key, haspDevice.get_version()); strcpy_P(key, PSTR("app_name")); strcpy_P(value, PSTR(D_MANUFACTURER)); diff --git a/src/sys/svc/hasp_slave.cpp b/src/sys/svc/hasp_slave.cpp index 39abf4df..d3259e1c 100644 --- a/src/sys/svc/hasp_slave.cpp +++ b/src/sys/svc/hasp_slave.cpp @@ -70,10 +70,9 @@ void TASMO_TELE_JSON() char data[3 * 128]; { char buffer[128]; - haspGetVersion(buffer, sizeof(buffer)); - snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"), buffer, - long(millis() / 1000)); + snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"), + haspDevice.get_version(), long(millis() / 1000)); snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"), haspGetPage(), (HASP_NUM_PAGES)); From 62540e8443d79a89c561515b178ff23fd3e12c0f Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 04:20:05 +0200 Subject: [PATCH 221/227] Add static_text for labels --- src/hasp/hasp_attribute.h | 6 ++++++ src/hasp/hasp_attribute_helper.h | 36 +++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index 0e8db12a..792d1fed 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -451,4 +451,10 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_OBJID 41010 #define ATTR_OBJ 53623 +#define ATTR_TEXT_MAC 38107 +#define ATTR_TEXT_IP 41785 +#define ATTR_TEXT_HOSTNAME 10125 +#define ATTR_TEXT_MODEL 54561 +#define ATTR_TEXT_VERSION 60178 + #endif diff --git a/src/hasp/hasp_attribute_helper.h b/src/hasp/hasp_attribute_helper.h index 15379023..e7df8cd2 100644 --- a/src/hasp/hasp_attribute_helper.h +++ b/src/hasp/hasp_attribute_helper.h @@ -138,24 +138,36 @@ static const char* my_label_get_text(const lv_obj_t* label) static void my_label_set_text(lv_obj_t* label, const char* text) { if(text[0] == '%') { - uint16_t hash = Parser::get_sdbm(text); - size_t len = strlen(text); - const char* static_text; + uint16_t hash = Parser::get_sdbm(text); + size_t len = strlen(text); + const char* static_text = NULL; switch(hash) { - - case 10125: - static_text = haspDevice.get_hostname(); + case ATTR_TEXT_MAC: + case ATTR_TEXT_IP: + if(len == 4) break; + break; + + case ATTR_TEXT_HOSTNAME: + if(len == 10) static_text = haspDevice.get_hostname(); + break; + + case ATTR_TEXT_MODEL: + if(len == 7) static_text = haspDevice.get_model(); + break; + + case ATTR_TEXT_VERSION: + if(len == 9) static_text = haspDevice.get_version(); break; - default: - lv_label_set_text(label, text); - return; } - lv_label_set_text_static(label, static_text); - } else { - lv_label_set_text(label, text); + if(static_text) { + lv_label_set_text_static(label, static_text); + return; + } } + + lv_label_set_text(label, text); } // OK From 952ab55b983cc06a5410fc5a0197bba5267b4545 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 13:41:00 +0200 Subject: [PATCH 222/227] Add ssid and ip dynamic text parameters --- src/hasp/hasp_attribute.h | 1 + src/hasp/hasp_attribute_helper.h | 28 ++++++++++++++++++---------- src/sys/net/hasp_wifi.cpp | 24 ++++++++++++++++++------ src/sys/net/hasp_wifi.h | 2 ++ 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/hasp/hasp_attribute.h b/src/hasp/hasp_attribute.h index 792d1fed..f35cac27 100644 --- a/src/hasp/hasp_attribute.h +++ b/src/hasp/hasp_attribute.h @@ -456,5 +456,6 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_TEXT_HOSTNAME 10125 #define ATTR_TEXT_MODEL 54561 #define ATTR_TEXT_VERSION 60178 +#define ATTR_TEXT_SSID 62981 #endif diff --git a/src/hasp/hasp_attribute_helper.h b/src/hasp/hasp_attribute_helper.h index e7df8cd2..0cc2cc15 100644 --- a/src/hasp/hasp_attribute_helper.h +++ b/src/hasp/hasp_attribute_helper.h @@ -120,15 +120,6 @@ lv_obj_t* FindButtonLabel(lv_obj_t* btn) return NULL; } -// OK -static inline void my_btn_set_text(lv_obj_t* obj, const char* value) -{ - lv_obj_t* label = FindButtonLabel(obj); - if(label) { - lv_label_set_text(label, value); - } -} - // OK - lvgl does not return a const char * static const char* my_label_get_text(const lv_obj_t* label) { @@ -144,10 +135,18 @@ static void my_label_set_text(lv_obj_t* label, const char* text) switch(hash) { case ATTR_TEXT_MAC: - case ATTR_TEXT_IP: if(len == 4) break; break; +#if HASP_USE_WIFI > 0 + case ATTR_TEXT_SSID: + if(len == 6) static_text = wifi_get_ssid(); + break; + + case ATTR_TEXT_IP: + if(len == 4) static_text = wifi_get_ip_address(); + break; +#endif case ATTR_TEXT_HOSTNAME: if(len == 10) static_text = haspDevice.get_hostname(); break; @@ -200,6 +199,15 @@ static const char* my_btn_get_text(const lv_obj_t* obj) return NULL; } +// OK +static inline void my_btn_set_text(lv_obj_t* obj, const char* value) +{ + lv_obj_t* label = FindButtonLabel(obj); + if(label) { + my_label_set_text(label, value); + } +} + /** * Set a new value_str for an object. Memory will be allocated to store the text by the object. * @param obj pointer to a object diff --git a/src/sys/net/hasp_wifi.cpp b/src/sys/net/hasp_wifi.cpp index 9cfa1af8..1a55de43 100644 --- a/src/sys/net/hasp_wifi.cpp +++ b/src/sys/net/hasp_wifi.cpp @@ -48,6 +48,7 @@ char wifiPassword[64] = WIFI_PASSW; #else char wifiPassword[64] = ""; #endif +char wifiIpAddress[16] = ""; uint8_t wifiReconnectCounter = 0; // const byte DNS_PORT = 53; @@ -60,10 +61,11 @@ static void wifiConnected(IPAddress ipaddress) #if defined(STM32F4xx) IPAddress ip; ip = WiFi.localIP(); - LOG_TRACE(TAG_WIFI, F("Received IP address %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); + snprintf_P(wifiIpAddress, sizeof(wifiIpAddress), PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); #else - LOG_TRACE(TAG_WIFI, F(D_NETWORK_IP_ADDRESS_RECEIVED), ipaddress.toString().c_str()); + strncpy(wifiIpAddress, ipaddress.toString().c_str(), sizeof(wifiIpAddress)); #endif + LOG_TRACE(TAG_WIFI, F(D_NETWORK_IP_ADDRESS_RECEIVED), wifiIpAddress); LOG_VERBOSE(TAG_WIFI, F("Connected = %s"), WiFi.status() == WL_CONNECTED ? PSTR(D_NETWORK_ONLINE) : PSTR(D_NETWORK_OFFLINE)); @@ -73,8 +75,9 @@ static void wifiConnected(IPAddress ipaddress) static void wifiDisconnected(const char* ssid, uint8_t reason) { wifiReconnectCounter++; + char buffer[64]; - haspProgressVal(wifiReconnectCounter * 3); + // haspProgressVal(wifiReconnectCounter * 3); // networkStop(); if(wifiReconnectCounter > 33) { @@ -82,8 +85,6 @@ static void wifiDisconnected(const char* ssid, uint8_t reason) dispatch_reboot(false); } - char buffer[64]; - switch(reason) { #if defined(ARDUINO_ARCH_ESP8266) case REASON_UNSPECIFIED: @@ -514,11 +515,22 @@ void wifi_get_statusupdate(char* buffer, size_t len) snprintf_P(buffer, len, PSTR("\"ssid\":\"%s\",\"rssi\":%i,\"ip\":\"%d.%d.%d.%d\","), WiFi.SSID(), WiFi.RSSI(), ip[0], ip[1], ip[2], ip[3]); #else + strncpy(wifiIpAddress, WiFi.localIP().toString().c_str(), sizeof(wifiIpAddress)); snprintf_P(buffer, len, PSTR("\"ssid\":\"%s\",\"rssi\":%i,\"ip\":\"%s\","), WiFi.SSID().c_str(), WiFi.RSSI(), - WiFi.localIP().toString().c_str()); + wifiIpAddress); #endif } +const char* wifi_get_ssid() +{ + return wifiSsid; +} + +const char* wifi_get_ip_address() +{ + return wifiIpAddress; +} + void wifi_get_info(JsonDocument& doc) { String buffer((char*)0); diff --git a/src/sys/net/hasp_wifi.h b/src/sys/net/hasp_wifi.h index b949bc9a..7abba5bf 100644 --- a/src/sys/net/hasp_wifi.h +++ b/src/sys/net/hasp_wifi.h @@ -16,6 +16,8 @@ bool wifiValidateSsid(const char* ssid, const char* pass); void wifi_get_statusupdate(char* buffer, size_t len); void wifi_get_info(JsonDocument& doc); +const char* wifi_get_ssid(); +const char* wifi_get_ip_address(); #if HASP_USE_CONFIG > 0 bool wifiGetConfig(const JsonObject& settings); From 95d00076420decc66f46996d694e5b543d5c99ce Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 13:41:24 +0200 Subject: [PATCH 223/227] Code cleanup --- src/hasp/hasp.h | 1 - src/sys/net/hasp_network.cpp | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hasp/hasp.h b/src/hasp/hasp.h index 632d615f..1a76532f 100644 --- a/src/hasp/hasp.h +++ b/src/hasp/hasp.h @@ -50,7 +50,6 @@ void haspEverySecond(void); void haspReconnect(void); void haspDisconnect(void); -// void haspGetVersion(char* version, size_t len); // void haspBackground(uint16_t pageid, uint16_t imageid); // void haspNewObject(const JsonObject & config, uint8_t & saved_page_id); diff --git a/src/sys/net/hasp_network.cpp b/src/sys/net/hasp_network.cpp index 820a85bd..17b2fa86 100644 --- a/src/sys/net/hasp_network.cpp +++ b/src/sys/net/hasp_network.cpp @@ -3,9 +3,7 @@ #include #include -// #ifdef USE_CONFIG_OVERRIDE -// #include "user_config_override.h" -// #endif + #include #include "ArduinoLog.h" @@ -29,7 +27,7 @@ void networkStart(void) configTzTime(MYTZ, "pool.ntp.org", "time.nist.gov", NULL); // literal string #endif - haspProgressVal(255); // hide + // haspProgressVal(255); // hide haspReconnect(); debugStartSyslog(); // mqttStart(); From 35da04d96a92f5562d748d787d87784525fae62c Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Tue, 18 May 2021 13:42:52 +0200 Subject: [PATCH 224/227] Version bump TFT_eSPI@^2.3.69 --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index a15bf3f5..c245956f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -75,7 +75,7 @@ lib_deps = ;git+https://github.com/andrethomas/TasmotaSlave.git ;git+https://github.com/lvgl/lvgl.git lvgl/lvgl@^7.11.0 ; from PIO library - bodmer/TFT_eSPI@^2.3.67 + bodmer/TFT_eSPI@^2.3.69 ;git+https://github.com/Bodmer/TFT_eSPI.git ; ------ Unused / Test libraries ;https://github.com/netwizeBE/TFT_eSPI.git From 083c8caad3236c606fb10d4049908eb36fb366b5 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 20 May 2021 13:48:34 +0200 Subject: [PATCH 225/227] Set font sizes to HASP_FONT_SIZE_x --- src/hasp/hasp_attribute.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 258af713..558f579e 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -197,24 +197,24 @@ static lv_font_t* haspPayloadToFont(const char* payload) #ifndef ARDUINO_ARCH_ESP8266 #ifdef HASP_FONT_1 - case 12: + case HASP_FONT_SIZE_1: return &HASP_FONT_1; #endif #ifdef HASP_FONT_2 - case 16: + case HASP_FONT_SIZE_2: LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_2); return &HASP_FONT_2; #endif #ifdef HASP_FONT_3 - case 22: + case HASP_FONT_SIZE_3: LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_3); return &HASP_FONT_3; #endif #ifdef HASP_FONT_4 - case 28: + case HASP_FONT_SIZE_4: LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_4); return &HASP_FONT_4; #endif @@ -1833,7 +1833,8 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char int32_t val; char temp_buffer[128] = ""; // buffer to hold return strings char* text = &temp_buffer[0]; // pointer to temp_buffer - hasp_attribute_type_t ret; // the return code determines the attribute return value type + hasp_attribute_type_t ret = + hasp_attribute_type_t::ATTR_NOT_FOUND; // the return code determines the attribute return value type uint16_t attr_hash = Parser::get_sdbm(attribute); switch(attr_hash) { @@ -2019,6 +2020,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char } else { ret = ATTR_NOT_FOUND; } + LOG_VERBOSE(TAG_ATTR, "%s %d ret:%d", __FILE__, __LINE__, ret); } // Positive return codes have returned a value, negative are warnings From 12344b8c738be457b17e1d8001762055c26b42ee Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 20 May 2021 13:54:16 +0200 Subject: [PATCH 226/227] Set font sizes to HASP_FONT_SIZE_x --- include/lv_conf_v7.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index 8c2acb9d..707000e7 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -407,6 +407,19 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in #endif // WT32SC01 +#ifndef HASP_FONT_SIZE_1 +#define HASP_FONT_SIZE_1 16 +#endif +#ifndef HASP_FONT_SIZE_2 +#define HASP_FONT_SIZE_2 24 +#endif +#ifndef HASP_FONT_SIZE_3 +#define HASP_FONT_SIZE_3 32 +#endif +#ifndef HASP_FONT_SIZE_4 +#define HASP_FONT_SIZE_4 48 +#endif + #else // not 320x480 #ifndef HASP_FONT_1 @@ -435,6 +448,19 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in #define ROBOTOCONDENSED_REGULAR_32_LATIN1 1 #endif +#ifndef HASP_FONT_SIZE_1 +#define HASP_FONT_SIZE_1 12 +#endif +#ifndef HASP_FONT_SIZE_2 +#define HASP_FONT_SIZE_2 16 +#endif +#ifndef HASP_FONT_SIZE_3 +#define HASP_FONT_SIZE_3 24 +#endif +#ifndef HASP_FONT_SIZE_4 +#define HASP_FONT_SIZE_4 32 +#endif + #endif /* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. From f10494b268dc2eaebc79c93db2ed4558a35be4fe Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Thu, 20 May 2021 15:35:56 +0200 Subject: [PATCH 227/227] Fix typo --- src/hasp/hasp_attribute.cpp | 2 +- src/main_arduino.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 558f579e..4010eff6 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -2051,7 +2051,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char break; case ATTR_TYPE_COLOR_INVALID: - LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_ALIGN_INVALID), payload); + LOG_WARNING(TAG_ATTR, F(D_ATTRIBUTE_COLOR_INVALID), payload); break; case ATTR_TYPE_COLOR: diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index dea795c5..292030cf 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -170,9 +170,10 @@ IRAM_ATTR void loop() case 5: mainLoopCounter = 0; - if(statLoopCounter) - LOG_VERBOSE(TAG_MAIN, F("%d millis per loop, %d counted"), 5000 / statLoopCounter, statLoopCounter); - statLoopCounter = 0; + // if(statLoopCounter) + // LOG_VERBOSE(TAG_MAIN, F("%d millis per loop, %d counted"), 5000 / statLoopCounter, + // statLoopCounter); + // statLoopCounter = 0; break; } }