diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index 0635be9b2..b116e7abf 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -366,11 +366,14 @@ enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD,SCRIPT_EVENT_HANDLED,SML_JSON_ENABLE,S #ifdef USE_UFILESYS extern uint8_t ufs_type; extern FS *ufsp; +extern FS *ffsp; #ifndef UFSYS_SIZE #define UFSYS_SIZE 8192 #endif +#define SSIZE_PSTORE (uint16_t *) (glob_script_mem.script_pram + glob_script_mem.script_pram_size - 2) + #define FAT_SCRIPT_NAME "/script.txt" #endif // USE_UFILESYS @@ -717,6 +720,8 @@ typedef struct { uint8_t tasm_cmd_activ = 0; + uint16_t ufs_script_size; + } SCRIPT_MEM; SCRIPT_MEM glob_script_mem; @@ -1603,6 +1608,24 @@ TS_FLOAT *Get_MFAddr(uint8_t index, uint16_t *len, uint16_t *ipos) { return 0; } +#ifdef USE_UFILESYS +FS *script_file_path(char *path) { + if (!strncmp_P(path, PSTR("/ffs/"), 5)) { + memmove(path, path + 4, strlen(path) + 1); + return ffsp; + } + if (!strncmp_P(path, PSTR("/sdfs/"), 6)) { + memmove(path, path + 5, strlen(path) + 1); + return ufsp; + } + if (path[0] != '/') { + memmove(path + 1, path, strlen(path) + 1); + path[0] = '/'; + } + return ufsp; +} +#endif + char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, TS_FLOAT *fp, char *sp, struct GVARS *gv); char *get_array_by_name(char *lp, TS_FLOAT **fp, uint16_t *alen, uint16_t *ipos); @@ -3413,6 +3436,7 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); if (!strncmp_XP(lp, XPSTR("fo("), 3)) { char str[SCRIPT_MAX_SBSIZE]; lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); + FS *cfp = script_file_path(str); while (*lp == ' ') lp++; uint8_t mode = 0; if ((*lp == 'r') || (*lp == 'w') || (*lp == 'a')) { @@ -3439,7 +3463,7 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); #ifdef DEBUG_FS AddLog(LOG_LEVEL_INFO, PSTR("SCR: open file for read %d"), cnt); #endif - glob_script_mem.files[cnt] = ufsp->open(str, FS_FILE_READ); + glob_script_mem.files[cnt] = cfp->open(str, FS_FILE_READ); if (glob_script_mem.files[cnt].isDirectory()) { glob_script_mem.files[cnt].rewindDirectory(); glob_script_mem.file_flags[cnt].is_dir = 1; @@ -3449,12 +3473,12 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); } else { if (mode == 1) { - glob_script_mem.files[cnt] = ufsp->open(str,FS_FILE_WRITE); + glob_script_mem.files[cnt] = cfp->open(str,FS_FILE_WRITE); #ifdef DEBUG_FS AddLog(LOG_LEVEL_INFO, PSTR("SCR: open file for write %d"), cnt); #endif } else { - glob_script_mem.files[cnt] = ufsp->open(str,FS_FILE_APPEND); + glob_script_mem.files[cnt] = cfp->open(str,FS_FILE_APPEND); #ifdef DEBUG_FS AddLog(LOG_LEVEL_INFO, PSTR("SCR: open file for append %d"), cnt); #endif @@ -3660,7 +3684,8 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); if (!strncmp_XP(lp, XPSTR("fd("), 3)) { char str[SCRIPT_MAX_SBSIZE]; lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); - ufsp->remove(str); + FS *cfp = script_file_path(str); + cfp->remove(str); goto nfuncexit; } #ifdef USE_UFILESYS @@ -3728,7 +3753,8 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); if (!strncmp_XP(lp, XPSTR("fmd("), 4)) { char str[SCRIPT_MAX_SBSIZE]; lp = GetStringArgument(lp + 4, OPER_EQU, str, 0); - fvar = ufsp->mkdir(str); + FS *cfp = script_file_path(str); + fvar = cfp->mkdir(str); goto nfuncexit; } if (!strncmp_XP(lp, XPSTR("fmt("), 4)) { @@ -3743,13 +3769,15 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); if (!strncmp_XP(lp, XPSTR("frd("), 4)) { char str[SCRIPT_MAX_SBSIZE]; lp = GetStringArgument(lp + 4, OPER_EQU, str, 0); - fvar = ufsp->rmdir(str); + FS *cfp = script_file_path(str); + fvar = cfp->rmdir(str); goto nfuncexit; } if (!strncmp_XP(lp, XPSTR("fx("), 3)) { char str[SCRIPT_MAX_SBSIZE]; lp = GetStringArgument(lp + 3, OPER_EQU, str, 0); - if (ufsp->exists(str)) fvar = 1; + FS *cfp = script_file_path(str); + if (cfp->exists(str)) fvar = 1; else fvar = 0; goto nfuncexit; } @@ -3768,8 +3796,8 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); char fn_to[SCRIPT_MAX_SBSIZE]; lp = GetStringArgument(lp, OPER_EQU, fn_to, 0); SCRIPT_SKIP_SPACES - - fvar = ufsp->rename(fn_from, fn_to); + FS *cfp = script_file_path(fn_from); + fvar = cfp->rename(fn_from, fn_to); goto nfuncexit; } @@ -4521,14 +4549,40 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); uint8_t selector = fvar; switch (selector) { case 0: - // start streaming - char url[SCRIPT_MAX_SBSIZE]; - lp = GetStringArgument(lp, OPER_EQU, url, 0); - TS_FLOAT xp, yp, scale ; - lp = GetNumericArgument(lp, OPER_EQU, &xp, 0); - lp = GetNumericArgument(lp, OPER_EQU, &yp, 0); - lp = GetNumericArgument(lp, OPER_EQU, &scale, 0); - fvar = fetch_jpg(0, url, xp, yp, scale); + { + // start streaming + char url[SCRIPT_MAX_SBSIZE]; + lp = GetStringArgument(lp, OPER_EQU, url, 0); + TS_FLOAT xp, yp, scale ; + lp = GetNumericArgument(lp, OPER_EQU, &xp, 0); + lp = GetNumericArgument(lp, OPER_EQU, &yp, 0); + lp = GetNumericArgument(lp, OPER_EQU, &scale, 0); + fvar = fetch_jpg(0, url, xp, yp, scale); + } + break; + case 1: + { + char file[SCRIPT_MAX_SBSIZE]; + lp = GetStringArgument(lp, OPER_EQU, file, 0); + File fp; + FS *cfp = script_file_path(file); + fp = cfp->open(file, FS_FILE_READ); + if (fp) { + uint32_t size = fp.size(); + uint8_t *mem = (uint8_t *)special_malloc(size); + if (mem) { + uint8_t res = fp.read(mem, size); + uint16_t xsize; + uint16_t ysize; + get_jpeg_size(mem, size, &xsize, &ysize); + xsize &= 0x7ff; + ysize &= 0x7ff; + fvar = (xsize << 11) | ysize; + free(mem); + fp.close(); + } + } + } break; default: // other cmds @@ -5899,13 +5953,14 @@ extern char *SML_GetSVal(uint32_t index); #endif //USE_TOUCH_BUTTONS #endif //USE_DISPLAY -uint32_t directRead(uint32_t pin); -void directWriteLow(uint32_t pin); -void directWriteHigh(uint32_t pin); -void directModeInput(uint32_t pin); -void directModeOutput(uint32_t pin); - #if 0 +/* +uint32_t tmod_directRead(uint32_t pin); +void tmod_directWriteLow(uint32_t pin); +void tmod_directWriteHigh(uint32_t pin); +void tmod_directModeInput(uint32_t pin); +void tmod_directModeOutput(uint32_t pin); +*/ if (!strncmp_XP(lp, XPSTR("test("), 5)) { lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, gv); uint32_t sel = fvar; @@ -5914,19 +5969,19 @@ void directModeOutput(uint32_t pin); switch (sel) { case 0: - fvar = directRead(pin); + fvar = tmod_directRead(pin); break; case 1: - directWriteLow(pin); + tmod_directWriteLow(pin); break; case 2: - directWriteHigh(pin); + tmod_directWriteHigh(pin); break; case 3: - directModeInput(pin); + tmod_directModeInput(pin); break; case 4: - directModeOutput(pin); + tmod_directModeOutput(pin); break; } @@ -8765,7 +8820,7 @@ void Scripter_save_pvars(void) { uint16_t len = 0; TS_FLOAT *fa = Get_MFAddr(index, &len, 0); mlen += sizeof(TS_FLOAT) * len; - if (mlen>glob_script_mem.script_pram_size) { + if (mlen > glob_script_mem.script_pram_size) { vtp[count].bits.is_permanent = 0; return; } @@ -8774,7 +8829,7 @@ void Scripter_save_pvars(void) { } } else { mlen += sizeof(TS_FLOAT); - if (mlen>glob_script_mem.script_pram_size) { + if (mlen > glob_script_mem.script_pram_size) { vtp[count].bits.is_permanent = 0; return; } @@ -8789,7 +8844,7 @@ void Scripter_save_pvars(void) { char *sp = glob_script_mem.glob_snp + (index * glob_script_mem.max_ssize); uint8_t slen = strlen(sp); mlen += slen + 1; - if (mlen>glob_script_mem.script_pram_size) { + if (mlen > glob_script_mem.script_pram_size) { vtp[count].bits.is_permanent = 0; return; } @@ -9934,14 +9989,18 @@ void execute_script(char *script) { #define D_CMND_SCRIPT "Script" #define D_CMND_SUBSCRIBE "Subscribe" #define D_CMND_UNSUBSCRIBE "Unsubscribe" +#define D_CMND_BUFFERSIZE "ScriptSize" - -enum ScriptCommands { CMND_SCRIPT,CMND_SUBSCRIBE, CMND_UNSUBSCRIBE, CMND_SUBTEST}; +enum ScriptCommands { CMND_SCRIPT,CMND_SUBSCRIBE, CMND_UNSUBSCRIBE, CMND_BSIZE, CMND_SUBTEST}; const char kScriptCommands[] PROGMEM = D_CMND_SCRIPT "|" D_CMND_SUBSCRIBE "|" D_CMND_UNSUBSCRIBE +#ifdef USE_UFILESYS + "|" D_CMND_BUFFERSIZE +#endif #ifdef DEBUG_MQTT_EVENT "|" "SUBTEST" #endif ; + bool ScriptCommand(void) { char command[CMDSZ]; bool serviced = true; @@ -10045,7 +10104,20 @@ bool ScriptCommand(void) { serviced = true; #endif #endif //SUPPORT_MQTT_EVENT - } +#ifdef USE_UFILESYS +#ifndef NO_SCRIPT_VARBSIZE + } else if (CMND_BSIZE == command_code) { + // set script buffer size + if (XdrvMailbox.payload >= 1000) { + *SSIZE_PSTORE = XdrvMailbox.payload; + TasmotaGlobal.restart_flag = 2; + } + Response_P(PSTR("{\"script buffer\":%d}"), *SSIZE_PSTORE); + serviced = true; +#endif +#endif + + } return serviced; } @@ -11019,7 +11091,7 @@ char *gc_get_arrays(char *lp, TS_FLOAT **arrays, uint8_t *ranum, uint16_t *rentr char *gc_get_arrays(char *lp, TS_FLOAT **arrays, uint8_t *ranum, uint16_t *rentries, uint16_t *ipos) { struct T_INDEX ind; uint8_t vtype; -uint16 entries = 0; +uint16_t entries = 0; uint16_t cipos = 0; uint8_t anum = 0; @@ -12037,7 +12109,7 @@ exgc: todflg = -2; lp += 4; } - uint16 segments = 1; + uint16_t segments = 1; for (uint32_t cnt = 0; cnt < strlen(lp); cnt++) { if (lp[cnt] == '|') { segments++; @@ -13288,23 +13360,38 @@ bool Xdrv10(uint32_t function) { glob_script_mem.FLAGS.eeprom = false; glob_script_mem.script_pram = (uint8_t*)Settings->script_pram[0]; glob_script_mem.script_pram_size = PMEM_SIZE; - + #ifdef USE_UFILESYS if (ufs_type) { +#ifndef NO_SCRIPT_VARBSIZE + glob_script_mem.script_pram = (uint8_t*)Settings->rules[0]; + glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE; + uint16_t sbsize = *SSIZE_PSTORE; + if (sbsize > UFSYS_SIZE) { + sbsize = UFSYS_SIZE; + } + if (sbsize < 1000) { + sbsize = UFSYS_SIZE; + } + glob_script_mem.ufs_script_size = sbsize; +#else + glob_script_mem.ufs_script_size = UFSYS_SIZE; +#endif + // we have a file system AddLog(LOG_LEVEL_INFO,PSTR("SCR: ufilesystem found")); char *script; - script = (char*)special_malloc(UFSYS_SIZE + 4); + script = (char*)special_malloc(glob_script_mem.ufs_script_size + 4); if (!script) break; - memset(script, 0, UFSYS_SIZE); + memset(script, 0, glob_script_mem.ufs_script_size); glob_script_mem.script_ram = script; - glob_script_mem.script_size = UFSYS_SIZE; + glob_script_mem.script_size = glob_script_mem.ufs_script_size; if (ufsp->exists(FAT_SCRIPT_NAME)) { File file = ufsp->open(FAT_SCRIPT_NAME, FS_FILE_READ); - file.read((uint8_t*)script, UFSYS_SIZE); + file.read((uint8_t*)script, glob_script_mem.ufs_script_size); file.close(); } - script[UFSYS_SIZE - 1] = 0; + script[glob_script_mem.ufs_script_size - 1] = 0; // use rules storage for permanent vars glob_script_mem.script_pram = (uint8_t*)Settings->rules[0]; glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE;