From 6d6e1b99ef658c988ee23d51942b8f2fee8bc9ab Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 26 Feb 2021 23:24:46 +0100 Subject: [PATCH 01/18] Make commands array autosized --- src/hasp/hasp_dispatch.cpp | 88 +++++++++++++++++++------------------- src/hasp/hasp_dispatch.h | 2 +- 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 55eb8770..16491f63 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -40,10 +40,48 @@ extern uint8_t hasp_sleep_state; dispatch_conf_t dispatch_setings = {.teleperiod = 10}; - uint32_t dispatchLastMillis; -uint8_t nCommands = 0; -haspCommand_t commands[17]; + +/* Declare all Command Handlers */ +void dispatch_parse_json(const char*, const char* payload); +void dispatch_parse_jsonl(const char*, const char* payload); +void dispatch_page(const char*, const char* payload); +void dispatch_wakeup(const char*, const char* payload); +void dispatch_output_statusupdate(const char*, const char* payload); +void dispatch_clear_page(const char*, const char* payload); +void dispatch_dim(const char*, const char* payload); +void dispatch_backlight(const char*, const char* payload); +void dispatch_moodlight(const char*, const char* payload); +void dispatch_calibrate(const char*, const char* payload); +void dispatch_web_update(const char*, const char* payload); +void dispatch_reboot(const char*, const char* payload); +void dispatch_screenshot(const char*, const char* payload); +void dispatch_factory_reset(const char*, const char* payload); + +/* Map Commands to Command Handlers */ +haspCommand_t commands[] = { + + {PSTR("json"), dispatch_parse_json}, + {PSTR("page"), dispatch_page}, + {PSTR("wakeup"), dispatch_wakeup}, + {PSTR("statusupdate"), dispatch_output_statusupdate}, + {PSTR("clearpage"), dispatch_clear_page}, + {PSTR("jsonl"), dispatch_parse_jsonl}, + {PSTR("dim"), dispatch_dim}, + {PSTR("brightness"), dispatch_dim}, + {PSTR("light"), dispatch_backlight}, + {PSTR("moodlight"), dispatch_moodlight}, + {PSTR("calibrate"), dispatch_calibrate}, + {PSTR("update"), dispatch_web_update}, + {PSTR("reboot"), dispatch_reboot}, + {PSTR("restart"), dispatch_reboot}, + {PSTR("screenshot"), dispatch_screenshot}, +#if HASP_USE_CONFIG > 0 + {PSTR("setupap"), oobeFakeSetup}, +#endif + {PSTR("factoryreset"), dispatch_factory_reset} + +}; struct moodlight_t { @@ -59,7 +97,6 @@ static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const void dispatch_screenshot(const char*, const char* filename) { #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 - if(strlen(filename) == 0) { // no filename given char tempfile[32]; memcpy_P(tempfile, PSTR("/screenshot.bmp"), sizeof(tempfile)); @@ -200,7 +237,7 @@ void dispatch_command(const char* topic, const char* payload) /* ================================= Standard payload commands ======================================= */ // check and execute commands from commands array - for(int i = 0; i < nCommands; i++) { + for(int i = 0; i < sizeof(commands) / sizeof(haspCommand_t); i++) { if(!strcasecmp_P(topic, commands[i].p_cmdstr)) { // LOG_DEBUG(TAG_MSGR, F("Command %d found in array !!!"), i); commands[i].func(topic, payload); /* execute command */ @@ -901,7 +938,6 @@ void dispatch_current_state() void dispatch_output_statusupdate(const char*, const char*) { #if HASP_USE_MQTT > 0 - char data[3 * 128]; { char buffer[128]; @@ -970,46 +1006,8 @@ void dispatch_factory_reset(const char*, const char*) /******************************************* Commands builder *******************************************/ -static void dispatch_add_command(const char* p_cmdstr, void (*func)(const char*, const char*)) -{ - if(nCommands >= sizeof(commands) / sizeof(haspCommand_t)) { - LOG_FATAL(TAG_MSGR, F("CMD_OVERFLOW %d"), nCommands); - while(1) { - } - } else { - commands[nCommands].p_cmdstr = p_cmdstr; - commands[nCommands].func = func; - nCommands++; - } -} - void dispatchSetup() -{ - // In order of importance : commands are NOT case-sensitive - // The command.func() call will receive the full topic and payload parameters! - - /* 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); - dispatch_add_command(PSTR("wakeup"), dispatch_wakeup); - dispatch_add_command(PSTR("statusupdate"), dispatch_output_statusupdate); - dispatch_add_command(PSTR("clearpage"), dispatch_clear_page); - dispatch_add_command(PSTR("jsonl"), dispatch_parse_jsonl); - dispatch_add_command(PSTR("dim"), dispatch_dim); - dispatch_add_command(PSTR("brightness"), dispatch_dim); - dispatch_add_command(PSTR("light"), dispatch_backlight); - dispatch_add_command(PSTR("moodlight"), dispatch_moodlight); - dispatch_add_command(PSTR("calibrate"), dispatch_calibrate); - dispatch_add_command(PSTR("update"), dispatch_web_update); - 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("factoryreset"), dispatch_factory_reset); -#if HASP_USE_CONFIG > 0 - dispatch_add_command(PSTR("setupap"), oobeFakeSetup); -#endif - /* WARNING: remember to expand the commands array when adding new commands */ -} +{} void dispatchLoop() { diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index 39f8cacc..1dba3b41 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -79,8 +79,8 @@ void dispatch_send_obj_attribute_color(uint8_t pageid, uint8_t btnid, const char /* ===== Structs and Constants ===== */ struct haspCommand_t { - void (*func)(const char*, const char*); const char* p_cmdstr; + void (*func)(const char*, const char*); }; #endif \ No newline at end of file From da00c41a21b24b360889ed76eb4b49d49e989304 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Fri, 26 Feb 2021 23:52:54 +0100 Subject: [PATCH 02/18] Move dispatchSetup to haspSetup --- src/hasp/hasp.cpp | 1 + src/hasp/hasp_dispatch.cpp | 88 +++++++++++++++++++------------------- src/main_arduino.cpp | 3 +- src/main_windows.cpp | 3 +- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 0cc018be..dbae6d46 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -319,6 +319,7 @@ static void custom_font_apply_cb(lv_theme_t* th, lv_obj_t* obj, lv_theme_style_t */ void haspSetup(void) { + dispatchSetup(); haspDevice.set_backlight_level(haspStartDim); /******* File System Test ********************************************************************/ diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 16491f63..55eb8770 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -40,48 +40,10 @@ extern uint8_t hasp_sleep_state; dispatch_conf_t dispatch_setings = {.teleperiod = 10}; + uint32_t dispatchLastMillis; - -/* Declare all Command Handlers */ -void dispatch_parse_json(const char*, const char* payload); -void dispatch_parse_jsonl(const char*, const char* payload); -void dispatch_page(const char*, const char* payload); -void dispatch_wakeup(const char*, const char* payload); -void dispatch_output_statusupdate(const char*, const char* payload); -void dispatch_clear_page(const char*, const char* payload); -void dispatch_dim(const char*, const char* payload); -void dispatch_backlight(const char*, const char* payload); -void dispatch_moodlight(const char*, const char* payload); -void dispatch_calibrate(const char*, const char* payload); -void dispatch_web_update(const char*, const char* payload); -void dispatch_reboot(const char*, const char* payload); -void dispatch_screenshot(const char*, const char* payload); -void dispatch_factory_reset(const char*, const char* payload); - -/* Map Commands to Command Handlers */ -haspCommand_t commands[] = { - - {PSTR("json"), dispatch_parse_json}, - {PSTR("page"), dispatch_page}, - {PSTR("wakeup"), dispatch_wakeup}, - {PSTR("statusupdate"), dispatch_output_statusupdate}, - {PSTR("clearpage"), dispatch_clear_page}, - {PSTR("jsonl"), dispatch_parse_jsonl}, - {PSTR("dim"), dispatch_dim}, - {PSTR("brightness"), dispatch_dim}, - {PSTR("light"), dispatch_backlight}, - {PSTR("moodlight"), dispatch_moodlight}, - {PSTR("calibrate"), dispatch_calibrate}, - {PSTR("update"), dispatch_web_update}, - {PSTR("reboot"), dispatch_reboot}, - {PSTR("restart"), dispatch_reboot}, - {PSTR("screenshot"), dispatch_screenshot}, -#if HASP_USE_CONFIG > 0 - {PSTR("setupap"), oobeFakeSetup}, -#endif - {PSTR("factoryreset"), dispatch_factory_reset} - -}; +uint8_t nCommands = 0; +haspCommand_t commands[17]; struct moodlight_t { @@ -97,6 +59,7 @@ static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const void dispatch_screenshot(const char*, const char* filename) { #if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 + if(strlen(filename) == 0) { // no filename given char tempfile[32]; memcpy_P(tempfile, PSTR("/screenshot.bmp"), sizeof(tempfile)); @@ -237,7 +200,7 @@ void dispatch_command(const char* topic, const char* payload) /* ================================= Standard payload commands ======================================= */ // check and execute commands from commands array - for(int i = 0; i < sizeof(commands) / sizeof(haspCommand_t); i++) { + for(int i = 0; i < nCommands; i++) { if(!strcasecmp_P(topic, commands[i].p_cmdstr)) { // LOG_DEBUG(TAG_MSGR, F("Command %d found in array !!!"), i); commands[i].func(topic, payload); /* execute command */ @@ -938,6 +901,7 @@ void dispatch_current_state() void dispatch_output_statusupdate(const char*, const char*) { #if HASP_USE_MQTT > 0 + char data[3 * 128]; { char buffer[128]; @@ -1006,8 +970,46 @@ void dispatch_factory_reset(const char*, const char*) /******************************************* Commands builder *******************************************/ +static void dispatch_add_command(const char* p_cmdstr, void (*func)(const char*, const char*)) +{ + if(nCommands >= sizeof(commands) / sizeof(haspCommand_t)) { + LOG_FATAL(TAG_MSGR, F("CMD_OVERFLOW %d"), nCommands); + while(1) { + } + } else { + commands[nCommands].p_cmdstr = p_cmdstr; + commands[nCommands].func = func; + nCommands++; + } +} + void dispatchSetup() -{} +{ + // In order of importance : commands are NOT case-sensitive + // The command.func() call will receive the full topic and payload parameters! + + /* 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); + dispatch_add_command(PSTR("wakeup"), dispatch_wakeup); + dispatch_add_command(PSTR("statusupdate"), dispatch_output_statusupdate); + dispatch_add_command(PSTR("clearpage"), dispatch_clear_page); + dispatch_add_command(PSTR("jsonl"), dispatch_parse_jsonl); + dispatch_add_command(PSTR("dim"), dispatch_dim); + dispatch_add_command(PSTR("brightness"), dispatch_dim); + dispatch_add_command(PSTR("light"), dispatch_backlight); + dispatch_add_command(PSTR("moodlight"), dispatch_moodlight); + dispatch_add_command(PSTR("calibrate"), dispatch_calibrate); + dispatch_add_command(PSTR("update"), dispatch_web_update); + 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("factoryreset"), dispatch_factory_reset); +#if HASP_USE_CONFIG > 0 + dispatch_add_command(PSTR("setupap"), oobeFakeSetup); +#endif + /* WARNING: remember to expand the commands array when adding new commands */ +} void dispatchLoop() { diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index 3b014ace..8dfec4c7 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -57,7 +57,6 @@ void setup() configSetup(); // also runs debugPreSetup(), debugSetup() and debugStart() #endif - dispatchSetup(); guiSetup(); debugSetup(); // Init the console @@ -100,7 +99,7 @@ void setup() telnetSetup(); #endif -#if HASP_USE_TASMOTA_CLINET > 0 +#if HASP_USE_TASMOTA_CLIENT > 0 slaveSetup(); #endif diff --git a/src/main_windows.cpp b/src/main_windows.cpp index 8ccf9171..2efb6f21 100644 --- a/src/main_windows.cpp +++ b/src/main_windows.cpp @@ -103,9 +103,8 @@ void setup() lv_log_register_print_cb(debugLvglLogEvent); lv_init(); - haspDevice.init(); + haspDevice.init(); // hardware setup // hal_setup(); - dispatchSetup(); guiSetup(); // debugSetup(); // Init the console From 80052140f347c681eee2ce2bd525be0c97df0b2d Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 27 Feb 2021 01:17:51 +0100 Subject: [PATCH 03/18] Add lvfs config --- include/lv_conf_v7.h | 14 +- lib/lv_fs_if/lv_fs_pc.c | 219 ++++++++++++++------------ src/hasp/hasp_lvfs.cpp | 36 +++++ src/hasp/hasp_lvfs.h | 9 ++ src/hasp_gui.cpp | 9 +- src/hasplib.h | 1 + user_setups/win32/emulator_64bits.ini | 1 - 7 files changed, 176 insertions(+), 113 deletions(-) create mode 100644 src/hasp/hasp_lvfs.cpp create mode 100644 src/hasp/hasp_lvfs.h diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h index 0e7024f5..68955047 100644 --- a/include/lv_conf_v7.h +++ b/include/lv_conf_v7.h @@ -5,9 +5,9 @@ #if 1 /*Set it to "1" to enable content*/ - #ifndef LV_CONF_H - #define LV_CONF_H - /* clang-format off */ +#ifndef LV_CONF_H +#define LV_CONF_H +/* clang-format off */ #include @@ -183,14 +183,14 @@ 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(ARDUINO_ARCH_ESP32) // || defined(ARDUINO_ARCH_ESP8266) -# define LV_FS_IF_PC 'S' +#if defined(STM32F4xx) // || defined(ARDUINO_ARCH_ESP8266) +# define LV_FS_IF_PC '\0' # define LV_FS_IF_SPIFFS '\0' // internal esp Flash #else -# define LV_FS_IF_PC '\0' +# define LV_FS_IF_PC 'S' # define LV_FS_IF_SPIFFS '\0' // no internal esp Flash #endif #endif /*LV_USE_FS_IF*/ diff --git a/lib/lv_fs_if/lv_fs_pc.c b/lib/lv_fs_if/lv_fs_pc.c index d76ab87e..e3dd160d 100644 --- a/lib/lv_fs_if/lv_fs_pc.c +++ b/lib/lv_fs_if/lv_fs_pc.c @@ -8,58 +8,62 @@ *********************/ #include "lv_fs_if.h" #if LV_USE_FS_IF - #if LV_FS_IF_PC != '\0' +#if LV_FS_IF_PC != '\0' - #include - #include - #include - #include - #ifdef WIN32 - #include - #endif +#include +#include +#include +#if !defined(ARDUINO_ARCH_ESP8266) && !defined(STM32F4xx) +#include +#endif +#ifdef WIN32 +#include +#endif - /********************* - * DEFINES - *********************/ - #ifndef LV_FS_PC_PATH - #ifndef WIN32 - #define LV_FS_PC_PATH "/fs" /*Projet root*/ - #else - #define LV_FS_PC_PATH ".\\" /*Projet root*/ - #endif - #endif /*LV_FS_PATH*/ +/********************* + * DEFINES + *********************/ +#ifndef LV_FS_PC_PATH +#ifndef WIN32 +#define LV_FS_PC_PATH "/fs" /*Projet root*/ +#else +#define LV_FS_PC_PATH ".\\" /*Projet root*/ +#endif +#endif /*LV_FS_PATH*/ /********************** * TYPEDEFS **********************/ /* Create a type to store the required data about your file. */ -typedef FILE * file_t; +typedef FILE* file_t; - /*Similarly to `file_t` create a type for directory reading too */ - #ifndef WIN32 -typedef DIR * dir_t; - #else +/*Similarly to `file_t` create a type for directory reading too */ +#if defined(WIN32) typedef HANDLE dir_t; - #endif +#elif defined(ARDUINO_ARCH_ESP8266) || defined(STM32F4xx) +typedef FILE* dir_t; +#else +typedef DIR* dir_t; +#endif /********************** * STATIC PROTOTYPES **********************/ -static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode); -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); -static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); -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); -static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); -static lv_fs_res_t fs_remove(lv_fs_drv_t * drv, const char * path); -static lv_fs_res_t fs_trunc(lv_fs_drv_t * drv, void * file_p); -static lv_fs_res_t fs_rename(lv_fs_drv_t * drv, const char * oldname, const char * newname); -static lv_fs_res_t fs_free(lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p); -static lv_fs_res_t fs_dir_open(lv_fs_drv_t * drv, void * dir_p, const char * path); -static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn); -static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p); +static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode); +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); +static lv_fs_res_t fs_write(lv_fs_drv_t* drv, void* file_p, const void* buf, uint32_t btw, uint32_t* bw); +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); +static lv_fs_res_t fs_tell(lv_fs_drv_t* drv, void* file_p, uint32_t* pos_p); +static lv_fs_res_t fs_remove(lv_fs_drv_t* drv, const char* path); +static lv_fs_res_t fs_trunc(lv_fs_drv_t* drv, void* file_p); +static lv_fs_res_t fs_rename(lv_fs_drv_t* drv, const char* oldname, const char* newname); +static lv_fs_res_t fs_free(lv_fs_drv_t* drv, uint32_t* total_p, uint32_t* free_p); +static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path); +static lv_fs_res_t fs_dir_read(lv_fs_drv_t* drv, void* dir_p, char* fn); +static lv_fs_res_t fs_dir_close(lv_fs_drv_t* drv, void* dir_p); /********************** * STATIC VARIABLES @@ -121,12 +125,12 @@ void lv_fs_if_pc_init(void) * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) +static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { (void)drv; /*Unused*/ errno = 0; - const char * flags = ""; + const char* flags = ""; if(mode == LV_FS_MODE_WR) flags = "wb"; @@ -135,16 +139,16 @@ static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = "rb+"; - /*Make the path relative to the current directory (the projects root folder)*/ + /*Make the path relative to the current directory (the projects root folder)*/ - #ifndef WIN32 +#ifndef WIN32 char buf[256]; sprintf(buf, LV_FS_PC_PATH "/%s", path); printf("%s\n", buf); - #else +#else char buf[256]; sprintf(buf, LV_FS_PC_PATH "\\%s", path); - #endif +#endif file_t f = fopen(buf, flags); if(f == NULL) { @@ -156,8 +160,8 @@ static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, /* 'file_p' is pointer to a file descriptor and * we need to store our file descriptor here*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ - *fp = f; + file_t* fp = file_p; /*Just avoid the confusing casings*/ + *fp = f; return LV_FS_RES_OK; } @@ -169,10 +173,10 @@ static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, * @return LV_FS_RES_OK: no error, the file is read * any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) +static lv_fs_res_t fs_close(lv_fs_drv_t* drv, void* file_p) { - (void)drv; /*Unused*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ + (void)drv; /*Unused*/ + file_t* fp = file_p; /*Just avoid the confusing casings*/ fclose(*fp); return LV_FS_RES_OK; } @@ -187,11 +191,11 @@ static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) * @return LV_FS_RES_OK: no error, the file is read * any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +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*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ - *br = fread(buf, 1, btr, *fp); + (void)drv; /*Unused*/ + file_t* fp = file_p; /*Just avoid the confusing casings*/ + *br = fread(buf, 1, btr, *fp); return LV_FS_RES_OK; } @@ -204,11 +208,11 @@ static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_ * @param br the number of real written bytes (Bytes Written). NULL if unused. * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) +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*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ - *bw = fwrite(buf, 1, btw, *fp); + (void)drv; /*Unused*/ + file_t* fp = file_p; /*Just avoid the confusing casings*/ + *bw = fwrite(buf, 1, btw, *fp); return LV_FS_RES_OK; } @@ -220,10 +224,10 @@ static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, * @return LV_FS_RES_OK: no error, the file is read * any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos) +static lv_fs_res_t fs_seek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { - (void)drv; /*Unused*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ + (void)drv; /*Unused*/ + file_t* fp = file_p; /*Just avoid the confusing casings*/ fseek(*fp, pos, SEEK_SET); return LV_FS_RES_OK; } @@ -235,10 +239,10 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos) * @param size pointer to a variable to store the size * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -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_size(lv_fs_drv_t* drv, void* file_p, uint32_t* size_p) { - (void)drv; /*Unused*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ + (void)drv; /*Unused*/ + file_t* fp = file_p; /*Just avoid the confusing casings*/ uint32_t cur = ftell(*fp); @@ -258,11 +262,11 @@ static lv_fs_res_t fs_size(lv_fs_drv_t * drv, void * file_p, uint32_t * size_p) * @return LV_FS_RES_OK: no error, the file is read * any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +static lv_fs_res_t fs_tell(lv_fs_drv_t* drv, void* file_p, uint32_t* pos_p) { - (void)drv; /*Unused*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ - *pos_p = ftell(*fp); + (void)drv; /*Unused*/ + file_t* fp = file_p; /*Just avoid the confusing casings*/ + *pos_p = ftell(*fp); return LV_FS_RES_OK; } @@ -272,7 +276,7 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) * @param path path of the file to delete * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_remove(lv_fs_drv_t * drv, const char * path) +static lv_fs_res_t fs_remove(lv_fs_drv_t* drv, const char* path) { (void)drv; /*Unused*/ lv_fs_res_t res = LV_FS_RES_NOT_IMP; @@ -289,10 +293,10 @@ static lv_fs_res_t fs_remove(lv_fs_drv_t * drv, const char * path) * @return LV_FS_RES_OK: no error, the file is read * any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_trunc(lv_fs_drv_t * drv, void * file_p) +static lv_fs_res_t fs_trunc(lv_fs_drv_t* drv, void* file_p) { - (void)drv; /*Unused*/ - file_t * fp = file_p; /*Just avoid the confusing casings*/ + (void)drv; /*Unused*/ + file_t* fp = file_p; /*Just avoid the confusing casings*/ fflush(*fp); /*If not syncronized fclose can write the truncated part*/ uint32_t p = ftell(*fp); @@ -307,7 +311,7 @@ static lv_fs_res_t fs_trunc(lv_fs_drv_t * drv, void * file_p) * @param newname path with the new name * @return LV_FS_RES_OK or any error from 'fs_res_t' */ -static lv_fs_res_t fs_rename(lv_fs_drv_t * drv, const char * oldname, const char * newname) +static lv_fs_res_t fs_rename(lv_fs_drv_t* drv, const char* oldname, const char* newname) { (void)drv; /*Unused*/ static char new[512]; @@ -316,12 +320,14 @@ static lv_fs_res_t fs_rename(lv_fs_drv_t * drv, const char * oldname, const char sprintf(old, LV_FS_PC_PATH "/%s", oldname); sprintf(new, LV_FS_PC_PATH "/%s", newname); - int r = rename(old, new); + return LV_FS_RES_UNKNOWN; - if(r == 0) - return LV_FS_RES_OK; - else - return LV_FS_RES_UNKNOWN; + // int r = rename(old, new); + + // if(r == 0) + // return LV_FS_RES_OK; + // else + // return LV_FS_RES_UNKNOWN; } /** @@ -332,7 +338,7 @@ static lv_fs_res_t fs_rename(lv_fs_drv_t * drv, const char * oldname, const char * @param free_p pointer to store the free size [kB] * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_free(lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p) +static lv_fs_res_t fs_free(lv_fs_drv_t* drv, uint32_t* total_p, uint32_t* free_p) { (void)drv; /*Unused*/ lv_fs_res_t res = LV_FS_RES_NOT_IMP; @@ -342,9 +348,9 @@ static lv_fs_res_t fs_free(lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * fre return res; } - #ifdef WIN32 +#ifdef WIN32 static char next_fn[256]; - #endif +#endif /** * Initialize a 'fs_read_dir_t' variable for directory reading @@ -353,11 +359,14 @@ static char next_fn[256]; * @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) +static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path) { (void)drv; /*Unused*/ dir_t d; - #ifndef WIN32 +#if defined(ARDUINO_ARCH_ESP8266) || defined(STM32F4xx) + return LV_FS_RES_UNKNOWN; + +#elif !defined(WIN32) /*Make the path relative to the current directory (the projects root folder)*/ char buf[256]; sprintf(buf, LV_FS_PC_PATH "/%s", path); @@ -366,10 +375,10 @@ static lv_fs_res_t fs_dir_open(lv_fs_drv_t * drv, void * dir_p, const char * pat } else { /* 'dir_p' is pointer to a file descriptor and * we need to store our file descriptor here*/ - dir_t * dp = dir_p; /*Just avoid the confusing casings*/ - *dp = d; + dir_t* dp = dir_p; /*Just avoid the confusing casings*/ + *dp = d; } - #else +#else d = INVALID_HANDLE_VALUE; WIN32_FIND_DATA fdata; @@ -393,10 +402,10 @@ static lv_fs_res_t fs_dir_open(lv_fs_drv_t * drv, void * dir_p, const char * pat } } while(FindNextFileA(d, &fdata)); - dir_t * dp = dir_p; /*Just avoid the confusing casings*/ - *dp = d; + dir_t* dp = dir_p; /*Just avoid the confusing casings*/ + *dp = d; - #endif +#endif return LV_FS_RES_OK; } @@ -409,17 +418,18 @@ static lv_fs_res_t fs_dir_open(lv_fs_drv_t * drv, void * dir_p, const char * pat * @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) +static lv_fs_res_t fs_dir_read(lv_fs_drv_t* drv, void* dir_p, char* fn) { - (void)drv; /*Unused*/ - dir_t * dp = dir_p; /*Just avoid the confusing casings*/ + (void)drv; /*Unused*/ + dir_t* dp = dir_p; /*Just avoid the confusing casings*/ - #ifndef WIN32 - struct dirent * entry; +#ifdef ARDUINO_ARCH_ESP32 + struct dirent* entry; do { entry = readdir(*dp); if(entry) { + if(entry->d_type == DT_DIR) sprintf(fn, "/%s", entry->d_name); else @@ -428,7 +438,9 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn) strcpy(fn, ""); } } while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0); - #else +#endif + +#ifdef WIN32 strcpy(fn, next_fn); strcpy(next_fn, ""); @@ -449,7 +461,7 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn) } } while(FindNextFile(*dp, &fdata)); - #endif +#endif return LV_FS_RES_OK; } @@ -459,18 +471,21 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn) * @param dir_p pointer to an initialized 'fs_read_dir_t' variable * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ -static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p) +static lv_fs_res_t fs_dir_close(lv_fs_drv_t* drv, void* dir_p) { (void)drv; /*Unused*/ - dir_t * dp = dir_p; - #ifndef WIN32 + dir_t* dp = dir_p; +#if defined(ARDUINO_ARCH_ESP8266) || defined(STM32F4xx) + return LV_FS_RES_UNKNOWN; + +#elif !defined(WIN32) closedir(*dp); - #else +#else FindClose(*dp); *dp = INVALID_HANDLE_VALUE; - #endif +#endif return LV_FS_RES_OK; } - #endif /*LV_USE_FS_IF*/ -#endif /*LV_FS_IF_FATFS*/ +#endif /*LV_USE_FS_IF*/ +#endif /*LV_FS_IF_FATFS*/ diff --git a/src/hasp/hasp_lvfs.cpp b/src/hasp/hasp_lvfs.cpp new file mode 100644 index 00000000..996ba567 --- /dev/null +++ b/src/hasp/hasp_lvfs.cpp @@ -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 */ + +#include "lv_fs_if.h" + +#include "hasp_conf.h" // include first +#include "hasp_debug.h" + +void filesystem_list_path(const char* path) +{ + lv_fs_dir_t dir; + lv_fs_res_t res; + res = lv_fs_dir_open(&dir, path); + if(res != LV_FS_RES_OK) { + LOG_ERROR(TAG_LVFS, "Error opening directory %s", path); + } else { + char fn[256]; + while(1) { + res = lv_fs_dir_read(&dir, fn); + if(res != LV_FS_RES_OK) { + LOG_ERROR(TAG_LVFS, "Directory %s can not be read", path); + break; + } + + /*fn is empty, if not more files to read*/ + if(strlen(fn) == 0) { + LOG_WARNING(TAG_LVFS, "Directory %s listing complete", path); + break; + } + + LOG_VERBOSE(TAG_LVFS, D_BULLET "%s", fn); + } + } + + lv_fs_dir_close(&dir); +} diff --git a/src/hasp/hasp_lvfs.h b/src/hasp/hasp_lvfs.h new file mode 100644 index 00000000..2dde864d --- /dev/null +++ b/src/hasp/hasp_lvfs.h @@ -0,0 +1,9 @@ +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_LVFS_H +#define HASP_LVFS_H + +void filesystem_list_path(const char* path); + +#endif \ No newline at end of file diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index de4e2ece..0a9ef0b0 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -23,8 +23,7 @@ #include "hasp_gui.h" #include "hasp_oobe.h" -#include "hasp/hasp_dispatch.h" -#include "hasp/hasp.h" +#include "hasplib.h" #ifdef WINDOWS #include "display/monitor.h" @@ -194,8 +193,12 @@ void guiSetup(void) /* Initialize Filesystems */ #if LV_USE_FS_IF != 0 - _lv_fs_init(); // lvgl File System + // _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 : Enabled")); lv_fs_if_init(); // auxilary file system drivers + filesystem_list_path("S:/"); +#else + LOG_VERBOSE(TAG_LVGL, F("Filesystem : Disabled")); #endif /* Initialize PNG decoder */ diff --git a/src/hasplib.h b/src/hasplib.h index 8f1596e9..158a6e56 100644 --- a/src/hasplib.h +++ b/src/hasplib.h @@ -6,5 +6,6 @@ #include "hasp/hasp_object.h" #include "hasp/hasp_parser.h" #include "hasp/hasp_utilities.h" +#include "hasp/hasp_lvfs.h" #include "hasp/lv_theme_hasp.h" \ No newline at end of file diff --git a/user_setups/win32/emulator_64bits.ini b/user_setups/win32/emulator_64bits.ini index 67cf5d38..1e359947 100644 --- a/user_setups/win32/emulator_64bits.ini +++ b/user_setups/win32/emulator_64bits.ini @@ -80,7 +80,6 @@ lib_ignore = paho AXP192 ArduinoLog - lv_fs_if src_filter = +<*> From 51c97f16d94d297c86f1a2e2f90c4435251d8746 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 27 Feb 2021 13:51:49 +0100 Subject: [PATCH 04/18] Add mqtt username and password to tests --- test/config.yaml | 7 ++++--- test/test_colors.tavern.yaml | 3 +++ test/test_label.tavern.yaml | 3 +++ test/test_mqtt.tavern.yaml | 8 +++++--- test/test_obj.tavern.yaml | 31 ++++++++++++++++++++++++++++--- test/test_value_str.tavern.yaml | 14 ++++++++------ 6 files changed, 51 insertions(+), 15 deletions(-) diff --git a/test/config.yaml b/test/config.yaml index 123df340..8e75a5fc 100644 --- a/test/config.yaml +++ b/test/config.yaml @@ -1,10 +1,11 @@ # config.yaml --- - name: Common test information description: Connection information for MQTT Client variables: - host: 10.4.0.5 + host: homeassistant.local + username: hasp + password: hasp port: 1883 - plate: plate35 \ No newline at end of file + plate: plate35 diff --git a/test/test_colors.tavern.yaml b/test/test_colors.tavern.yaml index 172fff36..8db18eaf 100644 --- a/test/test_colors.tavern.yaml +++ b/test/test_colors.tavern.yaml @@ -13,6 +13,9 @@ paho-mqtt: host: "{host}" port: !int "{port:d}" timeout: 3 + auth: + username: "{username}" + password: "{password}" marks: - parametrize: diff --git a/test/test_label.tavern.yaml b/test/test_label.tavern.yaml index f5dace3d..207baafe 100644 --- a/test/test_label.tavern.yaml +++ b/test/test_label.tavern.yaml @@ -13,6 +13,9 @@ paho-mqtt: &mqtt_spec host: "{host}" port: !int "{port:d}" timeout: 1 + auth: + username: "{username}" + password: "{password}" stages: - name: Page 1 diff --git a/test/test_mqtt.tavern.yaml b/test/test_mqtt.tavern.yaml index 2e103523..c923b848 100644 --- a/test/test_mqtt.tavern.yaml +++ b/test/test_mqtt.tavern.yaml @@ -1,6 +1,5 @@ # test_page.tavern.yaml --- - test_name: Page command includes: @@ -14,6 +13,9 @@ paho-mqtt: host: "{host}" port: !int "{port:d}" timeout: 3 + auth: + username: "{username}" + password: "{password}" stages: - name: step 1 - Page test @@ -46,7 +48,7 @@ stages: - name: step 4 - Page test mqtt_publish: topic: hasp/{plate}/command/json - payload: "[\"page=1\"]" + payload: '["page=1"]' mqtt_response: topic: hasp/{plate}/state/page payload: "1" @@ -55,7 +57,7 @@ stages: - name: step 5 - Page test mqtt_publish: topic: hasp/{plate}/command/json - payload: "[\"page 300\"]" + payload: '["page 300"]' mqtt_response: topic: hasp/{plate}/state/page payload: "1" diff --git a/test/test_obj.tavern.yaml b/test/test_obj.tavern.yaml index 9fe6ae5a..684e7fd5 100644 --- a/test/test_obj.tavern.yaml +++ b/test/test_obj.tavern.yaml @@ -13,6 +13,9 @@ paho-mqtt: host: "{host}" port: !int "{port:d}" timeout: 3 + auth: + username: "{username}" + password: "{password}" marks: - parametrize: @@ -52,8 +55,30 @@ marks: 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."] + - [ + 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 @@ -202,7 +227,7 @@ stages: json: radius: !int "{radius:d}" timeout: 1 - + - name: Set value_str mqtt_publish: topic: "hasp/{plate}/command/p1b1.value_str" diff --git a/test/test_value_str.tavern.yaml b/test/test_value_str.tavern.yaml index e3448654..f22688e8 100644 --- a/test/test_value_str.tavern.yaml +++ b/test/test_value_str.tavern.yaml @@ -1,6 +1,5 @@ # test_value_str.tavern.yaml --- - test_name: Obj Standard Properties includes: @@ -14,6 +13,9 @@ paho-mqtt: host: "{host}" port: !int "{port:d}" timeout: 3 + auth: + username: "{username}" + password: "{password}" marks: - parametrize: @@ -26,14 +28,14 @@ marks: - 30 - 31 - 32 -# - 33 -# - 40 + # - 33 + # - 40 - 41 - 50 - 51 - 91 -# - 90 -# - 1 + # - 90 + # - 1 - 2 - 71 - 80 @@ -93,7 +95,7 @@ stages: x: 128 y: 128 delay_after: 0 - + - name: Set value_str mqtt_publish: topic: "hasp/{plate}/command/p[1].b[1].value_str" From 96dddbb5b2631ea6a7528692dfd78ce74c48ef5d Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 27 Feb 2021 18:25:46 +0100 Subject: [PATCH 05/18] Add config/gpio support --- src/hasp/hasp_dispatch.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 55eb8770..66fa5a7f 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -420,6 +420,15 @@ static void dispatch_config(const char* topic, const char* payload) haspGetConfig(settings); } +#if HASP_USE_GPIO > 0 + else if(strcasecmp_P(topic, PSTR("gpio")) == 0) { + if(update) + gpioSetConfig(settings); + else + gpioGetConfig(settings); + } +#endif + #if HASP_USE_WIFI > 0 else if(strcasecmp_P(topic, PSTR("wifi")) == 0) { if(update) From 489ccd40343802a434da398ffc184110a2d7b561 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sat, 27 Feb 2021 18:26:54 +0100 Subject: [PATCH 06/18] Move dispatchSetup to main setup for oobe support --- src/hasp/hasp.cpp | 1 - src/main_arduino.cpp | 3 ++- src/main_windows.cpp | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index dbae6d46..0cc018be 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -319,7 +319,6 @@ static void custom_font_apply_cb(lv_theme_t* th, lv_obj_t* obj, lv_theme_style_t */ void haspSetup(void) { - dispatchSetup(); haspDevice.set_backlight_level(haspStartDim); /******* File System Test ********************************************************************/ diff --git a/src/main_arduino.cpp b/src/main_arduino.cpp index 8dfec4c7..c9c792a8 100644 --- a/src/main_arduino.cpp +++ b/src/main_arduino.cpp @@ -58,7 +58,8 @@ void setup() #endif guiSetup(); - debugSetup(); // Init the console + debugSetup(); // Init the console + dispatchSetup(); // for hasp and oobe #if HASP_USE_CONFIG > 0 if(!oobeSetup()) diff --git a/src/main_windows.cpp b/src/main_windows.cpp index 2efb6f21..00a4272c 100644 --- a/src/main_windows.cpp +++ b/src/main_windows.cpp @@ -110,6 +110,7 @@ void setup() // debugSetup(); // Init the console printf("%s %d\n", __FILE__, __LINE__); + dispatchSetup(); // for hasp and oobe haspSetup(); #if HASP_USE_MQTT > 0 From 51a6a7396726c891d4324e810d4c7d9d412605ab Mon Sep 17 00:00:00 2001 From: arovak Date: Sun, 28 Feb 2021 00:13:15 +0100 Subject: [PATCH 07/18] add stmpe610 touch driver --- src/drv/hasp_drv_touch.cpp | 8 +++++ src/drv/touch/hasp_drv_stmpe610.cpp | 54 +++++++++++++++++++++++++++++ src/drv/touch/hasp_drv_stmpe610.h | 15 ++++++++ 3 files changed, 77 insertions(+) create mode 100644 src/drv/touch/hasp_drv_stmpe610.cpp create mode 100644 src/drv/touch/hasp_drv_stmpe610.h diff --git a/src/drv/hasp_drv_touch.cpp b/src/drv/hasp_drv_touch.cpp index a7a872e9..446018b6 100644 --- a/src/drv/hasp_drv_touch.cpp +++ b/src/drv/hasp_drv_touch.cpp @@ -23,6 +23,8 @@ #include "drv/touch/hasp_drv_ft5206.h" #elif TOUCH_DRIVER == 6336 #include "drv/touch/hasp_drv_ft6336u.h" +#elif TOUCH_DRIVER == 610 +#include "drv/touch/hasp_drv_stmpe610.h" #else //#include "tp_i2c.h" //#include "ft6x36.h" @@ -56,6 +58,9 @@ void drv_touch_init(uint8_t rotation) #elif TOUCH_DRIVER == 6336 FT6336U_init(); +#elif TOUCH_DRIVER == 610 + STMPE610_init(); + #else // xpt2046_alt_drv_read(indev_driver, data); // xpt2046_read(indev_driver, data); @@ -86,6 +91,9 @@ static inline bool drv_touchpad_getXY(int16_t* touchX, int16_t* touchY) #elif TOUCH_DRIVER == 6336 touched = FT6336U_getXY(&normal_x, &normal_y, true); +#elif TOUCH_DRIVER == 610 + touched = STMPE610_getXY(&normal_x, &normal_y, drv_touch_rotation, true); + #else // xpt2046_alt_drv_read(indev_driver, data); // xpt2046_read(indev_driver, data); diff --git a/src/drv/touch/hasp_drv_stmpe610.cpp b/src/drv/touch/hasp_drv_stmpe610.cpp new file mode 100644 index 00000000..27dbc245 --- /dev/null +++ b/src/drv/touch/hasp_drv_stmpe610.cpp @@ -0,0 +1,54 @@ +#if TOUCH_DRIVER == 610 + + #include + #include "Adafruit_STMPE610.h" + #include "ArduinoLog.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 + +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) +{ + uint16_t x, y; + uint8_t z; + if(! touch.touched()) return false; + + 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) { + y = map(y, TS_MINX, TS_MAXX, 0, TFT_WIDTH); + x = map(x, TS_MINY, TS_MAXY, 0, TFT_HEIGHT); + } else if (2 == touchRotation) { + x = map(x, TS_MAXX, TS_MINX, 0, TFT_WIDTH); + y = map(y, TS_MAXY, TS_MINY, 0, TFT_HEIGHT); + } else { + x = map(x, TS_MINX, TS_MAXX, 0, TFT_WIDTH); + y = map(y, TS_MINY, TS_MAXY, 0, TFT_HEIGHT); + } + + *touchX = x; + *touchY = y; + return true; + +} + +void STMPE610_init() +{ + if (! touch.begin()) { + Log.trace(TAG_DRVR, F("STMPE610 not found!")); + } else { + Log.trace(TAG_DRVR, F("STMPE610 touch driver started")); + } +} +#endif \ No newline at end of file diff --git a/src/drv/touch/hasp_drv_stmpe610.h b/src/drv/touch/hasp_drv_stmpe610.h new file mode 100644 index 00000000..2eb07f99 --- /dev/null +++ b/src/drv/touch/hasp_drv_stmpe610.h @@ -0,0 +1,15 @@ +/* MIT License - Copyright (c) 2020 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_DRV_STMPE610_H +#define HASP_DRV_STMPE610_H + +#if TOUCH_DRIVER == 610 + + #include "hasp_debug.h" // for TAG_DRVR + +bool IRAM_ATTR STMPE610_getXY(int16_t * touchX, int16_t * touchY, uint8_t touchRotation, bool debug); +void STMPE610_init(); + +#endif +#endif \ No newline at end of file From b62b2841c93856427f1490141dd7a677a3d4acb0 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 28 Feb 2021 00:51:16 +0100 Subject: [PATCH 08/18] Change event names to lower case --- src/hasp/hasp_dispatch.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 66fa5a7f..3b7bc995 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -500,31 +500,31 @@ void dispatch_get_event_name(uint8_t eventid, char* buffer, size_t size) { switch(eventid) { case HASP_EVENT_ON: - memcpy_P(buffer, PSTR("ON"), size); + memcpy_P(buffer, PSTR("on"), size); break; case HASP_EVENT_OFF: - memcpy_P(buffer, PSTR("OFF"), size); + memcpy_P(buffer, PSTR("off"), size); break; case HASP_EVENT_UP: - memcpy_P(buffer, PSTR("UP"), size); + memcpy_P(buffer, PSTR("up"), size); break; case HASP_EVENT_DOWN: - memcpy_P(buffer, PSTR("DOWN"), size); + memcpy_P(buffer, PSTR("down"), size); break; case HASP_EVENT_SHORT: - memcpy_P(buffer, PSTR("SHORT"), size); + memcpy_P(buffer, PSTR("short"), size); break; case HASP_EVENT_LONG: - memcpy_P(buffer, PSTR("LONG"), size); + memcpy_P(buffer, PSTR("long"), size); break; case HASP_EVENT_HOLD: - memcpy_P(buffer, PSTR("HOLD"), size); + memcpy_P(buffer, PSTR("hold"), size); break; case HASP_EVENT_LOST: - memcpy_P(buffer, PSTR("LOST"), size); + memcpy_P(buffer, PSTR("lost"), size); break; default: - memcpy_P(buffer, PSTR("UNKNOWN"), size); + memcpy_P(buffer, PSTR("unknown"), size); } } @@ -811,8 +811,8 @@ void dispatch_moodlight(const char* topic, const char* payload) moodlight.power = Utilities::is_true(json[F("state")].as().c_str()); if(!json[F("r")].isNull()) moodlight.r = json[F("r")].as(); - if(!json[F("g")].isNull()) moodlight.r = json[F("g")].as(); - if(!json[F("b")].isNull()) moodlight.r = json[F("b")].as(); + if(!json[F("g")].isNull()) moodlight.g = json[F("g")].as(); + if(!json[F("b")].isNull()) moodlight.b = json[F("b")].as(); if(!json[F("color")].isNull()) { if(!json[F("color")]["r"].isNull()) { From 6d8a3967d7058632cfd32136df9d5cc78b0eea0a Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 28 Feb 2021 02:10:23 +0100 Subject: [PATCH 09/18] Change idle events to lowercase --- src/hasp/hasp_dispatch.cpp | 6 +++--- src/mqtt/hasp_mqtt_ha.cpp | 2 +- test/test_mqtt.tavern.yaml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 3b7bc995..bbf8853c 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -322,13 +322,13 @@ void dispatch_output_idle_state(uint8_t state) char payload[6]; switch(state) { case HASP_SLEEP_LONG: - memcpy_P(payload, PSTR("LONG"), 5); + memcpy_P(payload, PSTR("long"), 5); break; case HASP_SLEEP_SHORT: - memcpy_P(payload, PSTR("SHORT"), 6); + memcpy_P(payload, PSTR("short"), 6); break; default: - memcpy_P(payload, PSTR("OFF"), 4); + memcpy_P(payload, PSTR("off"), 4); } dispatch_state_msg(F("idle"), payload); } diff --git a/src/mqtt/hasp_mqtt_ha.cpp b/src/mqtt/hasp_mqtt_ha.cpp index 2de8af07..2ef28441 100644 --- a/src/mqtt/hasp_mqtt_ha.cpp +++ b/src/mqtt/hasp_mqtt_ha.cpp @@ -151,7 +151,7 @@ void mqtt_ha_register_switch(uint8_t page, uint8_t id) doc[F("t")] = buffer; // topic doc[F("atype")] = F("binary_sensor"); // automation_type - doc[F("pl")] = F("SHORT"); // payload + doc[F("pl")] = F("short"); // payload doc[F("type")] = F("button_short_release"); snprintf_P(buffer, sizeof(buffer), PSTR("%s/device_automation/%s/" HASP_OBJECT_NOTATION "_%s/config"), diff --git a/test/test_mqtt.tavern.yaml b/test/test_mqtt.tavern.yaml index c923b848..c0aa526a 100644 --- a/test/test_mqtt.tavern.yaml +++ b/test/test_mqtt.tavern.yaml @@ -112,7 +112,7 @@ stages: payload: "wakeup" mqtt_response: topic: hasp/{plate}/state/idle - payload: "LONG" + payload: "long" timeout: 190 delay_after: 0 @@ -122,7 +122,7 @@ stages: payload: "wakeup" mqtt_response: topic: hasp/{plate}/state/idle - payload: "SHORT" + payload: "short" timeout: 70 delay_after: 0 @@ -132,6 +132,6 @@ stages: payload: "wakeup" mqtt_response: topic: hasp/{plate}/state/idle - payload: "OFF" + payload: "off" timeout: 1 delay_after: 0 From 5e25c85689d78cf6430394bec598e6e2ee0bd63e Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 28 Feb 2021 02:16:20 +0100 Subject: [PATCH 10/18] Change on/off states to lower case --- src/hasp/hasp_dispatch.cpp | 4 ++-- src/mqtt/hasp_mqtt_ha.cpp | 8 ++++---- src/sys/net/hasp_ethernet_esp32.cpp | 2 +- src/sys/net/hasp_ethernet_stm32.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index bbf8853c..cd566a68 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -846,7 +846,7 @@ 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); + moodlight.power ? "on" : "off", moodlight.r, moodlight.g, moodlight.b); dispatch_state_msg(F("moodlight"), buffer); } @@ -857,7 +857,7 @@ void dispatch_backlight(const char*, const char* payload) // Return the current state char buffer[4]; - memcpy_P(buffer, haspDevice.get_backlight_power() ? PSTR("ON") : PSTR("OFF"), sizeof(buffer)); + memcpy_P(buffer, haspDevice.get_backlight_power() ? PSTR("on") : PSTR("off"), sizeof(buffer)); dispatch_state_msg(F("light"), buffer); } diff --git a/src/mqtt/hasp_mqtt_ha.cpp b/src/mqtt/hasp_mqtt_ha.cpp index 2ef28441..8a8acde5 100644 --- a/src/mqtt/hasp_mqtt_ha.cpp +++ b/src/mqtt/hasp_mqtt_ha.cpp @@ -195,8 +195,8 @@ void mqtt_ha_register_backlight() mqtt_ha_add_device_ids(doc); mqtt_ha_add_unique_id(doc, item); - // doc[F("pl_on")] = F("ON"); - // doc[F("pl_off")] = F("OFF"); + // doc[F("pl_on")] = F("on"); + // doc[F("pl_off")] = F("off"); char buffer[128]; snprintf_P(buffer, sizeof(buffer), PSTR("%s/light/%s/%s/config"), discovery_prefix, haspDevice.get_hostname(), @@ -341,8 +341,8 @@ device: "bri_stat_t": "~/state/dim", "bri_cmd_t": "~/command/dim", "bri_scl": 100, - "pl_on": "ON", - "pl_off": "OFF" + "pl_on": "on", + "pl_off": "off" } { diff --git a/src/sys/net/hasp_ethernet_esp32.cpp b/src/sys/net/hasp_ethernet_esp32.cpp index c3244afe..a0415e71 100644 --- a/src/sys/net/hasp_ethernet_esp32.cpp +++ b/src/sys/net/hasp_ethernet_esp32.cpp @@ -67,7 +67,7 @@ bool ethernetEvery5Seconds() void ethernet_get_statusupdate(char* buffer, size_t len) { snprintf_P(buffer, len, PSTR("\"eth\":\"%s\",\"link\":\"%d Mbps\",\"ip\":\"%s\","), - eth_connected ? F("ON") : F("OFF"), ETH.linkSpeed(), ETH.localIP().toString().c_str()); + eth_connected ? F("on") : F("off"), ETH.linkSpeed(), ETH.localIP().toString().c_str()); } #endif \ No newline at end of file diff --git a/src/sys/net/hasp_ethernet_stm32.cpp b/src/sys/net/hasp_ethernet_stm32.cpp index 8741a89c..39787953 100644 --- a/src/sys/net/hasp_ethernet_stm32.cpp +++ b/src/sys/net/hasp_ethernet_stm32.cpp @@ -106,7 +106,7 @@ void ethernet_get_statusupdate(char* buffer, size_t len) #endif IPAddress ip = Ethernet.localIP(); - snprintf_P(buffer, len, PSTR("\"eth\":\"%s\",\"link\":%d,\"ip\":\"%d.%d.%d.%d\","), state ? F("ON") : F("OFF"), 10, + snprintf_P(buffer, len, PSTR("\"eth\":\"%s\",\"link\":%d,\"ip\":\"%d.%d.%d.%d\","), state ? F("on") : F("off"), 10, ip[0], ip[1], ip[2], ip[3]); } #endif \ No newline at end of file From 56bbc19414803f51e8c8d9461f8f6cdb3b323e98 Mon Sep 17 00:00:00 2001 From: arovak Date: Sun, 28 Feb 2021 20:13:07 +0100 Subject: [PATCH 11/18] huzzah32-featherwings ini files --- user_setups/esp32/huzzah32-featherwing-24.ini | 33 +++++++++++++++++++ user_setups/esp32/huzzah32-featherwing-35.ini | 33 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 user_setups/esp32/huzzah32-featherwing-24.ini create mode 100644 user_setups/esp32/huzzah32-featherwing-35.ini diff --git a/user_setups/esp32/huzzah32-featherwing-24.ini b/user_setups/esp32/huzzah32-featherwing-24.ini new file mode 100644 index 00000000..79b57552 --- /dev/null +++ b/user_setups/esp32/huzzah32-featherwing-24.ini @@ -0,0 +1,33 @@ +;***************************************************; +; HUZZAH32 ESP32 with Featherwing TFT 2.4" ; +; - HUZZAH32 esp32 board ; +; - ili9341 TFT Featherwing 2.4" ; +; - STMPE610 touch controller ; +;***************************************************; + +[env:huzzah32-featherwing-24] +extends = esp32 +board = featheresp32 + +build_flags = + ${env.build_flags} + ${esp32.build_flags} +;region -- TFT_eSPI build options ------------------------ + ${lcd.featherwing-24} + -D TFT_MISO=19 + -D TFT_MOSI=18 + -D TFT_SCLK=5 + -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 STMPE_CS=32 +;endregion + +lib_deps = + ${env.lib_deps} + ${esp32.lib_deps} + +lib_ignore = + ${env.lib_ignore} + ${esp32.lib_ignore} \ No newline at end of file diff --git a/user_setups/esp32/huzzah32-featherwing-35.ini b/user_setups/esp32/huzzah32-featherwing-35.ini new file mode 100644 index 00000000..db9e512f --- /dev/null +++ b/user_setups/esp32/huzzah32-featherwing-35.ini @@ -0,0 +1,33 @@ +;***************************************************; +; HUZZAH32 ESP32 with Featherwing TFT 3.5" ; +; - HUZZAH32 esp32 board ; +; - HX8357D TFT Featherwing 3.5" ; +; - STMPE610 touch controller ; +;***************************************************; + +[env:huzzah32-featherwing-35] +extends = esp32 +board = featheresp32 + +build_flags = + ${env.build_flags} + ${esp32.build_flags} +;region -- TFT_eSPI build options ------------------------ + ${lcd.featherwing-35} + -D TFT_MISO=19 + -D TFT_MOSI=18 + -D TFT_SCLK=5 + -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 STMPE_CS=32 +;endregion + +lib_deps = + ${env.lib_deps} + ${esp32.lib_deps} + +lib_ignore = + ${env.lib_ignore} + ${esp32.lib_ignore} \ No newline at end of file From 3ecf71c1aca3072668221b78cc41ffd1db87ffde Mon Sep 17 00:00:00 2001 From: arovak Date: Sun, 28 Feb 2021 20:14:07 +0100 Subject: [PATCH 12/18] add featherwing lcd_config --- user_setups/lcd_config.ini | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/user_setups/lcd_config.ini b/user_setups/lcd_config.ini index 366fd709..2065f3c9 100644 --- a/user_setups/lcd_config.ini +++ b/user_setups/lcd_config.ini @@ -86,3 +86,27 @@ wt32-sc01 = -D SPI_FREQUENCY=40000000 -D USER_SETUP_LOADED=1 ;-D SUPPORT_TRANSACTIONS ; Default on ESP32 + +featherwing-35 = + -D HX8357D_DRIVER=1 + -D TFT_WIDTH=320 + -D TFT_HEIGHT=480 + -D TFT_ROTATION=0 ; Use default, see TFT_ROTATION values + -D SPI_FREQUENCY=27000000 + -D SPI_TOUCH_FREQUENCY=2500000 + -D SPI_READ_FREQUENCY=20000000 + -D USER_SETUP_LOADED=1 + -D TOUCH_DRIVER=610 ;STMPE610 + ;-D SUPPORT_TRANSACTIONS ; Default on ESP32 + +featherwing-24 = + -D ILI9341_DRIVER=1 + -D TFT_WIDTH=240 + -D TFT_HEIGHT=320 + -D TFT_ROTATION=0 ; Use default, see TFT_ROTATION values + -D SPI_FREQUENCY=27000000 + -D SPI_TOUCH_FREQUENCY=2500000 + -D SPI_READ_FREQUENCY=20000000 + -D USER_SETUP_LOADED=1 + -D TOUCH_DRIVER=610 ;STMPE610 + ;-D SUPPORT_TRANSACTIONS ; Default on ESP32 \ No newline at end of file From a1971947f34dd58ed8395c73e32c5fc2a1487da8 Mon Sep 17 00:00:00 2001 From: arovak Date: Sun, 28 Feb 2021 20:15:59 +0100 Subject: [PATCH 13/18] stmpe610 touch driver --- platformio.ini | 1 + src/drv/touch/hasp_drv_stmpe610.cpp | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 9edb1cce..e2dfa89a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -83,6 +83,7 @@ lib_deps = ;AsyncTCP ;https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip ;https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip + adafruit/Adafruit STMPE610@^1.1.3 ;STMPE610 touch controller src_filter = +<*> -<.git/> - - - - - diff --git a/src/drv/touch/hasp_drv_stmpe610.cpp b/src/drv/touch/hasp_drv_stmpe610.cpp index 27dbc245..f1a6df4a 100644 --- a/src/drv/touch/hasp_drv_stmpe610.cpp +++ b/src/drv/touch/hasp_drv_stmpe610.cpp @@ -27,14 +27,29 @@ bool IRAM_ATTR STMPE610_getXY(int16_t * touchX, int16_t * touchY, uint8_t touchR } touch.writeRegister8(STMPE_INT_STA, 0xFF); if (1 == touchRotation) { - y = map(y, TS_MINX, TS_MAXX, 0, TFT_WIDTH); - x = map(x, TS_MINY, TS_MAXY, 0, TFT_HEIGHT); - } else if (2 == 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 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 + x = map(x, TS_MAXX, TS_MINX, TFT_WIDTH, 0); + y = map(y, TS_MAXY, TS_MINY, 0, TFT_HEIGHT); + #else + x = map(x, TS_MAXX, TS_MINX, 0, TFT_WIDTH); + y = map(y, TS_MAXY, TS_MINY, 0, TFT_HEIGHT); + #endif } else { + #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 x = map(x, TS_MINX, TS_MAXX, 0, TFT_WIDTH); y = map(y, TS_MINY, TS_MAXY, 0, TFT_HEIGHT); + #endif } *touchX = x; From 190f2d649eb8faed545ba11f30c732f5447eb75b Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 28 Feb 2021 20:49:04 +0100 Subject: [PATCH 14/18] Add D_ERROR_UNKNOWN --- src/lang/en_US.h | 1 + src/lang/nl_NL.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/lang/en_US.h b/src/lang/en_US.h index e5747b38..02a73ae1 100644 --- a/src/lang/en_US.h +++ b/src/lang/en_US.h @@ -6,6 +6,7 @@ #define D_SSID "Ssid:" #define D_ERROR_OUT_OF_MEMORY "Out of memory" +#define D_ERROR_UNKNOWN "Unkown error" #define D_CONFIG_NOT_CHANGED "Settings did not change" #define D_CONFIG_CHANGED "Settings changed" diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h index 6a5022fc..be8d2202 100644 --- a/src/lang/nl_NL.h +++ b/src/lang/nl_NL.h @@ -6,6 +6,7 @@ #define D_SSID "Ssid:" #define D_ERROR_OUT_OF_MEMORY "Geen geheugen bechikbaar" +#define D_ERROR_UNKNOWN "Unbekende fout" #define D_CONFIG_NOT_CHANGED "Instellingen ongewijzigd" #define D_CONFIG_CHANGED "Instellingen gewijzigd" From 17550d7b66c7b9944fc6d4d990a93dfe58d8ffc8 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 28 Feb 2021 20:49:55 +0100 Subject: [PATCH 15/18] Add MQTT error codes --- src/mqtt/hasp_mqtt.h | 16 ++++++++--- src/mqtt/hasp_mqtt_paho_async.cpp | 2 +- src/mqtt/hasp_mqtt_paho_single.cpp | 44 ++++++++++++++--------------- src/mqtt/hasp_mqtt_pubsubclient.cpp | 30 +++++++++----------- 4 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h index 18f007ea..5760bede 100644 --- a/src/mqtt/hasp_mqtt.h +++ b/src/mqtt/hasp_mqtt.h @@ -13,16 +13,24 @@ #define __FlashStringHelper char #endif +enum hasp_mqtt_error_t { + MQTT_ERR_OK = 0, + MQTT_ERR_DISABLED = -1, + MQTT_ERR_NO_CONN = -2, + MQTT_ERR_SUB_FAIL = -3, + MQTT_ERR_PUB_FAIL = -4, + MQTT_ERR_UNKNOWN = -128 +}; + void mqttSetup(); void mqttLoop(); void mqttEvery5Seconds(bool wifiIsConnected); void mqttStart(); void mqttStop(); -void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char* payload); -void mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload); - -bool mqttPublish(const char* topic, const char* payload, size_t len, bool retain); +int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload); +int mqtt_send_state(const char* subtopic, const char* payload); +int mqttPublish(const char* topic, const char* payload, size_t len, bool retain); bool mqttIsConnected(); diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp index d8b94f2b..be17e3f9 100644 --- a/src/mqtt/hasp_mqtt_paho_async.cpp +++ b/src/mqtt/hasp_mqtt_paho_async.cpp @@ -343,7 +343,7 @@ void mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload) mqttPublish(tmp_topic, payload, false); } -void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char* payload) +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); diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp index bcdbdcb0..a1e45b66 100644 --- a/src/mqtt/hasp_mqtt_paho_single.cpp +++ b/src/mqtt/hasp_mqtt_paho_single.cpp @@ -106,7 +106,7 @@ int disc_finished = 0; int subscribed = 0; int connected = 0; -bool mqttPublish(const char* topic, const char* payload, size_t len, bool retain); +int mqttPublish(const char* topic, const char* payload, size_t len, bool retain); /* ===== Paho event callbacks ===== */ @@ -207,30 +207,28 @@ void mqtt_subscribe(void* context, const char* topic) /* ===== Local HASP MQTT functions ===== */ -bool mqttPublish(const char* topic, const char* payload, size_t len, bool retain) +int mqttPublish(const char* topic, const char* payload, size_t len, bool retain) { - if(mqttIsConnected()) { - MQTTClient_message pubmsg = MQTTClient_message_initializer; - MQTTClient_deliveryToken token; + if(!mqttIsConnected()) return MQTT_ERR_NO_CONN; - pubmsg.payload = (char*)payload; - pubmsg.payloadlen = len; // (int)strlen(payload); - pubmsg.qos = QOS; - pubmsg.retained = retain; + MQTTClient_message pubmsg = MQTTClient_message_initializer; + MQTTClient_deliveryToken token; - MQTTClient_publishMessage(mqtt_client, topic, &pubmsg, &token); - int rc = MQTTClient_waitForCompletion(mqtt_client, token, TIMEOUT); + pubmsg.payload = (char*)payload; + pubmsg.payloadlen = len; // (int)strlen(payload); + pubmsg.qos = QOS; + pubmsg.retained = retain; - if(rc != MQTTCLIENT_SUCCESS) { - LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " '%s' => %s"), topic, payload); - } else { - LOG_TRACE(TAG_MQTT_PUB, F("'%s' => %s OK"), topic, payload); - return true; - } + MQTTClient_publishMessage(mqtt_client, topic, &pubmsg, &token); + int rc = MQTTClient_waitForCompletion(mqtt_client, token, TIMEOUT); + + if(rc != MQTTCLIENT_SUCCESS) { + LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " '%s' => %s"), topic, payload); + return MQTT_ERR_PUB_FAIL; } else { - LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED)); + LOG_TRACE(TAG_MQTT_PUB, F("'%s' => %s OK"), topic, payload); + return MQTT_ERR_OK; } - return false; } // static bool mqttPublish(const char* topic, const char* payload, bool retain) @@ -245,19 +243,19 @@ bool mqttIsConnected() return connected == 1; } -void mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload) +int 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); - mqttPublish(tmp_topic, payload, strlen(payload), false); + return mqttPublish(tmp_topic, payload, strlen(payload), false); } -void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char* payload) +int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char* payload) { char tmp_topic[strlen(mqttNodeTopic) + 20]; snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/p%ub%u"), mqttNodeTopic, pageid, btnid); - mqttPublish(tmp_topic, payload, strlen(payload), false); + return mqttPublish(tmp_topic, payload, strlen(payload), false); } static void onConnect(void* context) diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index 73afab25..05a795cb 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -89,25 +89,21 @@ char mqttGroupName[16] = MQTT_GROUPNAME; uint16_t mqttPort = MQTT_PORT; PubSubClient mqttClient(mqttNetworkClient); -bool mqttPublish(const char* topic, const char* payload, size_t len, bool retain) +int mqttPublish(const char* topic, const char* payload, size_t len, bool retain) { - if(mqttIsConnected()) { - if(mqttClient.beginPublish(topic, len, retain)) { - mqttClient.write((uint8_t*)payload, len); - mqttClient.endPublish(); + if(!mqttEnabled) return MQTT_ERR_DISABLED; + if(!mqttClient.connected()) return MQTT_ERR_NO_CONN; - LOG_TRACE(TAG_MQTT_PUB, F("%s => %s"), topic, payload); - return true; - } else { - LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " %s => %s"), topic, payload); - } - } else { - LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED)); + if(mqttClient.beginPublish(topic, len, retain)) { + mqttClient.write((uint8_t*)payload, len); + mqttClient.endPublish(); + return MQTT_ERR_OK; } - return false; + + return MQTT_ERR_PUB_FAIL; } -static bool mqttPublish(const char* topic, const char* payload, bool retain) +int mqttPublish(const char* topic, const char* payload, bool retain) { return mqttPublish(topic, payload, strlen(payload), retain); } @@ -132,18 +128,18 @@ void mqtt_send_lwt(bool online) bool res = mqttPublish(tmp_topic, tmp_payload, len, true); } -void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char* payload) +void 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); mqttPublish(tmp_topic, payload, false); } -void mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload) +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); - mqttPublish(tmp_topic, payload, false); + return mqttPublish(tmp_topic, payload, false); } //////////////////////////////////////////////////////////////////////////////////////////////////// From 9f71460a65915ee2fb5d8ebfa505c1a8a364e676 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 28 Feb 2021 21:19:03 +0100 Subject: [PATCH 16/18] Fix 255.255.255.255 IP error --- src/sys/net/hasp_wifi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/net/hasp_wifi.cpp b/src/sys/net/hasp_wifi.cpp index c2fa9170..6ed4a553 100644 --- a/src/sys/net/hasp_wifi.cpp +++ b/src/sys/net/hasp_wifi.cpp @@ -362,7 +362,7 @@ static void wifiReconnect(void) // https://github.com/espressif/arduino-esp32/issues/3438#issuecomment-721428310 WiFi.disconnect(true); WiFi.begin(wifiSsid, wifiPassword); - WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); + // WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); // causes 255.255.255.255 IP errors WiFi.setHostname(haspDevice.get_hostname()); #endif } From 0ef0f8c52077cde7e5bad04d7cb240ed8ef56779 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Sun, 28 Feb 2021 22:04:12 +0100 Subject: [PATCH 17/18] New event handler state senders --- src/hasp/hasp_dispatch.cpp | 230 ++++++++++++++++++++-------- src/hasp/hasp_dispatch.h | 11 +- src/hasp/hasp_object.cpp | 62 ++++---- src/mqtt/hasp_mqtt.h | 6 +- src/mqtt/hasp_mqtt_paho_single.cpp | 2 +- src/mqtt/hasp_mqtt_pubsubclient.cpp | 4 +- 6 files changed, 217 insertions(+), 98 deletions(-) diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index cd566a68..00af337f 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -54,25 +54,63 @@ moodlight_t moodlight; static void dispatch_config(const char* topic, const char* payload); // void dispatch_group_value(uint8_t groupid, int16_t state, lv_obj_t * obj); -static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const char* payload); -void dispatch_screenshot(const char*, const char* filename) +/* Sends the payload out on the state/subtopic + */ +void dispatch_state_subtopic(const char* subtopic, const char* payload) { -#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 - - if(strlen(filename) == 0) { // no filename given - char tempfile[32]; - 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); - } else { // Valid filename - guiTakeScreenshot(filename); - } - +#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_CLIENT) + LOG_TRACE(TAG_MSGR, F("%s => %s"), subtopic, payload); #else - LOG_WARNING(TAG_MSGR, "Failed to save %s, no storage", filename); + +#if HASP_USE_MQTT > 0 + switch(mqtt_send_state(subtopic, payload)) { + case MQTT_ERR_OK: + LOG_TRACE(TAG_MQTT_PUB, F("%s => %s"), subtopic, payload); + break; + case MQTT_ERR_PUB_FAIL: + 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)); + break; + default: + LOG_ERROR(TAG_MQTT, F(D_ERROR_UNKNOWN)); + } #endif + +#if HASP_USE_TASMOTA_CLIENT > 0 + slave_send_state(subtopic, payload); +#endif + +#endif +} + +/* Sends the data out on the state/pxby topic + */ +void dispatch_state_object(uint8_t pageid, uint8_t btnid, const char* payload) +{ + char topic[16]; + snprintf_P(topic, sizeof(topic), PSTR(HASP_OBJECT_NOTATION), pageid, btnid); + dispatch_state_subtopic(topic, payload); +} + +/* Takes and lv_obj and finds the pageid and objid + Then sends the data out on the state/pxby topic +*/ +void dispatch_obj_data(lv_obj_t* obj, const char* data) +{ + uint8_t pageid; + uint8_t objid; + + if(hasp_find_id_from_obj(obj, &pageid, &objid)) { + if(!data) return; +#if HASP_USE_MQTT > 0 + dispatch_state_object(pageid, objid, data); +#endif + } else { + LOG_ERROR(TAG_MSGR, F(D_OBJECT_UNKNOWN)); + } } // Format filesystem and erase EEPROM @@ -319,6 +357,7 @@ void dispatch_text_line(const char* cmnd) // send idle state to the client void dispatch_output_idle_state(uint8_t state) { + char topic[6]; char payload[6]; switch(state) { case HASP_SLEEP_LONG: @@ -330,17 +369,20 @@ void dispatch_output_idle_state(uint8_t state) default: memcpy_P(payload, PSTR("off"), 4); } - dispatch_state_msg(F("idle"), payload); + memcpy_P(topic, PSTR("idle"), 5); + dispatch_state_subtopic(topic, payload); } void dispatch_output_group_state(uint8_t groupid, uint16_t state) { char payload[64]; char number[16]; // Return the current state + char topic[8]; itoa(state, number, DEC); snprintf_P(payload, sizeof(payload), PSTR("{\"group\":%d,\"state\":\"%s\"}"), groupid, number); - dispatch_state_msg(F("output"), payload); + memcpy_P(topic, PSTR("output"), 7); + dispatch_state_subtopic(topic, payload); } void dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char* attribute, const char* data) @@ -350,7 +392,7 @@ void dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char* char payload[32 + strlen(data) + strlen(attribute)]; snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"%s\"}"), attribute, data); - mqtt_send_object_state(pageid, btnid, payload); + dispatch_state_object(pageid, btnid, payload); } void dispatch_send_obj_attribute_int(uint8_t pageid, uint8_t btnid, const char* attribute, int32_t val) @@ -360,7 +402,7 @@ void dispatch_send_obj_attribute_int(uint8_t pageid, uint8_t btnid, const char* char payload[64 + strlen(attribute)]; snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":%d}"), attribute, val); - mqtt_send_object_state(pageid, btnid, payload); + dispatch_state_object(pageid, btnid, payload); } void dispatch_send_obj_attribute_color(uint8_t pageid, uint8_t btnid, const char* attribute, uint8_t r, uint8_t g, @@ -372,7 +414,7 @@ void dispatch_send_obj_attribute_color(uint8_t pageid, uint8_t btnid, const char snprintf_P(payload, sizeof(payload), PSTR("{\"%s\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), attribute, r, g, b, r, g, b); - mqtt_send_object_state(pageid, btnid, payload); + dispatch_state_object(pageid, btnid, payload); } #if HASP_USE_CONFIG > 0 @@ -468,9 +510,12 @@ static void dispatch_config(const char* topic, const char* payload) // Send output if(!update) { + char subtopic[8]; settings.remove(F("pass")); // hide password in output + size_t size = serializeJson(doc, buffer, sizeof(buffer)); - dispatch_state_msg(F("config"), buffer); + memcpy_P(subtopic, PSTR("config"), 7); + dispatch_state_subtopic(subtopic, buffer); } } #endif // HASP_USE_CONFIG @@ -523,6 +568,9 @@ void dispatch_get_event_name(uint8_t eventid, char* buffer, size_t size) case HASP_EVENT_LOST: memcpy_P(buffer, PSTR("lost"), size); break; + case HASP_EVENT_CHANGED: + memcpy_P(buffer, PSTR("changed"), size); + break; default: memcpy_P(buffer, PSTR("unknown"), size); } @@ -532,12 +580,14 @@ void dispatch_get_event_name(uint8_t eventid, char* buffer, size_t size) void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid) { char payload[64]; + char topic[8]; char event[8]; dispatch_get_event_name(eventid, event, sizeof(event)); snprintf_P(payload, sizeof(payload), PSTR("{\"pin\":%d,\"group\":%d,\"event\":\"%s\"}"), pin, group, event); #if HASP_USE_MQTT > 0 - mqtt_send_state(F("input"), payload); + memcpy_P(topic, PSTR("input"), 6); + dispatch_state_subtopic(topic, payload); #endif // update outputstates @@ -545,45 +595,67 @@ void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid) } #endif -void dispatch_object_event(lv_obj_t* obj, uint8_t eventid) +/* ============================== Event Senders ============================ */ + +// Send out the event that occured +void dispatch_object_generic_event(lv_obj_t* obj, uint8_t eventid) { - char topic[8]; - char payload[8]; - uint8_t pageid, objid; + char data[40]; + char eventname[8]; - snprintf_P(topic, sizeof(topic), PSTR("event")); - dispatch_get_event_name(eventid, payload, sizeof(payload)); - - if(hasp_find_id_from_obj(obj, &pageid, &objid)) { - dispatch_send_obj_attribute_str(pageid, objid, topic, payload); - } - - // dispatch_group_onoff(obj->user_data.groupid, dispatch_get_event_state(eventid), obj); + dispatch_get_event_name(eventid, eventname, sizeof(eventname)); + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname); + dispatch_obj_data(obj, data); } +// Send out the on/off event, with the val +void dispatch_object_toggle_event(lv_obj_t* obj, bool state) +{ + char data[40]; + char eventname[8]; + + dispatch_get_event_name(state, eventname, sizeof(eventname)); + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, state); + dispatch_obj_data(obj, data); +} + +// Send out the changed event, with the val void dispatch_object_value_changed(lv_obj_t* obj, int16_t state) { - char topic[4]; + char data[48]; - hasp_update_sleep_state(); // wakeup? - snprintf_P(topic, sizeof(topic), PSTR("val")); - hasp_send_obj_attribute_int(obj, topic, state); + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"changed\",\"val\":%d}"), state); + dispatch_obj_data(obj, data); +} + +// Send out the changed event, with the val and text +void dispatch_object_selection_changed(lv_obj_t* obj, int16_t val, const char* text) +{ + char data[200]; + + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"changed\",\"val\":%d,\"text\":\"%s\"}"), val, text); + dispatch_obj_data(obj, data); +} + +// Send out the changed event, with the color +void dispatch_object_color_changed(lv_obj_t* obj, lv_color_t color) +{ + char data[80]; + lv_color32_t c32; + c32.full = lv_color_to32(color); + + snprintf_P(data, sizeof(data), + PSTR("{\"event\":\"changed\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), c32.ch.red, + c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); + dispatch_obj_data(obj, data); } /********************************************** Output States ******************************************/ +/* static inline void dispatch_state_msg(const __FlashStringHelper* subtopic, const char* payload) { -#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_CLIENT) - LOG_TRACE(TAG_MSGR, F("%s => %s"), String(subtopic).c_str(), payload); -#else -#if HASP_USE_MQTT > 0 - mqtt_send_state(subtopic, payload); -#endif -#if HASP_USE_TASMOTA_CLIENT > 0 - slave_send_state(subtopic, payload); -#endif -#endif -} + +}*/ // void dispatch_group_onoff(uint8_t groupid, uint16_t eventid, lv_obj_t * obj) // { @@ -624,6 +696,25 @@ void dispatch_normalized_group_value(uint8_t groupid, uint16_t value, lv_obj_t* /********************************************** Native Commands ****************************************/ +void dispatch_screenshot(const char*, const char* filename) +{ +#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 + + if(strlen(filename) == 0) { // no filename given + char tempfile[32]; + 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); + } else { // Valid filename + guiTakeScreenshot(filename); + } + +#else + LOG_WARNING(TAG_MSGR, "Failed to save %s, no storage", filename); +#endif +} + void dispatch_parse_json(const char*, const char* payload) { // Parse an incoming JSON array into individual commands /* if(strPayload.endsWith(",]")) { @@ -719,10 +810,12 @@ void dispatch_parse_jsonl(const char*, const char* payload) void dispatch_output_current_page() { - // Log result - char payload[4]; - itoa(haspGetPage(), payload, DEC); - dispatch_state_msg(F("page"), payload); + char topic[8]; + char payload[8]; + + memcpy_P(topic, PSTR("page"), 5); + snprintf_P(payload, sizeof(payload), PSTR("%d"), haspGetPage()); + dispatch_state_subtopic(topic, payload); } // Get or Set a page @@ -785,9 +878,12 @@ void dispatch_dim(const char*, const char* level) // Set the current state if(strlen(level) != 0) haspDevice.set_backlight_level(atoi(level)); - char payload[5]; - itoa(haspDevice.get_backlight_level(), payload, DEC); - dispatch_state_msg(F("dim"), payload); + char topic[8]; + char payload[8]; + + memcpy_P(topic, PSTR("dim"), 4); + snprintf_P(payload, sizeof(payload), PSTR("%d"), haspDevice.get_backlight_level()); + dispatch_state_subtopic(topic, payload); } void dispatch_moodlight(const char* topic, const char* payload) @@ -843,11 +939,14 @@ void dispatch_moodlight(const char* topic, const char* payload) // Return the current state char buffer[128]; + char out_topic[16]; + memcpy_P(out_topic, PSTR("moodlight"), 10); 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\":\"#%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); - dispatch_state_msg(F("moodlight"), buffer); + dispatch_state_subtopic(out_topic, buffer); } void dispatch_backlight(const char*, const char* payload) @@ -856,9 +955,11 @@ void dispatch_backlight(const char*, const char* payload) if(strlen(payload) != 0) haspDevice.set_backlight_power(Utilities::is_true(payload)); // Return the current state + char topic[8]; char buffer[4]; + memcpy_P(topic, PSTR("light"), 6); memcpy_P(buffer, haspDevice.get_backlight_power() ? PSTR("on") : PSTR("off"), sizeof(buffer)); - dispatch_state_msg(F("light"), buffer); + dispatch_state_subtopic(topic, buffer); } void dispatch_web_update(const char*, const char* espOtaUrl) @@ -925,12 +1026,12 @@ void dispatch_output_statusupdate(const char*, const char*) strcat(data, buffer); #endif - snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"espCore\":\"%s\","), + snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"core\":\"%s\","), haspDevice.get_free_heap(), haspDevice.get_heap_fragmentation(), haspDevice.get_core_version()); strcat(data, buffer); - snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"), - haspGetPage(), (HASP_NUM_PAGES)); + snprintf_P(buffer, sizeof(buffer), PSTR("\"canUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"), haspGetPage(), + (HASP_NUM_PAGES)); strcat(data, buffer); #if defined(ARDUINO_ARCH_ESP8266) @@ -942,7 +1043,10 @@ void dispatch_output_statusupdate(const char*, const char*) Utilities::tft_driver_name().c_str(), (TFT_WIDTH), (TFT_HEIGHT)); strcat(data, buffer); } - mqtt_send_state(F("statusupdate"), data); + + char topic[16]; + memcpy_P(topic, PSTR("statusupdate"), 13); + dispatch_state_subtopic(topic, data); dispatchLastMillis = millis(); /* if(updateEspAvailable) { diff --git a/src/hasp/hasp_dispatch.h b/src/hasp/hasp_dispatch.h index 1dba3b41..ac0e591b 100644 --- a/src/hasp/hasp_dispatch.h +++ b/src/hasp/hasp_dispatch.h @@ -22,7 +22,9 @@ enum hasp_event_t { // even = released, odd = pressed HASP_EVENT_LONG = 5, HASP_EVENT_LOST = 6, HASP_EVENT_HOLD = 7, - HASP_EVENT_DOUBLE = 8 + HASP_EVENT_DOUBLE = 8, + + HASP_EVENT_CHANGED = 32 }; /* ===== Default Event Processors ===== */ @@ -60,7 +62,6 @@ void dispatch_output_statusupdate(const char*, const char*); void dispatch_current_state(); void dispatch_gpio_input_event(uint8_t pin, uint8_t group, uint8_t eventid); -void dispatch_object_event(lv_obj_t* obj, uint8_t eventid); bool dispatch_get_event_state(uint8_t eventid); void dispatch_get_event_name(uint8_t eventid, char* buffer, size_t size); void dispatch_object_value_changed(lv_obj_t* obj, int16_t state); @@ -72,6 +73,12 @@ void dispatch_send_obj_attribute_int(uint8_t pageid, uint8_t btnid, const char* void dispatch_send_obj_attribute_color(uint8_t pageid, uint8_t btnid, const char* attribute, uint8_t r, uint8_t g, uint8_t b); +void dispatch_object_generic_event(lv_obj_t* obj, uint8_t eventid); +void dispatch_object_toggle_event(lv_obj_t* obj, bool state); +void dispatch_object_value_changed(lv_obj_t* obj, int16_t state); +void dispatch_object_selection_changed(lv_obj_t* obj, int16_t val, const char* text); +void dispatch_object_color_changed(lv_obj_t* obj, lv_color_t color); + /* ===== Getter and Setter Functions ===== */ /* ===== Read/Write Configuration ===== */ diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp index 46610f2e..a91e7a76 100644 --- a/src/hasp/hasp_object.cpp +++ b/src/hasp/hasp_object.cpp @@ -269,6 +269,23 @@ void hasp_send_obj_attribute_color(lv_obj_t* obj, const char* attribute, lv_colo // ##################### Event Handlers ######################################################## +/** + * Called when a press on the system layer is detected + * @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) +{ + if(obj == lv_disp_get_layer_sys(NULL)) { + hasp_update_sleep_state(); // wakeup? + + if(event == LV_EVENT_CLICKED) { + lv_obj_set_click(obj, false); // disable first touch + LOG_VERBOSE(TAG_HASP, F("Wakeup touch disabled")); + } + } +} + /** * Called when a button-style object is clicked * @param obj pointer to a button object @@ -317,7 +334,7 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) return; case LV_EVENT_VALUE_CHANGED: - LOG_WARNING(TAG_HASP, F("Value changed Event %d occured"), event); + LOG_WARNING(TAG_HASP, F("Value changed Event %d occured"), event); // Shouldn't happen in this event handler last_press_was_short = false; return; @@ -333,28 +350,11 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) return; } - hasp_update_sleep_state(); // wakeup? - dispatch_object_event(obj, eventid); // send object event + hasp_update_sleep_state(); // wakeup? + dispatch_object_generic_event(obj, eventid); // send object event dispatch_normalized_group_value(obj->user_data.groupid, NORMALIZE(dispatch_get_event_state(eventid), 0, 1), obj); } -/** - * Called when a press on the system layer is detected - * @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) -{ - if(obj == lv_disp_get_layer_sys(NULL)) { - hasp_update_sleep_state(); // wakeup? - - if(event == LV_EVENT_CLICKED) { - lv_obj_set_click(obj, false); // disable first touch - LOG_VERBOSE(TAG_HASP, F("Wakeup touch disabled")); - } - } -} - /** * Called when a object state is toggled on/off * @param obj pointer to a switch object @@ -363,7 +363,7 @@ void wakeup_event_handler(lv_obj_t* obj, lv_event_t event) void toggle_event_handler(lv_obj_t* obj, lv_event_t event) { if(event == LV_EVENT_VALUE_CHANGED) { - char property[4]; + char property[36]; // 4 for val only bool val = 0; hasp_update_sleep_state(); // wakeup? @@ -385,8 +385,11 @@ void toggle_event_handler(lv_obj_t* obj, lv_event_t event) return; } - snprintf_P(property, sizeof(property), PSTR("val")); - hasp_send_obj_attribute_int(obj, property, val); + // snprintf_P(property, sizeof(property), PSTR("val")); + // hasp_send_obj_attribute_int(obj, property, val); + + hasp_update_sleep_state(); // wakeup? + dispatch_object_toggle_event(obj, val); dispatch_normalized_group_value(obj->user_data.groupid, NORMALIZE(val, 0, 1), obj); } else if(event == LV_EVENT_DELETE) { @@ -437,7 +440,7 @@ static void selector_event_handler(lv_obj_t* obj, lv_event_t event) const char* txt = lv_table_get_cell_value(obj, row, col); strncpy(buffer, txt, sizeof(buffer)); - snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"txt"), row, col); + snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"text"), row, col); hasp_send_obj_attribute_str(obj, property, buffer); return; } @@ -447,8 +450,10 @@ static void selector_event_handler(lv_obj_t* obj, lv_event_t event) } // set the property - snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val); - hasp_send_obj_attribute_str(obj, property, buffer); + // snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val); + // hasp_send_obj_attribute_str(obj, property, buffer); + + dispatch_object_selection_changed(obj, val, buffer); if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, NORMALIZE(val, 0, max), obj); } else if(event == LV_EVENT_DELETE) { @@ -481,6 +486,7 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event) int16_t val = 0; int16_t min = 0; int16_t max = 0; + hasp_update_sleep_state(); // wakeup? if(obj->user_data.objid == LV_HASP_SLIDER) { val = lv_slider_get_value(obj); @@ -514,7 +520,9 @@ static void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) if(event == LV_EVENT_VALUE_CHANGED) { hasp_update_sleep_state(); // wakeup? - hasp_send_obj_attribute_color(obj, color, lv_cpicker_get_color(obj)); + // hasp_send_obj_attribute_color(obj, color, lv_cpicker_get_color(obj)); + dispatch_object_color_changed(obj, lv_cpicker_get_color(obj)); + } else if(event == LV_EVENT_DELETE) { LOG_VERBOSE(TAG_HASP, F(D_OBJECT_DELETED)); hasp_object_delete(obj); diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h index 5760bede..aa67ff0b 100644 --- a/src/mqtt/hasp_mqtt.h +++ b/src/mqtt/hasp_mqtt.h @@ -9,9 +9,9 @@ #include "hasp_conf.h" -#ifdef WINDOWS -#define __FlashStringHelper char -#endif +// #ifdef WINDOWS +// #define __FlashStringHelper char +// #endif enum hasp_mqtt_error_t { MQTT_ERR_OK = 0, diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp index a1e45b66..c2afbe56 100644 --- a/src/mqtt/hasp_mqtt_paho_single.cpp +++ b/src/mqtt/hasp_mqtt_paho_single.cpp @@ -251,7 +251,7 @@ int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload) return mqttPublish(tmp_topic, payload, strlen(payload), false); } -int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, char* payload) +int 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); diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index 05a795cb..a485721b 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -128,11 +128,11 @@ void mqtt_send_lwt(bool online) bool res = mqttPublish(tmp_topic, tmp_payload, len, true); } -void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload) +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); - mqttPublish(tmp_topic, payload, false); + return mqttPublish(tmp_topic, payload, false); } int mqtt_send_state(const char* subtopic, const char* payload) From c780fabead9f67942503b167af05ca836c398d39 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 1 Mar 2021 04:29:53 +0100 Subject: [PATCH 18/18] Switch HA message order --- src/mqtt/hasp_mqtt_pubsubclient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp index a485721b..3fe89dff 100644 --- a/src/mqtt/hasp_mqtt_pubsubclient.cpp +++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp @@ -169,8 +169,8 @@ static void mqtt_message_cb(char* topic, byte* payload, unsigned int length) } else if(topic == strstr_P(topic, PSTR("homeassistant/status"))) { // HA discovery topic if(mqttHAautodiscover && !strcasecmp_P((char*)payload, PSTR("online"))) { - dispatch_current_state(); - mqtt_ha_register_auto_discovery(); + mqtt_ha_register_auto_discovery(); // auto-discovery first + dispatch_current_state(); // send the data } return;