added @vars in flash

pull/16/head
Martin Ger 2017-08-23 20:57:38 +02:00
rodzic 671a543ce3
commit 12c937c9d4
6 zmienionych plików z 142 dodań i 37 usunięć

Wyświetl plik

@ -101,6 +101,11 @@ do
% Device number
setvar $device_number = 1
% @<num> vars are stored in flash and are persistent even after reboot
setvar $run = @1 + 1
setvar @1 = $run
println "This is boot no "|$run
% Status of the relay
setvar $relay_status=0
gpio_out 12 $relay_status
@ -200,13 +205,13 @@ do
publish local $command_topic "off"
```
Currently the interpreter is configured for a maximum of 10 variables, with a significant id length of 15. Some (additional) vars contain special status: $this_topic and $this_data are only defined in 'on topic' clauses and contain the current topic and its data. $this_gpio contains the state of the GPIO in an 'on gpio_interrupt' clause and $timestamp contains the current time of day in 'hh:mm:ss' format.
Currently the interpreter is configured for a maximum of 10 variables, with a significant id length of 15. Some (additional) vars contain special status: $this_topic and $this_data are only defined in 'on topic' clauses and contain the current topic and its data. $this_gpio contains the state of the GPIO in an 'on gpio_interrupt' clause and $timestamp contains the current time of day in 'hh:mm:ss' format.
In general, scripts have the following BNF:
```
<statement> ::= on <event> do <action> |
config <param> <value> |
config <param> (<value> | @<num>) |
<statement> <statement>
<event> ::= init |
@ -220,7 +225,7 @@ In general, scripts have the following BNF:
subscribe (local|remote) <topic-id> |
unsubscribe (local|remote) <topic-id> |
settimer <num> <expr> |
setvar $[any ASCII]* = <expr> |
setvar ($[any ASCII]* | @<NUM>) = <expr> |
gpio_pinmode <num> [pullup]
gpio_out <num> <expr> |
if <expr> then <action> [else <action>] endif |
@ -233,7 +238,7 @@ In general, scripts have the following BNF:
<op> := '=' | '>' | gte | str_ge | str_gte | '+' | '-' | '*' | '|' | div
<val> := <string> | <const> | #<hex-string> | $[any ASCII]* | gpio_in(<num>) |
$this_item | $this_data | $this_gpio | $timestamp
@<num> | $this_item | $this_data | $this_gpio | $timestamp
<string> := "[any ASCII]*" | [any ASCII]*

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -766,22 +766,36 @@ int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) {
else if (is_token(next_token, "setvar")) {
len_check(3);
if (syn_chk && (my_token[next_token + 1][0] != '$' || my_token[next_token + 1][1] == '\0'))
return syntax_error(next_token, "invalid var identifier");
bool flash_var = false;
uint32_t slot_no;
var_entry_t *this_var, *free_var;
uint8_t *var_id = my_token[next_token + 1];
this_var = find_var(&(my_token[next_token + 1][1]), &free_var);
if (this_var == NULL) {
if (free_var == NULL)
return syntax_error(next_token, "too many vars used");
if (var_id[0] == '@') {
slot_no = atoi(&var_id[1]);
if (syn_chk && (slot_no == 0 || slot_no > MAX_FLASH_SLOTS))
return syntax_error(next_token + 1, "invalid flash var number");
flash_var = true;
}
this_var = free_var;
this_var->free = 0;
os_strncpy(this_var->name, &(my_token[next_token + 1][1]), 14);
this_var->name[14] = '\0';
this_var->data = (uint8_t *)os_malloc(DEFAULT_VAR_LEN);
this_var->buffer_len = DEFAULT_VAR_LEN;
else if (var_id[0] == '$') {
if (syn_chk && var_id[1] == '\0')
return syntax_error(next_token, "invalid var identifier");
this_var = find_var(&var_id[1], &free_var);
if (this_var == NULL) {
if (free_var == NULL)
return syntax_error(next_token, "too many vars used");
this_var = free_var;
this_var->free = 0;
os_strncpy(this_var->name, &var_id[1], 14);
this_var->name[14] = '\0';
this_var->data = (uint8_t *)os_malloc(DEFAULT_VAR_LEN);
this_var->buffer_len = DEFAULT_VAR_LEN;
}
} else {
return syntax_error(next_token, "invalid var identifier");
}
if (syn_chk && os_strcmp(my_token[next_token + 2], "=") != 0)
@ -795,26 +809,40 @@ int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) {
if (doit) {
if (var_type == STRING_T) {
lang_log("setvar %s = %s\r\n", this_var->name, var_data);
lang_log("setvar %s = %s\r\n", var_id, var_data);
} else {
lang_log("setvar %s = binary (%d bytes)\r\n", this_var->name, var_len);
lang_log("setvar %s = binary (%d bytes)\r\n", var_id, var_len);
}
lang_debug("setvar $%s\r\n", this_var->name);
if (var_len > this_var->buffer_len - 1) {
os_free(this_var->data);
this_var->data = (uint8_t *)os_malloc(var_len+1);
this_var->buffer_len = var_len+1;
if (this_var->data == NULL) {
os_printf("Out of mem for var $%s\r\n", this_var->name);
this_var->data = (uint8_t *)os_malloc(DEFAULT_VAR_LEN);
this_var->buffer_len = DEFAULT_VAR_LEN;
return next_token;
lang_debug("setvar $%s\r\n", var_id);
if (flash_var) {
if (var_len > FLASH_SLOT_LEN)
var_len = FLASH_SLOT_LEN;
slot_no--;
uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN];
blob_load(1, slots, sizeof(slots));
os_memcpy(&slots[slot_no*FLASH_SLOT_LEN], var_data, var_len);
slots[slot_no*FLASH_SLOT_LEN+FLASH_SLOT_LEN-1] = '\0';
blob_save(1, slots, sizeof(slots));
} else {
if (var_len > this_var->buffer_len - 1) {
os_free(this_var->data);
this_var->data = (uint8_t *)os_malloc(var_len+1);
this_var->buffer_len = var_len+1;
if (this_var->data == NULL) {
os_printf("Out of mem for var $%s\r\n", this_var->name);
this_var->data = (uint8_t *)os_malloc(DEFAULT_VAR_LEN);
this_var->buffer_len = DEFAULT_VAR_LEN;
return next_token;
}
}
os_memcpy(this_var->data, var_data, var_len);
this_var->data[var_len] = '\0';
this_var->data_len = var_len;
this_var->data_type = var_type;
}
os_memcpy(this_var->data, var_data, var_len);
this_var->data[var_len] = '\0';
this_var->data_len = var_len;
this_var->data_type = var_type;
}
}
#ifdef GPIO
@ -864,6 +892,10 @@ int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) {
}
}
#endif
else if (is_token(next_token, "write_flash")) {
}
else
return syntax_error(next_token, "action command expected");
@ -912,7 +944,7 @@ int ICACHE_FLASH_ATTR parse_expression(int next_token, char **data, int *data_le
*data = "0";
*data_len = 1;
*data_type = STRING_T;
if (easygpio_inputGet(gpio_no)) {
if (doit && easygpio_inputGet(gpio_no)) {
*data = "1";
}
}
@ -1116,6 +1148,26 @@ int ICACHE_FLASH_ATTR parse_value(int next_token, char **data, int *data_len, Va
return next_token + 1;
}
else if (my_token[next_token][0] == '@' && my_token[next_token][1] != '\0') {
lang_debug("val flashvar %s\r\n", my_token[next_token]);
uint32_t slot_no = atoi(&my_token[next_token][1]);
if (slot_no == 0 || slot_no > MAX_FLASH_SLOTS)
return syntax_error(next_token+2, "invalid flash slot number");
*data = "0";
*data_len = 1;
*data_type = STRING_T;
slot_no--;
uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN];
blob_load(1, slots, sizeof(slots));
os_memcpy(tmp_buffer, &slots[slot_no*FLASH_SLOT_LEN], FLASH_SLOT_LEN);
*data = tmp_buffer;
*data_len = os_strlen(tmp_buffer);
return next_token + 1;
}
else {
lang_debug("val num/str(%s)\r\n", my_token[next_token]);
@ -1151,9 +1203,26 @@ int ICACHE_FLASH_ATTR interpreter_config() {
while ((next_token = search_token(next_token, "config")) < max_token) {
lang_debug("statement config\r\n");
uint8_t *val;
len_check(2);
do_command("set", my_token[next_token + 1], my_token[next_token + 2]);
if (my_token[next_token + 2][0] == '@') {
uint32_t slot_no = atoi(&my_token[next_token + 2][1]);
if (slot_no == 0 || slot_no > MAX_FLASH_SLOTS)
return syntax_error(next_token + 1, "invalid flash slot number");
slot_no--;
uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN];
blob_load(1, slots, sizeof(slots));
val = &slots[slot_no*FLASH_SLOT_LEN];
if (val[0] == '\0')
val = "_undefined_";
} else {
val = my_token[next_token + 2];
}
do_command("set", my_token[next_token + 1], val);
next_token += 3;
}
return next_token;

Wyświetl plik

@ -37,6 +37,8 @@
#define MAX_VARS 10
#define DEFAULT_VAR_LEN 16
#define MAX_TIMESTAMPS 6
#define MAX_FLASH_SLOTS 8
#define FLASH_SLOT_LEN 64
//
// Define this if you want to have GPIO OUT support in scripts.

Wyświetl plik

@ -120,8 +120,19 @@ static void ICACHE_FLASH_ATTR mqttDataCb(uint32_t * args, const char *topic,
#ifdef SCRIPTED
MQTT_Client *client = (MQTT_Client *) args;
pub_insert(topic, topic_len, data, data_len, false);
system_os_post(user_procTaskPrio, SIG_TOPIC_RECEIVED, 0);
char *topic_copy = (char*)os_malloc(topic_len+1);
if (topic_copy == NULL)
return;
os_memcpy(topic_copy, topic, topic_len);
topic_copy[topic_len] = '\0';
interpreter_topic_received(topic_copy, data, data_len, false);
os_free(topic_copy);
// Any local topics to process as result?
pub_process();
#endif
}
#endif /* MQTT_CLIENT */
@ -147,6 +158,7 @@ static void ICACHE_FLASH_ATTR script_discon_cb(void *arg) {
*(uint32_t *) load_script = load_size + 5;
blob_save(0, (uint32_t *) load_script, load_size + 5);
os_free(load_script);
blob_zero(1, MAX_FLASH_SLOTS * FLASH_SLOT_LEN);
os_sprintf(response, "\rScript upload completed (%d Bytes)\r\n", load_size);
to_console(response);
@ -634,6 +646,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
#ifdef SCRIPTED
// clear script
blob_zero(0, MAX_SCRIPT_SIZE);
blob_zero(1, MAX_FLASH_SLOTS * FLASH_SLOT_LEN);
#endif
}
os_printf("Restarting ... \r\n");
@ -672,6 +685,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
if (my_script != NULL)
free_script();
blob_zero(0, MAX_SCRIPT_SIZE);
blob_zero(1, MAX_FLASH_SLOTS * FLASH_SLOT_LEN);
os_sprintf(response, "Script deleted\r\n");
goto command_handled;
}
@ -969,6 +983,21 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
os_sprintf(response, "Script logging set\r\n");
goto command_handled;
}
if (tokens[1][0] == '@') {
uint32_t slot_no = atoi(&tokens[1][1]);
if (slot_no == 0 || slot_no > MAX_FLASH_SLOTS) {
os_sprintf(response, "Invalid flash slot number");
} else {
slot_no--;
uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN];
blob_load(1, (uint32_t *)slots, sizeof(slots));
os_strcpy(&slots[slot_no*FLASH_SLOT_LEN], tokens[2]);
blob_save(1, (uint32_t *)slots, sizeof(slots));
os_sprintf(response, "%s written to flash", tokens[1]);
}
goto command_handled;
}
#endif
#ifdef NTP
if (strcmp(tokens[1], "ntp_server") == 0) {