scripter update

fix unishox define conflict
fix for next loop exit bugs
add full pagewebserver (also support for jpg, html and txt files from filesystem)
This commit is contained in:
gemu2015 2020-06-26 09:22:57 +02:00
parent c8bdf11f80
commit 6553a775f4
1 changed files with 240 additions and 19 deletions

View File

@ -67,14 +67,16 @@ keywords if then else endif, or, and are better readable for beginners (others m
uint32_t EncodeLightId(uint8_t relay_id);
uint32_t DecodeLightId(uint32_t hue_id);
#ifdef USE_UNISHOX_COMPRESSION
#define USE_SCRIPT_COMPRESSION
#endif
// solve conficting defines
// highest priority
#ifdef USE_SCRIPT_FATFS
#undef LITTLEFS_SCRIPT_SIZE
#undef EEP_SCRIPT_SIZE
#undef USE_UNISHOX_COMPRESSION
#undef USE_SCRIPT_COMPRESSION
#if USE_SCRIPT_FATFS==-1
#ifdef ESP32
#error "script fat file option -1 currently not supported for ESP32"
@ -89,13 +91,13 @@ uint32_t DecodeLightId(uint32_t hue_id);
// lfs on esp8266 spiffs on esp32
#ifdef LITTLEFS_SCRIPT_SIZE
#undef EEP_SCRIPT_SIZE
#undef USE_UNISHOX_COMPRESSION
#undef USE_SCRIPT_COMPRESSION
#pragma message "script little file system option used"
#endif // LITTLEFS_SCRIPT_SIZE
// eeprom script
#ifdef EEP_SCRIPT_SIZE
#undef USE_UNISHOX_COMPRESSION
#undef USE_SCRIPT_COMPRESSION
#ifdef USE_24C256
#pragma message "script 24c256 file option used"
#else
@ -105,12 +107,12 @@ uint32_t DecodeLightId(uint32_t hue_id);
#endif // EEP_SCRIPT_SIZE
// compression last option before default
#ifdef USE_UNISHOX_COMPRESSION
#ifdef USE_SCRIPT_COMPRESSION
#pragma message "script compression option used"
#endif // USE_UNISHOX_COMPRESSION
#ifdef USE_UNISHOX_COMPRESSION
#ifdef USE_SCRIPT_COMPRESSION
#include <unishox.h>
#define SCRIPT_COMPRESS compressor.unishox_compress
@ -118,7 +120,7 @@ uint32_t DecodeLightId(uint32_t hue_id);
#ifndef UNISHOXRSIZE
#define UNISHOXRSIZE 2560
#endif
#endif // USE_UNISHOX_COMPRESSION
#endif // USE_SCRIPT_COMPRESSION
#ifdef USE_SCRIPT_TIMER
#include <Ticker.h>
@ -3370,7 +3372,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
lp=GetNumericResult(lp,OPER_EQU,&cv_inc,0);
//SCRIPT_SKIP_EOL
cv_ptr=lp;
if (*cv_count<cv_max) {
if (*cv_count<=cv_max) {
floop=1;
} else {
floop=2;
@ -3458,9 +3460,11 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
if (!strncmp(lp,"break",5)) {
lp+=5;
if (floop && lp_next) {
if (floop) {
// should break loop
lp=lp_next;
if (lp_next) {
lp=lp_next;
}
floop=0;
} else {
section=0;
@ -4568,7 +4572,7 @@ void SaveScriptEnd(void) {
glob_script_mem.script_mem_size=0;
}
#ifdef USE_UNISHOX_COMPRESSION
#ifdef USE_SCRIPT_COMPRESSION
//AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram));
uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1);
if (len_compressed > 0) {
@ -4577,7 +4581,7 @@ void SaveScriptEnd(void) {
} else {
AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed);
}
#endif // USE_UNISHOX_COMPRESSION
#endif // USE_SCRIPT_COMPRESSION
if (bitRead(Settings.rule_enabled, 0)) {
int16_t res=Init_Scripter();
@ -5400,12 +5404,181 @@ String ScriptUnsubscribe(const char * data, int data_len)
#ifdef USE_SCRIPT_WEB_DISPLAY
#ifdef SCRIPT_FULL_WEBPAGE
const char HTTP_WEB_FULL_DISPLAY[] PROGMEM =
"<p><form action='" "sfd" "' method='get'><button>" "%s" "</button></form></p>";
const char HTTP_SCRIPT_FULLPAGE1[] PROGMEM =
"<!DOCTYPE html><html lang=\"" D_HTML_LANGUAGE "\" class=\"\">"
"<head>"
"<meta charset='utf-8'>"
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,user-scalable=no\"/>"
"<title>%s - %s</title>"
"<script>"
"var x=null,lt,to,tp,pc='';" // x=null allow for abortion
"function eb(s){"
"return document.getElementById(s);" // Alias to save code space
"}"
"function qs(s){" // Alias to save code space
"return document.querySelector(s);"
"}"
"function wl(f){" // Execute multiple window.onload
"window.addEventListener('load',f);"
"}"
"var rfsh=1;"
"function la(p){"
"var a='';"
"if(la.arguments.length==1){"
"a=p;"
"clearTimeout(lt);"
"}"
"if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1)
"x=new XMLHttpRequest();"
"x.onreadystatechange=function(){"
"if(x.readyState==4&&x.status==200){"
"var s=x.responseText.replace(/{t}/g,\"<table style='width:100%%'>\").replace(/{s}/g,\"<tr><th>\").replace(/{m}/g,\"</th><td>\").replace(/{e}/g,\"</td></tr>\").replace(/{c}/g,\"%%'><div style='text-align:center;font-weight:\");"
"eb('l1').innerHTML=s;"
"}"
"};"
"if (rfsh) {"
"x.open('GET','./sfd?m=1'+a,true);" // ?m related to Webserver->hasArg("m")
"x.send();"
"lt=setTimeout(la,%d);" // Settings.web_refresh
"}"
"}";
const char HTTP_SCRIPT_FULLPAGE2[] PROGMEM =
"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;"
"}"
"}"
"</script>";
#ifdef USE_SCRIPT_FATFS
const char HTTP_SCRIPT_MIMES[] PROGMEM =
"HTTP/1.1 200 OK\r\n"
"Content-disposition: inline; filename=%s"
"Content-type: %s\r\n\r\n";
void ScriptGetSDCard(void) {
if (!HttpCheckPriviledgedAccess()) { return; }
String stmp = Webserver->uri();
char *cp=strstr(stmp.c_str(),"/sdc/");
// if (cp) Serial.printf(">>>%s\n",cp);
if (cp) {
#ifdef ESP32
cp+=4
#else
cp+=5;
#endif
if (fsp->exists(cp)) {
SendFile(cp);
return;
}
}
HandleNotFound();
}
#endif // USE_SCRIPT_FATFS
void SendFile(char *fname) {
char buff[512];
const char *mime;
char *jpg=strstr(fname,".jpg");
if (jpg) {
mime="image/jpeg";
}
char *html=strstr(fname,".html");
if (html) {
mime="text/html";
}
char *txt=strstr(fname,".txt");
if (txt) {
mime="text/plain";
}
WSContentSend_P(HTTP_SCRIPT_MIMES,fname,mime);
File file=fsp->open(fname,FILE_READ);
uint32_t siz = file.size();
uint32_t len=sizeof(buff);
while (siz > 0) {
if (len>siz) len=siz;
file.read((uint8_t *)buff,len );
Webserver->client().write((const char*)buff, len);
siz -= len;
}
file.close();
Webserver->client().stop();
}
void ScriptFullWebpage(void) {
uint32_t fullpage_refresh=10000;
if (!HttpCheckPriviledgedAccess()) { return; }
String stmp = Webserver->uri();
if (Webserver->hasArg("m")) { // Status refresh requested
if (Webserver->hasArg("sv")) {
Script_Check_HTML_Setvars();
}
WSContentBegin(200, CT_HTML);
ScriptWebShow('w');
WSContentEnd();
Serial.printf("fwp update sv %s\n",stmp.c_str() );
return; //goto redraw;
// } else {
// Serial.printf("fwp update %s\n",stmp.c_str() );
// }
return;
} else {
Serial.printf("fwp other %s\n",stmp.c_str() );
}
WSContentBegin(200, CT_HTML);
const char *title="Full Screen";
WSContentSend_P(HTTP_SCRIPT_FULLPAGE1, SettingsText(SET_DEVICENAME), title, fullpage_refresh);
WSContentSend_P(HTTP_SCRIPT_FULLPAGE2, fullpage_refresh);
//WSContentSend_P(PSTR("<div id='l1' name='l1'></div>"));
//WSContentSendStyle();
WSContentSend_P(PSTR("<div id='l1' name='l1'>"));
ScriptWebShow('w');
WSContentSend_P(PSTR("</div>"));
ScriptWebShow('x');
WSContentStop();
}
#endif //SCRIPT_FULL_WEBPAGE
void Script_Check_HTML_Setvars(void) {
if (!HttpCheckPriviledgedAccess()) { return; }
if (Webserver->hasArg("sv")) {
String stmp = Webserver->arg("sv");
Serial.printf("fwp has arg dv %s\n",stmp.c_str());
char cmdbuf[64];
memset(cmdbuf,0,sizeof(cmdbuf));
char *cp=cmdbuf;
@ -5610,13 +5783,29 @@ uint32_t cnt;
}
void ScriptWebShow(char mc) {
uint8_t web_script=Run_Scripter(">W",-2,0);
uint8_t web_script,xflg=0;
if (mc=='w' || mc=='x') {
if (mc=='x') {
xflg=1;
mc='$';
}
web_script=Run_Scripter(">w",-2,0);
} else {
web_script=Run_Scripter(">W",-2,0);
}
if (web_script==99) {
char tmp[256];
uint8_t optflg=0;
uint8_t chartindex=1;
uint8_t google_libs=0;
char *lp=glob_script_mem.section_ptr+2;
if (mc=='w') {
while (*lp) {
if (*lp=='\n') break;
lp++;
}
}
while (lp) {
while (*lp==SCRIPT_EOL) {
lp++;
@ -5628,7 +5817,7 @@ void ScriptWebShow(char mc) {
// send this line to web
Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp));
char *lin=tmp;
if (!mc && (*lin!='$')) {
if ((!mc && (*lin!='$')) || (mc=='w' && (*lin!='$'))) {
// normal web section
if (*lin=='@') {
lin++;
@ -5788,18 +5977,24 @@ void ScriptWebShow(char mc) {
WSContentSend_PD(SCRIPT_MSG_NUMINP,label,minstr,maxstr,stepstr,vstr,vname);
} else {
if (optflg) {
WSContentSend_PD(PSTR("<div>%s</div>"),tmp);
if (mc=='w') {
WSContentSend_PD(PSTR("%s"),tmp);
} else {
WSContentSend_PD(PSTR("{s}%s{e}"),tmp);
if (optflg) {
WSContentSend_PD(PSTR("<div>%s</div>"),tmp);
} else {
WSContentSend_PD(PSTR("{s}%s{e}"),tmp);
}
}
}
// end standard web interface
} else {
// main section interface
if (*lin==mc) {
#ifdef USE_GOOGLE_CHARTS
lin++;
exgc:
char *lp;
if (!strncmp(lin,"gc(",3)) {
// get google table
@ -6007,6 +6202,8 @@ void ScriptWebShow(char mc) {
WSContentSend_PD(PSTR("%s"),lin);
}
#else
lin++;
WSContentSend_PD(PSTR("%s"),lin);
} else {
// WSContentSend_PD(PSTR("%s"),lin);
#endif //USE_GOOGLE_CHARTS
@ -6258,6 +6455,18 @@ uint32_t call2https(const char *host, const char *path) {
#endif // SCRIPT_GET_HTTPS_JP
void cpy2lf(char *dst,uint32_t dstlen, char *src) {
for (uint32_t cnt=0; cnt<dstlen; cnt++) {
if (src[cnt]==0 || src[cnt]=='\n') {
dst[cnt]=0;
break;
}
dst[cnt]=src[cnt];
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
@ -6278,7 +6487,7 @@ bool Xdrv10(uint8_t function)
glob_script_mem.script_pram=(uint8_t*)Settings.script_pram[0];
glob_script_mem.script_pram_size=PMEM_SIZE;
#ifdef USE_UNISHOX_COMPRESSION
#ifdef USE_SCRIPT_COMPRESSION
int32_t len_decompressed;
sprt=(char*)calloc(UNISHOXRSIZE+8,1);
if (!sprt) { break; }
@ -6287,7 +6496,7 @@ bool Xdrv10(uint8_t function)
len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size);
if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed]=0;
//AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed);
#endif // USE_UNISHOX_COMPRESSION
#endif // USE_SCRIPT_COMPRESSION
#ifdef USE_BUTTON_EVENT
for (uint32_t cnt=0;cnt<MAX_KEYS;cnt++) {
@ -6439,6 +6648,18 @@ bool Xdrv10(uint8_t function)
case FUNC_WEB_ADD_MAIN_BUTTON:
if (bitRead(Settings.rule_enabled, 0)) {
ScriptWebShow('$');
#ifdef SCRIPT_FULL_WEBPAGE
uint8_t web_script=Run_Scripter(">w",-2,0);
if (web_script==99) {
char bname[48];
cpy2lf(bname,sizeof(bname),glob_script_mem.section_ptr+3);
WSContentSend_PD(HTTP_WEB_FULL_DISPLAY,bname);
Webserver->on("/sfd", ScriptFullWebpage);
#ifdef USE_SCRIPT_FATFS
Webserver->onNotFound(ScriptGetSDCard);
#endif
}
#endif // SCRIPT_FULL_WEBPAGE
}
break;
#endif // USE_SCRIPT_WEB_DISPLAY