From 823c9a040484935bab6b70318ff7e03105edce82 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 31 Mar 2018 17:29:00 +0200 Subject: [PATCH 1/3] Add more validation to timer handling Add more validation to timer handling --- sonoff/i18n.h | 1 + sonoff/sonoff_post.h | 2 +- sonoff/webserver.ino | 22 +++++--- sonoff/xdrv_09_timers.ino | 107 ++++++++++++++++++++------------------ 4 files changed, 72 insertions(+), 60 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 12db1d541..b026d0af5 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -358,6 +358,7 @@ #define D_JSON_TIMER_REPEAT "Repeat" #define D_JSON_TIMER_OUTPUT "Output" #define D_JSON_TIMER_POWER "Power" + #define D_JSON_TIMER_NO_DEVICE "No GPIO as output configured" #define D_CMND_TIMERS "Timers" /********************************************************************************************/ diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index 67678c6e2..f1f980edf 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -45,7 +45,7 @@ void WifiWpsStatusCallback(wps_cb_status status); #define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code) #define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code) #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code) -#define USE_SGP30 // Add I2C code for SGP30 sensor (+4k code) +#define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code) #define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code) #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code) #define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Adafruit TSL2561 Arduino (+1k2 code) diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index 45bde262f..b697e2bab 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -181,15 +181,17 @@ const char HTTP_BTN_MENU1[] PROGMEM = "
"; const char HTTP_BTN_RSTRT[] PROGMEM = "
"; -const char HTTP_BTN_MENU2[] PROGMEM = - "
" +const char HTTP_BTN_MENU_MODULE[] PROGMEM = + "
"; #ifdef USE_TIMERS #ifdef USE_TIMERS_WEB - "
" +const char HTTP_BTN_MENU_TIMER[] PROGMEM = + "
"; #endif // USE_TIMERS_WEB #endif // USE_TIMERS +const char HTTP_BTN_MENU_WIFI[] PROGMEM = "
"; -const char HTTP_BTN_MENU3[] PROGMEM = +const char HTTP_BTN_MENU_MQTT[] PROGMEM = "
" #ifdef USE_DOMOTICZ "
" @@ -629,10 +631,14 @@ void HandleConfiguration() String page = FPSTR(HTTP_HEAD); page.replace(F("{v}"), FPSTR(S_CONFIGURATION)); page += FPSTR(HTTP_HEAD_STYLE); - page += FPSTR(HTTP_BTN_MENU2); - if (Settings.flag.mqtt_enabled) { - page += FPSTR(HTTP_BTN_MENU3); - } + page += FPSTR(HTTP_BTN_MENU_MODULE); +#ifdef USE_TIMERS +#ifdef USE_TIMERS_WEB + if (devices_present) page += FPSTR(HTTP_BTN_MENU_TIMER); +#endif // USE_TIMERS_WEB +#endif // USE_TIMERS + page += FPSTR(HTTP_BTN_MENU_WIFI); + if (Settings.flag.mqtt_enabled) page += FPSTR(HTTP_BTN_MENU_MQTT); page += FPSTR(HTTP_BTN_MENU4); page += FPSTR(HTTP_BTN_MAIN); ShowPage(page); diff --git a/sonoff/xdrv_09_timers.ino b/sonoff/xdrv_09_timers.ino index f1ddeb68c..b82eb7e2c 100644 --- a/sonoff/xdrv_09_timers.ino +++ b/sonoff/xdrv_09_timers.ino @@ -97,65 +97,70 @@ boolean TimerCommand() Settings.timer[index -1].data = Settings.timer[XdrvMailbox.payload -1].data; // Copy timer } } else { - StaticJsonBuffer<128> jsonBuffer; - JsonObject& root = jsonBuffer.parseObject(dataBufUc); - if (!root.success()) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_INVALID_JSON "\"}"), index); // JSON decode failed - error = 1; - } - else { - char parm_uc[10]; - index--; - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_ARM))].success()) { - Settings.timer[index].arm = (root[parm_uc] != 0); + if (devices_present) { + StaticJsonBuffer<128> jsonBuffer; + JsonObject& root = jsonBuffer.parseObject(dataBufUc); + if (!root.success()) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_INVALID_JSON "\"}"), index); // JSON decode failed + error = 1; } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_TIME))].success()) { - uint16_t itime = 0; - uint8_t value = 0; - char time_str[10]; + else { + char parm_uc[10]; + index--; + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_ARM))].success()) { + Settings.timer[index].arm = (root[parm_uc] != 0); + } + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_TIME))].success()) { + uint16_t itime = 0; + uint8_t value = 0; + char time_str[10]; - snprintf(time_str, sizeof(time_str), root[parm_uc]); - const char *substr = strtok(time_str, ":"); - if (substr != NULL) { - value = atoi(substr); - if (value > 23) value = 23; - itime = value * 60; - substr = strtok(NULL, ":"); + snprintf(time_str, sizeof(time_str), root[parm_uc]); + const char *substr = strtok(time_str, ":"); if (substr != NULL) { value = atoi(substr); - if (value > 59) value = 59; - itime += value; + if (value > 23) value = 23; + itime = value * 60; + substr = strtok(NULL, ":"); + if (substr != NULL) { + value = atoi(substr); + if (value > 59) value = 59; + itime += value; + } + } + Settings.timer[index].time = itime; + } + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_DAYS))].success()) { + // SMTWTFS = 1234567 = 0011001 = 00TW00S = --TW--S + Settings.timer[index].days = 0; + const char *tday = root[parm_uc]; + char ch = '.'; + + uint8_t i = 0; + while ((ch != '\0') && (i < 7)) { + ch = *tday++; + if (ch == '-') ch = '0'; + uint8_t mask = 1 << i++; + Settings.timer[index].days |= (ch == '0') ? 0 : mask; } } - Settings.timer[index].time = itime; - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_DAYS))].success()) { - // SMTWTFS = 1234567 = 0011001 = 00TW00S = --TW--S - Settings.timer[index].days = 0; - const char *tday = root[parm_uc]; - char ch = '.'; - - uint8_t i = 0; - while ((ch != '\0') && (i < 7)) { - ch = *tday++; - if (ch == '-') ch = '0'; - uint8_t mask = 1 << i++; - Settings.timer[index].days |= (ch == '0') ? 0 : mask; + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_REPEAT))].success()) { + Settings.timer[index].repeat = (root[parm_uc] != 0); } - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_REPEAT))].success()) { - Settings.timer[index].repeat = (root[parm_uc] != 0); - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_OUTPUT))].success()) { - uint8_t device = ((uint8_t)root[parm_uc] -1) & 0x0F; - Settings.timer[index].device = (device < devices_present) ? device : devices_present -1; - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_POWER))].success()) { - Settings.timer[index].power = (uint8_t)root[parm_uc] & 0x03; - } - if (Settings.timer[index].arm) bitClear(fired, index); + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_OUTPUT))].success()) { + uint8_t device = ((uint8_t)root[parm_uc] -1) & 0x0F; + Settings.timer[index].device = (device < devices_present) ? device : devices_present -1; + } + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_POWER))].success()) { + Settings.timer[index].power = (uint8_t)root[parm_uc] & 0x03; + } + if (Settings.timer[index].arm) bitClear(fired, index); - index++; + index++; + } + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_TIMER_NO_DEVICE "\"}"), index); // No outputs defined so nothing to control + error = 1; } } } From 96212834cf3bbc31f8baf98fe7fb21a128e489ee Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 31 Mar 2018 18:59:37 +0200 Subject: [PATCH 2/3] Change Backlog max commands to 30 5.12.0i * Change max number of commands in Backlog from 15 to 30 --- sonoff/_releasenotes.ino | 1 + sonoff/sonoff.h | 2 +- sonoff/sonoff.ino | 18 +++++------------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 35ae88f27..f87587c10 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -6,6 +6,7 @@ * Add support for SGP30 gas and air quality sensor (#2307) * Change webpage parameter communication * Change Timer parameter Device to more obvious Output + * Change max number of commands in Backlog from 15 to 30 * Change MQTT response topic for Energy changes from ENERGY to SENSOR (#2229, #2251) * Change default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268) * diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 61ef81adb..0869c6929 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -97,7 +97,7 @@ typedef unsigned long power_t; // Power (Relay) type #define WEB_LOG_SIZE 4000 // Max number of characters in weblog #endif -#define MAX_BACKLOG 16 // Max number of commands in backlog (chk backlog_index and backlog_pointer code) +#define MAX_BACKLOG 30 // Max number of commands in backlog #define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds #define SOFT_BAUDRATE 9600 // Default software serial baudrate diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 6ef37513e..aff1fd224 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -463,16 +463,13 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) int command_code = GetCommandCode(command, sizeof(command), type, kTasmotaCommands); if (CMND_BACKLOG == command_code) { if (data_len) { + uint8_t bl_pointer = (!backlog_pointer) ? MAX_BACKLOG -1 : backlog_pointer; + bl_pointer--; char *blcommand = strtok(dataBuf, ";"); - while (blcommand != NULL) { + while ((blcommand != NULL) && (backlog_index != bl_pointer)) { backlog[backlog_index] = String(blcommand); backlog_index++; -/* - if (backlog_index >= MAX_BACKLOG) { - backlog_index = 0; - } -*/ - backlog_index &= 0xF; + if (backlog_index >= MAX_BACKLOG) backlog_index = 0; blcommand = strtok(NULL, ";"); } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_APPENDED); @@ -1756,12 +1753,7 @@ void StateLoop() ExecuteCommand((char*)backlog[backlog_pointer].c_str()); backlog_mutex = 0; backlog_pointer++; -/* - if (backlog_pointer >= MAX_BACKLOG) { - backlog_pointer = 0; - } -*/ - backlog_pointer &= 0xF; + if (backlog_pointer >= MAX_BACKLOG) backlog_pointer = 0; } } From ce98c6cacc448830b4eac4ab4f2f9e3eb738f2a3 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 31 Mar 2018 19:56:16 +0200 Subject: [PATCH 3/3] Add multiple colors to Led command 5.12.0i * Add multiple color entry support for command Led like Led2 120000.001200.000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) --- sonoff/_releasenotes.ino | 3 ++- sonoff/xdrv_01_light.ino | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index f87587c10..50b7a7ca0 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -4,9 +4,10 @@ * Add optional Timer configuration webpage to be enabled in user_config.h with define USE_TIMERS_WEB * Add Home Assistant MQTT Discovery for Buttons and change SetOption19 response (#2277) * Add support for SGP30 gas and air quality sensor (#2307) + * Add multiple color entry support for command Led like Led2 120000.001200.000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) * Change webpage parameter communication * Change Timer parameter Device to more obvious Output - * Change max number of commands in Backlog from 15 to 30 + * Change max number of commands in Backlog from 15 to 30 and ignore commands overflowing * Change MQTT response topic for Energy changes from ENERGY to SENSOR (#2229, #2251) * Change default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268) * diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_01_light.ino index 54c7cebc9..9158442a9 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_01_light.ino @@ -1114,8 +1114,16 @@ boolean LightCommand() #ifdef USE_WS2812 // *********************************************************************** else if ((CMND_LED == command_code) && (LT_WS2812 == light_type) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= Settings.light_pixels)) { if (XdrvMailbox.data_len > 0) { - if (LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len)) { - Ws2812SetColor(XdrvMailbox.index, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]); + char *p; + uint16_t idx = XdrvMailbox.index; + for (char *color = strtok_r(XdrvMailbox.data, ".", &p); color; color = strtok_r(NULL, ".", &p)) { + if (LightColorEntry(color, strlen(color))) { + Ws2812SetColor(idx, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]); + idx++; + if (idx >= Settings.light_pixels) break; + } else { + break; + } } } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, Ws2812GetColor(XdrvMailbox.index, scolor));