Move Scripter to JSMN

This commit is contained in:
Stephan Hadinger 2020-09-25 08:52:28 +02:00
parent 3e1f61462d
commit f0f4433941
1 changed files with 66 additions and 52 deletions

View File

@ -470,8 +470,8 @@ void f2char(float num, uint32_t dprec, uint32_t lzeros, char *nbuff) {
int8_t script_button[MAX_KEYS]; int8_t script_button[MAX_KEYS];
#endif //USE_BUTTON_EVENT #endif //USE_BUTTON_EVENT
char *GetNumericArgument(char *lp,uint8_t lastop,float *fp,JsonObject *jo); char *GetNumericArgument(char *lp,uint8_t lastop,float *fp, JsonParserObject *jo);
char *GetStringArgument(char *lp,uint8_t lastop,char *cp,JsonObject *jo); char *GetStringArgument(char *lp,uint8_t lastop,char *cp, JsonParserObject *jo);
char *ForceStringVar(char *lp,char *dstr); char *ForceStringVar(char *lp,char *dstr);
void send_download(void); void send_download(void);
uint8_t reject(char *name); uint8_t reject(char *name);
@ -1155,7 +1155,7 @@ float *Get_MFAddr(uint8_t index, uint16_t *len, uint16_t *ipos) {
return 0; return 0;
} }
char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, JsonObject *jo); char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, JsonParserObject *jo);
float *get_array_by_name(char *name, uint16_t *alen) { float *get_array_by_name(char *name, uint16_t *alen) {
@ -1515,7 +1515,7 @@ float fvar;
// vtype => ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number // vtype => ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number
// no flash strings here for performance reasons!!! // no flash strings here for performance reasons!!!
char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, JsonObject *jo) { char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, JsonParserObject *jo) {
uint16_t count,len = 0; uint16_t count,len = 0;
uint8_t nres = 0; uint8_t nres = 0;
char vname[32]; char vname[32];
@ -1664,7 +1664,7 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp,
if (aindex<1 || aindex>6) aindex = 1; if (aindex<1 || aindex>6) aindex = 1;
aindex--; aindex--;
} }
if (jo->success()) { if (jo->isValid()) {
char *subtype = strchr(jvname, '#'); char *subtype = strchr(jvname, '#');
char *subtype2; char *subtype2;
if (subtype) { if (subtype) {
@ -1677,23 +1677,23 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp,
} }
} }
vn = jvname; vn = jvname;
str_value = (*jo)[vn]; str_value = (*jo)[vn].getStr();
if ((*jo)[vn].success()) { if ((*jo)[vn].isValid()) {
if (subtype) { if (subtype) {
JsonObject &jobj1 = (*jo)[vn]; JsonParserObject jobj1 = (*jo)[vn];
if (jobj1.success()) { if (jobj1.isValid()) {
vn = subtype; vn = subtype;
jo = &jobj1; jo = &jobj1;
str_value = (*jo)[vn]; str_value = (*jo)[vn].getStr();
if ((*jo)[vn].success()) { if ((*jo)[vn].isValid()) {
// 2. stage // 2. stage
if (subtype2) { if (subtype2) {
JsonObject &jobj2 = (*jo)[vn]; JsonParserObject jobj2 = (*jo)[vn];
if ((*jo)[vn].success()) { if ((*jo)[vn].isValid()) {
vn = subtype2; vn = subtype2;
jo = &jobj2; jo = &jobj2;
str_value = (*jo)[vn]; str_value = (*jo)[vn].getStr();
if ((*jo)[vn].success()) { if ((*jo)[vn].isValid()) {
goto skip; goto skip;
} else { } else {
goto chknext; goto chknext;
@ -1712,10 +1712,10 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp,
skip: skip:
if (ja) { if (ja) {
// json array // json array
str_value = (*jo)[vn][aindex]; str_value = (*jo)[vn].getArray()[aindex].getStr();
} }
if (str_value && *str_value) { if (str_value && *str_value) {
if ((*jo).is<char*>(vn)) { if ((*jo)[vn].isStr()) {
if (!strncmp(str_value, "ON", 2)) { if (!strncmp(str_value, "ON", 2)) {
if (fp) *fp = 1; if (fp) *fp = 1;
goto nexit; goto nexit;
@ -3281,7 +3281,7 @@ uint16_t GetStack(void) {
} }
#endif //ESP8266 #endif //ESP8266
char *GetStringArgument(char *lp, uint8_t lastop, char *cp, JsonObject *jo) { char *GetStringArgument(char *lp, uint8_t lastop, char *cp, JsonParserObject *jo) {
uint8_t operand = 0; uint8_t operand = 0;
uint8_t vtype; uint8_t vtype;
char *slp; char *slp;
@ -3327,7 +3327,7 @@ char *GetStringArgument(char *lp, uint8_t lastop, char *cp, JsonObject *jo) {
return lp; return lp;
} }
char *GetNumericArgument(char *lp, uint8_t lastop, float *fp, JsonObject *jo) { char *GetNumericArgument(char *lp, uint8_t lastop, float *fp, JsonParserObject *jo) {
uint8_t operand = 0; uint8_t operand = 0;
float fvar1,fvar; float fvar1,fvar;
char *slp; char *slp;
@ -3552,7 +3552,7 @@ void toSLog(const char *str) {
#endif #endif
} }
char *Evaluate_expression(char *lp, uint8_t and_or, uint8_t *result,JsonObject *jo) { char *Evaluate_expression(char *lp, uint8_t and_or, uint8_t *result, JsonParserObject *jo) {
float fvar,*dfvar,fvar1; float fvar,*dfvar,fvar1;
uint8_t numeric; uint8_t numeric;
struct T_INDEX ind; struct T_INDEX ind;
@ -3715,19 +3715,17 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
if (tasm_cmd_activ && tlen>0) return 0; if (tasm_cmd_activ && tlen>0) return 0;
JsonObject *jo = 0; JsonParserObject jo;
DynamicJsonBuffer jsonBuffer; // on heap
JsonObject &jobj = jsonBuffer.parseObject(js);
if (js) { if (js) {
jo = &jobj; String jss = js; // copy the string to a new buffer, not sure we can change the original buffer
} else { JsonParser parser((char*)jss.c_str());
jo = 0; jo = parser.getRootObject();
} }
return Run_script_sub(type, tlen, jo); return Run_script_sub(type, tlen, &jo);
} }
int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) { int16_t Run_script_sub(const char *type, int8_t tlen, JsonParserObject *jo) {
uint8_t vtype=0,sindex,xflg,floop=0,globvindex,fromscriptcmd=0; uint8_t vtype=0,sindex,xflg,floop=0,globvindex,fromscriptcmd=0;
char *lp_next; char *lp_next;
int16_t globaindex,saindex; int16_t globaindex,saindex;
@ -5527,15 +5525,16 @@ void Script_Handle_Hue(String *path) {
if (Webserver->args()) { if (Webserver->args()) {
response = "["; response = "[";
StaticJsonBuffer<400> jsonBuffer; JsonParser parser((char*) Webserver->arg((Webserver->args())-1).c_str());
JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args()) - 1)); JsonParserObject root = parser.getRootObject();
if (hue_json.containsKey("on")) { JsonParserToken hue_on = root[PSTR("on")];
if (hue_on) {
response += FPSTR(sHUE_LIGHT_RESPONSE_JSON); response += FPSTR(sHUE_LIGHT_RESPONSE_JSON);
response.replace("{id", String(EncodeLightId(device))); response.replace("{id", String(EncodeLightId(device)));
response.replace("{cm", "on"); response.replace("{cm", "on");
bool on = hue_json["on"]; bool on = hue_on.getBool();
if (on==false) { if (on==false) {
glob_script_mem.fvars[hue_script[index].index[0] - 1] = 0; glob_script_mem.fvars[hue_script[index].index[0] - 1] = 0;
response.replace("{re", "false"); response.replace("{re", "false");
@ -5546,8 +5545,11 @@ void Script_Handle_Hue(String *path) {
glob_script_mem.type[hue_script[index].vindex[0]].bits.changed = 1; glob_script_mem.type[hue_script[index].vindex[0]].bits.changed = 1;
resp = true; resp = true;
} }
if (hue_json.containsKey("bri")) { // Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off.
tmp = hue_json["bri"]; parser.setCurrent();
JsonParserToken hue_bri = root[PSTR("bri")];
if (hue_bri) { // Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off.
tmp = hue_bri.getUInt();
bri = tmp; bri = tmp;
if (254 <= bri) { bri = 255; } if (254 <= bri) { bri = 255; }
if (resp) { response += ","; } if (resp) { response += ","; }
@ -5559,12 +5561,17 @@ void Script_Handle_Hue(String *path) {
glob_script_mem.type[hue_script[index].vindex[1]].bits.changed = 1; glob_script_mem.type[hue_script[index].vindex[1]].bits.changed = 1;
resp = true; resp = true;
} }
if (hue_json.containsKey("xy")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
JsonParserToken hue_xy = root[PSTR("xy")];
if (hue_xy) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
float x, y; float x, y;
x = hue_json["xy"][0]; JsonParserArray arr_xy = JsonParserArray(hue_xy);
y = hue_json["xy"][1]; JsonParserToken tok_x = arr_xy[0];
const String &x_str = hue_json["xy"][0]; JsonParserToken tok_y = arr_xy[1];
const String &y_str = hue_json["xy"][1]; x = tok_x.getFloat();
y = tok_y.getFloat();
const char * x_str = tok_x.getStr();
const char * y_str = tok_y.getStr();
uint8_t rr,gg,bb; uint8_t rr,gg,bb;
LightStateClass::XyToRgb(x, y, &rr, &gg, &bb); LightStateClass::XyToRgb(x, y, &rr, &gg, &bb);
LightStateClass::RgbToHsb(rr, gg, bb, &hue, &sat, nullptr); LightStateClass::RgbToHsb(rr, gg, bb, &hue, &sat, nullptr);
@ -5580,8 +5587,9 @@ void Script_Handle_Hue(String *path) {
resp = true; resp = true;
} }
if (hue_json.containsKey("hue")) { // The hue value is a wrapping value between 0 and 65535. Both 0 and 65535 are red, 25500 is green and 46920 is blue. JsonParserToken hue_hue = root[PSTR("hue")];
tmp = hue_json["hue"]; if (hue_hue) { // The hue value is a wrapping value between 0 and 65535. Both 0 and 65535 are red, 25500 is green and 46920 is blue.
tmp = hue_hue.getUInt();
//hue = changeUIntScale(tmp, 0, 65535, 0, 359); //hue = changeUIntScale(tmp, 0, 65535, 0, 359);
//tmp = changeUIntScale(hue, 0, 359, 0, 65535); //tmp = changeUIntScale(hue, 0, 359, 0, 65535);
hue = tmp; hue = tmp;
@ -5594,8 +5602,10 @@ void Script_Handle_Hue(String *path) {
glob_script_mem.type[hue_script[index].vindex[2]].bits.changed = 1; glob_script_mem.type[hue_script[index].vindex[2]].bits.changed = 1;
resp = true; resp = true;
} }
if (hue_json.containsKey("sat")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
tmp = hue_json["sat"]; JsonParserToken hue_sat = root[PSTR("sat")];
if (hue_sat) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
tmp = hue_sat.getUInt();
sat = tmp; sat = tmp;
if (254 <= sat) { sat = 255; } if (254 <= sat) { sat = 255; }
if (resp) { response += ","; } if (resp) { response += ","; }
@ -5607,8 +5617,10 @@ void Script_Handle_Hue(String *path) {
glob_script_mem.type[hue_script[index].vindex[3]].bits.changed = 1; glob_script_mem.type[hue_script[index].vindex[3]].bits.changed = 1;
resp = true; resp = true;
} }
if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm)
ct = hue_json["ct"]; JsonParserToken hue_ct = root[PSTR("ct")];
if (hue_ct) { // Color temperature 153 (Cold) to 500 (Warm)
ct = hue_ct.getUInt();
if (resp) { response += ","; } if (resp) { response += ","; }
response += FPSTR(sHUE_LIGHT_RESPONSE_JSON); response += FPSTR(sHUE_LIGHT_RESPONSE_JSON);
response.replace("{id", String(EncodeLightId(device))); response.replace("{id", String(EncodeLightId(device)));
@ -5826,21 +5838,23 @@ bool ScriptMqttData(void)
if (event_item.Key.length() == 0) { //If did not specify Key if (event_item.Key.length() == 0) { //If did not specify Key
value = sData; value = sData;
} else { //If specified Key, need to parse Key/Value from JSON data } else { //If specified Key, need to parse Key/Value from JSON data
StaticJsonBuffer<MQTT_EVENT_JSIZE> jsonBuf; JsonParser parser((char*)sData.c_str());
JsonObject& jsonData = jsonBuf.parseObject(sData); JsonParserObject jsonData = parser.getRootObject();
String key1 = event_item.Key; String key1 = event_item.Key;
String key2; String key2;
if (!jsonData.success()) break; //Failed to parse JSON data, ignore this message. if (!jsonData) break; //Failed to parse JSON data, ignore this message.
int dot; int dot;
if ((dot = key1.indexOf('.')) > 0) { if ((dot = key1.indexOf('.')) > 0) {
key2 = key1.substring(dot+1); key2 = key1.substring(dot+1);
key1 = key1.substring(0, dot); key1 = key1.substring(0, dot);
lkey = key2; lkey = key2;
if (!jsonData[key1][key2].success()) break; //Failed to get the key/value, ignore this message. JsonParserToken val = jsonData[key1.c_str()].getObject()[key2.c_str()];
value = (const char *)jsonData[key1][key2]; if (!val) break; //Failed to get the key/value, ignore this message.
value = val.getStr();
} else { } else {
if (!jsonData[key1].success()) break; JsonParserToken val = jsonData[key1.c_str()];
value = (const char *)jsonData[key1]; if (!val) break;
value = val.getStr();
lkey = key1; lkey = key1;
} }
} }