scripter enhancements

This commit is contained in:
gemu2015 2022-05-26 17:22:39 +02:00
parent 8284649c43
commit 9484f1d2b3
2 changed files with 452 additions and 109 deletions

View File

@ -74,6 +74,7 @@ keywords if then else endif, or, and are better readable for beginners (others m
uint32_t EncodeLightId(uint8_t relay_id); uint32_t EncodeLightId(uint8_t relay_id);
uint32_t DecodeLightId(uint32_t hue_id); uint32_t DecodeLightId(uint32_t hue_id);
char *web_send_line(char mc, char *lp); char *web_send_line(char mc, char *lp);
int32_t web_send_file(char mc, char *file);
#define SPECIAL_EEPMODE_SIZE 6200 #define SPECIAL_EEPMODE_SIZE 6200
@ -451,7 +452,7 @@ struct SCRIPT_MEM {
char *fast_script = 0; char *fast_script = 0;
char *event_script = 0; char *event_script = 0;
char *html_script = 0; char *html_script = 0;
char *web_pages[7]; char *web_pages[10];
uint32_t script_lastmillis; uint32_t script_lastmillis;
bool event_handeled = false; bool event_handeled = false;
#ifdef USE_BUTTON_EVENT #ifdef USE_BUTTON_EVENT
@ -1241,7 +1242,7 @@ float *Get_MFAddr(uint8_t index, uint16_t *len, uint16_t *ipos) {
char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, struct GVARS *gv); char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, struct GVARS *gv);
char *get_array_by_name(char *lp, float **fp, uint16_t *alen) { char *get_array_by_name(char *lp, float **fp, uint16_t *alen, uint16_t *ipos) {
struct T_INDEX ind; struct T_INDEX ind;
uint8_t vtype; uint8_t vtype;
lp = isvar(lp, &vtype, &ind, 0, 0, 0); lp = isvar(lp, &vtype, &ind, 0, 0, 0);
@ -1250,7 +1251,7 @@ char *get_array_by_name(char *lp, float **fp, uint16_t *alen) {
uint16_t index = glob_script_mem.type[ind.index].index; uint16_t index = glob_script_mem.type[ind.index].index;
if (glob_script_mem.type[ind.index].bits.is_filter) { if (glob_script_mem.type[ind.index].bits.is_filter) {
float *fa = Get_MFAddr(index, alen, 0); float *fa = Get_MFAddr(index, alen, ipos);
*fp = fa; *fp = fa;
return lp; return lp;
} }
@ -2023,6 +2024,10 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp,
iob = '\n'; iob = '\n';
} else if (*lp == 'r') { } else if (*lp == 'r') {
iob = '\r'; iob = '\r';
} else if (*lp == '0' && *(lp+1) == 'x') {
lp += 2;
iob = strtol(lp, 0, 16);
lp++;
} else if (*lp == '\\') { } else if (*lp == '\\') {
iob = '\\'; iob = '\\';
} else { } else {
@ -2295,11 +2300,11 @@ chknext:
uint16_t alend; uint16_t alend;
fvar = -1; fvar = -1;
float *fpd; float *fpd;
lp = get_array_by_name(lp, &fpd, &alend); lp = get_array_by_name(lp, &fpd, &alend, 0);
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
uint16_t alens; uint16_t alens;
float *fps; float *fps;
lp = get_array_by_name(lp, &fps, &alens); lp = get_array_by_name(lp, &fps, &alens, 0);
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
if (alens < alend) { if (alens < alend) {
alend = alens; alend = alens;
@ -2308,6 +2313,26 @@ chknext:
fvar = alend; fvar = alend;
goto nfuncexit; goto nfuncexit;
} }
if (!strncmp(lp, "af(", 3)) {
// array to float
uint16_t alend;
float *fpd;
lp = get_array_by_name(lp + 3, &fpd, &alend, 0);
SCRIPT_SKIP_SPACES
if (fpd) {
uint8_t fbytes[4];
fbytes[0] = *fpd++;
fbytes[1] = *fpd++;
fbytes[2] = *fpd++;
fbytes[3] = *fpd++;
fpd = (float*)fbytes;
fvar = *fpd;
} else {
fvar = 0;
}
goto nfuncexit;
}
break; break;
case 'b': case 'b':
@ -2906,7 +2931,7 @@ chknext:
uint8_t index = 0; uint8_t index = 0;
while (index < MAX_EXT_ARRAYS) { while (index < MAX_EXT_ARRAYS) {
lp = get_array_by_name(lp, &a_ptr[index], &a_len[index]); lp = get_array_by_name(lp, &a_ptr[index], &a_len[index], 0);
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
index++; index++;
if (*lp == ')' || *lp == '\n') { if (*lp == ')' || *lp == '\n') {
@ -2952,7 +2977,7 @@ chknext:
if (!strncmp(lp, "fwa(", 4)) { if (!strncmp(lp, "fwa(", 4)) {
uint16_t alen; uint16_t alen;
float *fa; float *fa;
lp = get_array_by_name(lp + 4, &fa, &alen); lp = get_array_by_name(lp + 4, &fa, &alen, 0);
if (!fa) { if (!fa) {
fvar = 0; fvar = 0;
goto exit; goto exit;
@ -2993,7 +3018,7 @@ chknext:
if (!strncmp(lp, "fra(", 4)) { if (!strncmp(lp, "fra(", 4)) {
uint16_t alen; uint16_t alen;
float *fa; float *fa;
lp = get_array_by_name(lp + 4, &fa, &alen); lp = get_array_by_name(lp + 4, &fa, &alen, 0);
if (!fa) { if (!fa) {
fvar = 0; fvar = 0;
goto exit; goto exit;
@ -3370,6 +3395,20 @@ chknext:
#endif // USE_SCRIPT_I2C #endif // USE_SCRIPT_I2C
break; break;
#ifdef USE_KNX
case 'k':
if (!strncmp(lp, "knx(", 4)) {
float type;
lp = GetNumericArgument(lp + 4, OPER_EQU, &type, gv);
SCRIPT_SKIP_SPACES
lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv);
SCRIPT_SKIP_SPACES
KnxSensor(type, fvar);
goto nfuncexit;
}
break;
#endif
case 'l': case 'l':
if (!strncmp(lp, "lip", 3)) { if (!strncmp(lp, "lip", 3)) {
if (sp) strlcpy(sp, (const char*)WiFi.localIP().toString().c_str(), glob_script_mem.max_ssize); if (sp) strlcpy(sp, (const char*)WiFi.localIP().toString().c_str(), glob_script_mem.max_ssize);
@ -4058,13 +4097,72 @@ extern char *SML_GetSVal(uint32_t index);
len = 0; len = 0;
goto exit; goto exit;
} }
// serial write array
if (!strncmp(lp, "swa(", 4)) {
fvar = -1;
if (glob_script_mem.sp) {
uint8_t modbus_buffer[64];
uint16_t alen;
float *array;
lp = get_array_by_name(lp + 4, &array, &alen, 0);
SCRIPT_SKIP_SPACES
if (!array) {
goto exit;
}
float len;
lp = GetNumericArgument(lp, OPER_EQU, &len, 0);
SCRIPT_SKIP_SPACES
if (len > alen) len = alen;
if (len < 1) len = 1;
if (*lp != ')') {
float opts = 0;
lp = GetNumericArgument(lp, OPER_EQU, &opts, 0);
SCRIPT_SKIP_SPACES
// calc modbus checksum
#ifdef USE_SML_M
// calc modbus checksum
if (len > sizeof(modbus_buffer)) len = sizeof(modbus_buffer);
for (uint32_t cnt = 0; cnt < len; cnt++) {
modbus_buffer[cnt] = *array++;
}
uint16_t crc = 0xffff;
uint8_t *mbp = modbus_buffer;
if (opts == 1) {
mbp++;
crc = 0;
}
crc = MBUS_calculateCRC(mbp, mbp[2] + 3, crc);
if (opts == 1) {
mbp[mbp[2] + 3] = highByte(crc);
mbp[mbp[2] + 4] = lowByte(crc);
} else {
mbp[mbp[2] + 3] = lowByte(crc);
mbp[mbp[2] + 4] = highByte(crc);
}
#endif
uint8_t *ucp = modbus_buffer;
while (len) {
glob_script_mem.sp->write(*ucp);
//AddLog(LOG_LEVEL_INFO,PSTR(">> %02x"),*ucp);
ucp++;
len--;
}
} else {
while (len) {
glob_script_mem.sp->write((uint8_t)*array++);
len--;
}
}
}
goto nfuncexit;
}
// serial read array // serial read array
if (!strncmp(lp, "sra(", 4)) { if (!strncmp(lp, "sra(", 4)) {
fvar = -1; fvar = -1;
if (glob_script_mem.sp) { if (glob_script_mem.sp) {
uint16_t alen; uint16_t alen;
float *array; float *array;
lp = get_array_by_name(lp + 4, &array, &alen); lp = get_array_by_name(lp + 4, &array, &alen, 0);
if (!array) { if (!array) {
goto exit; goto exit;
} }
@ -4082,16 +4180,14 @@ extern char *SML_GetSVal(uint32_t index);
for (uint8_t cnt = 0; cnt < 8; cnt++) { for (uint8_t cnt = 0; cnt < 8; cnt++) {
modbus_response[cnt] = array[cnt]; modbus_response[cnt] = array[cnt];
} }
uint16_t crc = MBUS_calculateCRC(modbus_response, 6); uint16_t crc = MBUS_calculateCRC(modbus_response, 6, 0xFFFF);
if ( (lowByte(crc) != modbus_response[6]) || (highByte(crc) != modbus_response[7]) ) { if ( (lowByte(crc) != modbus_response[6]) || (highByte(crc) != modbus_response[7]) ) {
fvar = -2; fvar = -2;
} }
} }
#endif #endif
} }
lp++; goto nfuncexit;
len = 0;
goto exit;
} }
#ifdef USE_SML_M #ifdef USE_SML_M
// serial modbus write float, 010404ffffffffxxxx // serial modbus write float, 010404ffffffffxxxx
@ -4104,52 +4200,95 @@ extern char *SML_GetSVal(uint32_t index);
float mode; float mode;
lp = GetNumericArgument(lp, OPER_EQU, &mode, 0); lp = GetNumericArgument(lp, OPER_EQU, &mode, 0);
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
float mval;
lp = GetNumericArgument(lp, OPER_EQU, &mval, 0); uint16_t alend;
float *fpd;
lp = get_array_by_name(lp, &fpd, &alend, 0);
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
float nvals;
lp = GetNumericArgument(lp, OPER_EQU, &nvals, 0);
SCRIPT_SKIP_SPACES
if (nvals > alend) {
nvals = alend;
}
uint8_t modbus_response[128];
uint8_t mb_index = 0;
modbus_response[mb_index] = addr;
mb_index++;
modbus_response[mb_index] = 4;
mb_index++;
if (mode == 0) {
modbus_response[mb_index] = 2 * nvals;
} else {
modbus_response[mb_index] = 4 * nvals;
}
mb_index++;
for (uint16_t cnt = 0; cnt < nvals; cnt++) {
float fpval = *fpd++;
uint32_t ui32 = fpval;
uint32_t uval, *uvp; uint32_t uval, *uvp;
uvp = &uval; uvp = &uval;
*(uvp) = *(uint32_t*)&mval; *(uvp) = *(uint32_t*)&fpval;
uint8_t modbus_response[10];
uint32_t ui32 = mval;
modbus_response[0] = addr;
modbus_response[1] = 4;
switch ((uint8_t)mode) { switch ((uint8_t)mode) {
case 0: case 0:
// UINT16 // UINT16
modbus_response[2] = 2; modbus_response[mb_index] = (ui32 >> 16);
modbus_response[3] = (ui32 >> 16); mb_index++;
modbus_response[4] = (ui32 >> 0); modbus_response[mb_index] = (ui32 >> 0);
mb_index++;
break; break;
case 1: case 1:
// UINT32 // UINT32
modbus_response[2] = 4; modbus_response[mb_index] = (ui32 >> 24);
modbus_response[3] = (ui32 >> 24); mb_index++;
modbus_response[4] = (ui32 >> 16); modbus_response[mb_index] = (ui32 >> 16);
modbus_response[5] = (ui32 >> 8); mb_index++;
modbus_response[6] = (ui32 >> 0); modbus_response[mb_index] = (ui32 >> 8);
mb_index++;
modbus_response[mb_index] = (ui32 >> 0);
mb_index++;
break; break;
default: default:
// float // float
modbus_response[2] = 4; modbus_response[mb_index] = (uval >> 24);
modbus_response[3] = (uval >> 24); mb_index++;
modbus_response[4] = (uval >> 16); modbus_response[mb_index] = (uval >> 16);
modbus_response[5] = (uval >> 8); mb_index++;
modbus_response[6] = (uval >> 0); modbus_response[mb_index] = (uval >> 8);
mb_index++;
modbus_response[mb_index] = (uval >> 0);
mb_index++;
break; break;
} }
}
// calc modbus checksum
// calc mobus checksum uint16_t crc = MBUS_calculateCRC(modbus_response, modbus_response[2] + 3, 0xFFFF);
uint16_t crc = MBUS_calculateCRC(modbus_response, modbus_response[2] + 3);
modbus_response[modbus_response[2] + 3] = lowByte(crc); modbus_response[modbus_response[2] + 3] = lowByte(crc);
modbus_response[modbus_response[2] + 4] = highByte(crc); modbus_response[modbus_response[2] + 4] = highByte(crc);
glob_script_mem.sp->write(modbus_response, 9); glob_script_mem.sp->write(modbus_response, mb_index + 2);
fvar = 0; fvar = 0;
#if 0
// show response
char hexbuff[256];
sprintf(hexbuff,"%02x%02x%02x - ",modbus_response[0],modbus_response[1],modbus_response[2]);
for (uint16_t cnt = 3; cnt < mb_index; cnt+=4) {
char cbuff[32];
sprintf(cbuff," %02x%02x%02x%02x",modbus_response[cnt],modbus_response[cnt+1],modbus_response[cnt+2],modbus_response[cnt+3]);
strcat(hexbuff,cbuff);
}
char cbuff[32];
sprintf(cbuff," - %02x%02x",modbus_response[mb_index],modbus_response[mb_index+1]);
strcat(hexbuff,cbuff);
AddLog(LOG_LEVEL_INFO,PSTR(">> %s"),hexbuff);
#endif
} }
lp++; lp++;
len = 0; len = 0;
@ -4477,6 +4616,16 @@ extern char *SML_GetSVal(uint32_t index);
fvar = WcSetMotionDetect(fvar2); fvar = WcSetMotionDetect(fvar2);
} }
break; break;
/*
#ifdef USE_FACE_DETECT
case 7:
{ float fvar2;
lp = GetNumericArgument(lp, OPER_EQU, &fvar2, gv);
fvar = WcSetFaceDetect(fvar2);
}
break;
#endif //USE_FACE_DETECT
*/
default: default:
fvar = 0; fvar = 0;
} }
@ -5830,13 +5979,13 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
lp += 4; lp += 4;
// skip one space after cmd // skip one space after cmd
web_send_line(0, lp); web_send_line(0, lp);
/*
char tmp[256];
Replace_Cmd_Vars(lp ,1 , tmp, sizeof(tmp));
WSContentFlush(); WSContentFlush();
WSContentSend_P(PSTR("%s"),tmp); goto next_line;
*/ }
else if (!strncmp(lp, "wfs", 3)) {
lp += 4;
// skip one space after cmd
web_send_file(0, lp);
WSContentFlush(); WSContentFlush();
goto next_line; goto next_line;
} }
@ -6810,20 +6959,39 @@ void SaveScriptEnd(void) {
} }
} }
void set_callbacks() { void set_callbacks() {
if (Run_Scripter1(">F", -2, 0) == 99) {glob_script_mem.fast_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.fast_script = 0;} if (Run_Scripter1(">F", -2, 0) == 99) {glob_script_mem.fast_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.fast_script = 0;}
if (Run_Scripter1(">E", -2, 0) == 99) {glob_script_mem.event_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.event_script = 0;} if (Run_Scripter1(">E", -2, 0) == 99) {glob_script_mem.event_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.event_script = 0;}
if (Run_Scripter1(">C", -2, 0) == 99) {glob_script_mem.html_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.html_script = 0;} if (Run_Scripter1(">C", -2, 0) == 99) {glob_script_mem.html_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.html_script = 0;}
} }
void set_wpages(char *id, uint16_t index) {
uint16_t idlen = strlen(id);
uint16_t idl2 = idlen;
if (id[idlen - 1] ==' ') idl2--;
if (Run_Scripter1(id, -idlen, 0) == 99) {glob_script_mem.web_pages[index] = glob_script_mem.section_ptr + idl2;} else {glob_script_mem.web_pages[index] = 0;}
}
#define WEB_PAGE_WS 8
#define WEB_PAGE_WM 9
const char SWPAGES[] PROGMEM = {"W|w |w1 |w2 |w3 |w4 |w5 |w6 |WS|WM|$"};
void script_set_web_pages(void) { void script_set_web_pages(void) {
if (Run_Scripter1(">W", -2, 0) == 99) {glob_script_mem.web_pages[0] = glob_script_mem.section_ptr + 2;} else {glob_script_mem.web_pages[0] = 0;} char lbl[6];
if (Run_Scripter1(">w ", -3, 0) == 99) {glob_script_mem.web_pages[1] = glob_script_mem.section_ptr + 2;} else {glob_script_mem.web_pages[1] = 0;} lbl[0] = '>';
if (Run_Scripter1(">w1 ", -4, 0) == 99) {glob_script_mem.web_pages[2] = glob_script_mem.section_ptr + 3;} else {glob_script_mem.web_pages[2] = 0;}
if (Run_Scripter1(">w2 ", -4, 0) == 99) {glob_script_mem.web_pages[3] = glob_script_mem.section_ptr + 3;} else {glob_script_mem.web_pages[3] = 0;} uint16_t index = 0;
if (Run_Scripter1(">w3 ", -4, 0) == 99) {glob_script_mem.web_pages[4] = glob_script_mem.section_ptr + 3;} else {glob_script_mem.web_pages[4] = 0;} while (1) {
if (Run_Scripter1(">WS", -3, 0) == 99) {glob_script_mem.web_pages[5] = glob_script_mem.section_ptr + 3;} else {glob_script_mem.web_pages[5] = 0;} GetTextIndexed(&lbl[1], sizeof(lbl) - 1, index, SWPAGES);
if (Run_Scripter1(">WM", -3, 0) == 99) {glob_script_mem.web_pages[6] = glob_script_mem.section_ptr + 3;} else {glob_script_mem.web_pages[6] = 0;} if (lbl[1] == '$') {
break;
}
set_wpages(lbl, index);
index++;
}
} }
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
@ -7869,6 +8037,8 @@ void script_download_task(void *path) {
} }
#endif // USE_DLTASK #endif // USE_DLTASK
#define REVERT_M5EPD
void SendFile_sub(char *fname) { void SendFile_sub(char *fname) {
char buff[512]; char buff[512];
uint8_t sflg = 0; uint8_t sflg = 0;
@ -7915,7 +8085,9 @@ char buff[512];
memset(lbuf, 0, Settings->display_width * 3); memset(lbuf, 0, Settings->display_width * 3);
if (!lbuf) return; if (!lbuf) return;
uint8_t dmflg = 0; uint8_t dmflg = 0;
if (renderer->disp_bpp & 0x40) dmflg = 1; if (renderer->disp_bpp & 0x40) {
dmflg = 1;
}
int8_t bpp = renderer->disp_bpp & 0xbf;; int8_t bpp = renderer->disp_bpp & 0xbf;;
uint8_t *lbp; uint8_t *lbp;
uint8_t fileHeader[fileHeaderSize]; uint8_t fileHeader[fileHeaderSize];
@ -7942,6 +8114,13 @@ char buff[512];
for (uint32_t lins = 0; lins < Settings->display_height; lins++) { for (uint32_t lins = 0; lins < Settings->display_height; lins++) {
lbp = lbuf + (Settings->display_width * 3); lbp = lbuf + (Settings->display_width * 3);
if (bpp == 4) { if (bpp == 4) {
// 16 gray scales
#ifdef REVERT_M5EPD
if (dmflg) {
bp = &renderer->framebuffer[(Settings->display_height - lins) * (Settings->display_width / 2)];
bp--;
}
#endif
for (uint32_t cols = 0; cols < Settings->display_width; cols += 2) { for (uint32_t cols = 0; cols < Settings->display_width; cols += 2) {
uint8_t pixel; uint8_t pixel;
if (!dmflg) { if (!dmflg) {
@ -7956,10 +8135,14 @@ char buff[512];
*--lbp = pixel; *--lbp = pixel;
*--lbp = pixel; *--lbp = pixel;
} }
bp++;
} else { } else {
for (uint32_t cnt = 0; cnt <= 1; cnt++) { for (uint32_t cnt = 0; cnt <= 1; cnt++) {
#ifdef REVERT_M5EPD
if (cnt & 1) {
#else
if (!(cnt & 1)) { if (!(cnt & 1)) {
#endif
pixel = *bp >> 4; pixel = *bp >> 4;
} else { } else {
pixel = *bp & 0xf; pixel = *bp & 0xf;
@ -7969,10 +8152,15 @@ char buff[512];
*--lbp = pixel; *--lbp = pixel;
*--lbp = pixel; *--lbp = pixel;
} }
} #ifdef REVERT_M5EPD
bp--;
#else
bp++; bp++;
#endif
}
} }
} else { } else {
// one bit
for (uint32_t cols = 0; cols < Settings->display_width; cols += 8) { for (uint32_t cols = 0; cols < Settings->display_width; cols += 8) {
uint8_t bits = 0x80; uint8_t bits = 0x80;
while (bits) { while (bits) {
@ -8081,6 +8269,15 @@ void ScriptFullWebpage3(void) {
void ScriptFullWebpage4(void) { void ScriptFullWebpage4(void) {
ScriptFullWebpage(4); ScriptFullWebpage(4);
} }
void ScriptFullWebpage5(void) {
ScriptFullWebpage(5);
}
void ScriptFullWebpage6(void) {
ScriptFullWebpage(6);
}
void ScriptFullWebpage7(void) {
ScriptFullWebpage(7);
}
void ScriptFullWebpage(uint8_t page) { void ScriptFullWebpage(uint8_t page) {
uint32_t fullpage_refresh = 10000; uint32_t fullpage_refresh = 10000;
@ -8248,7 +8445,8 @@ const char SCRIPT_MSG_GTABLEbx[] PROGMEM =
"google.charts.setOnLoadCallback(drawChart);</script>"; "google.charts.setOnLoadCallback(drawChart);</script>";
const char SCRIPT_MSG_GOPT1[] PROGMEM = const char SCRIPT_MSG_GOPT1[] PROGMEM =
"title:'%s',isStacked:false"; "title:'%s',isStacked:%s";
const char SCRIPT_MSG_GAUGEOPT[] PROGMEM = const char SCRIPT_MSG_GAUGEOPT[] PROGMEM =
"max:%d,redFrom:%d,redTo:%d,yellowFrom:%d,yellowTo:%d"; "max:%d,redFrom:%d,redTo:%d,yellowFrom:%d,yellowTo:%d";
@ -8257,7 +8455,7 @@ const char SCRIPT_MSG_GOPT2[] PROGMEM =
"showRowNumber:true,sort:'disable',allowHtml:true,width:'100%%',height:'100%%',cssClassNames:cssc"; "showRowNumber:true,sort:'disable',allowHtml:true,width:'100%%',height:'100%%',cssClassNames:cssc";
const char SCRIPT_MSG_GOPT3[] PROGMEM = const char SCRIPT_MSG_GOPT3[] PROGMEM =
"title:'%s',isStacked:false,vAxes:{0:{maxValue:%s},1:{maxValue:%s}},series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}}%s"; "title:'%s',isStacked:%s,vAxes:{0:{maxValue:%s},1:{maxValue:%s}},series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}}%s";
const char SCRIPT_MSG_GOPT4[] PROGMEM = const char SCRIPT_MSG_GOPT4[] PROGMEM =
//"hAxis:{minValue:new Date(0,1,1,0,0),maxValue:new Date(0,1,2,0,0),format:'HH:mm'}"; //"hAxis:{minValue:new Date(0,1,1,0,0),maxValue:new Date(0,1,2,0,0),format:'HH:mm'}";
@ -8267,7 +8465,7 @@ const char SCRIPT_MSG_GOPT5[] PROGMEM =
"new Date(0,0,0,%d,%d)"; "new Date(0,0,0,%d,%d)";
const char SCRIPT_MSG_GOPT6[] PROGMEM = const char SCRIPT_MSG_GOPT6[] PROGMEM =
"title:'%s',isStacked:false,vAxis:{viewWindow:{min:%s,max:%s}}%s"; "title:'%s',isStacked:%s,vAxis:{viewWindow:{min:%s,max:%s}}%s";
const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'"; const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'";
@ -8387,6 +8585,7 @@ uint32_t cnt;
#define WSO_NOCENTER 1 #define WSO_NOCENTER 1
#define WSO_NODIV 2 #define WSO_NODIV 2
#define WSO_FORCEPLAIN 4 #define WSO_FORCEPLAIN 4
#define WSO_FORCEMAIN 8
#define WSO_STOP_DIV 0x80 #define WSO_STOP_DIV 0x80
void WCS_DIV(uint8_t flag) { void WCS_DIV(uint8_t flag) {
@ -8414,7 +8613,7 @@ void ScriptWebShow(char mc, uint8_t page) {
//uint8_t web_script; //uint8_t web_script;
glob_script_mem.web_mode = mc; glob_script_mem.web_mode = mc;
if (mc == 'w' || mc == 'x' || page >= 5) { if (mc == 'w' || mc == 'x' || page >= WEB_PAGE_WS) {
if (mc == 'x') { if (mc == 'x') {
mc = '$'; mc = '$';
} }
@ -8485,6 +8684,11 @@ void ScriptWebShow(char mc, uint8_t page) {
lp = scripter_sub(lp + 1, 0); lp = scripter_sub(lp + 1, 0);
specopt = sflg; specopt = sflg;
//goto nextwebline; //goto nextwebline;
} else if (!strncmp(lp, "%/", 2)) {
// send file
if (mc) {
web_send_file(mc, lp + 1);
}
} else { } else {
web_send_line(mc, lp); web_send_line(mc, lp);
} }
@ -8501,6 +8705,44 @@ nextwebline:
} }
} }
#define WSF_BSIZE 256
int32_t web_send_file(char mc, char *fname) {
char path[32];
#ifdef USE_UFILESYS
char *lbuff = (char*)special_malloc(WSF_BSIZE);
if (!lbuff) {
return -1;
}
cpy2lf(path, sizeof(path), fname);
File file = ufsp->open(path, FS_FILE_READ);
if (file) {
WSContentFlush();
while (file.available()) {
uint16_t len;
len = file.readBytesUntil('\n', lbuff, WSF_BSIZE);
lbuff[len] = 0;
char *lp = lbuff;
while (*lp == ' ') lp++;
if (*lp == '/' && *(lp + 1) == '/') {
// skip comment lines
continue;
}
web_send_line(mc, lbuff);
}
file.close();
free(lbuff);
return 0;
} else {
AddLog(LOG_LEVEL_INFO, PSTR("WEB file %s not found"), path);
}
free(lbuff);
#endif
return -2;
}
char *web_send_line(char mc, char *lp1) { char *web_send_line(char mc, char *lp1) {
char tmp[256]; char tmp[256];
char center[10]; char center[10];
@ -8510,8 +8752,24 @@ const char *gc_str;
Replace_Cmd_Vars(lp1, 1, tmp, sizeof(tmp)); Replace_Cmd_Vars(lp1, 1, tmp, sizeof(tmp));
char *lin = tmp; char *lin = tmp;
if ((!mc && (*lin != '$')) || (mc == 'w' && (*lin != '$'))) {
if (!strncmp(lin, "so(", 3)) {
// set options
float var;
lin = GetNumericArgument(lin + 3, OPER_EQU, &var, 0);
specopt = var;
return lin;
}
if (specopt & WSO_NOCENTER) {
center[0] = 0;
} else {
strcpy_P(center, PSTR("<center>"));
}
if ( ((!mc && (*lin != '$')) || (mc == 'w' && (*lin != '$'))) && (!(specopt&WSO_FORCEMAIN)) ) {
// normal web section // normal web section
//AddLog(LOG_LEVEL_INFO, PSTR("normal %s"), lin);
if (*lin == '@') { if (*lin == '@') {
lin++; lin++;
optflg = 1; optflg = 1;
@ -8525,21 +8783,7 @@ const char *gc_str;
strcpy_P(center, PSTR("<center>")); strcpy_P(center, PSTR("<center>"));
} }
if (!strncmp(lin, "so(", 3)) { if (!strncmp(lin, "sl(", 3)) {
// set options
char *lp = lin;
float var;
lp = GetNumericArgument(lp + 3, OPER_EQU, &var, 0);
SCRIPT_SKIP_SPACES
lp++;
specopt = var;
// bit 0 = center mode
if (specopt & WSO_NOCENTER) {
center[0] = 0;
} else {
strcpy_P(center, PSTR("<center>"));
}
} else if (!strncmp(lin, "sl(", 3)) {
// insert slider sl(min max var left mid right) // insert slider sl(min max var left mid right)
char *lp = lin; char *lp = lin;
float min; float min;
@ -8864,14 +9108,63 @@ const char *gc_str;
// end standard web interface // end standard web interface
} else { } else {
// main section interface // main section interface
if (*lin == mc || mc == 'z') { //AddLog(LOG_LEVEL_INFO, PSTR("main %s"), lin);
if ( (*lin == mc) || (mc == 'z') || (specopt&WSO_FORCEMAIN)) {
#ifdef USE_GOOGLE_CHARTS #ifdef USE_GOOGLE_CHARTS
if (mc != 'z') { if (mc != 'z') {
if (!(specopt&WSO_FORCEMAIN)) {
lin++; lin++;
} }
}
exgc: exgc:
char *lp; char *lp;
char *cp = strstr_P(lin, PSTR("insa("));
if (cp) {
// insert array
char valstr[128];
uint16_t len = (uint32_t)cp - (uint32_t)lin;
strncpy(valstr, lin, len);
valstr[len] = 0;
WSContentSend_PD(PSTR("%s"), valstr);
float *fpd = 0;
uint16_t alend;
uint16_t ipos;
lp = get_array_by_name(cp + 5, &fpd, &alend, &ipos);
if (ipos >= alend) ipos = 0;
if (fpd) {
for (uint32_t cnt = 0; cnt < alend; cnt++) {
dtostrfd(fpd[ipos], 3, valstr);
ipos++;
if (ipos >= alend) {
ipos = 0;
}
if (cnt == 0) {
WSContentSend_PD(PSTR("%s"), valstr);
} else {
WSContentSend_PD(PSTR(",%s"), valstr);
}
}
}
lp++;
WSContentSend_PD(PSTR("%s"), lp);
return lp;
}
cp = strstr_P(lin, PSTR("=#"));
if (cp) {
// insert from subroutine
char valstr[128];
uint16_t len = (uint32_t)cp - (uint32_t)lin;
strncpy(valstr, lin, len);
valstr[len] = 0;
WSContentSend_PD(PSTR("%s"), valstr);
lp = scripter_sub(cp , 0);
WSContentSend_PD(PSTR("%s"), lp);
return lp;
}
if (!strncmp(lin, "gc(", 3)) { if (!strncmp(lin, "gc(", 3)) {
// get google table // get google table
lp = lin + 3; lp = lin + 3;
@ -8920,13 +9213,18 @@ exgc:
return lp1; return lp1;
} }
char stacked[6];
strcpy_P(stacked,"false");
if (gs_ctype == 'l' && *lp == 'f') { if (gs_ctype == 'l' && *lp == 'f') {
lp++; lp++;
func = PSTR(",curveType:'function'"); func = PSTR(",curveType:'function'");
} else { } else {
func = ""; func = "";
} }
if (gs_ctype == 'c' && *lp == 's') {
lp++;
strcpy_P(stacked,"true");
}
if (*lp=='2') { if (*lp=='2') {
lp++; lp++;
nanum = 2; nanum = 2;
@ -8939,6 +9237,22 @@ exgc:
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
//Serial.printf("type %d\n",ctype); //Serial.printf("type %d\n",ctype);
float max_entries = 0;
struct T_INDEX ind;
uint8_t vtype;
char *slp = lp;
lp = isvar(lp, &vtype, &ind, &max_entries, 0, 0);
if (vtype != VAR_NV) {
if ((vtype&STYPE) == 0) {
// numeric result
if (!ind.bits.constant && glob_script_mem.type[ind.index].bits.is_filter) {
// is 1. array
lp = slp;
}
}
}
SCRIPT_SKIP_SPACES
float *arrays[MAX_GARRAY]; float *arrays[MAX_GARRAY];
uint8_t anum = 0; uint8_t anum = 0;
@ -8950,6 +9264,15 @@ exgc:
return lp1; return lp1;
//goto nextwebline; //goto nextwebline;
} }
// override array size
if (max_entries > 0) {
if (max_entries > entries) {
max_entries = entries;
}
entries = max_entries;
}
// we know how many arrays and the number of entries // we know how many arrays and the number of entries
//Serial.printf("arrays %d\n",anum); //Serial.printf("arrays %d\n",anum);
//Serial.printf("entries %d\n",entries); //Serial.printf("entries %d\n",entries);
@ -9061,6 +9384,7 @@ exgc:
} }
} }
divflg = entries / segments; divflg = entries / segments;
if (!divflg) divflg = 1;
} }
uint32_t aind = ipos; uint32_t aind = ipos;
@ -9070,7 +9394,11 @@ exgc:
char lbl[16]; char lbl[16];
if (todflg >= 0) { if (todflg >= 0) {
uint16_t mins = (float)(todflg % divflg) * (float)((float)60 / (float)divflg); uint16_t mins = (float)(todflg % divflg) * (float)((float)60 / (float)divflg);
if (hmflg) {
sprintf(lbl, "%d:%02d", todflg / divflg, mins); sprintf(lbl, "%d:%02d", todflg / divflg, mins);
} else {
sprintf(lbl, "%d", todflg / divflg);
}
todflg++; todflg++;
if (hmflg == 0) { if (hmflg == 0) {
if (todflg >= entries) { if (todflg >= entries) {
@ -9128,7 +9456,7 @@ exgc:
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT2); snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT2);
break; break;
default: default:
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT1, header); snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT1, header, stacked);
break; break;
} }
// check for 2 axis option // check for 2 axis option
@ -9146,7 +9474,7 @@ exgc:
char maxstr2[16]; char maxstr2[16];
dtostrfd(max2, 3, maxstr2); dtostrfd(max2, 3, maxstr2);
//snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT3, header, (uint32_t)max1, (uint32_t)max2, func); //snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT3, header, (uint32_t)max1, (uint32_t)max2, func);
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT3, header, maxstr1, maxstr2, func); snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT3, header, stacked, maxstr1, maxstr2, func);
} else { } else {
SCRIPT_SKIP_SPACES SCRIPT_SKIP_SPACES
if (gs_ctype != 'g') { if (gs_ctype != 'g') {
@ -9162,7 +9490,7 @@ exgc:
char maxstr2[16]; char maxstr2[16];
dtostrfd(max2, 3, maxstr2); dtostrfd(max2, 3, maxstr2);
//nprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT6, header, (uint32_t)max1, (uint32_t)max2, func); //nprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT6, header, (uint32_t)max1, (uint32_t)max2, func);
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT6, header, maxstr1, maxstr2, func); snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT6, header, stacked, maxstr1, maxstr2, func);
} }
} }
} }
@ -9190,7 +9518,9 @@ exgc:
WSContentSend_PD(PSTR("%s"), lin); WSContentSend_PD(PSTR("%s"), lin);
} }
#else #else
if (!(specopt&WSO_FORCEMAIN)) {
lin++; lin++;
}
WSContentSend_PD(PSTR("%s"), lin); WSContentSend_PD(PSTR("%s"), lin);
} else { } else {
// WSContentSend_PD(PSTR("%s"),lin); // WSContentSend_PD(PSTR("%s"),lin);
@ -10060,6 +10390,15 @@ void script_add_subpage(uint8_t num) {
case 4: case 4:
wptr = ScriptFullWebpage4; wptr = ScriptFullWebpage4;
break; break;
case 5:
wptr = ScriptFullWebpage5;
break;
case 6:
wptr = ScriptFullWebpage6;
break;
case 7:
wptr = ScriptFullWebpage7;
break;
} }
sprintf_P(id, PSTR("/sfd%1d"), num); sprintf_P(id, PSTR("/sfd%1d"), num);
Webserver->on(id, wptr); Webserver->on(id, wptr);
@ -10293,8 +10632,8 @@ bool Xdrv10(uint8_t function)
#ifdef USE_SCRIPT_WEB_DISPLAY #ifdef USE_SCRIPT_WEB_DISPLAY
case FUNC_WEB_ADD_MAIN_BUTTON: case FUNC_WEB_ADD_MAIN_BUTTON:
if (bitRead(Settings->rule_enabled, 0)) { if (bitRead(Settings->rule_enabled, 0)) {
if (glob_script_mem.web_pages[6]) { if (glob_script_mem.web_pages[WEB_PAGE_WM]) {
ScriptWebShow('z', 6); ScriptWebShow('z', WEB_PAGE_WM);
} else { } else {
ScriptWebShow('$', 0); ScriptWebShow('$', 0);
} }
@ -10303,6 +10642,9 @@ bool Xdrv10(uint8_t function)
script_add_subpage(2); script_add_subpage(2);
script_add_subpage(3); script_add_subpage(3);
script_add_subpage(4); script_add_subpage(4);
script_add_subpage(5);
script_add_subpage(6);
script_add_subpage(7);
#endif // SCRIPT_FULL_WEBPAGE #endif // SCRIPT_FULL_WEBPAGE
} }
@ -10338,8 +10680,8 @@ bool Xdrv10(uint8_t function)
#ifdef USE_SCRIPT_WEB_DISPLAY #ifdef USE_SCRIPT_WEB_DISPLAY
case FUNC_WEB_SENSOR: case FUNC_WEB_SENSOR:
if (bitRead(Settings->rule_enabled, 0)) { if (bitRead(Settings->rule_enabled, 0)) {
if (glob_script_mem.web_pages[5]) { if (glob_script_mem.web_pages[WEB_PAGE_WS]) {
ScriptWebShow(0, 5); ScriptWebShow(0, WEB_PAGE_WS);
} else { } else {
ScriptWebShow(0, 0); ScriptWebShow(0, 0);
} }

View File

@ -2171,7 +2171,7 @@ void SML_Decode(uint8_t index) {
} }
uint16_t pos = smltbuf[mindex][2]+3; uint16_t pos = smltbuf[mindex][2]+3;
if (pos>32) pos=32; if (pos>32) pos=32;
uint16_t crc = MBUS_calculateCRC(&smltbuf[mindex][0],pos); uint16_t crc = MBUS_calculateCRC(&smltbuf[mindex][0],pos,0xFFFF);
if (lowByte(crc)!=smltbuf[mindex][pos]) goto nextsect; if (lowByte(crc)!=smltbuf[mindex][pos]) goto nextsect;
if (highByte(crc)!=smltbuf[mindex][pos+1]) goto nextsect; if (highByte(crc)!=smltbuf[mindex][pos+1]) goto nextsect;
dval=mbus_dval; dval=mbus_dval;
@ -3279,7 +3279,7 @@ void SML_Send_Seq(uint32_t meter,char *seq) {
slen += 2; slen += 2;
} }
// append crc // append crc
uint16_t crc = MBUS_calculateCRC(sbuff, slen); uint16_t crc = MBUS_calculateCRC(sbuff, slen, 0xFFFF);
*ucp++ = lowByte(crc); *ucp++ = lowByte(crc);
*ucp++ = highByte(crc); *ucp++ = highByte(crc);
slen += 2; slen += 2;
@ -3313,9 +3313,10 @@ void SML_Send_Seq(uint32_t meter,char *seq) {
} }
#endif // USE_SCRIPT #endif // USE_SCRIPT
uint16_t MBUS_calculateCRC(uint8_t *frame, uint8_t num) { uint16_t MBUS_calculateCRC(uint8_t *frame, uint8_t num, uint16_t start) {
uint16_t crc, flag; uint16_t crc, flag;
crc = 0xFFFF; //crc = 0xFFFF;
crc = start;
for (uint32_t i = 0; i < num; i++) { for (uint32_t i = 0; i < num; i++) {
crc ^= frame[i]; crc ^= frame[i];
for (uint32_t j = 8; j; j--) { for (uint32_t j = 8; j; j--) {