diff --git a/SCRIPTING.md b/SCRIPTING.md index 89e5c40..7fb3b8e 100644 --- a/SCRIPTING.md +++ b/SCRIPTING.md @@ -58,6 +58,7 @@ In general, scripts conform to the following BNF: ::= | | () | not () | retained_topic() | substr(,,) | + binary () | byte_val(,) | csvstr(,,) | eatwhite () | json_parse (,) @@ -219,6 +220,16 @@ retained_topic() ``` Interpretes the argument as topic name (incl. wildcards) and searches the first local retained topic that matches this name. The stored value of this topic is returned (empty, if nothing found). Can be used to check the status of the system synchronously without the need to subscribe for that retained topic, wait for status changes and store them in a variable. +``` +binary() +``` +Converts the numerical value of the given expression into a single character string, e.g. binary(65) is "A". + +``` +byte_val(,) +``` +Converts the byte at the given position of a string (first is postion 0) into a numerical value, e.g. byte_val("ABC", 0) is "65". + ``` substr(,,) ``` @@ -227,7 +238,7 @@ Extracts characters from a string. The two constant numbers give the starting po ``` csvstr(,,) ``` -Extracts strings from a CSV-list (correctly a string with a delimiter character). The constant number gives the position (first is postion 1) and the char is the delimiter. Examples: csvstr("one,two,three", 2, ",") is "two", csvstr("system/test/1", 2, "/") is "test". +Extracts strings from a CSV-list (correctly a string with a delimiter character). The constant number gives the position (first is postion 0) and the char is the delimiter. Examples: csvstr("one,two,three", 1, ",") is "two", csvstr("system/test/1", 0, "/") is "system". ``` eatwhite() @@ -269,11 +280,12 @@ gpio_in() Reads the current boolean input value of the given GPIO pin. This pin has to be defined as input before using the "gpio_pinmode" action. ``` -$adc | $this_item | $this_data | $this_gpio | $timestamp | $weekday | $this_http_body | $this_http_code +$adc | $this_item | $this_data | $this_serial | $this_gpio | $timestamp | $weekday | $this_http_body | $this_http_code ``` Special variables: - $adc gives you the current value of the ADC (analog to digital input pin) - $this_topic and $this_data are only defined in "on topic" clauses and contain the current topic and its data. +- $this_serial contains the serial input string in an "on serial" clause. - $this_gpio contains the state of the GPIO in an "on gpio_interrupt" clause. - $timestamp contains the current time of day in "hh:mm:ss" format. If no NTP sync happened the time will be reported as "99:99:99". $weekday returns the day of week as three letters ("Mon","Tue",...). - $this_http_body and $this_http_code are only defined inside the "on http_response" clause and contain the body of an HTTP response and the HTTP return code. diff --git a/firmware/0x00000.bin b/firmware/0x00000.bin index d427239..3bdee57 100644 Binary files a/firmware/0x00000.bin and b/firmware/0x00000.bin differ diff --git a/firmware/0x10000.bin b/firmware/0x10000.bin index 84aa6f0..ad9862b 100644 Binary files a/firmware/0x10000.bin and b/firmware/0x10000.bin differ diff --git a/firmware/sha1sums b/firmware/sha1sums index 42cccb8..91ec1c0 100644 --- a/firmware/sha1sums +++ b/firmware/sha1sums @@ -1,2 +1,2 @@ -f8fcbc261888a7fe6c4d2db2e9b9ce2b13de7a29 0x00000.bin -476c9ae67db3a4117c410d9b664315f83590c9d8 0x10000.bin +d8ba3e38c5c27e69d64f23cc408bceb7adeec416 0x00000.bin +94d406c685a6f15b4f2ff42c93c9ec5297d43425 0x10000.bin diff --git a/user/lang.c b/user/lang.c index 20aebf4..3711784 100644 --- a/user/lang.c +++ b/user/lang.c @@ -1277,8 +1277,6 @@ int ICACHE_FLASH_ATTR parse_expression(int next_token, char **data, int *data_le next_token++; int16_t num = atoi(my_token[next_token]); - if (num == 0) - return syntax_error(next_token, "value > 0 expected"); next_token++; if (syn_chk && !is_token(next_token, ",")) @@ -1327,6 +1325,71 @@ int ICACHE_FLASH_ATTR parse_expression(int next_token, char **data, int *data_le *data_type = STRING_T; } } + + else if (is_token(next_token, "byte_val")) { + lang_debug("val byte_val\r\n"); + + len_check(5); + if (syn_chk && !is_token(next_token+1, "(")) + return syntax_error(next_token+1, "expected '('"); + + char *str_data; + int str_data_len; + Value_Type str_data_type; + // parse path string + if ((next_token = parse_expression(next_token + 2, &str_data, &str_data_len, &str_data_type, doit)) == -1) + return -1; + + if (syn_chk && !is_token(next_token, ",")) + return syntax_error(next_token, "expected ','"); + next_token++; + + int16_t num = atoi(my_token[next_token]); + next_token++; + + if (syn_chk && !is_token(next_token, ")")) + return syntax_error(next_token, "expected ')'"); + next_token++; + + if (doit) { + if (num >= str_data_len) { + *data_len = 0; + *data = ""; + } else { + os_sprintf(tmp_buffer, "%d", str_data[num]); + *data_len = os_strlen(tmp_buffer); + *data = tmp_buffer; + } + *data_type = STRING_T; + } + } + + else if (is_token(next_token, "binary")) { + lang_debug("val binary\r\n"); + + len_check(3); + if (syn_chk && !is_token(next_token+1, "(")) + return syntax_error(next_token+1, "expected '('"); + + char *str_data; + int str_data_len; + Value_Type str_data_type; + // parse path string + if ((next_token = parse_expression(next_token + 2, &str_data, &str_data_len, &str_data_type, doit)) == -1) + return -1; + + if (syn_chk && !is_token(next_token, ")")) + return syntax_error(next_token, "expected ')'"); + next_token++; + + if (doit) { + tmp_buffer[0] = atoi(str_data); + tmp_buffer[1] = '\0'; + *data = tmp_buffer; + *data_len = 1; + *data_type = DATA_T; + } + } #ifdef GPIO else if (is_token(next_token, "gpio_in")) { lang_debug("val gpio_in\r\n"); @@ -1436,6 +1499,15 @@ int ICACHE_FLASH_ATTR parse_expression(int next_token, char **data, int *data_le int r_data_len; Value_Type r_data_type; + if (!doit) { + *data_len = 0; + } + char l_data[*data_len+1]; + if (doit) { + os_memcpy(l_data, *data, *data_len); + } + l_data[*data_len] = '\0'; + // parse second operand if ((next_token = parse_expression(next_token + 1, &r_data, &r_data_len, &r_data_type, doit)) == -1) return -1; @@ -1446,45 +1518,53 @@ int ICACHE_FLASH_ATTR parse_expression(int next_token, char **data, int *data_le *data_type = STRING_T; if (is_token(op, "=")) { - *data = os_strcmp(*data, r_data) ? "0" : "1"; + *data = os_strcmp(l_data, r_data) ? "0" : "1"; } else if (is_token(op, "+")) { - os_sprintf(tmp_buffer, "%d", atoi(*data) + atoi(r_data)); + os_sprintf(tmp_buffer, "%d", atoi(l_data) + atoi(r_data)); *data = tmp_buffer; *data_len = os_strlen(tmp_buffer); } else if (is_token(op, "-")) { - os_sprintf(tmp_buffer, "%d", atoi(*data) - atoi(r_data)); + os_sprintf(tmp_buffer, "%d", atoi(l_data) - atoi(r_data)); *data = tmp_buffer; *data_len = os_strlen(tmp_buffer); } else if (is_token(op, "*")) { - os_sprintf(tmp_buffer, "%d", atoi(*data) * atoi(r_data)); + os_sprintf(tmp_buffer, "%d", atoi(l_data) * atoi(r_data)); *data = tmp_buffer; *data_len = os_strlen(tmp_buffer); } else if (is_token(op, "div")) { - os_sprintf(tmp_buffer, "%d", atoi(*data) / atoi(r_data)); + os_sprintf(tmp_buffer, "%d", atoi(l_data) / atoi(r_data)); *data = tmp_buffer; *data_len = os_strlen(tmp_buffer); } else if (is_token(op, "|")) { - uint16_t len = os_strlen(*data) + os_strlen(r_data); +/* + uint16_t len = os_strlen(l_data) + os_strlen(r_data); char catbuf[len+1]; - os_sprintf(catbuf, "%s%s", *data, r_data); + os_sprintf(catbuf, "%s%s", l_data, r_data); +*/ + uint16_t len = *data_len + r_data_len; + char catbuf[len+1]; + os_memcpy(catbuf, l_data, *data_len); + os_memcpy(&catbuf[*data_len], r_data, r_data_len); + if (len > sizeof(tmp_buffer)-1) { len = sizeof(tmp_buffer); - catbuf[len] = '\0'; } + catbuf[len] = '\0'; *data_len = len; os_memcpy(tmp_buffer, catbuf, *data_len + 1); *data = tmp_buffer; + } else if (is_token(op, ">")) { - *data = atoi(*data) > atoi(r_data) ? "1" : "0"; + *data = atoi(l_data) > atoi(r_data) ? "1" : "0"; *data_len = 1; } else if (is_token(op, "gte")) { - *data = atoi(*data) >= atoi(r_data) ? "1" : "0"; + *data = atoi(l_data) >= atoi(r_data) ? "1" : "0"; *data_len = 1; } else if (is_token(op, "str_gt")) { - *data = os_strcmp(*data, r_data) > 0 ? "1" : "0"; + *data = os_strcmp(l_data, r_data) > 0 ? "1" : "0"; *data_len = 1; } else if (is_token(op, "str_gte")) { - *data = os_strcmp(*data, r_data) >= 0 ? "1" : "0"; + *data = os_strcmp(l_data, r_data) >= 0 ? "1" : "0"; *data_len = 1; }