refactoring and bug fixes (#17798)

This commit is contained in:
gemu 2023-01-27 11:10:43 +01:00 committed by GitHub
parent 8d782caf15
commit 103e3f616a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 464 additions and 176 deletions

View File

@ -42,6 +42,9 @@ keywords if then else endif, or, and are better readable for beginners (others m
#define XDRV_10 10 #define XDRV_10 10
const uint8_t SCRIPT_VERS[2] = {5, 0};
#define SCRIPT_DEBUG 0 #define SCRIPT_DEBUG 0
#ifndef MAXVARS #ifndef MAXVARS
@ -100,7 +103,6 @@ char *Get_esc_char(char *cp, char *esc_chr);
#undef USE_SCRIPT_FATFS #undef USE_SCRIPT_FATFS
#define USE_SCRIPT_FATFS -1 #define USE_SCRIPT_FATFS -1
// #pragma message "universal file system used"
#else // USE_UFILESYS #else // USE_UFILESYS
@ -497,6 +499,10 @@ struct SCRIPT_MEM {
#ifdef USE_SCRIPT_SPI #ifdef USE_SCRIPT_SPI
struct SCRIPT_SPI spi; struct SCRIPT_SPI spi;
#endif #endif
#ifdef USE_FEXTRACT
uint32_t from_time;
uint32_t to_time;
#endif
#if defined(USE_SML_M) && defined(USE_SML_SCRIPT_CMD) && defined(USE_SCRIPT_SERIAL) #if defined(USE_SML_M) && defined(USE_SML_SCRIPT_CMD) && defined(USE_SCRIPT_SERIAL)
char *hstr; char *hstr;
#endif #endif
@ -549,7 +555,12 @@ char *GetStringArgument(char *lp,uint8_t lastop,char *cp, struct GVARS *gv);
char *ForceStringVar(char *lp,char *dstr); char *ForceStringVar(char *lp,char *dstr);
void send_download(void); void send_download(void);
uint8_t UfsReject(char *name); uint8_t UfsReject(char *name);
void fread_str(uint8_t fref, char *sp, uint16_t slen); #ifdef USE_UFILESYS
void fread_str_fp(File *fp, char *sp, uint16_t slen, uint16_t flg);
int32_t script_copy_file(File *source, File *dest, uint32_t sf_from, uint32_t sf_to, uint32_t flag, WiFiClient *client);
int32_t opt_fext(File *fp, char *ts_from, char *ts_to, uint32_t flg);
int32_t extract_from_file(File *fp, char *ts_from, char *ts_to, int8_t coffs, float **a_ptr, uint16_t *a_len, uint8_t numa, int16_t accum);
#endif
char *eval_sub(char *lp, float *fvar, char *rstr); char *eval_sub(char *lp, float *fvar, char *rstr);
void ScriptEverySecond(void) { void ScriptEverySecond(void) {
@ -1247,7 +1258,6 @@ void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) {
#endif //USE_LIGHT #endif //USE_LIGHT
float median_array(float *array, uint16_t len) { float median_array(float *array, uint16_t len) {
uint8_t ind[len]; uint8_t ind[len];
uint8_t mind = 0; uint8_t mind = 0;
@ -1441,24 +1451,74 @@ float DoMedian5(uint8_t index, float in) {
return median_array(mf->buffer, MEDIAN_SIZE); return median_array(mf->buffer, MEDIAN_SIZE);
} }
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
void fread_str(uint8_t fref, char *sp, uint16_t slen) { void fread_str_fp(File *fp, char *sp, uint16_t slen, uint16_t flg) {
uint16_t index = 0; uint16_t index = 0;
while (glob_script_mem.files[fref].available()) { while (fp->available()) {
uint8_t buf[1], iob; uint8_t buf[1], iob;
glob_script_mem.files[fref].read(buf,1); fp->read(buf, 1);
iob = buf[0]; iob = buf[0];
if (flg) {
if (iob == '\n') {
break;
}
} else {
if (iob == '\t' || iob == ',' || iob == '\n' || iob == '\r') { if (iob == '\t' || iob == ',' || iob == '\n' || iob == '\r') {
break; break;
} else { }
}
*sp++ = iob; *sp++ = iob;
index++; index++;
if (index >= slen - 1) break; if (index >= slen - 1) break;
} }
}
*sp = 0; *sp = 0;
} }
#endif
int32_t script_copy_file(File *source, File *dest, uint32_t sf_from, uint32_t sf_to, uint32_t flag, WiFiClient *client) {
int32_t res = 0;
uint32_t fsize = sf_to - sf_from;
uint8_t *fbuff = (uint8_t*)malloc(512);
uint16_t rsize = 512;
if (fbuff) {
if (flag) {
// flag > 0 copy header
source->seek(0, SeekSet);
fread_str_fp(source, (char*)fbuff, rsize, 1);
uint16_t ssize = strlen((char*)fbuff);
fbuff[ssize++] = '\n';
fbuff[ssize] = 0;
if (dest) {
dest->write(fbuff, ssize);
}
if (client) {
client->write(fbuff, ssize);
}
}
// seek to start
source->seek(sf_from, SeekSet);
while (fsize) {
if (fsize < rsize) {
rsize = fsize;
}
source->read(fbuff, rsize);
if (dest) {
dest->write(fbuff, rsize);
}
if (client) {
client->write(fbuff, rsize);
}
fsize -= rsize;
}
free(fbuff);
} else {
return -3;
}
return res;
}
#ifdef USE_FEXTRACT #ifdef USE_FEXTRACT
@ -1540,9 +1600,13 @@ uint32_t ts2ts(struct FE_TM *tm, char *ts) {
} }
void tss2ts(struct FE_TM *tm, char *dst, uint8_t mode) { void tss2ts(struct FE_TM *tm, char *dst, uint8_t mode) {
if (mode == 1) { if (mode & 1 == 1) {
// was tsm format go to 16.12.20 15:36 // was tsm format go to 16.12.20 15:36
sprintf(dst, "%01d.%01d.%01d %01d:%02d", tm->day, tm->month, tm->year, tm->hour, tm->mins); char c = ' ';
if (mode & 0x80) {
c = '-';
}
sprintf(dst, "%01d.%01d.%01d%c%01d:%02d", tm->day, tm->month, tm->year, c, tm->hour, tm->mins);
} else { } else {
// 2020-12-16T15:36:41 // 2020-12-16T15:36:41
sprintf(dst, "%04d-%02d-%02dT%02d:%02d:%02d", tm->year + 2000, tm->month, tm->day, tm->hour, tm->mins, tm->secs); sprintf(dst, "%04d-%02d-%02dT%02d:%02d:%02d", tm->year + 2000, tm->month, tm->day, tm->hour, tm->mins, tm->secs);
@ -1573,16 +1637,72 @@ struct tm tmx;
return tmd; return tmd;
} }
// convert seconds to tasmota time stamp
uint32_t s2tstamp(char *ts, uint32_t tsize, uint32_t seconds, uint32_t flg) {
time_t tmd = seconds;
struct tm *tmp;
struct FE_TM tm;
tmp = gmtime(&tmd);
if (!flg) {
tm.secs = tmp->tm_sec;
tm.mins = tmp->tm_min;
tm.hour = tmp->tm_hour;
} else {
tm.secs = 0;
tm.mins = 0;
tm.hour = 0;
}
tm.month = tmp->tm_mon + 1;
tm.year = tmp->tm_year - 100;
tm.day = tmp->tm_mday;
tss2ts(&tm, ts, 0);
return 0;
}
// optimized access, estimate entry point
int32_t opt_fext(File *fp, char *ts_from, char *ts_to, uint32_t flg) {
// seek to start
int32_t fres = extract_from_file(fp, ts_from, ts_to, -2, 0, 0, 0, 0);
int32_t start = fres;
char tsf[32];
fread_str_fp(fp, tsf, sizeof(tsf), 0);
uint32_t ltsf = tstamp2l(tsf);
fres = extract_from_file(fp, ts_from, ts_to, -1, 0, 0, 0, 0);
int32_t end = fres;
fread_str_fp(fp, tsf, sizeof(tsf), 0);
uint32_t tssiz = tstamp2l(tsf) - ltsf;
uint32_t tspos = tstamp2l(ts_from) - ltsf;
float perc = (float)tspos / (float)tssiz * 0.8;
if (perc < 0) perc = 0;
if (perc > 1) perc = 1;
float fsize = fp->size();
uint32_t spos = perc * fsize;
//AddLog(LOG_LEVEL_INFO,PSTR(">>> 1 %d, %d"), (uint32_t)perc, spos);
fp->seek(spos, SeekSet);
fres = extract_from_file(fp, ts_from, ts_to, -3, 0, 0, 0, 0);
if (fres < 0) {
if (flg) {
if (flg == 1) {
fres = start;
} else {
fres = end;
}
}
}
return fres;
}
// assume 1. entry is timestamp, others are tab delimited values until LF // assume 1. entry is timestamp, others are tab delimited values until LF
// file reference, from timestamp, to timestampm, column offset, array pointers, array lenght, number of arrays // file reference, from timestamp, to timestampm, column offset, array pointers, array lenght, number of arrays
int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coffs, float **a_ptr, uint16_t *a_len, uint8_t numa, int16_t accum) { int32_t extract_from_file(File *fp, char *ts_from, char *ts_to, int8_t coffs, float **a_ptr, uint16_t *a_len, uint8_t numa, int16_t accum) {
if (!glob_script_mem.file_flags[fref].is_open) return -1;
char rstr[32]; char rstr[32];
uint8_t sindex = 0; uint8_t sindex = 0;
uint8_t colpos = 0; uint8_t colpos = 0;
uint8_t range = 0; uint8_t range = 0;
if (coffs < 0) { if (coffs < 0) {
uint32_t cpos = glob_script_mem.files[fref].size(); uint32_t cpos = fp->size();
if (coffs == -1) { if (coffs == -1) {
// seek to last entry // seek to last entry
if (cpos > 1) cpos -= 2; if (cpos > 1) cpos -= 2;
@ -1590,8 +1710,8 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
uint8_t lbuff[256]; uint8_t lbuff[256];
uint8_t iob; uint8_t iob;
uint16_t index = sizeof(lbuff) -1; uint16_t index = sizeof(lbuff) -1;
glob_script_mem.files[fref].seek(cpos - sizeof(lbuff), SeekSet); fp->seek(cpos - sizeof(lbuff), SeekSet);
glob_script_mem.files[fref].read(lbuff, sizeof(lbuff)); fp->read(lbuff, sizeof(lbuff));
while (cpos) { while (cpos) {
iob = lbuff[index]; iob = lbuff[index];
if (iob == '\n' || iob == '\r') { if (iob == '\n' || iob == '\r') {
@ -1600,12 +1720,13 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
cpos--; cpos--;
index--; index--;
} }
glob_script_mem.files[fref].seek(cpos, SeekSet); fp->seek(cpos, SeekSet);
} else if (coffs == -2) { } else if (coffs == -2) {
// seek to line 2 // seek to line 2
fp->seek(0, SeekSet);
for (uint32_t cp = 0; cp < cpos; cp++) { for (uint32_t cp = 0; cp < cpos; cp++) {
uint8_t buff[2], iob; uint8_t buff[2], iob;
glob_script_mem.files[fref].read(buff, 1); fp->read(buff, 1);
iob = buff[0]; iob = buff[0];
if (iob == '\n' || iob == '\r') { if (iob == '\n' || iob == '\r') {
cpos = cp + 1; cpos = cp + 1;
@ -1614,24 +1735,24 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
} }
} else { } else {
// seek to pos of ts_from // seek to pos of ts_from
cpos = glob_script_mem.files[fref].position(); cpos = fp->position();
uint32_t tsfrom = tstamp2l(ts_from); uint32_t tsfrom = tstamp2l(ts_from);
while (glob_script_mem.files[fref].available()) { while (fp->available()) {
uint8_t buff[2], iob; uint8_t buff[2], iob;
glob_script_mem.files[fref].read(buff, 1); fp->read(buff, 1);
cpos++; cpos++;
iob = buff[0]; iob = buff[0];
if (iob == '\n' || iob == '\r') { if (iob == '\n' || iob == '\r') {
// read time stamp // read time stamp
char ts[22]; char ts[22];
glob_script_mem.files[fref].read((uint8_t*)ts, sizeof(ts)); fp->read((uint8_t*)ts, sizeof(ts));
char *cp = strchr(ts, '\t'); char *cp = strchr(ts, '\t');
if (cp) { if (cp) {
*cp = 0; *cp = 0;
uint32_t tstc = tstamp2l(ts); uint32_t tstc = tstamp2l(ts);
//Serial.printf(">>> %s - %d - %d\n",ts, tstc, cpos ); //Serial.printf(">>> %s - %d - %d\n",ts, tstc, cpos );
if (tstc >= tsfrom) { if (tstc >= tsfrom) {
glob_script_mem.files[fref].seek(cpos, SeekSet); fp->seek(cpos, SeekSet);
return cpos; return cpos;
} }
} }
@ -1642,8 +1763,8 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
} }
return cpos; return cpos;
} }
uint32_t ipos = glob_script_mem.files[fref].position(); uint32_t ipos = fp->position();
glob_script_mem.files[fref].seek(0, SeekSet); fp->seek(0, SeekSet);
uint32_t tsfrom = tstamp2l(ts_from); uint32_t tsfrom = tstamp2l(ts_from);
uint32_t tsto = tstamp2l(ts_to); uint32_t tsto = tstamp2l(ts_to);
//AddLog(LOG_LEVEL_INFO, PSTR("from: %d to: %d"),tsfrom, tsto); //AddLog(LOG_LEVEL_INFO, PSTR("from: %d to: %d"),tsfrom, tsto);
@ -1666,10 +1787,10 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
accum = -accum; accum = -accum;
} }
if (accum == 0) accum = 1; if (accum == 0) accum = 1;
while (glob_script_mem.files[fref].available()) { while (fp->available()) {
// scan through file // scan through file
uint8_t buff[2], iob; uint8_t buff[2], iob;
glob_script_mem.files[fref].read(buff, 1); fp->read(buff, 1);
iob = buff[0]; iob = buff[0];
if (iob == '\t' || iob == ',' || iob == '\n' || iob == '\r') { if (iob == '\t' || iob == ',' || iob == '\n' || iob == '\r') {
rstr[sindex] = 0; rstr[sindex] = 0;
@ -1694,7 +1815,7 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
uint32_t cts = tstamp2l(rstr); uint32_t cts = tstamp2l(rstr);
if (cts > tsto) { if (cts > tsto) {
// end of range must seek back to last LF, for next scan // end of range must seek back to last LF, for next scan
glob_script_mem.files[fref].seek(lastpos, SeekSet); fp->seek(lastpos, SeekSet);
break; break;
} }
if (cts >= tsfrom && cts <= tsto) { if (cts >= tsfrom && cts <= tsto) {
@ -1751,12 +1872,12 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
} }
colpos++; colpos++;
if (iob == '\n' || iob == '\r') { if (iob == '\n' || iob == '\r') {
lastpos = glob_script_mem.files[fref].position(); lastpos = fp->position();
colpos = 0; colpos = 0;
lines ++; lines ++;
if (lines == 1) { if (lines == 1) {
if (ipos) { if (ipos) {
glob_script_mem.files[fref].seek(ipos, SeekSet); fp->seek(ipos, SeekSet);
} }
} }
} }
@ -1767,7 +1888,7 @@ int32_t extract_from_file(uint8_t fref, char *ts_from, char *ts_to, int8_t coff
return rlines; return rlines;
} }
#endif // USE_FEXTRACT #endif // USE_FEXTRACT
#endif // USE_UFILESYS
uint32_t script_bcd(uint8_t sel, uint32_t val) { uint32_t script_bcd(uint8_t sel, uint32_t val) {
uint32_t res = 0; uint32_t res = 0;
@ -2633,17 +2754,13 @@ chknext:
lp = isvar(lp + 4, &vtype, &ind, 0, 0, gv); lp = isvar(lp + 4, &vtype, &ind, 0, 0, gv);
if (!ind.bits.constant) { if (!ind.bits.constant) {
uint8_t index = glob_script_mem.type[ind.index].index; uint8_t index = glob_script_mem.type[ind.index].index;
if (glob_script_mem.fvars[index] != glob_script_mem.s_fvars[index]) { fvar = glob_script_mem.fvars[index] != glob_script_mem.s_fvars[index];
// var has changed
glob_script_mem.s_fvars[index] = glob_script_mem.fvars[index]; glob_script_mem.s_fvars[index] = glob_script_mem.fvars[index];
fvar = 1;
goto nfuncexit;
} else { } else {
fvar = 0; fvar = 0;
}
goto nfuncexit; goto nfuncexit;
} }
}
}
#ifdef ESP32 #ifdef ESP32
if (!strncmp(vname, "core", 4)) { if (!strncmp(vname, "core", 4)) {
fvar = xPortGetCoreID(); fvar = xPortGetCoreID();
@ -2727,6 +2844,39 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
goto nfuncexit; goto nfuncexit;
} }
#endif #endif
#ifdef USE_UFILESYS
if (!strncmp(lp, "cpf(", 4)) {
// copy file with offsets sfd, sfstart, sfstop, df
float sfd, sf_from, sf_to, dfd;
lp = GetNumericArgument(lp + 4, OPER_EQU, &sfd, 0);
lp = GetNumericArgument(lp, OPER_EQU, &sf_from, 0);
lp = GetNumericArgument(lp, OPER_EQU, &sf_to, 0);
lp = GetNumericArgument(lp, OPER_EQU, &dfd, 0);
if (*lp != ')') {
lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
} else {
fvar = 0;
}
uint8_t source = sfd;
uint8_t dest = dfd;
if (!glob_script_mem.file_flags[source].is_open) {
fvar -1;
goto nfuncexit;
}
if (!glob_script_mem.file_flags[dest].is_open) {
fvar -2;
goto nfuncexit;
}
fvar = script_copy_file(&glob_script_mem.files[source], &glob_script_mem.files[dest], sf_from, sf_to, fvar, 0);
glob_script_mem.files[source].close();
glob_script_mem.file_flags[source].is_open = 0;
glob_script_mem.files[dest].close();
glob_script_mem.file_flags[dest].is_open = 0;
goto nfuncexit;
}
#endif
break; break;
case 'd': case 'd':
if (!strncmp(vname, "day", 3)) { if (!strncmp(vname, "day", 3)) {
@ -2751,6 +2901,19 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
fvar = 0; fvar = 0;
goto nfuncexit; goto nfuncexit;
} }
if (!strncmp(lp, "diff[", 5)) {
struct T_INDEX ind;
uint8_t vtype;
lp = isvar(lp + 5, &vtype, &ind, 0, 0, gv);
if (!ind.bits.constant) {
uint8_t index = glob_script_mem.type[ind.index].index;
fvar = glob_script_mem.fvars[index] - glob_script_mem.s_fvars[index];
glob_script_mem.s_fvars[index] = glob_script_mem.fvars[index];
} else {
fvar = 0;
}
goto nfuncexit;
}
break; break;
case 'e': case 'e':
if (!strncmp(vname, "epoch", 5)) { if (!strncmp(vname, "epoch", 5)) {
@ -3187,12 +3350,6 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
} else { } else {
break; break;
} }
/*
if (oflg) {
lp = GetNumericArgument(lp, OPER_EQU, &pfac, gv);
SCRIPT_SKIP_SPACES
}*/
// extract from file // extract from file
lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv);
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
@ -3227,37 +3384,31 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
break; break;
} }
} }
if (!glob_script_mem.file_flags[fref].is_open) {
fvar = -1;
goto nfuncexit;
}
if (oflg) { if (oflg) {
// optimized access // optimized access
// seek to start int32_t fres = opt_fext(&glob_script_mem.files[fref], ts_from, ts_to, 1);
uint32_t fres = extract_from_file(fref, ts_from, ts_to, -2, 0, 0, 0, 0);
char tsf[32];
fread_str(fref, tsf, sizeof(tsf));
uint32_t ltsf = tstamp2l(tsf);
fres = extract_from_file(fref, ts_from, ts_to, -1, 0, 0, 0, 0);
fread_str(fref, tsf, sizeof(tsf));
uint32_t tssiz = tstamp2l(tsf) - ltsf;
uint32_t tspos = tstamp2l(ts_from) - ltsf;
float perc = (float)tspos / (float)tssiz * 0.9;
if (perc < 0) perc = 0;
if (perc > 1) perc = 1;
float fsize = glob_script_mem.files[fref].size();
uint32_t spos = perc * fsize;
//AddLog(LOG_LEVEL_INFO,PSTR(">>> 1 %d, %d"), (uint32_t)perc, spos);
glob_script_mem.files[fref].seek(spos, SeekSet);
fres = extract_from_file(fref, ts_from, ts_to, -3, 0, 0, 0, 0);
//AddLog(LOG_LEVEL_INFO,PSTR(">>> 2 %s - %d - %d"), ts_from, fres, (uint32_t)(perc*100)); //AddLog(LOG_LEVEL_INFO,PSTR(">>> 2 %s - %d - %d"), ts_from, fres, (uint32_t)(perc*100));
if (fres > 0) { if (fres > 0) {
fvar = extract_from_file(fref, ts_from, ts_to, coffs, a_ptr, a_len, index, accum); fvar = extract_from_file(&glob_script_mem.files[fref], ts_from, ts_to, coffs, a_ptr, a_len, index, accum);
} else { } else {
// fatal error time stamp out of range // fatal error time stamp out of range
fvar = -2; fvar = -2;
} }
} else { } else {
fvar = extract_from_file(fref, ts_from, ts_to, coffs, a_ptr, a_len, index, accum); fvar = extract_from_file(&glob_script_mem.files[fref], ts_from, ts_to, coffs, a_ptr, a_len, index, accum);
} }
} else { } else {
fvar = extract_from_file(fref, ts_from, ts_to, coffs, 0, 0, 0, 0); if (oflg) {
fvar = opt_fext(&glob_script_mem.files[fref], ts_from, ts_to, 0);
if (coffs == -4) {
goto nfuncexit;
}
}
fvar = extract_from_file(&glob_script_mem.files[fref], ts_from, ts_to, coffs, 0, 0, 0, 0);
} }
goto nfuncexit; goto nfuncexit;
@ -3361,7 +3512,6 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
} }
if (!strncmp(lp, "fsm", 3)) { if (!strncmp(lp, "fsm", 3)) {
fvar = (uint32_t)ufsp; fvar = (uint32_t)ufsp;
//card_init();
goto exit; goto exit;
} }
#endif //USE_SCRIPT_FATFS #endif //USE_SCRIPT_FATFS
@ -3978,17 +4128,6 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value);
if (!strncmp(lp, "pd[", 3)) { if (!strncmp(lp, "pd[", 3)) {
GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv); GetNumericArgument(lp + 3, OPER_EQU, &fvar, gv);
uint8_t gpiopin = fvar; uint8_t gpiopin = fvar;
/*
for (uint8_t i=0;i<GPIO_SENSOR_END;i++) {
// if (pin_gpio[i]==gpiopin) {
if (Pin(i)==gpiopin) {
fvar=i;
// skip ] bracket
len++;
goto exit;
}
}
*/
if ((gpiopin < nitems(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) { if ((gpiopin < nitems(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) {
fvar = TasmotaGlobal.gpio_pin[gpiopin]; fvar = TasmotaGlobal.gpio_pin[gpiopin];
// skip ] bracket // skip ] bracket
@ -4944,6 +5083,16 @@ extern char *SML_GetSVal(uint32_t index);
len = 0; len = 0;
goto strexit; goto strexit;
} }
#ifdef USE_FEXTRACT
if (!strncmp(lp, "s2t(", 4)) {
lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
char str[SCRIPT_MAXSSIZE];
s2tstamp(str, SCRIPT_MAXSSIZE, fvar, 0);
if (sp) strlcpy(sp, str, glob_script_mem.max_ssize);
len = 0;
goto strexit;
}
#endif // USE_FEXTRACT
break; break;
case 't': case 't':
@ -5239,6 +5388,11 @@ extern char *SML_GetSVal(uint32_t index);
fvar = !TasmotaGlobal.global_state.wifi_down; fvar = !TasmotaGlobal.global_state.wifi_down;
goto exit; goto exit;
} }
if (!strncmp(vname, "wlp", 3)) {
OsWatchLoop();
fvar = 0;
goto exit;
}
#ifdef xUSE_SHINE #ifdef xUSE_SHINE
if (!strncmp(vname, "wav2mp3(", 8)) { if (!strncmp(vname, "wav2mp3(", 8)) {
char path[SCRIPT_MAXSSIZE]; char path[SCRIPT_MAXSSIZE];
@ -7341,7 +7495,6 @@ void script_upload_start(void) {
script_ex_ptr += csiz; script_ex_ptr += csiz;
uplsize += csiz; uplsize += csiz;
} }
//AddLog(LOG_LEVEL_INFO, PSTR("HTP: write %d - %d"),csiz,uplsize);
} }
//if (upload_file) upload_file.write(upload.buf,upload.currentSize); //if (upload_file) upload_file.write(upload.buf,upload.currentSize);
@ -7493,7 +7646,6 @@ void HandleScriptConfiguration(void) {
void SaveScript(void) { void SaveScript(void) {
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
if (glob_script_mem.FLAGS.fsys == true) { if (glob_script_mem.FLAGS.fsys == true) {
ufsp->remove(FAT_SCRIPT_NAME); ufsp->remove(FAT_SCRIPT_NAME);
@ -7514,10 +7666,12 @@ void SaveScript(void) {
} else { } else {
uint8_t *ucs; uint8_t *ucs;
ucs = (uint8_t*)calloc(SPI_FLASH_SEC_SIZE + 4, 1); ucs = (uint8_t*)calloc(SPI_FLASH_SEC_SIZE + 4, 1);
if (ucs) {
if (!script_compress((char*)ucs, EEP_SCRIPT_SIZE - 1)) { if (!script_compress((char*)ucs, EEP_SCRIPT_SIZE - 1)) {
alt_eeprom_writeBytes(0, EEP_SCRIPT_SIZE, ucs); alt_eeprom_writeBytes(0, EEP_SCRIPT_SIZE, ucs);
} }
if (ucs) free(ucs); free(ucs);
}
} }
} }
#else #else
@ -7562,8 +7716,10 @@ void ScriptSaveSettings(void) {
// //
uint32_t script_compress(char *dest, uint32_t size) { uint32_t script_compress(char *dest, uint32_t size) {
//AddLog(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); //AddLog(LOG_LEVEL_INFO,PSTR("len: %d dsize = %d"), size, strlen(glob_script_mem.script_ram));
yield();
int32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), dest, size); int32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), dest, size);
yield();
if (len_compressed > 0) { if (len_compressed > 0) {
dest[len_compressed] = 0; dest[len_compressed] = 0;
AddLog(LOG_LEVEL_INFO,PSTR("script compressed to %d bytes = %d %%"),len_compressed,len_compressed * 100 / strlen(glob_script_mem.script_ram)); AddLog(LOG_LEVEL_INFO,PSTR("script compressed to %d bytes = %d %%"),len_compressed,len_compressed * 100 / strlen(glob_script_mem.script_ram));
@ -8183,6 +8339,89 @@ bool Script_SubCmd(void) {
} }
#endif //USE_SCRIPT_SUB_COMMAND #endif //USE_SCRIPT_SUB_COMMAND
void script_version(void) {
uint32_t options = 0;
#ifdef USE_BUTTON_EVENT
options |= 0x00000001;
#endif
#ifdef USE_SCRIPT_JSON_EXPORT
options |= 0x00000002;
#endif
#ifdef USE_SCRIPT_SUB_COMMAND
options |= 0x00000004;
#endif
#ifdef USE_SCRIPT_HUE
options |= 0x00000008;
#endif
#ifdef USE_HOMEKIT
options |= 0x00000010;
#endif
#ifdef USE_SCRIPT_STATUS
options |= 0x00000020;
#endif
#ifdef SUPPORT_MQTT_EVENT
options |= 0x00000040;
#endif
#ifdef USE_SENDMAIL
options |= 0x00000080;
#endif
#ifdef USE_SCRIPT_WEB_DISPLAY
options |= 0x00000100;
#endif
#ifdef SCRIPT_FULL_WEBPAGE
options |= 0x00000200;
#endif
#ifdef USE_TOUCH_BUTTONS
options |= 0x00000400;
#endif
#ifdef USE_WEBSEND_RESPONSE
options |= 0x00000800;
#endif
#ifdef USE_ANGLE_FUNC
options |= 0x00001000;
#endif
#ifdef USE_SCRIPT_TASK
options |= 0x00002000;
#endif
#ifdef USE_SCRIPT_GLOBVARS
options |= 0x00004000;
#endif
#ifdef USE_SCRIPT_TIMER
options |= 0x00008000;
#endif
#ifdef SCRIPT_GET_HTTPS_JP
options |= 0x00010000;
#endif
#ifdef LARGE_ARRAYS
options |= 0x00020000;
#endif
#ifdef SCRIPT_LARGE_VNBUFF
options |= 0x00040000;
#endif
#ifdef USE_GOOGLE_CHARTS
options |= 0x00080000;
#endif
#ifdef USE_FEXTRACT
options |= 0x00100000;
#endif
#ifdef USE_SCRIPT_SPI
options |= 0x00200000;
#endif
#ifdef USE_SCRIPT_I2C
options |= 0x00400000;
#endif
#ifdef USE_DSIPLAY_DUMP
options |= 0x00800000;
#endif
#ifdef USE_SCRIPT_SERIAL
options |= 0x01000000;
#endif
Response_P(PSTR("{\"script\":{\"vers\":%d.%d,\"opts\":%08x}}"), SCRIPT_VERS[0], SCRIPT_VERS[1], options);
}
void execute_script(char *script) { void execute_script(char *script) {
char *svd_sp = glob_script_mem.scriptptr; char *svd_sp = glob_script_mem.scriptptr;
strcat(script, "\n#"); strcat(script, "\n#");
@ -8247,6 +8486,10 @@ bool ScriptCommand(void) {
execute_script(XdrvMailbox.data); execute_script(XdrvMailbox.data);
} }
} }
if (!strcmp(XdrvMailbox.data, "-v")) {
script_version();
return serviced;
}
if ('?' == XdrvMailbox.data[0]) { if ('?' == XdrvMailbox.data[0]) {
char *lp = XdrvMailbox.data; char *lp = XdrvMailbox.data;
lp++; lp++;
@ -8582,7 +8825,9 @@ void ScriptServeFile82(void) {
if (cp) { if (cp) {
cp += 4; cp += 4;
if (ufsp) { if (ufsp) {
#ifndef USE_FEXTRACT
if (ufsp->exists(cp)) { if (ufsp->exists(cp)) {
#endif
if (download82_busy == true) { if (download82_busy == true) {
AddLog(LOG_LEVEL_INFO, PSTR("UFS 82: Download is busy")); AddLog(LOG_LEVEL_INFO, PSTR("UFS 82: Download is busy"));
return; return;
@ -8594,7 +8839,9 @@ void ScriptServeFile82(void) {
//AddLog(LOG_LEVEL_INFO, PSTR("Sendfile 82 started")); //AddLog(LOG_LEVEL_INFO, PSTR("Sendfile 82 started"));
return; return;
} }
#ifndef USE_FEXTRACT
} }
#endif
} }
Handle82NotFound(); Handle82NotFound();
@ -8664,8 +8911,7 @@ void ScriptServeFile(void) {
SendFile(cp); SendFile(cp);
return; return;
} else { } else {
if (ufsp->exists(cp)) { if (!SendFile(cp)) {
SendFile(cp);
return; return;
} }
} }
@ -8679,27 +8925,28 @@ bool script_download_busy;
//#define USE_DLTASK //#define USE_DLTASK
void SendFile(char *fname) { int32_t SendFile(char *fname) {
#ifdef ESP8266 #ifdef ESP8266
SendFile_sub(fname, 0); return SendFile_sub(fname, 0);
#endif // ESP8266 #endif // ESP8266
#ifdef ESP32 #ifdef ESP32
#ifdef USE_DLTASK #ifdef USE_DLTASK
if (script_download_busy == true) { if (script_download_busy == true) {
AddLog(LOG_LEVEL_INFO, PSTR("UFS: Download is busy")); AddLog(LOG_LEVEL_INFO, PSTR("UFS: Download is busy"));
return; return -1;
} }
script_download_busy = true; script_download_busy = true;
char *path = (char*)malloc(128); char *path = (char*)malloc(128);
strcpy(path, fname); strcpy(path, fname);
xTaskCreatePinnedToCore(script_download_task, "DT", 6000, (void*)path, 3, NULL, 1); xTaskCreatePinnedToCore(script_download_task, "DT", 6000, (void*)path, 3, NULL, 1);
#else #else
SendFile_sub(fname, 0); return SendFile_sub(fname, 0);
#endif #endif
#endif // ESP32 #endif // ESP32
return 0;
} }
#ifdef USE_DLTASK #ifdef USE_DLTASK
@ -8713,13 +8960,29 @@ void script_download_task(void *path) {
#define REVERT_M5EPD #define REVERT_M5EPD
void SendFile_sub(char *path, uint8_t stype) { int32_t SendFile_sub(char *path, uint8_t stype) {
char buff[512]; char buff[512];
WiFiClient client; WiFiClient client;
uint8_t sflg = 0; uint8_t sflg = 0;
File file; File file;
uint32_t fsize; uint32_t fsize;
#ifdef USE_FEXTRACT
char *lp = strchr(path, '@');
if (lp) {
*lp = 0;
lp++;
// /ufs/test.txt@1.2.22-00:00_12.2.22-00:00
char *tp = strchr(lp, '_');
if (tp) {
*tp = 0;
tp++;
glob_script_mem.from_time = tstamp2l(lp);
glob_script_mem.to_time = tstamp2l(tp);
}
}
#endif // USE_FEXTRACT
#ifdef USE_DISPLAY_DUMP #ifdef USE_DISPLAY_DUMP
char *sbmp = strstr_P(path, PSTR("scrdmp.bmp")); char *sbmp = strstr_P(path, PSTR("scrdmp.bmp"));
if (sbmp) { if (sbmp) {
@ -8741,9 +9004,12 @@ uint32_t fsize;
strcpy_P(buff,PSTR("text/plain")); strcpy_P(buff,PSTR("text/plain"));
} }
if (!buff[0]) return; if (!buff[0]) return -2;
if (!sflg) { if (!sflg) {
if (!ufsp->exists(path)) {
return -1;
}
file = ufsp->open(path, FS_FILE_READ); file = ufsp->open(path, FS_FILE_READ);
fsize = file.size(); fsize = file.size();
} }
@ -8784,7 +9050,7 @@ uint32_t fsize;
uint8_t *bp = renderer->framebuffer; uint8_t *bp = renderer->framebuffer;
uint8_t *lbuf = (uint8_t*)special_malloc(Settings->display_width * 3 + 2); uint8_t *lbuf = (uint8_t*)special_malloc(Settings->display_width * 3 + 2);
memset(lbuf, 0, Settings->display_width * 3); memset(lbuf, 0, Settings->display_width * 3);
if (!lbuf) return; if (!lbuf) return -3;
uint8_t dmflg = 0; uint8_t dmflg = 0;
if (renderer->disp_bpp & 0x40) { if (renderer->disp_bpp & 0x40) {
dmflg = 1; dmflg = 1;
@ -8887,6 +9153,27 @@ uint32_t fsize;
} }
#endif // USE_DISPLAY_DUMP #endif // USE_DISPLAY_DUMP
} else { } else {
#ifdef USE_FEXTRACT
if (glob_script_mem.to_time > glob_script_mem.from_time) {
char ts[32];
s2tstamp(ts, sizeof(ts), glob_script_mem.from_time, 0);
int32_t fo_from = opt_fext(&file, ts, ts, 1);
s2tstamp(ts, sizeof(ts), glob_script_mem.to_time, 0);
//int32_t fo_to = opt_fext(&file, ts, ts, 2);
int32_t fo_to = extract_from_file(&file, ts, ts, -3, 0, 0, 0, 0);
if (fo_to < 0) {
fo_to = extract_from_file(&file, ts, ts, -1, 0, 0, 0, 0);
}
if (fo_from >= 0 && fo_to >= 0) {
script_copy_file(&file, 0, fo_from, fo_to, 1, &client);
}
file.close();
client.stop();
glob_script_mem.to_time = 0;
glob_script_mem.from_time = 0;
return 0;
}
#endif
uint32_t len = sizeof(buff); uint32_t len = sizeof(buff);
while (fsize > 0) { while (fsize > 0) {
if (len > fsize) len = fsize; if (len > fsize) len = fsize;
@ -8897,6 +9184,7 @@ uint32_t fsize;
file.close(); file.close();
client.stop(); client.stop();
} }
return 0;
} }
#endif // USE_UFILESYS #endif // USE_UFILESYS