mirror of https://github.com/arendst/Tasmota.git
scripter enhancements
This commit is contained in:
parent
8284649c43
commit
9484f1d2b3
|
@ -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 DecodeLightId(uint32_t hue_id);
|
||||
char *web_send_line(char mc, char *lp);
|
||||
int32_t web_send_file(char mc, char *file);
|
||||
|
||||
#define SPECIAL_EEPMODE_SIZE 6200
|
||||
|
||||
|
@ -451,7 +452,7 @@ struct SCRIPT_MEM {
|
|||
char *fast_script = 0;
|
||||
char *event_script = 0;
|
||||
char *html_script = 0;
|
||||
char *web_pages[7];
|
||||
char *web_pages[10];
|
||||
uint32_t script_lastmillis;
|
||||
bool event_handeled = false;
|
||||
#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 *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;
|
||||
uint8_t vtype;
|
||||
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;
|
||||
|
||||
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;
|
||||
return lp;
|
||||
}
|
||||
|
@ -2023,6 +2024,10 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp,
|
|||
iob = '\n';
|
||||
} else if (*lp == 'r') {
|
||||
iob = '\r';
|
||||
} else if (*lp == '0' && *(lp+1) == 'x') {
|
||||
lp += 2;
|
||||
iob = strtol(lp, 0, 16);
|
||||
lp++;
|
||||
} else if (*lp == '\\') {
|
||||
iob = '\\';
|
||||
} else {
|
||||
|
@ -2295,11 +2300,11 @@ chknext:
|
|||
uint16_t alend;
|
||||
fvar = -1;
|
||||
float *fpd;
|
||||
lp = get_array_by_name(lp, &fpd, &alend);
|
||||
lp = get_array_by_name(lp, &fpd, &alend, 0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
uint16_t alens;
|
||||
float *fps;
|
||||
lp = get_array_by_name(lp, &fps, &alens);
|
||||
lp = get_array_by_name(lp, &fps, &alens, 0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
if (alens < alend) {
|
||||
alend = alens;
|
||||
|
@ -2308,6 +2313,26 @@ chknext:
|
|||
fvar = alend;
|
||||
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;
|
||||
|
||||
case 'b':
|
||||
|
@ -2906,7 +2931,7 @@ chknext:
|
|||
|
||||
uint8_t index = 0;
|
||||
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
|
||||
index++;
|
||||
if (*lp == ')' || *lp == '\n') {
|
||||
|
@ -2952,7 +2977,7 @@ chknext:
|
|||
if (!strncmp(lp, "fwa(", 4)) {
|
||||
uint16_t alen;
|
||||
float *fa;
|
||||
lp = get_array_by_name(lp + 4, &fa, &alen);
|
||||
lp = get_array_by_name(lp + 4, &fa, &alen, 0);
|
||||
if (!fa) {
|
||||
fvar = 0;
|
||||
goto exit;
|
||||
|
@ -2993,7 +3018,7 @@ chknext:
|
|||
if (!strncmp(lp, "fra(", 4)) {
|
||||
uint16_t alen;
|
||||
float *fa;
|
||||
lp = get_array_by_name(lp + 4, &fa, &alen);
|
||||
lp = get_array_by_name(lp + 4, &fa, &alen, 0);
|
||||
if (!fa) {
|
||||
fvar = 0;
|
||||
goto exit;
|
||||
|
@ -3370,6 +3395,20 @@ chknext:
|
|||
#endif // USE_SCRIPT_I2C
|
||||
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':
|
||||
if (!strncmp(lp, "lip", 3)) {
|
||||
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;
|
||||
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
|
||||
if (!strncmp(lp, "sra(", 4)) {
|
||||
fvar = -1;
|
||||
if (glob_script_mem.sp) {
|
||||
uint16_t alen;
|
||||
float *array;
|
||||
lp = get_array_by_name(lp + 4, &array, &alen);
|
||||
lp = get_array_by_name(lp + 4, &array, &alen, 0);
|
||||
if (!array) {
|
||||
goto exit;
|
||||
}
|
||||
|
@ -4082,16 +4180,14 @@ extern char *SML_GetSVal(uint32_t index);
|
|||
for (uint8_t cnt = 0; cnt < 8; 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]) ) {
|
||||
fvar = -2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
lp++;
|
||||
len = 0;
|
||||
goto exit;
|
||||
goto nfuncexit;
|
||||
}
|
||||
#ifdef USE_SML_M
|
||||
// serial modbus write float, 010404ffffffffxxxx
|
||||
|
@ -4104,52 +4200,95 @@ extern char *SML_GetSVal(uint32_t index);
|
|||
float mode;
|
||||
lp = GetNumericArgument(lp, OPER_EQU, &mode, 0);
|
||||
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
|
||||
uint32_t uval, *uvp;
|
||||
uvp = &uval;
|
||||
*(uvp) = *(uint32_t*)&mval;
|
||||
|
||||
uint8_t modbus_response[10];
|
||||
float nvals;
|
||||
lp = GetNumericArgument(lp, OPER_EQU, &nvals, 0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
|
||||
uint32_t ui32 = mval;
|
||||
modbus_response[0] = addr;
|
||||
modbus_response[1] = 4;
|
||||
switch ((uint8_t)mode) {
|
||||
case 0:
|
||||
// UINT16
|
||||
modbus_response[2] = 2;
|
||||
modbus_response[3] = (ui32 >> 16);
|
||||
modbus_response[4] = (ui32 >> 0);
|
||||
break;
|
||||
case 1:
|
||||
// UINT32
|
||||
modbus_response[2] = 4;
|
||||
modbus_response[3] = (ui32 >> 24);
|
||||
modbus_response[4] = (ui32 >> 16);
|
||||
modbus_response[5] = (ui32 >> 8);
|
||||
modbus_response[6] = (ui32 >> 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
// float
|
||||
modbus_response[2] = 4;
|
||||
modbus_response[3] = (uval >> 24);
|
||||
modbus_response[4] = (uval >> 16);
|
||||
modbus_response[5] = (uval >> 8);
|
||||
modbus_response[6] = (uval >> 0);
|
||||
break;
|
||||
if (nvals > alend) {
|
||||
nvals = alend;
|
||||
}
|
||||
|
||||
uint8_t modbus_response[128];
|
||||
|
||||
// calc mobus checksum
|
||||
uint16_t crc = MBUS_calculateCRC(modbus_response, modbus_response[2] + 3);
|
||||
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;
|
||||
uvp = &uval;
|
||||
*(uvp) = *(uint32_t*)&fpval;
|
||||
|
||||
switch ((uint8_t)mode) {
|
||||
case 0:
|
||||
// UINT16
|
||||
modbus_response[mb_index] = (ui32 >> 16);
|
||||
mb_index++;
|
||||
modbus_response[mb_index] = (ui32 >> 0);
|
||||
mb_index++;
|
||||
break;
|
||||
case 1:
|
||||
// UINT32
|
||||
modbus_response[mb_index] = (ui32 >> 24);
|
||||
mb_index++;
|
||||
modbus_response[mb_index] = (ui32 >> 16);
|
||||
mb_index++;
|
||||
modbus_response[mb_index] = (ui32 >> 8);
|
||||
mb_index++;
|
||||
modbus_response[mb_index] = (ui32 >> 0);
|
||||
mb_index++;
|
||||
break;
|
||||
default:
|
||||
// float
|
||||
modbus_response[mb_index] = (uval >> 24);
|
||||
mb_index++;
|
||||
modbus_response[mb_index] = (uval >> 16);
|
||||
mb_index++;
|
||||
modbus_response[mb_index] = (uval >> 8);
|
||||
mb_index++;
|
||||
modbus_response[mb_index] = (uval >> 0);
|
||||
mb_index++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// calc modbus checksum
|
||||
uint16_t crc = MBUS_calculateCRC(modbus_response, modbus_response[2] + 3, 0xFFFF);
|
||||
modbus_response[modbus_response[2] + 3] = lowByte(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;
|
||||
|
||||
#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++;
|
||||
len = 0;
|
||||
|
@ -4477,6 +4616,16 @@ extern char *SML_GetSVal(uint32_t index);
|
|||
fvar = WcSetMotionDetect(fvar2);
|
||||
}
|
||||
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:
|
||||
fvar = 0;
|
||||
}
|
||||
|
@ -5827,22 +5976,22 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
|
|||
}
|
||||
#ifdef USE_SCRIPT_WEB_DISPLAY
|
||||
else if (!strncmp(lp, "wcs", 3)) {
|
||||
lp+=4;
|
||||
lp += 4;
|
||||
// skip one space after cmd
|
||||
web_send_line(0, lp);
|
||||
/*
|
||||
char tmp[256];
|
||||
Replace_Cmd_Vars(lp ,1 , tmp, sizeof(tmp));
|
||||
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();
|
||||
goto next_line;
|
||||
}
|
||||
#endif
|
||||
else if (!strncmp(lp, "rapp", 3)) {
|
||||
lp+=4;
|
||||
lp += 4;
|
||||
// skip one space after cmd
|
||||
char *tmp = (char*)malloc(256);
|
||||
if (tmp) {
|
||||
|
@ -6810,20 +6959,39 @@ void SaveScriptEnd(void) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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(">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;}
|
||||
}
|
||||
|
||||
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) {
|
||||
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;}
|
||||
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;}
|
||||
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;}
|
||||
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;}
|
||||
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;}
|
||||
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;}
|
||||
char lbl[6];
|
||||
lbl[0] = '>';
|
||||
|
||||
uint16_t index = 0;
|
||||
while (1) {
|
||||
GetTextIndexed(&lbl[1], sizeof(lbl) - 1, index, SWPAGES);
|
||||
if (lbl[1] == '$') {
|
||||
break;
|
||||
}
|
||||
set_wpages(lbl, index);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_WEBSERVER
|
||||
|
@ -7869,6 +8037,8 @@ void script_download_task(void *path) {
|
|||
}
|
||||
#endif // USE_DLTASK
|
||||
|
||||
#define REVERT_M5EPD
|
||||
|
||||
void SendFile_sub(char *fname) {
|
||||
char buff[512];
|
||||
uint8_t sflg = 0;
|
||||
|
@ -7915,7 +8085,9 @@ char buff[512];
|
|||
memset(lbuf, 0, Settings->display_width * 3);
|
||||
if (!lbuf) return;
|
||||
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;;
|
||||
uint8_t *lbp;
|
||||
uint8_t fileHeader[fileHeaderSize];
|
||||
|
@ -7939,9 +8111,16 @@ char buff[512];
|
|||
Webserver->client().write((const char*)lbuf, Settings->display_width * 3);
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
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) {
|
||||
uint8_t pixel;
|
||||
if (!dmflg) {
|
||||
|
@ -7956,10 +8135,14 @@ char buff[512];
|
|||
*--lbp = pixel;
|
||||
*--lbp = pixel;
|
||||
}
|
||||
|
||||
bp++;
|
||||
} else {
|
||||
for (uint32_t cnt = 0; cnt <= 1; cnt++) {
|
||||
#ifdef REVERT_M5EPD
|
||||
if (cnt & 1) {
|
||||
#else
|
||||
if (!(cnt & 1)) {
|
||||
#endif
|
||||
pixel = *bp >> 4;
|
||||
} else {
|
||||
pixel = *bp & 0xf;
|
||||
|
@ -7969,10 +8152,15 @@ char buff[512];
|
|||
*--lbp = pixel;
|
||||
*--lbp = pixel;
|
||||
}
|
||||
#ifdef REVERT_M5EPD
|
||||
bp--;
|
||||
#else
|
||||
bp++;
|
||||
#endif
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
} else {
|
||||
// one bit
|
||||
for (uint32_t cols = 0; cols < Settings->display_width; cols += 8) {
|
||||
uint8_t bits = 0x80;
|
||||
while (bits) {
|
||||
|
@ -8081,6 +8269,15 @@ void ScriptFullWebpage3(void) {
|
|||
void ScriptFullWebpage4(void) {
|
||||
ScriptFullWebpage(4);
|
||||
}
|
||||
void ScriptFullWebpage5(void) {
|
||||
ScriptFullWebpage(5);
|
||||
}
|
||||
void ScriptFullWebpage6(void) {
|
||||
ScriptFullWebpage(6);
|
||||
}
|
||||
void ScriptFullWebpage7(void) {
|
||||
ScriptFullWebpage(7);
|
||||
}
|
||||
|
||||
void ScriptFullWebpage(uint8_t page) {
|
||||
uint32_t fullpage_refresh = 10000;
|
||||
|
@ -8248,7 +8445,8 @@ const char SCRIPT_MSG_GTABLEbx[] PROGMEM =
|
|||
"google.charts.setOnLoadCallback(drawChart);</script>";
|
||||
|
||||
const char SCRIPT_MSG_GOPT1[] PROGMEM =
|
||||
"title:'%s',isStacked:false";
|
||||
"title:'%s',isStacked:%s";
|
||||
|
||||
|
||||
const char SCRIPT_MSG_GAUGEOPT[] PROGMEM =
|
||||
"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";
|
||||
|
||||
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 =
|
||||
//"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)";
|
||||
|
||||
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'";
|
||||
|
||||
|
@ -8387,6 +8585,7 @@ uint32_t cnt;
|
|||
#define WSO_NOCENTER 1
|
||||
#define WSO_NODIV 2
|
||||
#define WSO_FORCEPLAIN 4
|
||||
#define WSO_FORCEMAIN 8
|
||||
#define WSO_STOP_DIV 0x80
|
||||
|
||||
void WCS_DIV(uint8_t flag) {
|
||||
|
@ -8414,7 +8613,7 @@ void ScriptWebShow(char mc, uint8_t page) {
|
|||
|
||||
//uint8_t web_script;
|
||||
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') {
|
||||
mc = '$';
|
||||
}
|
||||
|
@ -8485,6 +8684,11 @@ void ScriptWebShow(char mc, uint8_t page) {
|
|||
lp = scripter_sub(lp + 1, 0);
|
||||
specopt = sflg;
|
||||
//goto nextwebline;
|
||||
} else if (!strncmp(lp, "%/", 2)) {
|
||||
// send file
|
||||
if (mc) {
|
||||
web_send_file(mc, lp + 1);
|
||||
}
|
||||
} else {
|
||||
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 tmp[256];
|
||||
char center[10];
|
||||
|
@ -8510,8 +8752,24 @@ const char *gc_str;
|
|||
Replace_Cmd_Vars(lp1, 1, tmp, sizeof(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
|
||||
//AddLog(LOG_LEVEL_INFO, PSTR("normal %s"), lin);
|
||||
if (*lin == '@') {
|
||||
lin++;
|
||||
optflg = 1;
|
||||
|
@ -8525,21 +8783,7 @@ const char *gc_str;
|
|||
strcpy_P(center, PSTR("<center>"));
|
||||
}
|
||||
|
||||
if (!strncmp(lin, "so(", 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)) {
|
||||
if (!strncmp(lin, "sl(", 3)) {
|
||||
// insert slider sl(min max var left mid right)
|
||||
char *lp = lin;
|
||||
float min;
|
||||
|
@ -8864,14 +9108,63 @@ const char *gc_str;
|
|||
// end standard web interface
|
||||
} else {
|
||||
// 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
|
||||
if (mc != 'z') {
|
||||
lin++;
|
||||
if (!(specopt&WSO_FORCEMAIN)) {
|
||||
lin++;
|
||||
}
|
||||
}
|
||||
exgc:
|
||||
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)) {
|
||||
// get google table
|
||||
lp = lin + 3;
|
||||
|
@ -8920,13 +9213,18 @@ exgc:
|
|||
return lp1;
|
||||
}
|
||||
|
||||
|
||||
if (gs_ctype=='l' && *lp=='f') {
|
||||
char stacked[6];
|
||||
strcpy_P(stacked,"false");
|
||||
if (gs_ctype == 'l' && *lp == 'f') {
|
||||
lp++;
|
||||
func = PSTR(",curveType:'function'");
|
||||
} else {
|
||||
func = "";
|
||||
}
|
||||
if (gs_ctype == 'c' && *lp == 's') {
|
||||
lp++;
|
||||
strcpy_P(stacked,"true");
|
||||
}
|
||||
if (*lp=='2') {
|
||||
lp++;
|
||||
nanum = 2;
|
||||
|
@ -8939,6 +9237,22 @@ exgc:
|
|||
SCRIPT_SKIP_SPACES
|
||||
|
||||
//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];
|
||||
uint8_t anum = 0;
|
||||
|
@ -8950,6 +9264,15 @@ exgc:
|
|||
return lp1;
|
||||
//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
|
||||
//Serial.printf("arrays %d\n",anum);
|
||||
//Serial.printf("entries %d\n",entries);
|
||||
|
@ -9061,6 +9384,7 @@ exgc:
|
|||
}
|
||||
}
|
||||
divflg = entries / segments;
|
||||
if (!divflg) divflg = 1;
|
||||
}
|
||||
|
||||
uint32_t aind = ipos;
|
||||
|
@ -9070,7 +9394,11 @@ exgc:
|
|||
char lbl[16];
|
||||
if (todflg >= 0) {
|
||||
uint16_t mins = (float)(todflg % divflg) * (float)((float)60 / (float)divflg);
|
||||
sprintf(lbl, "%d:%02d", todflg / divflg, mins);
|
||||
if (hmflg) {
|
||||
sprintf(lbl, "%d:%02d", todflg / divflg, mins);
|
||||
} else {
|
||||
sprintf(lbl, "%d", todflg / divflg);
|
||||
}
|
||||
todflg++;
|
||||
if (hmflg == 0) {
|
||||
if (todflg >= entries) {
|
||||
|
@ -9128,7 +9456,7 @@ exgc:
|
|||
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT2);
|
||||
break;
|
||||
default:
|
||||
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT1, header);
|
||||
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT1, header, stacked);
|
||||
break;
|
||||
}
|
||||
// check for 2 axis option
|
||||
|
@ -9146,11 +9474,11 @@ exgc:
|
|||
char maxstr2[16];
|
||||
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, maxstr1, maxstr2, func);
|
||||
snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT3, header, stacked, maxstr1, maxstr2, func);
|
||||
} else {
|
||||
SCRIPT_SKIP_SPACES
|
||||
if (gs_ctype!='g') {
|
||||
if (*lp!=')') {
|
||||
if (gs_ctype != 'g') {
|
||||
if (*lp != ')') {
|
||||
float max1;
|
||||
lp = GetNumericArgument(lp, OPER_EQU, &max1, 0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
|
@ -9162,12 +9490,12 @@ exgc:
|
|||
char maxstr2[16];
|
||||
dtostrfd(max2, 3, maxstr2);
|
||||
//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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gs_ctype=='g') {
|
||||
if (gs_ctype == 'g') {
|
||||
float yellowFrom;
|
||||
lp = GetNumericArgument(lp, OPER_EQU, &yellowFrom, 0);
|
||||
SCRIPT_SKIP_SPACES
|
||||
|
@ -9190,7 +9518,9 @@ exgc:
|
|||
WSContentSend_PD(PSTR("%s"), lin);
|
||||
}
|
||||
#else
|
||||
lin++;
|
||||
if (!(specopt&WSO_FORCEMAIN)) {
|
||||
lin++;
|
||||
}
|
||||
WSContentSend_PD(PSTR("%s"), lin);
|
||||
} else {
|
||||
// WSContentSend_PD(PSTR("%s"),lin);
|
||||
|
@ -10060,6 +10390,15 @@ void script_add_subpage(uint8_t num) {
|
|||
case 4:
|
||||
wptr = ScriptFullWebpage4;
|
||||
break;
|
||||
case 5:
|
||||
wptr = ScriptFullWebpage5;
|
||||
break;
|
||||
case 6:
|
||||
wptr = ScriptFullWebpage6;
|
||||
break;
|
||||
case 7:
|
||||
wptr = ScriptFullWebpage7;
|
||||
break;
|
||||
}
|
||||
sprintf_P(id, PSTR("/sfd%1d"), num);
|
||||
Webserver->on(id, wptr);
|
||||
|
@ -10293,8 +10632,8 @@ bool Xdrv10(uint8_t function)
|
|||
#ifdef USE_SCRIPT_WEB_DISPLAY
|
||||
case FUNC_WEB_ADD_MAIN_BUTTON:
|
||||
if (bitRead(Settings->rule_enabled, 0)) {
|
||||
if (glob_script_mem.web_pages[6]) {
|
||||
ScriptWebShow('z', 6);
|
||||
if (glob_script_mem.web_pages[WEB_PAGE_WM]) {
|
||||
ScriptWebShow('z', WEB_PAGE_WM);
|
||||
} else {
|
||||
ScriptWebShow('$', 0);
|
||||
}
|
||||
|
@ -10303,6 +10642,9 @@ bool Xdrv10(uint8_t function)
|
|||
script_add_subpage(2);
|
||||
script_add_subpage(3);
|
||||
script_add_subpage(4);
|
||||
script_add_subpage(5);
|
||||
script_add_subpage(6);
|
||||
script_add_subpage(7);
|
||||
#endif // SCRIPT_FULL_WEBPAGE
|
||||
|
||||
}
|
||||
|
@ -10338,8 +10680,8 @@ bool Xdrv10(uint8_t function)
|
|||
#ifdef USE_SCRIPT_WEB_DISPLAY
|
||||
case FUNC_WEB_SENSOR:
|
||||
if (bitRead(Settings->rule_enabled, 0)) {
|
||||
if (glob_script_mem.web_pages[5]) {
|
||||
ScriptWebShow(0, 5);
|
||||
if (glob_script_mem.web_pages[WEB_PAGE_WS]) {
|
||||
ScriptWebShow(0, WEB_PAGE_WS);
|
||||
} else {
|
||||
ScriptWebShow(0, 0);
|
||||
}
|
||||
|
|
|
@ -2171,7 +2171,7 @@ void SML_Decode(uint8_t index) {
|
|||
}
|
||||
uint16_t pos = smltbuf[mindex][2]+3;
|
||||
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 (highByte(crc)!=smltbuf[mindex][pos+1]) goto nextsect;
|
||||
dval=mbus_dval;
|
||||
|
@ -3279,7 +3279,7 @@ void SML_Send_Seq(uint32_t meter,char *seq) {
|
|||
slen += 2;
|
||||
}
|
||||
// append crc
|
||||
uint16_t crc = MBUS_calculateCRC(sbuff, slen);
|
||||
uint16_t crc = MBUS_calculateCRC(sbuff, slen, 0xFFFF);
|
||||
*ucp++ = lowByte(crc);
|
||||
*ucp++ = highByte(crc);
|
||||
slen += 2;
|
||||
|
@ -3313,9 +3313,10 @@ void SML_Send_Seq(uint32_t meter,char *seq) {
|
|||
}
|
||||
#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;
|
||||
crc = 0xFFFF;
|
||||
//crc = 0xFFFF;
|
||||
crc = start;
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
crc ^= frame[i];
|
||||
for (uint32_t j = 8; j; j--) {
|
||||
|
|
Loading…
Reference in New Issue