diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 922bd18d5..2e335e415 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -682,6 +682,11 @@ bool MqttShowSensor(void) } } XsnsCall(FUNC_JSON_APPEND); + +#ifdef USE_SCRIPT_JSON_EXPORT + XdrvCall(FUNC_JSON_APPEND); +#endif + bool json_data_available = (strlen(mqtt_data) - json_data_start); if (strstr_P(mqtt_data, PSTR(D_JSON_PRESSURE)) != nullptr) { ResponseAppend_P(PSTR(",\"" D_JSON_PRESSURE_UNIT "\":\"%s\""), PressureUnit().c_str()); diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index b7541910e..c50bef2da 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -1050,6 +1050,9 @@ bool HandleRootStatusRefresh(void) WSContentBegin(200, CT_HTML); WSContentSend_P(PSTR("{t}")); XsnsCall(FUNC_WEB_SENSOR); +#ifdef USE_SCRIPT_WEB_DISPLAY + XdrvCall(FUNC_WEB_SENSOR); +#endif WSContentSend_P(PSTR("")); if (devices_present) { diff --git a/sonoff/xdrv_10_scripter.ino b/sonoff/xdrv_10_scripter.ino index 696c7750f..ccf98a592 100644 --- a/sonoff/xdrv_10_scripter.ino +++ b/sonoff/xdrv_10_scripter.ino @@ -52,6 +52,9 @@ keywords if then else endif, or, and are better readable for beginners (others m #define SCRIPT_MAXPERM (MAX_RULE_MEMS*10)-4/sizeof(float) #define MAX_SCRIPT_SIZE MAX_RULE_SIZE*MAX_RULE_SETS +// offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution +#define EPOCH_OFFSET 1546300800 + enum {OPER_EQU=1,OPER_PLS,OPER_MIN,OPER_MUL,OPER_DIV,OPER_PLSEQU,OPER_MINEQU,OPER_MULEQU,OPER_DIVEQU,OPER_EQUEQU,OPER_NOTEQU,OPER_GRTEQU,OPER_LOWEQU,OPER_GRT,OPER_LOW,OPER_PERC,OPER_XOR,OPER_AND,OPER_OR,OPER_ANDEQU,OPER_OREQU,OPER_XOREQU,OPER_PERCEQU}; enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD}; @@ -78,10 +81,12 @@ enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD}; LinkedList subscriptions; #endif //SUPPORT_MQTT_EVENT +#ifdef USE_DISPLAY #ifdef USE_TOUCH_BUTTONS #include extern VButton *buttons[MAXBUTTONS]; #endif +#endif typedef union { uint8_t data; @@ -134,6 +139,7 @@ struct SCRIPT_MEM { uint8_t *vnp_offset; char *glob_snp; // string vars pointer char *scriptptr; + char *section_ptr; char *scriptptr_bu; char *script_ram; uint16_t script_size; @@ -1009,7 +1015,13 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso return lp+len; } } else { - if (fp) *fp=CharToFloat((char*)str_value); + if (fp) { + if (!strncmp(vn.c_str(),"Epoch",5)) { + *fp=atoi(str_value)-(uint32_t)EPOCH_OFFSET; + } else { + *fp=CharToFloat((char*)str_value); + } + } *vtype=NUM_RES; tind->bits.constant=1; tind->bits.is_string=0; @@ -1059,6 +1071,12 @@ chknext: goto exit; } break; + case 'e': + if (!strncmp(vname,"epoch",5)) { + fvar=UtcTime()-(uint32_t)EPOCH_OFFSET; + goto exit; + } + break; #ifdef USE_SCRIPT_FATFS case 'f': if (!strncmp(vname,"fo(",3)) { @@ -1634,6 +1652,7 @@ chknext: if (sp) strlcpy(sp,Settings.mqtt_topic,glob_script_mem.max_ssize); goto strexit; } +#ifdef USE_DISPLAY #ifdef USE_TOUCH_BUTTONS if (!strncmp(vname,"tbut[",5)) { GetNumericResult(vname+5,OPER_EQU,&fvar,0); @@ -1649,6 +1668,7 @@ chknext: goto exit; } +#endif #endif break; case 'u': @@ -2733,7 +2753,10 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { if (!strncmp(lp,type,tlen)) { // found section section=1; - if (check) return 99; + glob_script_mem.section_ptr=lp; + if (check) { + return 99; + } // check for subroutine if (*type=='#') { // check for parameter @@ -3387,6 +3410,7 @@ bool ScriptMqttData(void) //This topic is subscribed by us, so serve it serviced = true; String value; + String lkey; if (event_item.Key.length() == 0) { //If did not specify Key value = sData; } else { //If specified Key, need to parse Key/Value from JSON data @@ -3399,17 +3423,24 @@ bool ScriptMqttData(void) if ((dot = key1.indexOf('.')) > 0) { key2 = key1.substring(dot+1); key1 = key1.substring(0, dot); + lkey=key2; if (!jsonData[key1][key2].success()) break; //Failed to get the key/value, ignore this message. value = (const char *)jsonData[key1][key2]; } else { if (!jsonData[key1].success()) break; value = (const char *)jsonData[key1]; + lkey=key1; } } value.trim(); - char sbuffer[128]; - snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str()); + + if (!strncmp(lkey.c_str(),"Epoch",5)) { + uint32_t ep=atoi(value.c_str())-(uint32_t)EPOCH_OFFSET; + snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=%d\n"), event_item.Event.c_str(),ep); + } else { + snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str()); + } //toLog(sbuffer); execute_script(sbuffer); } @@ -3542,6 +3573,93 @@ String ScriptUnsubscribe(const char * data, int data_len) } #endif // SUPPORT_MQTT_EVENT +#ifdef USE_SCRIPT_WEB_DISPLAY +void ScriptWebShow(void) { + uint8_t web_script=Run_Scripter(">W",-2,0); + if (web_script==99) { + char line[128]; + char tmp[128]; + char *lp=glob_script_mem.section_ptr+2; + while (lp) { + while (*lp==SCRIPT_EOL) { + lp++; + } + if (!*lp || *lp=='#' || *lp=='>') { + break; + } + + // send this line to web + memcpy(line,lp,sizeof(line)); + line[sizeof(line)-1]=0; + char *cp=line; + for (uint32_t i=0; iJ",-2,0); + if (web_script==99) { + char line[128]; + char tmp[128]; + char *lp=glob_script_mem.section_ptr+2; + while (lp) { + while (*lp==SCRIPT_EOL) { + lp++; + } + if (!*lp || *lp=='#' || *lp=='>') { + break; + } + + // send this line to mqtt + memcpy(line,lp,sizeof(line)); + line[sizeof(line)-1]=0; + char *cp=line; + for (uint32_t i=0; i