mirror of https://github.com/arendst/Tasmota.git
commit
21296b6825
|
@ -94,7 +94,9 @@ special variables (read only):
|
|||
**med(n x)** = calculates a 5 value median filter of x (2 filters possible n=0,1)
|
||||
**int(x)** = gets the integer part of x (like floor)
|
||||
**hn(x)** = converts x (0..255) to a hex nibble string
|
||||
**st(svar c n)** = stringtoken gets the n th substring of svar separated by c
|
||||
**st(svar c n)** = stringtoken gets the n th substring of svar separated by c
|
||||
**sl(svar)** = gets the length of a string
|
||||
**sb(svar p n)** = gets a substring from svar at position p (if p<0 counts from end) and length n
|
||||
**s(x)** = explicit conversion from number x to string
|
||||
**mqtts** = state of mqtt disconnected=0, connected>0
|
||||
**wifis** = state of wifi disconnected=0, connected>0
|
||||
|
@ -139,7 +141,7 @@ a single percent sign must be given as **%%**
|
|||
|
||||
**special** cmds:
|
||||
|
||||
>**=\> print** prints to info log for debugging
|
||||
>**print** or **=\>print** prints to info log for debugging
|
||||
|
||||
to save code space nearly no error messages are provided. However it is taken care of that at least it should not crash on syntax errors.
|
||||
if a variable does not exist a **???** is given on commands
|
||||
|
@ -188,7 +190,8 @@ and on the same line conditions may be bracketed e.g. if ((a==b) and ((c==d) or
|
|||
>**#name** names a subroutine, subroutines are called with **=#name**
|
||||
**#name(param)** names a subroutines with a parameter is called with **=#name(param)**
|
||||
subroutines end with the next '#' or '>' line or break, may be nested
|
||||
params can be numbers or strings and on mismatch are converted
|
||||
params can be numbers or strings and on mismatch are converted
|
||||
**=(svar)** executes a script in a string variable (dynamic or self modifying code)
|
||||
|
||||
>**for var from to inc**
|
||||
**next**
|
||||
|
|
|
@ -298,7 +298,7 @@
|
|||
// Select none or only one of the below defines
|
||||
#define USE_RULES // Add support for rules (+8k code)
|
||||
//#define USE_SCRIPT // Add support for script (+17k code)
|
||||
#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support
|
||||
//#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support
|
||||
|
||||
// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem)
|
||||
// #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code)
|
||||
|
|
|
@ -2399,7 +2399,7 @@ int WebSend(char *buffer)
|
|||
int http_code = http.GET(); // Start connection and send HTTP header
|
||||
if (http_code > 0) { // http_code will be negative on error
|
||||
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
|
||||
/*
|
||||
#ifdef USE_WEBSEND_RESPONSE
|
||||
// Return received data to the user - Adds 900+ bytes to the code
|
||||
String result = http.getString(); // File found at server - may need lot of ram or trigger out of memory!
|
||||
uint32_t j = 0;
|
||||
|
@ -2412,7 +2412,13 @@ int WebSend(char *buffer)
|
|||
}
|
||||
mqtt_data[j] = '\0';
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_WEBSEND));
|
||||
*/
|
||||
#ifdef USE_SCRIPT
|
||||
extern uint8_t tasm_cmd_activ;
|
||||
// recursive call must be possible in this case
|
||||
tasm_cmd_activ=0;
|
||||
XdrvRulesProcess();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
status = 0; // No error - Done
|
||||
} else {
|
||||
|
|
|
@ -134,6 +134,7 @@ struct SCRIPT_MEM {
|
|||
uint8_t *vnp_offset;
|
||||
char *glob_snp; // string vars pointer
|
||||
char *scriptptr;
|
||||
char *scriptptr_bu;
|
||||
char *script_ram;
|
||||
uint16_t script_size;
|
||||
uint8_t *script_pram;
|
||||
|
@ -161,6 +162,7 @@ uint8_t tasm_cmd_activ=0;
|
|||
uint8_t fast_script=0;
|
||||
uint32_t script_lastmillis;
|
||||
|
||||
|
||||
char *GetNumericResult(char *lp,uint8_t lastop,float *fp,JsonObject *jo);
|
||||
char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo);
|
||||
char *ForceStringVar(char *lp,char *dstr);
|
||||
|
@ -241,6 +243,7 @@ char *script;
|
|||
|
||||
glob_script_mem.max_ssize=SCRIPT_SVARSIZE;
|
||||
glob_script_mem.scriptptr=0;
|
||||
|
||||
if (!*script) return -999;
|
||||
|
||||
float fvalues[MAXVARS];
|
||||
|
@ -539,6 +542,7 @@ char *script;
|
|||
|
||||
// store start of actual program here
|
||||
glob_script_mem.scriptptr=lp-1;
|
||||
glob_script_mem.scriptptr_bu=glob_script_mem.scriptptr;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -943,9 +947,15 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso
|
|||
}
|
||||
if (jo->success()) {
|
||||
char *subtype=strchr(vname,'#');
|
||||
char *subtype2;
|
||||
if (subtype) {
|
||||
*subtype=0;
|
||||
subtype++;
|
||||
subtype2=strchr(subtype,'#');
|
||||
if (subtype2) {
|
||||
*subtype2=0;
|
||||
*subtype2++;
|
||||
}
|
||||
}
|
||||
vn=vname;
|
||||
str_value = (*jo)[vn];
|
||||
|
@ -957,6 +967,23 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso
|
|||
jo=&jobj1;
|
||||
str_value = (*jo)[vn];
|
||||
if ((*jo)[vn].success()) {
|
||||
// 2. stage
|
||||
if (subtype2) {
|
||||
JsonObject &jobj2=(*jo)[vn];
|
||||
if ((*jo)[vn].success()) {
|
||||
vn=subtype2;
|
||||
jo=&jobj2;
|
||||
str_value = (*jo)[vn];
|
||||
if ((*jo)[vn].success()) {
|
||||
goto skip;
|
||||
} else {
|
||||
goto chknext;
|
||||
}
|
||||
} else {
|
||||
goto chknext;
|
||||
}
|
||||
}
|
||||
// end
|
||||
goto skip;
|
||||
}
|
||||
} else {
|
||||
|
@ -1492,6 +1519,34 @@ chknext:
|
|||
fvar=strlen(glob_script_mem.script_ram);
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname,"sl(",3)) {
|
||||
lp+=3;
|
||||
char str[SCRIPT_MAXSSIZE];
|
||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||
lp++;
|
||||
len=0;
|
||||
fvar=strlen(str);
|
||||
goto exit;
|
||||
}
|
||||
if (!strncmp(vname,"sb(",3)) {
|
||||
lp+=3;
|
||||
char str[SCRIPT_MAXSSIZE];
|
||||
lp=GetStringResult(lp,OPER_EQU,str,0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
float fvar1;
|
||||
lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
float fvar2;
|
||||
lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
|
||||
lp++;
|
||||
len=0;
|
||||
if (fvar1<0) {
|
||||
fvar1=strlen(str)+fvar1;
|
||||
}
|
||||
memcpy(sp,&str[(uint8_t)fvar1],(uint8_t)fvar2);
|
||||
sp[(uint8_t)fvar2] = '\0';
|
||||
goto strexit;
|
||||
}
|
||||
if (!strncmp(vname,"st(",3)) {
|
||||
lp+=3;
|
||||
char str[SCRIPT_MAXSSIZE];
|
||||
|
@ -2155,7 +2210,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
|
||||
if (tasm_cmd_activ && tlen>0) return 0;
|
||||
|
||||
uint8_t vtype=0,sindex,xflg,floop=0,globvindex;
|
||||
uint8_t vtype=0,sindex,xflg,floop=0,globvindex,fromscriptcmd=0;
|
||||
int8_t globaindex;
|
||||
struct T_INDEX ind;
|
||||
uint8_t operand,lastop,numeric=1,if_state[IF_NEST],if_exe[IF_NEST],if_result[IF_NEST],and_or,ifstck=0;
|
||||
|
@ -2445,11 +2500,17 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2)) {
|
||||
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"print",5)) {
|
||||
// execute cmd
|
||||
uint8_t sflag=0,svmqtt,swll;
|
||||
if (*lp=='-') sflag=1;
|
||||
lp+=2;
|
||||
uint8_t sflag=0,pflg=0,svmqtt,swll;
|
||||
if (*lp=='p') {
|
||||
pflg=1;
|
||||
lp+=5;
|
||||
}
|
||||
else {
|
||||
if (*lp=='-') sflag=1;
|
||||
lp+=2;
|
||||
}
|
||||
char *slp=lp;
|
||||
SCRIPT_SKIP_SPACES
|
||||
#define SCRIPT_CMDMEM 512
|
||||
|
@ -2472,8 +2533,9 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
Replace_Cmd_Vars(cmd,tmp,SCRIPT_CMDMEM/2);
|
||||
//toSLog(tmp);
|
||||
|
||||
if (!strncmp(tmp,"print",5)) {
|
||||
toLog(&tmp[5]);
|
||||
if (!strncmp(tmp,"print",5) || pflg) {
|
||||
if (pflg) toLog(tmp);
|
||||
else toLog(&tmp[5]);
|
||||
} else {
|
||||
if (!sflag) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("Script: performs \"%s\""), tmp);
|
||||
|
@ -2508,9 +2570,23 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
lp++;
|
||||
plen++;
|
||||
}
|
||||
Run_Scripter(slp,plen,0);
|
||||
if (fromscriptcmd) {
|
||||
char *sp=glob_script_mem.scriptptr;
|
||||
glob_script_mem.scriptptr=glob_script_mem.scriptptr_bu;
|
||||
Run_Scripter(slp,plen,0);
|
||||
glob_script_mem.scriptptr=sp;
|
||||
} else {
|
||||
Run_Scripter(slp,plen,0);
|
||||
}
|
||||
lp=slp;
|
||||
goto next_line;
|
||||
} else if (!strncmp(lp,"=(",2)) {
|
||||
lp+=2;
|
||||
char str[128];
|
||||
str[0]='>';
|
||||
lp=GetStringResult(lp,OPER_EQU,&str[1],0);
|
||||
lp++;
|
||||
execute_script(str);
|
||||
}
|
||||
|
||||
// check for variable result
|
||||
|
@ -2651,6 +2727,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
|
|||
// called from cmdline
|
||||
lp++;
|
||||
section=1;
|
||||
fromscriptcmd=1;
|
||||
goto startline;
|
||||
}
|
||||
if (!strncmp(lp,type,tlen)) {
|
||||
|
@ -3200,12 +3277,11 @@ void ScriptSaveSettings(void) {
|
|||
#endif
|
||||
|
||||
void execute_script(char *script) {
|
||||
char *svd_sp=glob_script_mem.scriptptr;
|
||||
char *svd_sp=glob_script_mem.scriptptr;
|
||||
strcat(script,"\n#");
|
||||
glob_script_mem.scriptptr=script;
|
||||
Run_Scripter(">",1,0);
|
||||
glob_script_mem.scriptptr=svd_sp;
|
||||
Scripter_save_pvars();
|
||||
}
|
||||
#define D_CMND_SCRIPT "Script"
|
||||
#define D_CMND_SUBSCRIBE "Subscribe"
|
||||
|
@ -3240,6 +3316,7 @@ bool ScriptCommand(void) {
|
|||
if (XdrvMailbox.data[count]==';') XdrvMailbox.data[count]='\n';
|
||||
}
|
||||
execute_script(XdrvMailbox.data);
|
||||
Scripter_save_pvars();
|
||||
}
|
||||
}
|
||||
return serviced;
|
||||
|
@ -3331,8 +3408,6 @@ bool ScriptMqttData(void)
|
|||
}
|
||||
value.trim();
|
||||
|
||||
//Create an new event. Cannot directly call RulesProcessEvent().
|
||||
//snprintf_P(Rules.event_data, sizeof(Rules.event_data), PSTR("%s=%s"), event_item.Event.c_str(), value.c_str());
|
||||
char sbuffer[128];
|
||||
snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str());
|
||||
//toLog(sbuffer);
|
||||
|
|
Loading…
Reference in New Issue