kopia lustrzana https://github.com/martin-ger/esp_mqtt
mqttconnect added, mem issues
rodzic
fcfd1985e5
commit
8507c45823
|
@ -178,7 +178,7 @@ You can examine the currently loaded script using the "show script" command. It
|
|||
# NTP Support
|
||||
NTP time is supported and timestamps are only available if the sync with an NTP server is done. By default the NTP client is enabled and set to "1.pool.ntp.org". It can be changed by setting the config parameter "ntp_server" to a hostname or an IP address. An ntp_server of "none" will disable the NTP client. Also you can set the "ntp_timezone" to an offset from GMT in hours. The system time will be synced with the NTP server every "ntp_interval" seconds (default ). Here it uses NOT the full NTP calculation and clock drift compensation. Instead it will just set the local time to the latest received time.
|
||||
|
||||
After NTP sync has been completed successfully once, the local time will be published every second under the topic "$SYS/broker/time" in the format "hh:mm:ss". You can also query the NTP time using the "time" command from the commandline.
|
||||
After NTP sync has been completed successfully once, the local time will be published every second under the topic "$SYS/broker/time" in the format "hh:mm:ss". You can also query the NTP time using the "time" command from the commandline and with the variable "$timestamp" from a script. If no NTP sync happened the time will be reported as "99:99:99".
|
||||
|
||||
- set ntp_server _IP_or_hostname_: sets the name or IP of an NTP server (default "1.pool.ntp.org", "none" disables NTP)
|
||||
- set ntp_interval _interval_: sets the NTP sync interval in seconds (default 300)
|
||||
|
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
|
@ -1,19 +1,26 @@
|
|||
% Config params, overwrite any previous settings from the commandline
|
||||
config ap_ssid MyAP
|
||||
config ap_password stupidPassword
|
||||
config ntp_server 1.pool.ntp.org
|
||||
config mqtt_host 192.168.1.20
|
||||
config ntp_server 1.de.pool.ntp.org
|
||||
config mqtt_host martinshome.fritz.box
|
||||
|
||||
% Now the initialization, this is done once after booting
|
||||
on init
|
||||
do
|
||||
println "MQTT Script 1.0 starting"
|
||||
subscribe local /test/#
|
||||
settimer 1 1000 % once per second
|
||||
subscribe local $SYS/broker/time
|
||||
% settimer 1 1000 % once per second
|
||||
setvar $1=0
|
||||
setvar $2=0
|
||||
setvar $3=10
|
||||
|
||||
% This is done each time the ESP connects to another MQTT broker
|
||||
on mqttconnect
|
||||
do
|
||||
println "(Re-)connected to client"
|
||||
subscribe remote $SYS/broker/time
|
||||
|
||||
% Now the events, checked whenever something happens
|
||||
|
||||
% Here a remote republish, of any local topic starting with "/test/"
|
||||
|
@ -21,6 +28,14 @@ on topic local /test/#
|
|||
do
|
||||
publish remote $this_topic $this_data
|
||||
|
||||
on topic remote $SYS/broker/time
|
||||
do
|
||||
println "Remote time: "|$this_data
|
||||
|
||||
on topic local $SYS/broker/time
|
||||
do
|
||||
println "Local time: "|$this_data
|
||||
|
||||
% When timer 1 expires, do some stuff
|
||||
on timer 1
|
||||
do
|
||||
|
@ -36,7 +51,7 @@ do
|
|||
|
||||
% And if we have reached 10, print that to the console
|
||||
if $2 = $3 then
|
||||
println "We have reached "|$2| " at " |$timestamp
|
||||
println "We have reached *"|$2| "* at " |$timestamp
|
||||
setvar $3=$2+10
|
||||
endif
|
||||
|
||||
|
|
78
user/lang.c
78
user/lang.c
|
@ -11,6 +11,7 @@
|
|||
#define lang_debug //os_printf
|
||||
#define lang_info //os_printf
|
||||
|
||||
extern uint8_t *my_script;
|
||||
extern void do_command(char *t1, char *t2, char *t3);
|
||||
extern void con_print(uint8_t *str);
|
||||
|
||||
|
@ -115,7 +116,7 @@ int ICACHE_FLASH_ATTR text_into_tokens(char *str) {
|
|||
bool in_token = false;
|
||||
|
||||
// preprocessing
|
||||
lang_debug("lexxer preprocessing\r\n");
|
||||
lang_debug("lexxer preprocessing (prog_len: %d)\r\n", os_strlen(str));
|
||||
|
||||
for (p = q = str; *p != 0; p++) {
|
||||
// special case "on" keyword - replace by special token ON (0xf0)
|
||||
|
@ -196,8 +197,13 @@ int ICACHE_FLASH_ATTR text_into_tokens(char *str) {
|
|||
}
|
||||
}
|
||||
*q = 0;
|
||||
|
||||
lang_debug("found %d tokens\r\n", token_count);
|
||||
|
||||
// resize (shrink) the mem needed for the script
|
||||
lang_debug("prog_len compact: %d\r\n", (q-str)+1);
|
||||
my_script = (char *)os_realloc(my_script, (q-str)+5);
|
||||
str = &my_script[4];
|
||||
|
||||
my_token = (char **)os_malloc(token_count * sizeof(char *));
|
||||
if (my_token == 0)
|
||||
return 0;
|
||||
|
@ -272,15 +278,15 @@ int ICACHE_FLASH_ATTR search_token(int i, char *s) {
|
|||
int ICACHE_FLASH_ATTR syntax_error(int i, char *message) {
|
||||
int j;
|
||||
|
||||
os_sprintf(syntax_error_buffer, "Error (%s) at >>", message);
|
||||
os_sprintf(tmp_buffer, "Error (%s) at >>", message);
|
||||
for (j = i; j < i + 5 && j < max_token; j++) {
|
||||
int pos = os_strlen(syntax_error_buffer);
|
||||
int pos = os_strlen(tmp_buffer);
|
||||
if (is_token(j, ON))
|
||||
my_token[j] = "on";
|
||||
if (is_token(j, CONFIG))
|
||||
my_token[j] = "config";
|
||||
if (sizeof(syntax_error_buffer) - pos - 2 > os_strlen(my_token[j])) {
|
||||
os_sprintf(syntax_error_buffer + pos, "%s ", my_token[j]);
|
||||
if (sizeof(tmp_buffer) - pos - 2 > os_strlen(my_token[j])) {
|
||||
os_sprintf(tmp_buffer + pos, "%s ", my_token[j]);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
@ -324,7 +330,14 @@ int ICACHE_FLASH_ATTR parse_event(int next_token, bool * happend) {
|
|||
if (is_token(next_token, "init")) {
|
||||
lang_debug("event init\r\n");
|
||||
|
||||
*happend = (interpreter_status == INIT || interpreter_status == RE_INIT);
|
||||
*happend = (interpreter_status == INIT);
|
||||
return next_token + 1;
|
||||
}
|
||||
|
||||
if (is_token(next_token, "mqttconnect")) {
|
||||
lang_debug("event mqttconnect\r\n");
|
||||
|
||||
*happend = (interpreter_status == MQTT_CLIENT_CONNECT);
|
||||
return next_token + 1;
|
||||
}
|
||||
|
||||
|
@ -381,7 +394,7 @@ int ICACHE_FLASH_ATTR parse_event(int next_token, bool * happend) {
|
|||
return next_token + 2;
|
||||
}
|
||||
|
||||
return syntax_error(next_token, "'init', 'topic', 'clock', or 'timer' expected");
|
||||
return syntax_error(next_token, "'init', 'mqttconnect', 'topic', 'clock', or 'timer' expected");
|
||||
}
|
||||
|
||||
int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) {
|
||||
|
@ -448,7 +461,7 @@ int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) {
|
|||
} else
|
||||
#endif
|
||||
if (is_token(lr_token, "local")) {
|
||||
if (doit && interpreter_status != RE_INIT) {
|
||||
if (doit) {
|
||||
MQTT_local_publish(topic, data, data_len, 0, retained);
|
||||
lang_info("published local %s len: %d\r\n", topic, data_len);
|
||||
}
|
||||
|
@ -470,7 +483,7 @@ int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) {
|
|||
} else
|
||||
#endif
|
||||
if (is_token(next_token + 1, "local")) {
|
||||
if (doit && interpreter_status != RE_INIT) {
|
||||
if (doit) {
|
||||
retval = MQTT_local_subscribe(my_token[next_token + 2], 0);
|
||||
lang_info("subsrcibe local %s %s\r\n", my_token[next_token + 2], retval ? "success" : "failed");
|
||||
}
|
||||
|
@ -493,7 +506,7 @@ int ICACHE_FLASH_ATTR parse_action(int next_token, bool doit) {
|
|||
} else
|
||||
#endif
|
||||
if (is_token(next_token + 1, "local")) {
|
||||
if (doit && interpreter_status != RE_INIT) {
|
||||
if (doit) {
|
||||
retval = MQTT_local_unsubscribe(my_token[next_token + 2]);
|
||||
lang_info("unsubsrcibe local %s %s\r\n", my_token[next_token + 2], retval ? "success" : "failed");
|
||||
}
|
||||
|
@ -654,39 +667,36 @@ int ICACHE_FLASH_ATTR parse_expression(int next_token, char **data, int *data_le
|
|||
if (!doit)
|
||||
return next_token;
|
||||
|
||||
// reuse of the syntax_error_buffer (unused during execution), dirty but saves RAM
|
||||
#define res_str syntax_error_buffer
|
||||
|
||||
*data_type = STRING_T;
|
||||
if (is_token(op, "=")) {
|
||||
*data = os_strcmp(*data, r_data) ? "0" : "1";
|
||||
} else if (is_token(op, "+")) {
|
||||
os_sprintf(res_str, "%d", atoi(*data) + atoi(r_data));
|
||||
*data = res_str;
|
||||
*data_len = os_strlen(res_str);
|
||||
os_sprintf(tmp_buffer, "%d", atoi(*data) + atoi(r_data));
|
||||
*data = tmp_buffer;
|
||||
*data_len = os_strlen(tmp_buffer);
|
||||
} else if (is_token(op, "-")) {
|
||||
os_sprintf(res_str, "%d", atoi(*data) - atoi(r_data));
|
||||
*data = res_str;
|
||||
*data_len = os_strlen(res_str);
|
||||
os_sprintf(tmp_buffer, "%d", atoi(*data) - atoi(r_data));
|
||||
*data = tmp_buffer;
|
||||
*data_len = os_strlen(tmp_buffer);
|
||||
} else if (is_token(op, "*")) {
|
||||
os_sprintf(res_str, "%d", atoi(*data) * atoi(r_data));
|
||||
*data = res_str;
|
||||
*data_len = os_strlen(res_str);
|
||||
os_sprintf(tmp_buffer, "%d", atoi(*data) * atoi(r_data));
|
||||
*data = tmp_buffer;
|
||||
*data_len = os_strlen(tmp_buffer);
|
||||
} else if (is_token(op, "div")) {
|
||||
os_sprintf(res_str, "%d", atoi(*data) / atoi(r_data));
|
||||
*data = res_str;
|
||||
*data_len = os_strlen(res_str);
|
||||
os_sprintf(tmp_buffer, "%d", atoi(*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);
|
||||
char catbuf[len+1];
|
||||
os_sprintf(catbuf, "%s%s", *data, r_data);
|
||||
if (len > sizeof(res_str)-1) {
|
||||
len = sizeof(res_str);
|
||||
if (len > sizeof(tmp_buffer)-1) {
|
||||
len = sizeof(tmp_buffer);
|
||||
catbuf[len] = '\0';
|
||||
}
|
||||
*data_len = len;
|
||||
os_memcpy(res_str, catbuf, *data_len + 1);
|
||||
*data = res_str;
|
||||
os_memcpy(tmp_buffer, catbuf, *data_len + 1);
|
||||
*data = tmp_buffer;
|
||||
} else if (is_token(op, "gt")) {
|
||||
*data = atoi(*data) > atoi(r_data) ? "1" : "0";
|
||||
*data_len = 1;
|
||||
|
@ -731,7 +741,7 @@ int ICACHE_FLASH_ATTR parse_value(int next_token, char **data, int *data_len, Va
|
|||
if (ntp_sync_done())
|
||||
*data = get_timestr();
|
||||
else
|
||||
*data = "invalid";
|
||||
*data = "99:99:99";
|
||||
*data_len = os_strlen(*data) + 1;
|
||||
*data_type = STRING_T;
|
||||
return next_token + 1;
|
||||
|
@ -807,7 +817,7 @@ int ICACHE_FLASH_ATTR parse_value(int next_token, char **data, int *data_len, Va
|
|||
int ICACHE_FLASH_ATTR interpreter_syntax_check() {
|
||||
lang_debug("interpreter_syntax_check\r\n");
|
||||
|
||||
os_sprintf(syntax_error_buffer, "Syntax okay");
|
||||
os_sprintf(tmp_buffer, "Syntax okay");
|
||||
interpreter_status = SYNTAX_CHECK;
|
||||
interpreter_topic = interpreter_data = "";
|
||||
interpreter_data_len = 0;
|
||||
|
@ -841,13 +851,13 @@ int ICACHE_FLASH_ATTR interpreter_init() {
|
|||
return parse_statement(0);
|
||||
}
|
||||
|
||||
int ICACHE_FLASH_ATTR interpreter_init_reconnect(void) {
|
||||
int ICACHE_FLASH_ATTR interpreter_reconnect(void) {
|
||||
if (!script_enabled)
|
||||
return -1;
|
||||
|
||||
lang_debug("interpreter_init_reconnect\r\n");
|
||||
|
||||
interpreter_status = RE_INIT;
|
||||
interpreter_status = MQTT_CLIENT_CONNECT;
|
||||
interpreter_topic = interpreter_data = "";
|
||||
interpreter_data_len = 0;
|
||||
return parse_statement(0);
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
extern MQTT_Client mqttClient;
|
||||
extern bool mqtt_enabled, mqtt_connected;
|
||||
uint8_t syntax_error_buffer[128];
|
||||
uint8_t tmp_buffer[128];
|
||||
|
||||
typedef enum {SYNTAX_CHECK, CONFIG, INIT, RE_INIT, TOPIC_LOCAL, TOPIC_REMOTE, TIMER, CLOCK} Interpreter_Status;
|
||||
typedef enum {SYNTAX_CHECK, CONFIG, INIT, MQTT_CLIENT_CONNECT, TOPIC_LOCAL, TOPIC_REMOTE, TIMER, CLOCK} Interpreter_Status;
|
||||
typedef enum {STRING_T, DATA_T} Value_Type;
|
||||
|
||||
int text_into_tokens(char *str);
|
||||
|
@ -23,7 +23,7 @@ extern bool script_enabled;
|
|||
int interpreter_syntax_check();
|
||||
int interpreter_config();
|
||||
int interpreter_init();
|
||||
int interpreter_init_reconnect(void);
|
||||
int interpreter_reconnect(void);
|
||||
int interpreter_topic_received(const char *topic, const char *data, int data_len, bool local);
|
||||
|
||||
void init_timestamps(uint8_t *curr_time);
|
||||
|
|
|
@ -78,7 +78,7 @@ static void ICACHE_FLASH_ATTR mqttConnectedCb(uint32_t * args) {
|
|||
MQTT_Client *client = (MQTT_Client *) args;
|
||||
mqtt_connected = true;
|
||||
#ifdef SCRIPTED
|
||||
interpreter_init_reconnect();
|
||||
interpreter_reconnect();
|
||||
#endif
|
||||
os_printf("MQTT client connected\r\n");
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ uint32_t ICACHE_FLASH_ATTR get_script_size(void) {
|
|||
return size;
|
||||
}
|
||||
|
||||
static uint8_t *my_script = NULL;
|
||||
uint8_t *my_script = NULL;
|
||||
uint32_t ICACHE_FLASH_ATTR read_script(void) {
|
||||
uint32_t size = get_script_size();
|
||||
if (size <= 5)
|
||||
|
@ -418,7 +418,8 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
|
|||
uint32_t time = (uint32_t) (get_long_systime() / 1000000);
|
||||
int16_t i;
|
||||
|
||||
os_sprintf(response, "System uptime: %d:%02d:%02d\r\n", time / 3600, (time % 3600) / 60, time % 60);
|
||||
os_sprintf(response, "System uptime: %d:%02d:%02d\r\nFree Mem: %d\r\n", time / 3600, (time % 3600) / 60, time % 60,
|
||||
system_get_free_heap_size());
|
||||
to_console(response);
|
||||
|
||||
if (connected) {
|
||||
|
@ -584,20 +585,22 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
|
|||
|
||||
if (strcmp(tokens[1], "delete") == 0) {
|
||||
script_enabled = false;
|
||||
free_script();
|
||||
if (my_script != NULL)
|
||||
free_script();
|
||||
blob_zero(0, MAX_SCRIPT_SIZE);
|
||||
os_sprintf(response, "Script deleted");
|
||||
os_sprintf(response, "Script deleted\r\n");
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
port = atoi(tokens[1]);
|
||||
if (port == 0) {
|
||||
os_sprintf(response, "Invalid port");
|
||||
os_sprintf(response, "Invalid port\r\n");
|
||||
goto command_handled;
|
||||
}
|
||||
// delete and disable existing script
|
||||
script_enabled = false;
|
||||
free_script();
|
||||
if (my_script != NULL)
|
||||
free_script();
|
||||
|
||||
scriptcon = pespconn;
|
||||
downloadCon = (struct espconn *)os_zalloc(sizeof(struct espconn));
|
||||
|
@ -877,8 +880,8 @@ void ICACHE_FLASH_ATTR do_command(char *t1, char *t2, char *t3) {
|
|||
ringbuf_memcpy_into(console_rx_buffer, " ", 1);
|
||||
ringbuf_memcpy_into(console_rx_buffer, t3, os_strlen(t3));
|
||||
console_handle_command(0);
|
||||
ringbuf_memcpy_from(syntax_error_buffer, console_tx_buffer, ringbuf_bytes_used(console_tx_buffer));
|
||||
os_printf("%s", syntax_error_buffer);
|
||||
ringbuf_memcpy_from(tmp_buffer, console_tx_buffer, ringbuf_bytes_used(console_tx_buffer));
|
||||
os_printf("%s", tmp_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -987,9 +990,8 @@ static void ICACHE_FLASH_ATTR user_procTask(os_event_t * events) {
|
|||
|
||||
if (read_script()) {
|
||||
interpreter_syntax_check();
|
||||
ringbuf_memcpy_into(console_tx_buffer, syntax_error_buffer, os_strlen(syntax_error_buffer));
|
||||
ringbuf_memcpy_into(console_tx_buffer, tmp_buffer, os_strlen(tmp_buffer));
|
||||
ringbuf_memcpy_into(console_tx_buffer, "\r\n", 2);
|
||||
free_script();
|
||||
}
|
||||
// continue to next case and print...
|
||||
}
|
||||
|
@ -1193,7 +1195,7 @@ void ICACHE_FLASH_ATTR user_init() {
|
|||
|
||||
config.locked = lockstat;
|
||||
} else {
|
||||
os_printf("ERROR in script: %s\r\nScript disabled\r\n", syntax_error_buffer);
|
||||
os_printf("ERROR in script: %s\r\nScript disabled\r\n", tmp_buffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1273,14 +1275,16 @@ void ICACHE_FLASH_ATTR user_init() {
|
|||
30 /*max_retained_items */ );
|
||||
|
||||
MQTT_local_onData(MQTT_local_DataCallback);
|
||||
|
||||
//Start task
|
||||
system_os_task(user_procTask, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);
|
||||
|
||||
#ifdef SCRIPTED
|
||||
timestamps_init = false;
|
||||
interpreter_init();
|
||||
#endif
|
||||
|
||||
// Start the timer
|
||||
os_timer_setfn(&ptimer, timer_func, 0);
|
||||
os_timer_arm(&ptimer, 500, 0);
|
||||
|
||||
//Start task
|
||||
system_os_task(user_procTask, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue