diff --git a/README.md b/README.md index 43aaead..885dcea 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ The console understands the following commands: General commands: - help: prints a short help message -- show [config|stats|script|mqtt]: prints the current config or some status information and statistics +- show [config|stats]: prints the current config or some status information and statistics - save: saves the current config parameters to flash - lock [_password_]: saves and locks the current config, changes are not allowed. Password can be left open if already set before - unlock _password_: unlocks the config, requires password from the lock command @@ -61,6 +61,7 @@ While the user interface looks similar to my esp_wifi_repeater at https://github MQTT broker related command: +- show [mqtt]: prints the current config or status information of the MQTT broker - set broker_user _unsername_: sets the username for authentication of MQTT clients ("none" if no auth, default) - set broker_password _password_: sets the password for authentication of MQTT clients ("none" if empty, default) - set broker_access _mode_: controls the networks that allow MQTT broker access (0: no access, 1: only internal, 2: only external, 3: both (default)) @@ -68,6 +69,7 @@ MQTT broker related command: - set broker_retained_messages _max_: sets the max number of retained messages the broker can store (default: 30) - set script_logging [0|1]: switches logging of script execution on or off (not permanently stored in the configuration) - script [_portno_|delete]: opens port for upload of scripts or deletes the current script +- set @[num] _value_: sets the flash variable "num" (for use in scripts) to the given inital value (must be shorter than 63 chars) # MQTT client/bridging functionality The broker comes with a "local" and a "remote" client, which means, the broker itself can publish and subscribe topics. The "local" client is a client to the own broker (without the need of an additional TCP connection). @@ -205,13 +207,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. If no NTP sync happened the time will be reported as "99:99:99". The variable "$weekday" returns the day of week as three letters ("Mon","Tue",...). In general, scripts have the following BNF: ``` ::= on do | - config ( | @) | + config ([any ASCII]* | @) | ::= init | @@ -238,7 +240,7 @@ In general, scripts have the following BNF: := '=' | '>' | gte | str_ge | str_gte | '+' | '-' | '*' | '|' | div := | | # | $[any ASCII]* | gpio_in() | - @ | $this_item | $this_data | $this_gpio | $timestamp + @ | $this_item | $this_data | $this_gpio | $timestamp | $weekday := "[any ASCII]*" | [any ASCII]* @@ -272,7 +274,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. 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 and with the variable "$timestamp" from a script. If no NTP sync happened the time will be reported as "99:99:99". +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. - 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) diff --git a/firmware/0x00000.bin b/firmware/0x00000.bin index ecb62ae..86dbd8f 100644 Binary files a/firmware/0x00000.bin and b/firmware/0x00000.bin differ diff --git a/firmware/0x10000.bin b/firmware/0x10000.bin index 9ab9298..5e429ac 100644 Binary files a/firmware/0x10000.bin and b/firmware/0x10000.bin differ diff --git a/ntp/ntp.c b/ntp/ntp.c index baaa110..bfee7d7 100644 --- a/ntp/ntp.c +++ b/ntp/ntp.c @@ -44,6 +44,16 @@ uint8_t *ICACHE_FLASH_ATTR get_timestr() { return buf; } + +uint8_t *ICACHE_FLASH_ATTR get_weekday() { + struct timeval tv; + static uint8_t *days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; + + get_cur_time(&tv); + tv.tv_sec += ntp_timezone * 3600; + return days[((tv.tv_sec / (3600 * 24)) + 3) % 7]; +} + void ICACHE_FLASH_ATTR ntp_to_tv(uint8_t ntp[8], struct timeval *tv) { uint64_t aux = 0; @@ -109,6 +119,7 @@ static void ICACHE_FLASH_ATTR ntp_udp_recv(void *arg, char *pdata, unsigned shor mm = (t_tv.tv_sec/60)%60; hh = (t_tv.tv_sec/3600)%24; os_printf("time: %2d:%02d:%02d\r\n", hh, mm, ss); + os_printf("Day: %s\r\n", get_weekday()); */ // clean up connection if (pCon) { diff --git a/ntp/ntp.h b/ntp/ntp.h index 60e68be..c934efb 100644 --- a/ntp/ntp.h +++ b/ntp/ntp.h @@ -24,5 +24,6 @@ void ntp_get_time(); void get_cur_time(struct timeval *tv); void set_timezone(int16_t timezone); uint8_t *get_timestr(); +uint8_t *get_weekday(); #endif diff --git a/scripts/script.pir b/scripts/script.pir index 9c23e1c..f640960 100644 --- a/scripts/script.pir +++ b/scripts/script.pir @@ -26,11 +26,16 @@ on init do println "Starting the PIR script" - % Delay constanst in secs - setvar $delay = 10; + % Device number ("* 1" to make even "" a number) + setvar $device_number = @1 * 1 - % Device number - setvar $device_number = 2 + % Read delay constanst in secs from flash @2 + setvar $delay = @2 * 1; + if $delay = 0 then + % Write default + setvar $delay = 10; + setvar @2 = 10; + endif % Status of the PIR setvar $pir_status=0 diff --git a/scripts/script.sonoff b/scripts/script.sonoff index 056c68f..556a7ec 100644 --- a/scripts/script.sonoff +++ b/scripts/script.sonoff @@ -10,8 +10,13 @@ config speed 160 % Now the initialization, this is done once after booting on init do - % Device number - setvar $device_number = 1 + % Device number ("* 1" to make even "" a number) + setvar $device_number = @1 * 1 + + % @ vars are stored in flash and are persistent even after reboot + setvar $run = @2 + 1 + setvar @2 = $run + println "This is reboot no "|$run % Status of the relay setvar $relay_status=0 diff --git a/user/lang.c b/user/lang.c index 43b1700..9a5e0ac 100644 --- a/user/lang.c +++ b/user/lang.c @@ -1132,6 +1132,18 @@ int ICACHE_FLASH_ATTR parse_value(int next_token, char **data, int *data_len, Va *data_type = STRING_T; return next_token + 1; } + + else if (is_token(next_token, "$weekday")) { + lang_debug("val $weekday\r\n"); + + if (ntp_sync_done()) + *data = get_weekday(); + else + *data = "xxx"; + *data_len = os_strlen(*data); + *data_type = STRING_T; + return next_token + 1; + } #endif else if (my_token[next_token][0] == '$' && my_token[next_token][1] != '\0') { lang_debug("val var %s\r\n", &(my_token[next_token][1])); @@ -1159,12 +1171,14 @@ int ICACHE_FLASH_ATTR parse_value(int next_token, char **data, int *data_len, Va *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); + if (!syn_chk) { + 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; } diff --git a/user/user_main.c b/user/user_main.c index fbdc6c9..cd3b77b 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -380,7 +380,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) { if (strcmp(tokens[0], "help") == 0) { os_sprintf(response, - "show [config|stats|mqtt|script]\r\n|set [ssid|password|auto_connect|ap_ssid|ap_password|network|dns|ip|netmask|gw|ap_on|ap_open|speed|config_port|config_access|broker_subscriptions|broker_retained_messages|broker_user|broker_password|broker_access] |\r\npublish [local|remote] |quit|save [config]|reset [factory]|lock []|unlock "); + "show [config|stats|mqtt|script|vars]\r\n|set [ssid|password|auto_connect|ap_ssid|ap_password|network|dns|ip|netmask|gw|ap_on|ap_open|speed|config_port|config_access|broker_subscriptions|broker_retained_messages|broker_user|broker_password|broker_access] |\r\npublish [local|remote] |quit|save [config]|reset [factory]|lock []|unlock "); to_console(response); #ifdef SCRIPTED os_sprintf(response, "|script "); @@ -459,7 +459,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) { if (config.mqtt_broker_access == REMOTE_ACCESS) os_sprintf(response, "MQTT broker: remote access only\r\n"); if (config.mqtt_broker_access == 0) - os_sprintf(response, "MQTT broker: no access!!\r\n"); + os_sprintf(response, "MQTT broker: disabled\r\n"); to_console(response); #ifdef MQTT_CLIENT os_sprintf(response, "MQTT client %s\r\n", mqtt_enabled ? "enabled" : "disabled"); @@ -607,6 +607,22 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) { os_free(script); goto command_handled_2; } + + if (nTokens >= 2 && strcmp(tokens[1], "vars") == 0) { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + int i; + uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN]; + blob_load(1, (uint32_t *)slots, sizeof(slots)); + + for (i = 0; i < MAX_FLASH_SLOTS; i++) { + os_sprintf(response, "@%d: %s\r\n", i, &slots[i*FLASH_SLOT_LEN]); + to_console(response); + } + goto command_handled_2; + } #endif } @@ -631,7 +647,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) { #endif #ifdef NTP if (strcmp(tokens[0], "time") == 0) { - os_sprintf(response, "%s\r\n", get_timestr()); + os_sprintf(response, "%s %s\r\n", get_weekday(), get_timestr()); goto command_handled; } #endif @@ -994,7 +1010,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) { 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]); + os_sprintf(response, "%s written to flash\r\n", tokens[1]); } goto command_handled; } @@ -1559,15 +1575,18 @@ void user_init() { system_update_cpu_freq(config.clock_speed); - espconn_tcp_set_max_con(10); - os_printf("Max number of TCP clients: %d\r\n", espconn_tcp_get_max_con()); + // Start the broker only if it accessible + if (config.mqtt_broker_access != 0) { + espconn_tcp_set_max_con(10); + os_printf("Max number of TCP clients: %d\r\n", espconn_tcp_get_max_con()); - MQTT_server_onData(MQTT_local_DataCallback); - MQTT_server_onConnect(mqtt_broker_connect); - MQTT_server_onAuth(mqtt_broker_auth); + MQTT_server_onData(MQTT_local_DataCallback); + MQTT_server_onConnect(mqtt_broker_connect); + MQTT_server_onAuth(mqtt_broker_auth); - MQTT_server_start(1883 /*port */ , config.max_subscriptions, - config.max_retained_messages); + MQTT_server_start(1883 /*port */ , config.max_subscriptions, + config.max_retained_messages); + } //Start task system_os_task(user_procTask, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);