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;
}
}
}