hasArg("m")
+ "x.send();"
+ "lt=setTimeout(la,%d);" // Settings.web_refresh
+ "}"
+ "}"
+ "function seva(par,ivar){"
+ "la('&sv='+ivar+'_'+par);"
+ "}"
+ "function siva(par,ivar){"
+ "rfsh=1;"
+ "la('&sv='+ivar+'_'+par);"
+ "rfsh=0;"
+ "}"
+ "function pr(f){"
+ "if (f) {"
+ "lt=setTimeout(la,%d);"
+ "rfsh=1;"
+ "} else {"
+ "clearTimeout(lt);"
+ "rfsh=0;"
+ "}"
+ "}"
+#else // USE_SCRIPT_WEB_DISPLAY
"function la(p){"
"var a='';"
"if(la.arguments.length==1){"
@@ -111,11 +151,7 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM =
"x.send();"
"lt=setTimeout(la,%d);" // Settings.web_refresh
"}"
-#ifdef USE_SCRIPT_WEB_DISPLAY
- "function seva(par,ivar){"
- "la('&sv='+ivar+'_'+par);"
- "}"
-#endif
+#endif // USE_SCRIPT_WEB_DISPLAY
#ifdef USE_JAVASCRIPT_ES6
@@ -939,7 +975,11 @@ void HandleRoot(void)
char stemp[5];
WSContentStart_P(S_MAIN_MENU);
+#ifdef USE_SCRIPT_WEB_DISPLAY
+ WSContentSend_P(HTTP_SCRIPT_ROOT, Settings.web_refresh, Settings.web_refresh);
+#else
WSContentSend_P(HTTP_SCRIPT_ROOT, Settings.web_refresh);
+#endif
WSContentSendStyle();
WSContentSend_P(PSTR("
"));
diff --git a/sonoff/xdrv_10_scripter.ino b/sonoff/xdrv_10_scripter.ino
index 265411637..40fa40391 100644
--- a/sonoff/xdrv_10_scripter.ino
+++ b/sonoff/xdrv_10_scripter.ino
@@ -42,8 +42,9 @@ keywords if then else endif, or, and are better readable for beginners (others m
#define SCRIPT_DEBUG 0
#define MAXVARS 50
-#define MAXNVARS 45
#define MAXSVARS 5
+#define MAXNVARS MAXVARS-MAXSVARS
+
#define MAXFILT 5
#define SCRIPT_SVARSIZE 20
#define SCRIPT_MAXSSIZE 48
@@ -465,6 +466,10 @@ char *script;
}
namep++;
index++;
+ if (index>255) {
+ free(glob_script_mem.script_mem);
+ return -5;
+ }
}
// copy string variables
@@ -1103,7 +1108,7 @@ chknext:
fvar=cnt;
glob_script_mem.file_flags[cnt].is_open=1;
} else {
- toLog("file open failed");
+ AddLog_P(LOG_LEVEL_INFO,PSTR("file open failed"));
}
break;
}
@@ -2103,6 +2108,7 @@ void toLog(const char *str) {
AddLog(LOG_LEVEL_INFO);
}
+
void toLogN(const char *cp,uint8_t len) {
if (!cp) return;
char str[32];
@@ -2295,12 +2301,10 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
if (section) {
// we are in section
if (*lp=='>') {
- section=0;
- break;
+ return 0;
}
if (*lp=='#') {
- section=0;
- break;
+ return 0;
}
glob_script_mem.var_not_found=0;
@@ -2734,6 +2738,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
char str[SCRIPT_MAXSSIZE];
lp=getop(lp,&lastop);
char *slp=lp;
+ glob_script_mem.glob_error=0;
lp=GetStringResult(lp,OPER_EQU,str,jo);
if (!js && glob_script_mem.glob_error) {
// mismatch
@@ -2778,19 +2783,20 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
return 99;
}
// check for subroutine
- if (*type=='#') {
+ char *ctype=(char*)type;
+ if (*ctype=='#') {
// check for parameter
- type+=tlen;
- if (*type=='(') {
+ ctype+=tlen;
+ if (*ctype=='(' && *(lp+tlen)=='(') {
float fparam;
numeric=1;
glob_script_mem.glob_error=0;
- GetNumericResult((char*)type,OPER_EQU,&fparam,0);
+ GetNumericResult((char*)ctype,OPER_EQU,&fparam,0);
if (glob_script_mem.glob_error==1) {
// was string, not number
numeric=0;
// get the string
- GetStringResult((char*)type+1,OPER_EQU,cmpstr,0);
+ GetStringResult((char*)ctype+1,OPER_EQU,cmpstr,0);
}
lp+=tlen;
if (*lp=='(') {
@@ -2821,6 +2827,12 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
}
}
}
+ } else {
+ lp+=tlen;
+ if (*ctype=='(' || (*lp!=SCRIPT_EOL && *lp!='?')) {
+ // revert
+ section=0;
+ }
}
}
}
@@ -2831,11 +2843,17 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
lp++;
} else {
lp = strchr(lp, SCRIPT_EOL);
- if (!lp) break;
+ if (!lp) {
+ if (section) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
lp++;
}
}
- return 0;
+ return -1;
}
uint8_t script_xsns_index = 0;
@@ -3151,13 +3169,13 @@ uint8_t DownloadFile(char *file) {
WiFiClient download_Client;
if (!SD.exists(file)) {
- toLog("file not found");
+ AddLog_P(LOG_LEVEL_INFO,PSTR("file not found"));
return 0;
}
download_file=SD.open(file,FILE_READ);
if (!download_file) {
- toLog("could not open file");
+ AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file"));
return 0;
}
@@ -3320,6 +3338,36 @@ void ScriptSaveSettings(void) {
#endif
+
+#ifdef USE_SCRIPT_SUB_COMMAND
+bool Script_SubCmd(void) {
+ if (!bitRead(Settings.rule_enabled, 0)) return false;
+
+ char cmdbuff[128];
+ char *cp=cmdbuff;
+ *cp++='#';
+ strcpy(cp,XdrvMailbox.topic);
+ uint8_t tlen=strlen(XdrvMailbox.topic);
+ cp+=tlen;
+ if (XdrvMailbox.index > 0) {
+ *cp++=XdrvMailbox.index|0x30;
+ tlen++;
+ }
+ if ((XdrvMailbox.payload>0) || (XdrvMailbox.data_len>0)) {
+ *cp++='(';
+ strncpy(cp,XdrvMailbox.data,XdrvMailbox.data_len);
+ cp+=XdrvMailbox.data_len;
+ *cp++=')';
+ *cp=0;
+ }
+ //toLog(cmdbuff);
+ uint32_t res=Run_Scripter(cmdbuff,tlen+1,0);
+ //AddLog_P2(LOG_LEVEL_INFO,">>%d",res);
+ if (res) return false;
+ else return true;
+}
+#endif
+
void execute_script(char *script) {
char *svd_sp=glob_script_mem.scriptptr;
strcat(script,"\n#");
@@ -3341,6 +3389,20 @@ bool ScriptCommand(void) {
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kScriptCommands);
if (-1 == command_code) {
+#ifdef USE_SCRIPT_SUB_COMMAND
+ strlcpy(command,XdrvMailbox.topic,CMDSZ);
+ uint32_t pl=XdrvMailbox.payload;
+ char pld[64];
+ strlcpy(pld,XdrvMailbox.data,sizeof(pld));
+ if (Script_SubCmd()) {
+ if (pl>=0) {
+ Response_P(S_JSON_COMMAND_NVALUE, command, pl);
+ } else {
+ Response_P(S_JSON_COMMAND_SVALUE, command, pld);
+ }
+ return serviced;
+ }
+#endif
serviced = false; // Unknown command
}
else if ((CMND_SCRIPT == command_code) && (index > 0)) {
@@ -3365,15 +3427,15 @@ bool ScriptCommand(void) {
return serviced;
}
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"Free\":%d}"),command, GetStateText(bitRead(Settings.rule_enabled,0)),glob_script_mem.script_size-strlen(glob_script_mem.script_ram));
- #ifdef SUPPORT_MQTT_EVENT
+#ifdef SUPPORT_MQTT_EVENT
} else if (CMND_SUBSCRIBE == command_code) { //MQTT Subscribe command. Subscribe
, [, ]
String result = ScriptSubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
Response_P(S_JSON_COMMAND_SVALUE, command, result.c_str());
} else if (CMND_UNSUBSCRIBE == command_code) { //MQTT Un-subscribe command. UnSubscribe
String result = ScriptUnsubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
Response_P(S_JSON_COMMAND_SVALUE, command, result.c_str());
- #endif //SUPPORT_MQTT_EVENT
- }
+#endif //SUPPORT_MQTT_EVENT
+ }
return serviced;
}
@@ -3628,24 +3690,43 @@ void Script_Check_HTML_Setvars(void) {
//toLog(cmdbuf);
execute_script(cmdbuf);
+ Run_Scripter(">E",2,0);
}
}
+
+const char SCRIPT_MSG_BUTTONa[] PROGMEM =
+ "";
+
+const char SCRIPT_MSG_BUTTONa_TBL[] PROGMEM =
+ " | ";
+
+const char SCRIPT_MSG_BUTTONb[] PROGMEM =
+ "<\img>";
+
+const char SCRIPT_MSG_BUT_START[] PROGMEM =
+ "";
+const char SCRIPT_MSG_BUT_START_TBL[] PROGMEM =
+ "
";
+
+const char SCRIPT_MSG_BUT_STOP[] PROGMEM =
+ "";
+const char SCRIPT_MSG_BUT_STOP_TBL[] PROGMEM =
+ "
";
+
const char SCRIPT_MSG_SLIDER[] PROGMEM =
"
%s
%s%s"
"
";
-const char SCRIPT_MSG_BUTTON[] PROGMEM =
- "
";
-
const char SCRIPT_MSG_CHKBOX[] PROGMEM =
"
";
const char SCRIPT_MSG_TEXTINP[] PROGMEM =
- "
";
+ "
";
+
+const char SCRIPT_MSG_NUMINP[] PROGMEM =
+ "
";
-//
-//
void ScriptGetVarname(char *nbuf,char *sp, uint32_t blen) {
uint32_t cnt;
@@ -3663,6 +3744,7 @@ void ScriptWebShow(void) {
if (web_script==99) {
char line[128];
char tmp[128];
+ uint8_t optflg=0;
char *lp=glob_script_mem.section_ptr+2;
while (lp) {
while (*lp==SCRIPT_EOL) {
@@ -3683,10 +3765,17 @@ void ScriptWebShow(void) {
}
cp++;
}
+ char *lin=line;
+ if (*lin=='@') {
+ lin++;
+ optflg=1;
+ } else {
+ optflg=0;
+ }
// check for input elements
- if (!strncmp(line,"sl(",3)) {
+ if (!strncmp(lin,"sl(",3)) {
// insert slider sl(min max var left mid right)
- char *lp=line;
+ char *lp=lin;
float min;
lp=GetNumericResult(lp+3,OPER_EQU,&min,0);
SCRIPT_SKIP_SPACES
@@ -3715,8 +3804,8 @@ void ScriptWebShow(void) {
WSContentSend_PD(SCRIPT_MSG_SLIDER,left,mid,right,(uint32_t)min,(uint32_t)max,(uint32_t)val,vname);
- } else if (!strncmp(line,"ck(",3)) {
- char *lp=line+3;
+ } else if (!strncmp(lin,"ck(",3)) {
+ char *lp=lin+3;
char *slp=lp;
float val;
lp=GetNumericResult(lp,OPER_EQU,&val,0);
@@ -3727,7 +3816,7 @@ void ScriptWebShow(void) {
char label[SCRIPT_MAXSSIZE];
lp=GetStringResult(lp,OPER_EQU,label,0);
- char *cp;
+ const char *cp;
uint8_t uval;
if (val>0) {
cp="checked='checked'";
@@ -3736,38 +3825,64 @@ void ScriptWebShow(void) {
cp="";
uval=1;
}
- WSContentSend_PD(SCRIPT_MSG_CHKBOX,label,cp,uval,vname);
+ WSContentSend_PD(SCRIPT_MSG_CHKBOX,label,(char*)cp,uval,vname);
- } else if (!strncmp(line,"bu(",3)) {
- char *lp=line+3;
- char *slp=lp;
- float val;
- lp=GetNumericResult(lp,OPER_EQU,&val,0);
- SCRIPT_SKIP_SPACES
-
- char vname[16];
- ScriptGetVarname(vname,slp,sizeof(vname));
-
- SCRIPT_SKIP_SPACES
- char ontxt[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,ontxt,0);
- SCRIPT_SKIP_SPACES
- char offtxt[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,offtxt,0);
-
- char *cp;
- uint8_t uval;
- if (val>0) {
- cp=ontxt;
- uval=0;
- } else {
- cp=offtxt;
- uval=1;
+ } else if (!strncmp(lin,"bu(",3)) {
+ char *lp=lin+3;
+ uint8_t bcnt=0;
+ char *found=lin;
+ while (bcnt<4) {
+ found=strstr(found,"bu(");
+ if (!found) break;
+ found+=3;
+ bcnt++;
}
- WSContentSend_PD(SCRIPT_MSG_BUTTON,uval,vname,cp);
+ uint8_t proz=100/bcnt;
+ if (!optflg && bcnt>1) proz-=2;
+ if (optflg) WSContentSend_PD(SCRIPT_MSG_BUT_START_TBL);
+ else WSContentSend_PD(SCRIPT_MSG_BUT_START);
+ for (uint32_t cnt=0;cnt
0) {
+ cp=ontxt;
+ uval=0;
+ } else {
+ cp=offtxt;
+ uval=1;
+ }
+ if (bcnt>1 && cnt==bcnt-1) {
+ if (!optflg) proz+=2;
+ }
+ if (!optflg) {
+ WSContentSend_PD(SCRIPT_MSG_BUTTONa,proz,uval,vname,cp);
+ } else {
+ WSContentSend_PD(SCRIPT_MSG_BUTTONa_TBL,proz,uval,vname,cp);
+ }
+ if (bcnt>1 && cnt%s "),&tmp[1]);
+ } else if (!strncmp(lin,"nm(",3)) {
+ char *lp=lin;
+ float min;
+ lp=GetNumericResult(lp+3,OPER_EQU,&min,0);
+ SCRIPT_SKIP_SPACES
+ float max;
+ lp=GetNumericResult(lp,OPER_EQU,&max,0);
+ SCRIPT_SKIP_SPACES
+ float step;
+ lp=GetNumericResult(lp,OPER_EQU,&step,0);
+ SCRIPT_SKIP_SPACES
+ float val;
+ char *slp=lp;
+ lp=GetNumericResult(lp,OPER_EQU,&val,0);
+ SCRIPT_SKIP_SPACES
+ char vname[16];
+ ScriptGetVarname(vname,slp,sizeof(vname));
+
+ char label[SCRIPT_MAXSSIZE];
+ lp=GetStringResult(lp,OPER_EQU,label,0);
+
+ char vstr[16],minstr[16],maxstr[16],stepstr[16];
+ dtostrfd(val,4,vstr);
+ dtostrfd(min,4,minstr);
+ dtostrfd(max,4,maxstr);
+ dtostrfd(step,4,stepstr);
+ WSContentSend_PD(SCRIPT_MSG_NUMINP,label,minstr,maxstr,stepstr,vstr,vname);
+
+ } else {
+ Replace_Cmd_Vars(lin,tmp,sizeof(tmp));
+ if (optflg) {
+ WSContentSend_PD(PSTR("%s
"),tmp);
} else {
WSContentSend_PD(PSTR("{s}%s{e}"),tmp);
}