diff --git a/README.md b/README.md index a5ad618e8a0d..2583d3ca3b7b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.1.5** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. +Current version is **5.1.6** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. ### **** ATTENTION Version 5.x.x specific information **** diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 36a3d3617dd5..991eea9f749c 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,13 @@ -/* 5.1.5 20170604 +/* 5.1.6 20170606 + * Shrink code + * Removed online configuration of Domoticz In and Domoticz Out MQTT strings + * Removed commands DomoticzInTopic and DomoticzOutTopic + * Add define KEY_HOLD_TIME to configure button hold threshold before sending MQTT Hold message + * Add command StateText4 to configure button MQTT Hold text (= MQTT_CMND_HOLD) + * Add command SetOption11 0|1 to swap pushbutton single and double press functionality (#200) + * Add command SwitchMode 5 (PUSHBUTTONHOLD) and 6 (PUSHBUTTONHOLD_INV) (#489) + * + * 5.1.5 20170604 * Shrink code in preparation to ESP8266-Arduino 2.4.0-rc1 * Add effect parameter to HUE Device (#464) * @@ -14,7 +23,7 @@ * 5.1.2 20170519 * Fix Counter/Timer JSON message and update Counter/Timer on webpage * Fix WS2812 Domoticz related regression issues - * + * * 5.1.1 20170517 * Allow command FullTopic in group mode * Prepare for more use of RTC memory diff --git a/sonoff/settings.h b/sonoff/settings.h index ef244a812636..43d04996b1b1 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -17,21 +17,21 @@ along with this program. If not, see . */ -typedef union { // Restricted by MISRA-C Rule 18.4 but so usefull... - uint32_t data; // Allow bit manipulation using SetOption +typedef union { // Restricted by MISRA-C Rule 18.4 but so usefull... + uint32_t data; // Allow bit manipulation using SetOption struct { - uint32_t savestate : 1; // bit 0 - uint32_t button_restrict : 1; // bit 1 - uint32_t value_units : 1; // bit 2 + uint32_t savestate : 1; // bit 0 + uint32_t button_restrict : 1; // bit 1 + uint32_t value_units : 1; // bit 2 uint32_t mqtt_enabled : 1; - uint32_t mqtt_response : 1; // bit 4 + uint32_t mqtt_response : 1; // bit 4 uint32_t mqtt_power_retain : 1; uint32_t mqtt_button_retain : 1; uint32_t mqtt_switch_retain : 1; - uint32_t temperature_conversion : 1; // bit 8 + uint32_t temperature_conversion : 1; // bit 8 uint32_t mqtt_sensor_retain : 1; - uint32_t mqtt_offline : 1; // bit 10 - uint32_t spare11 : 1; + uint32_t mqtt_offline : 1; // bit 10 + uint32_t button_swap : 1; // bit 11 (v5.1.6) uint32_t spare12 : 1; uint32_t spare13 : 1; uint32_t spare14 : 1; @@ -54,15 +54,15 @@ struct SYSCFG { unsigned long saveFlag; unsigned long version; unsigned long bootcount; - sysBitfield flag; // Add flag since 5.0.2 + sysBitfield flag; // Add flag since 5.0.2 int16_t savedata; int8_t timezone; char otaUrl[101]; - char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5 + char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5 - byte serial_enable; // Not used (ever) + byte serial_enable; // Not used (ever) byte seriallog_level; uint8_t sta_config; byte sta_active; @@ -84,19 +84,20 @@ struct SYSCFG { char mqtt_topic[33]; char button_topic[33]; char mqtt_grptopic[33]; - char state_text[3][11]; // was ex_mqtt_subtopic[33] until 4.1.1 - byte ex_mqtt_button_retain; // Not used since 5.0.2 - byte ex_mqtt_power_retain; // Not used since 5.0.2 - byte ex_value_units; // Not used since 5.0.2 - byte ex_button_restrict; // Not used since 5.0.2 + char ex_state_text[3][11]; // was state_text until 5.1.6, was ex_mqtt_subtopic[33] until 4.1.1 + byte ex_mqtt_button_retain; // Not used since 5.0.2 + byte ex_mqtt_power_retain; // Not used since 5.0.2 + byte ex_value_units; // Not used since 5.0.2 + byte ex_button_restrict; // Not used since 5.0.2 uint16_t tele_period; uint8_t power; uint8_t ledstate; - uint8_t ex_switchmode; // Not used since 3.9.21 + uint8_t ex_switchmode; // Not used since 3.9.21 - char domoticz_in_topic[33]; - char domoticz_out_topic[33]; + char ex_domoticz_in_topic[22]; // Not used since 5.1.6 + char state_text[4][11]; // was domoticz_out_topic until 5.1.6 + uint16_t domoticz_update_timer; unsigned long domoticz_relay_idx[4]; unsigned long domoticz_key_idx[4]; @@ -123,7 +124,7 @@ struct SYSCFG { uint16_t hlw_mkwhs; // MaxEnergyStart // 3.0.6 - uint16_t mqtt_retry; // was ex_pulsetime until 4.0.4 + uint16_t mqtt_retry; // was ex_pulsetime until 4.0.4 // 3.1.1 uint8_t poweronstate; @@ -150,8 +151,8 @@ struct SYSCFG { // 3.2.8 char switch_topic[33]; - byte ex_mqtt_switch_retain; // Not used since 5.0.2 - uint8_t ex_mqtt_enabled; // Not used since 5.0.2 + byte ex_mqtt_switch_retain; // Not used since 5.0.2 + uint8_t ex_mqtt_enabled; // Not used since 5.0.2 // 3.2.12 uint8_t sleep; @@ -172,7 +173,7 @@ struct SYSCFG { uint16_t led_wakeup; // 3.9.7 - uint8_t ex_emulation; // Not used since 5.0.2 + uint8_t ex_emulation; // Not used since 5.0.2 // 3.9.20 char web_password[33]; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 0a7282d3ad41..fa1da628af3a 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -386,8 +386,6 @@ void CFG_DefaultSet2() sysCfg.blinkcount = APP_BLINKCOUNT; sysCfg.sleep = APP_SLEEP; - strlcpy(sysCfg.domoticz_in_topic, DOMOTICZ_IN_TOPIC, sizeof(sysCfg.domoticz_in_topic)); - strlcpy(sysCfg.domoticz_out_topic, DOMOTICZ_OUT_TOPIC, sizeof(sysCfg.domoticz_out_topic)); sysCfg.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER; for (byte i = 0; i < 4; i++) { sysCfg.switchmode[i] = SWITCH_MODE; @@ -443,7 +441,7 @@ void CFG_DefaultSet2() // 4.0.9 CFG_DefaultSet_4_0_9(); - // 4.1.1 + // 4.1.1 + 5.1.6 CFG_DefaultSet_4_1_1(); // 5.0.2 @@ -540,6 +538,7 @@ void CFG_DefaultSet_4_1_1() strlcpy(sysCfg.state_text[0], MQTT_STATUS_OFF, sizeof(sysCfg.state_text[0])); strlcpy(sysCfg.state_text[1], MQTT_STATUS_ON, sizeof(sysCfg.state_text[1])); strlcpy(sysCfg.state_text[2], MQTT_CMND_TOGGLE, sizeof(sysCfg.state_text[2])); + strlcpy(sysCfg.state_text[3], MQTT_CMND_HOLD, sizeof(sysCfg.state_text[3])); // v5.1.6 } void CFG_DefaultSet_5_0_2() @@ -647,6 +646,11 @@ void CFG_Delta() rtcMem.pCounter[i] = 0; } } + if (sysCfg.version < 0x05010600) { + memcpy(sysCfg.state_text, sysCfg.ex_state_text, 33); + strlcpy(sysCfg.state_text[3], MQTT_CMND_HOLD, sizeof(sysCfg.state_text[3])); + } + sysCfg.version = VERSION; } } diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index b4a3bc62356b..f7890f5eb280 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -24,14 +24,14 @@ - Select IDE Tools - Flash size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x05010500 // 5.1.5 +#define VERSION 0x05010600 // 5.1.6 enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; enum week_t {Last, First, Second, Third, Fourth}; enum dow_t {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat}; enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; enum wifi_t {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, MAX_WIFI_OPTION}; -enum swtch_t {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, MAX_SWITCH_OPTION}; +enum swtch_t {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, MAX_SWITCH_OPTION}; enum led_t {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; @@ -278,6 +278,7 @@ uint8_t holdcount = 0; // Timer recording button hold uint8_t multiwindow = 0; // Max time between button presses to record press count uint8_t multipress = 0; // Number of button presses within multiwindow uint8_t lastwallswitch[4]; // Last wall switch states +uint8_t wallswitchtimer[4] = { 0 }; // Timer for wallswitch push button hold uint8_t blockgpio0 = 4; // Block GPIO0 for 4 seconds after poweron to workaround Wemos D1 RTS circuit mytmplt my_module; // Active copy of GPIOs @@ -348,7 +349,7 @@ void getTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic) char* getStateText(byte state) { - if (state > 2) { + if (state > 3) { state = 1; } return sysCfg.state_text[state]; @@ -646,26 +647,26 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, snprintf_P(svalue, ssvalue, PSTR("{\"MqttHost\",\"%s\"}"), sysCfg.mqtt_host); } else if (!strcmp_P(type,PSTR("MQTTPORT"))) { - if ((data_len > 0) && (payload > 0) && (payload < 32766)) { + if ((payload > 0) && (payload < 32766)) { sysCfg.mqtt_port = (1 == payload) ? MQTT_PORT : payload; restartflag = 2; } snprintf_P(svalue, ssvalue, PSTR("{\"MqttPort\":%d}"), sysCfg.mqtt_port); } else if (!strcmp_P(type,PSTR("MQTTRETRY"))) { - if ((data_len > 0) && (payload >= MQTT_RETRY_SECS) && (payload < 32001)) { + if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) { sysCfg.mqtt_retry = payload; mqttcounter = sysCfg.mqtt_retry; } snprintf_P(svalue, ssvalue, PSTR("{\"MqttRetry\":%d}"), sysCfg.mqtt_retry); } else if (!strcmp_P(type,PSTR("MQTTRESPONSE"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.mqtt_response = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"MqttResponse\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_response)); } - else if (!strcmp_P(type,PSTR("STATETEXT")) && (index > 0) && (index <= 3)) { + else if (!strcmp_P(type,PSTR("STATETEXT")) && (index > 0) && (index <= 4)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.state_text[0]))) { for(i = 0; i <= data_len; i++) { if (dataBuf[i] == ' ') { @@ -803,11 +804,11 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, snprintf_P(svalue, ssvalue, PSTR("{\"SwitchTopic\":\"%s\"}"), sysCfg.switch_topic); } else if (!strcmp_P(type,PSTR("BUTTONRETAIN"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic)); if (!payload) { for(i = 1; i <= Maxdevice; i++) { - send_button_power(0, i, 3); // Clear MQTT retain in broker + send_button_power(0, i, 9); // Clear MQTT retain in broker } } sysCfg.flag.mqtt_button_retain = payload; @@ -815,11 +816,11 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, snprintf_P(svalue, ssvalue, PSTR("{\"ButtonRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_button_retain)); } else if (!strcmp_P(type,PSTR("SWITCHRETAIN"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic)); if (!payload) { for(i = 1; i <= 4; i++) { - send_button_power(1, i, 3); // Clear MQTT retain in broker + send_button_power(1, i, 9); // Clear MQTT retain in broker } } sysCfg.flag.mqtt_switch_retain = payload; @@ -827,7 +828,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, snprintf_P(svalue, ssvalue, PSTR("{\"SwitchRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_switch_retain)); } else if (!strcmp_P(type,PSTR("POWERRETAIN"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { if (!payload) { for(i = 1; i <= Maxdevice; i++) { // Clear MQTT retain in broker snprintf_P(stemp2, sizeof(stemp2), PSTR("%d"), i); @@ -845,7 +846,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, snprintf_P(svalue, ssvalue, PSTR("{\"PowerRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_power_retain)); } else if (!strcmp_P(type,PSTR("SENSORRETAIN"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { if (!payload) { svalue[0] = '\0'; mqtt_publish_topic_P(2, PSTR("SENSOR"), svalue, sysCfg.flag.mqtt_sensor_retain); @@ -948,8 +949,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) if (!strcmp(dataBufUc,"?")) { data_len = 0; } - int16_t payload = atoi(dataBuf); // -32766 - 32767 + int16_t payload = -1; + if (data_len && isdigit(dataBuf[0])) { + payload = atoi(dataBuf); // -32766 - 32767 + } uint16_t payload16 = atoi(dataBuf); // 0 - 65535 + if (!strcmp_P(dataBufUc,PSTR("OFF")) || !strcmp_P(dataBufUc,PSTR("FALSE")) || !strcmp_P(dataBufUc,PSTR("STOP")) || !strcmp_P(dataBufUc,PSTR("CELSIUS"))) { payload = 0; } @@ -966,25 +971,28 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) payload = 4; } +// snprintf_P(svalue, sizeof(svalue), PSTR("RSLT: Payload %d, Payload16 %d"), payload, payload16); +// addLog(LOG_LEVEL_DEBUG, svalue); + if (!strcmp_P(type,PSTR("POWER")) && (index > 0) && (index <= Maxdevice)) { - if ((0 == data_len) || (payload > 4)) { + if ((payload < 0) || (payload > 4)) { payload = 9; } do_cmnd_power(index, payload); return; } else if (!strcmp_P(type,PSTR("STATUS"))) { - if ((0 == data_len) || (payload < 0) || (payload > MAX_STATUS)) { + if ((payload < 0) || (payload > MAX_STATUS)) { payload = 99; } publish_status(payload); return; } else if ((sysCfg.module != MOTOR) && !strcmp_P(type,PSTR("POWERONSTATE"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 4)) { + if ((payload >= 0) && (payload <= 4)) { sysCfg.poweronstate = payload; if (4 == sysCfg.poweronstate) { - for(byte i = 1; i <= Maxdevice; i++) { + for (byte i = 1; i <= Maxdevice; i++) { do_cmnd_power(i, 1); } } @@ -999,7 +1007,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"PulseTime%d\":%d}"), index, sysCfg.pulsetime[index -1]); } else if (!strcmp_P(type,PSTR("BLINKTIME"))) { - if ((data_len > 0) && (payload > 2) && (payload <= 3600)) { + if ((payload > 2) && (payload <= 3600)) { sysCfg.blinktime = payload; if (blink_timer) { blink_timer = sysCfg.blinktime; @@ -1020,7 +1028,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) // Serviced } else if (!strcmp_P(type,PSTR("SAVEDATA"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 3600)) { + if ((payload >= 0) && (payload <= 3600)) { sysCfg.savedata = payload; savedatacounter = sysCfg.savedata; } @@ -1033,8 +1041,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveData\":\"%s\"}"), (sysCfg.savedata > 1) ? stemp1 : getStateText(sysCfg.savedata)); } - else if (!strcmp_P(type,PSTR("SETOPTION")) && (index >= 0) && (index <= 10)) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + else if (!strcmp_P(type,PSTR("SETOPTION")) && (index >= 0) && (index <= 11)) { + if ((payload >= 0) && (payload <= 1)) { switch (index) { case 0: // savestate case 1: // button_restrict @@ -1042,68 +1050,69 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) case 4: // mqtt_response case 8: // temperature_conversion case 10: // mqtt_offline + case 11: // button_swap bitWrite(sysCfg.flag.data, index, payload); } } snprintf_P(svalue, sizeof(svalue), PSTR("{\"SetOption%d\":\"%s\"}"), index, getStateText(bitRead(sysCfg.flag.data, index))); } else if (!strcmp_P(type,PSTR("SAVESTATE"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.savestate = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveState\":\"%s\"}"), getStateText(sysCfg.flag.savestate)); } else if (!strcmp_P(type,PSTR("BUTTONRESTRICT"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.button_restrict = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonRestrict\":\"%s\"}"), getStateText(sysCfg.flag.button_restrict)); } else if (!strcmp_P(type,PSTR("UNITS"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.value_units = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"Units\":\"%s\"}"), getStateText(sysCfg.flag.value_units)); } else if (!strcmp_P(type,PSTR("MQTT"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.mqtt_enabled = payload; restartflag = 2; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"Mqtt\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_enabled)); } else if (!strcmp_P(type,PSTR("TEMPUNIT"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.temperature_conversion = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"TempUnit\":\"%s\"}"), (sysCfg.flag.temperature_conversion) ? "Fahrenheit" : "Celsius"); } else if (!strcmp_P(type,PSTR("TEMPRES"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { + if ((payload >= 0) && (payload <= 3)) { sysCfg.flag.temperature_resolution = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"TempRes\":%d}"), sysCfg.flag.temperature_resolution); } else if (!strcmp_P(type,PSTR("HUMRES"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { + if ((payload >= 0) && (payload <= 3)) { sysCfg.flag.humidity_resolution = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"HumRes\":%d}"), sysCfg.flag.humidity_resolution); } else if (!strcmp_P(type,PSTR("PRESSRES"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { + if ((payload >= 0) && (payload <= 3)) { sysCfg.flag.pressure_resolution = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"PressRes\":%d}"), sysCfg.flag.pressure_resolution); } else if (!strcmp_P(type,PSTR("ENERGYRES"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 5)) { + if ((payload >= 0) && (payload <= 5)) { sysCfg.flag.energy_resolution = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"EnergyRes\":%d}"), sysCfg.flag.energy_resolution); } else if (!strcmp_P(type,PSTR("MODULE"))) { - if ((data_len > 0) && (payload > 0) && (payload <= MAXMODULE)) { + if ((payload > 0) && (payload <= MAXMODULE)) { payload--; byte new_modflg = (sysCfg.module != payload); sysCfg.module = payload; @@ -1146,7 +1155,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) else if (!strcmp_P(type,PSTR("GPIO")) && (index < MAX_GPIO_PIN)) { mytmplt cmodule; memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule)); - if ((data_len > 0) && (GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { + if ((GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { for (byte i = 0; i < MAX_GPIO_PIN; i++) { if ((GPIO_USER == cmodule.gp.io[i]) && (sysCfg.my_module.gp.io[i] == payload)) { sysCfg.my_module.gp.io[i] = 0; @@ -1199,7 +1208,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue); } else if (!strcmp_P(type,PSTR("PWM")) && (index > pwm_idxoffset) && (index <= 5)) { - if ((data_len > 0) && (payload >= 0) && (payload <= PWM_RANGE) && (pin[GPIO_PWM1 + index -1] < 99)) { + if ((payload >= 0) && (payload <= PWM_RANGE) && (pin[GPIO_PWM1 + index -1] < 99)) { sysCfg.pwmvalue[index -1] = payload; analogWrite(pin[GPIO_PWM1 + index -1], payload); } @@ -1221,7 +1230,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"Counter%d\":%d}"), index, rtcMem.pCounter[index -1]); } else if (!strcmp_P(type,PSTR("COUNTERTYPE")) && (index > 0) && (index <= MAX_COUNTERS)) { - if ((data_len > 0) && (payload >= 0) && (payload <= 1) && (pin[GPIO_CNTR1 + index -1] < 99)) { + if ((payload >= 0) && (payload <= 1) && (pin[GPIO_CNTR1 + index -1] < 99)) { bitWrite(sysCfg.pCounterType, index -1, payload &1); rtcMem.pCounter[index -1] = 0; sysCfg.pCounter[index -1] = 0; @@ -1235,7 +1244,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"CounterDebounce\":%d}"), sysCfg.pCounterDebounce); } else if (!strcmp_P(type,PSTR("SLEEP"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 251)) { + if ((payload >= 0) && (payload < 251)) { if ((!sysCfg.sleep && payload) || (sysCfg.sleep && !payload)) { restartflag = 2; } @@ -1245,7 +1254,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.flag.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.flag.value_units) ? " mS" : ""); } else if (!strcmp_P(type,PSTR("FLASHMODE"))) { // 0 = QIO, 1 = QOUT, 2 = DIO, 3 = DOUT - if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { + if ((payload >= 0) && (payload <= 3)) { if (ESP.getFlashChipMode() != payload) { setFlashMode(0, payload &3); } @@ -1253,7 +1262,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"FlashMode\":%d}"), ESP.getFlashChipMode()); } else if (!strcmp_P(type,PSTR("UPGRADE")) || !strcmp_P(type,PSTR("UPLOAD"))) { - if ((data_len > 0) && (1 == payload)) { + if (1 == payload) { otaflag = 3; snprintf_P(svalue, sizeof(svalue), PSTR("{\"Upgrade\":\"Version %s from %s\"}"), Version, sysCfg.otaUrl); } else { @@ -1266,7 +1275,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"OtaUrl\":\"%s\"}"), sysCfg.otaUrl); } else if (!strcmp_P(type,PSTR("SERIALLOG"))) { - if ((data_len > 0) && (payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { + if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { sysCfg.seriallog_level = payload; seriallog_level = payload; seriallog_timer = 0; @@ -1274,7 +1283,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"SerialLog\":\"%d (Active %d)\"}"), sysCfg.seriallog_level, seriallog_level); } else if (!strcmp_P(type,PSTR("SYSLOG"))) { - if ((data_len > 0) && (payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { + if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { sysCfg.syslog_level = payload; syslog_level = (sysCfg.flag.emulation) ? 0 : payload; syslog_timer = 0; @@ -1288,7 +1297,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"LogHost\":\"%s\"}"), sysCfg.syslog_host); } else if (!strcmp_P(type,PSTR("LOGPORT"))) { - if ((data_len > 0) && (payload > 0) && (payload < 32766)) { + if ((payload > 0) && (payload < 32766)) { sysCfg.syslog_port = (1 == payload) ? SYS_LOG_PORT : payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"LogPort\":%d}"), sysCfg.syslog_port); @@ -1314,7 +1323,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"NtpServer%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]); } else if (!strcmp_P(type,PSTR("AP"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { + if ((payload >= 0) && (payload <= 2)) { switch (payload) { case 0: // Toggle sysCfg.sta_active ^= 1; @@ -1354,7 +1363,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"Hostname\":\"%s\"}"), sysCfg.hostname); } else if (!strcmp_P(type,PSTR("WIFICONFIG"))) { - if ((data_len > 0) && (payload >= WIFI_RESTART) && (payload < MAX_WIFI_OPTION)) { + if ((payload >= WIFI_RESTART) && (payload < MAX_WIFI_OPTION)) { sysCfg.sta_config = payload; wificheckflag = sysCfg.sta_config; snprintf_P(stemp1, sizeof(stemp1), wificfg[sysCfg.sta_config]); @@ -1380,14 +1389,14 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"FriendlyName%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]); } else if (swt_flg && !strcmp_P(type,PSTR("SWITCHMODE")) && (index > 0) && (index <= 4)) { - if ((data_len > 0) && (payload >= 0) && (payload < MAX_SWITCH_OPTION)) { + if ((payload >= 0) && (payload < MAX_SWITCH_OPTION)) { sysCfg.switchmode[index -1] = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"SwitchMode%d\":%d}"), index, sysCfg.switchmode[index-1]); } #ifdef USE_WEBSERVER else if (!strcmp_P(type,PSTR("WEBSERVER"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { + if ((payload >= 0) && (payload <= 2)) { sysCfg.webserver = payload; } if (sysCfg.webserver) { @@ -1404,14 +1413,14 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebPassword\":\"%s\"}"), sysCfg.web_password); } else if (!strcmp_P(type,PSTR("WEBLOG"))) { - if ((data_len > 0) && (payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { + if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { sysCfg.weblog_level = payload; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebLog\":%d}"), sysCfg.weblog_level); } #ifdef USE_EMULATION else if (!strcmp_P(type,PSTR("EMULATION"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { + if ((payload >= 0) && (payload <= 2)) { sysCfg.flag.emulation = payload; restartflag = 2; } @@ -1420,7 +1429,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) #endif // USE_EMULATION #endif // USE_WEBSERVER else if (!strcmp_P(type,PSTR("TELEPERIOD"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.tele_period = (1 == payload) ? TELE_PERIOD : payload; if ((sysCfg.tele_period > 0) && (sysCfg.tele_period < 10)) { sysCfg.tele_period = 10; // Do not allow periods < 10 seconds @@ -1464,7 +1473,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"Timezone\":%d}"), sysCfg.timezone); } else if (!strcmp_P(type,PSTR("LEDPOWER"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { + if ((payload >= 0) && (payload <= 2)) { sysCfg.ledstate &= 8; switch (payload) { case 0: // Off @@ -1481,7 +1490,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"LedPower\":\"%s\"}"), getStateText(bitRead(sysCfg.ledstate, 3))); } else if (!strcmp_P(type,PSTR("LEDSTATE"))) { - if ((data_len > 0) && (payload >= 0) && (payload < MAX_LED_OPTION)) { + if ((payload >= 0) && (payload < MAX_LED_OPTION)) { sysCfg.ledstate = payload; if (!sysCfg.ledstate) { setLed(0); @@ -1555,38 +1564,49 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) /********************************************************************************************/ -void send_button_power(byte key, byte device, byte state) +boolean send_button_power(byte key, byte device, byte state) { // key 0 = button_topic // key 1 = switch_topic +// state 0 = off +// state 1 = on +// state 2 = toggle +// state 3 = hold +// state 9 = clear retain flag char stopic[TOPSZ]; char scommand[CMDSZ]; char svalue[TOPSZ]; char stemp1[10]; + boolean result = false; - if (!key && (device > Maxdevice)) { - device = 1; - } - snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device); - snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (key || (Maxdevice > 1)) ? stemp1 : ""); - getTopic_P(stopic, 0, (key) ? sysCfg.switch_topic : sysCfg.button_topic, scommand); + char *key_topic = (key) ? sysCfg.switch_topic : sysCfg.button_topic; + if (sysCfg.flag.mqtt_enabled && mqttClient.connected() && (strlen(key_topic) != 0) && strcmp(key_topic, "0")) { + if (!key && (device > Maxdevice)) { + device = 1; + } + snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device); + snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (key || (Maxdevice > 1)) ? stemp1 : ""); + getTopic_P(stopic, 0, key_topic, scommand); - if (3 == state) { - svalue[0] = '\0'; - } else { - if (!strcmp(sysCfg.mqtt_topic,(key) ? sysCfg.switch_topic : sysCfg.button_topic) && (2 == state)) { - state = ~(power >> (device -1)) & 0x01; + if (9 == state) { + svalue[0] = '\0'; + } else { + if (!strcmp(sysCfg.mqtt_topic, key_topic) && (2 == state)) { + state = ~(power >> (device -1)) & 0x01; + } + snprintf_P(svalue, sizeof(svalue), PSTR("%s"), getStateText(state)); } - snprintf_P(svalue, sizeof(svalue), PSTR("%s"), getStateText(state)); - } #ifdef USE_DOMOTICZ - if (!(domoticz_button(key, device, state, strlen(svalue)))) { - mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); - } + if (!(domoticz_button(key, device, state, strlen(svalue)))) { + mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); + } #else - mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); + mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); #endif // USE_DOMOTICZ + result = true; + } + return result; } void do_cmnd_power(byte device, byte state) @@ -1804,7 +1824,7 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) snprintf_P(svalue, ssvalue, PSTR("%s{\"Time\":\"%s\""), svalue, getDateTime().c_str()); for (byte i = 0; i < 4; i++) { if (pin[GPIO_SWT1 +i] < 99) { - boolean swm = ((FOLLOW_INV == sysCfg.switchmode[i]) || (PUSHBUTTON_INV == sysCfg.switchmode[i])); + boolean swm = ((FOLLOW_INV == sysCfg.switchmode[i]) || (PUSHBUTTON_INV == sysCfg.switchmode[i]) || (PUSHBUTTONHOLD_INV == sysCfg.switchmode[i])); snprintf_P(svalue, ssvalue, PSTR("%s, \"Switch%d\":\"%s\""), svalue, i +1, getStateText(swm ^ lastwallswitch[i])); *djson = 1; } @@ -2062,10 +2082,14 @@ void stateloop() holdcount = 0; } else { holdcount++; - if (!sysCfg.flag.button_restrict && ((STATES *4) == holdcount)) { // 4 seconds button hold - snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1")); + if (KEY_HOLD_TIME == holdcount) { // 4 seconds button hold multipress = 0; - do_cmnd(scmnd); + if (!sysCfg.flag.button_restrict) { // no restriction (OPTION + snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1")); + do_cmnd(scmnd); + } else { + send_button_power(0, 1, 3); // Execute command via MQTT + } } } if (multiwindow) { @@ -2075,10 +2099,11 @@ void stateloop() if ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module)) { flag = ((1 == multipress) || (2 == multipress)); } else { - flag = (1 == multipress); +// flag = (1 == multipress); + flag = (sysCfg.flag.button_swap +1 == multipress); } - if (flag && sysCfg.flag.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) { - send_button_power(0, multipress, 2); // Execute command via MQTT using ButtonTopic to sync external clients + if (flag && send_button_power(0, multipress, 2)) { // Execute command via MQTT using ButtonTopic to sync external clients + // Success } else { if ((1 == multipress) || (2 == multipress)) { if (WIFI_State()) { // WPSconfig, Smartconfig or Wifimanager active @@ -2101,10 +2126,8 @@ void stateloop() if (pin[GPIO_KEY1 +i] < 99) { button = digitalRead(pin[GPIO_KEY1 +i]); if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { - if (sysCfg.flag.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) { - send_button_power(0, i +1, 2); // Execute commend via MQTT - } else { - do_cmnd_power(i +1, 2); // Execute command internally + if (!send_button_power(0, i +1, 2)) { // Execute command via MQTT + do_cmnd_power(i +1, 2); // Execute command internally } } lastbutton[i] = button; @@ -2113,6 +2136,14 @@ void stateloop() for (byte i = 0; i < 4; i++) { if (pin[GPIO_SWT1 +i] < 99) { + + if (wallswitchtimer[i]) { + wallswitchtimer[i]--; + if (0 == wallswitchtimer[i]) { + send_button_power(1, i +1, 3); // Execute command via MQTT + } + } + button = digitalRead(pin[GPIO_SWT1 +i]); if (button != lastwallswitch[i]) { switchflag = 3; @@ -2135,14 +2166,33 @@ void stateloop() if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i])) { switchflag = 2; // Toggle with releasing pushbutton from Gnd } + break; + case PUSHBUTTONHOLD: + if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i])) { + wallswitchtimer[i] = KEY_HOLD_TIME; + } + if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i]) && (wallswitchtimer[i])) { + wallswitchtimer[i] = 0; + switchflag = 2; // Toggle with pushbutton to Gnd + } + break; + case PUSHBUTTONHOLD_INV: + if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i])) { + wallswitchtimer[i] = KEY_HOLD_TIME; + } + if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i]) && (wallswitchtimer[i])) { + wallswitchtimer[i] = 0; + switchflag = 2; // Toggle with pushbutton to Gnd + } + break; } + if (switchflag < 3) { - if (sysCfg.flag.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.switch_topic) != 0) && strcmp(sysCfg.switch_topic, "0")) { - send_button_power(1, i +1, switchflag); // Execute commend via MQTT - } else { - do_cmnd_power(i +1, switchflag); // Execute command internally (if i < Maxdevice) + if (!send_button_power(1, i +1, switchflag)) { // Execute command via MQTT + do_cmnd_power(i +1, switchflag); // Execute command internally (if i < Maxdevice) } } + lastwallswitch[i] = button; } } diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 10833a396076..fe39a53a332f 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -81,6 +81,7 @@ #define MQTT_STATUS_OFF "OFF" // [StateText1] Command or Status result when turned off (needs to be a string like "0" or "Off") #define MQTT_STATUS_ON "ON" // [StateText2] Command or Status result when turned on (needs to be a string like "1" or "On") #define MQTT_CMND_TOGGLE "TOGGLE" // [StateText3] Command to send when toggling (needs to be a string like "2" or "Toggle") +#define MQTT_CMND_HOLD "HOLD" // [StateText4] Command to send when button is kept down for over KEY_HOLD_TIME * 0.1 seconds (needs to be a string like "HOLD") // -- MQTT topics --------------------------------- //#define MQTT_FULLTOPIC "tasmota/bedroom/%topic%/%prefix%/" // Up to max 80 characers @@ -101,8 +102,8 @@ // -- MQTT - Domoticz ----------------------------- #define USE_DOMOTICZ // Enable Domoticz (+7k code, +0.3k mem) - Disable by // - #define DOMOTICZ_IN_TOPIC "domoticz/in" // [DomoticzInTopic] - #define DOMOTICZ_OUT_TOPIC "domoticz/out" // [DomoticzOutTopic] + #define DOMOTICZ_IN_TOPIC "domoticz/in" // Domoticz Input Topic + #define DOMOTICZ_OUT_TOPIC "domoticz/out" // Domoticz Output Topic #define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional) // -- HTTP ---------------------------------------- @@ -140,7 +141,8 @@ #define APP_BLINKCOUNT 10 // [BlinkCount] Number of blinks (0 = 32000) #define APP_SLEEP 0 // [Sleep] Sleep time to lower energy consumption (0 = Off, 1 - 250 mSec) -#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON or PUSHBUTTON_INV (the wall switch state) +#define KEY_HOLD_TIME 40 // Number of 0.1 seconds to hold Button or external Pushbutton before sending HOLD message +#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD or PUSHBUTTONHOLD_INV (the wall switch state) #define WS2812_LEDS 30 // [Pixels] Number of WS2812 LEDs to start with #define TEMP_CONVERSION 0 // [TempUnit] Return temperature in (0 = Celsius or 1 = Fahrenheit) diff --git a/sonoff/xdrv_domoticz.ino b/sonoff/xdrv_domoticz.ino index 50fee13e801a..baccde99c08c 100644 --- a/sonoff/xdrv_domoticz.ino +++ b/sonoff/xdrv_domoticz.ino @@ -25,16 +25,14 @@ const char HTTP_FORM_DOMOTICZ[] PROGMEM = "
 Domoticz parameters 
" "" - "
" - "" - ""; + "
In topic (" DOMOTICZ_IN_TOPIC ")
Out topic (" DOMOTICZ_OUT_TOPIC ")
"; const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM = - "" + "" ""; const char HTTP_FORM_DOMOTICZ_SWITCH[] PROGMEM = - ""; + ""; const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM = - ""; + ""; const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM = ""; #endif // USE_WEBSERVER @@ -42,6 +40,9 @@ const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM = const char domoticz_sensors[DOMOTICZ_MAX_SENSORS][14] PROGMEM = { "Temp", "Temp,Hum", "Temp,Hum,Baro", "Power,Energy", "Illuminance", "Count" }; +char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC; +char domoticz_out_topic[] = DOMOTICZ_OUT_TOPIC; + boolean domoticz_subscribe = false; int domoticz_update_timer = 0; byte domoticz_update_flag = 1; @@ -50,7 +51,7 @@ void mqtt_publishDomoticzPowerState(byte device) { char svalue[64]; // was MESSZ - if (sysCfg.domoticz_relay_idx[device -1] && (strlen(sysCfg.domoticz_in_topic) != 0)) { + if (sysCfg.domoticz_relay_idx[device -1]) { if ((device < 1) || (device > Maxdevice)) { device = 1; } @@ -58,16 +59,16 @@ void mqtt_publishDomoticzPowerState(byte device) if (SONOFF_LED == sysCfg.module) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"idx\":%d,\"nvalue\":2,\"svalue\":\"%d\"}"), sysCfg.domoticz_relay_idx[device -1], sysCfg.led_dimmer[device -1]); - mqtt_publish(sysCfg.domoticz_in_topic, svalue); + mqtt_publish(domoticz_in_topic, svalue); } else if ((Maxdevice == device) && (pin[GPIO_WS2812] < 99)) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"idx\":%d,\"nvalue\":2,\"svalue\":\"%d\"}"), sysCfg.domoticz_relay_idx[device -1], sysCfg.ws_dimmer); - mqtt_publish(sysCfg.domoticz_in_topic, svalue); + mqtt_publish(domoticz_in_topic, svalue); } snprintf_P(svalue, sizeof(svalue), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"\"}"), sysCfg.domoticz_relay_idx[device -1], (power & (0x01 << (device -1))) ? 1 : 0); - mqtt_publish(sysCfg.domoticz_in_topic, svalue); + mqtt_publish(domoticz_in_topic, svalue); } } @@ -104,9 +105,9 @@ void domoticz_mqttSubscribe() domoticz_subscribe = true; } } - if (domoticz_subscribe && (strlen(sysCfg.domoticz_out_topic) != 0)) { + if (domoticz_subscribe) { char stopic[TOPSZ]; - snprintf_P(stopic, sizeof(stopic), PSTR("%s/#"), sysCfg.domoticz_out_topic); // domoticz topic + snprintf_P(stopic, sizeof(stopic), PSTR("%s/#"), domoticz_out_topic); // domoticz topic mqttClient.subscribe(stopic); mqttClient.loop(); // Solve LmacRxBlk:1 messages } @@ -144,7 +145,7 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin int16_t found = 0; domoticz_update_flag = 1; - if (!strncmp(topicBuf, sysCfg.domoticz_out_topic, strlen(sysCfg.domoticz_out_topic)) != 0) { + if (!strncmp(topicBuf, domoticz_out_topic, strlen(domoticz_out_topic)) != 0) { if (sdataBuf < 20) { return 1; } @@ -210,47 +211,33 @@ boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16 boolean serviced = true; if (!strncmp_P(type,PSTR("DOMOTICZ"),8)) { - if (!strcmp_P(type +8,PSTR("INTOPIC"))) { - if ((data_len > 0) && (data_len < sizeof(sysCfg.domoticz_in_topic))) { - strlcpy(sysCfg.domoticz_in_topic, (1 == payload) ? DOMOTICZ_IN_TOPIC : dataBuf, sizeof(sysCfg.domoticz_in_topic)); - restartflag = 2; - } - snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzInTopic\":\"%s\"}"), sysCfg.domoticz_in_topic); - } - else if (!strcmp_P(type +8,PSTR("OUTTOPIC"))) { - if ((data_len > 0) && (data_len < sizeof(sysCfg.domoticz_out_topic))) { - strlcpy(sysCfg.domoticz_out_topic, (1 == payload) ? DOMOTICZ_OUT_TOPIC : dataBuf, sizeof(sysCfg.domoticz_out_topic)); - restartflag = 2; - } - snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzOutTopic\":\"%s\"}"), sysCfg.domoticz_out_topic); - } - else if (!strcmp_P(type +8,PSTR("IDX")) && (index > 0) && (index <= Maxdevice)) { - if ((data_len > 0) && (payload >= 0)) { + if (!strcmp_P(type +8,PSTR("IDX")) && (index > 0) && (index <= Maxdevice)) { + if (payload >= 0) { sysCfg.domoticz_relay_idx[index -1] = payload; restartflag = 2; } snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzIdx%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]); } else if (!strcmp_P(type +8,PSTR("KEYIDX")) && (index > 0) && (index <= Maxdevice)) { - if ((data_len > 0) && (payload >= 0)) { + if (payload >= 0) { sysCfg.domoticz_key_idx[index -1] = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzKeyIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]); } else if (!strcmp_P(type +8,PSTR("SWITCHIDX")) && (index > 0) && (index <= Maxdevice)) { - if ((data_len > 0) && (payload >= 0)) { + if (payload >= 0) { sysCfg.domoticz_switch_idx[index -1] = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSwitchIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]); } else if (!strcmp_P(type +8,PSTR("SENSORIDX")) && (index > 0) && (index <= DOMOTICZ_MAX_SENSORS)) { - if ((data_len > 0) && (payload >= 0)) { + if (payload >= 0) { sysCfg.domoticz_sensor_idx[index -1] = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSensorIdx%d\":%d}"), index, sysCfg.domoticz_sensor_idx[index -1]); } else if (!strcmp_P(type +8,PSTR("UPDATETIMER"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.domoticz_update_timer = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzUpdateTimer\":%d}"), sysCfg.domoticz_update_timer); @@ -268,7 +255,7 @@ boolean domoticz_button(byte key, byte device, byte state, byte svalflg) snprintf_P(svalue, sizeof(svalue), PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"), (key) ? sysCfg.domoticz_switch_idx[device -1] : sysCfg.domoticz_key_idx[device -1], (state) ? (2 == state) ? "Toggle" : "On" : "Off"); - mqtt_publish(sysCfg.domoticz_in_topic, svalue); + mqtt_publish(domoticz_in_topic, svalue); return 1; } else { return 0; @@ -289,10 +276,10 @@ void dom_sensor(byte idx, char *data) { char dmess[64]; - if (sysCfg.domoticz_sensor_idx[idx] && (strlen(sysCfg.domoticz_in_topic) != 0)) { + if (sysCfg.domoticz_sensor_idx[idx]) { snprintf_P(dmess, sizeof(dmess), PSTR("{\"idx\":%d,\"nvalue\":0,\"svalue\":\"%s\"}"), sysCfg.domoticz_sensor_idx[idx], data); - mqtt_publish(sysCfg.domoticz_in_topic, dmess); + mqtt_publish(domoticz_in_topic, dmess); } } @@ -354,8 +341,6 @@ void handleDomoticz() String page = FPSTR(HTTP_HEAD); page.replace("{v}", "Configure Domoticz"); page += FPSTR(HTTP_FORM_DOMOTICZ); - page.replace("{d1}", String(sysCfg.domoticz_in_topic)); - page.replace("{d2}", String(sysCfg.domoticz_out_topic)); for (int i = 0; i < 4; i++) { if (i < Maxdevice) { page += FPSTR(HTTP_FORM_DOMOTICZ_RELAY); @@ -387,8 +372,6 @@ void domoticz_saveSettings() { char log[LOGSZ], stemp[20]; - strlcpy(sysCfg.domoticz_in_topic, (!strlen(webServer->arg("it").c_str())) ? DOMOTICZ_IN_TOPIC : webServer->arg("it").c_str(), sizeof(sysCfg.domoticz_in_topic)); - strlcpy(sysCfg.domoticz_out_topic, (!strlen(webServer->arg("ot").c_str())) ? DOMOTICZ_OUT_TOPIC : webServer->arg("ot").c_str(), sizeof(sysCfg.domoticz_out_topic)); for (byte i = 0; i < 4; i++) { snprintf_P(stemp, sizeof(stemp), PSTR("r%d"), i +1); sysCfg.domoticz_relay_idx[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str()); @@ -402,8 +385,7 @@ void domoticz_saveSettings() sysCfg.domoticz_sensor_idx[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str()); } sysCfg.domoticz_update_timer = (!strlen(webServer->arg("ut").c_str())) ? DOMOTICZ_UPDATE_TIMER : atoi(webServer->arg("ut").c_str()); - snprintf_P(log, sizeof(log), PSTR("HTTP: Domoticz in %s, out %s, idx %d, %d, %d, %d, update timer %d"), - sysCfg.domoticz_in_topic, sysCfg.domoticz_out_topic, + snprintf_P(log, sizeof(log), PSTR("HTTP: Domoticz idx %d, %d, %d, %d, update timer %d"), sysCfg.domoticz_relay_idx[0], sysCfg.domoticz_relay_idx[1], sysCfg.domoticz_relay_idx[2], sysCfg.domoticz_relay_idx[3], sysCfg.domoticz_update_timer); addLog(LOG_LEVEL_INFO, log); diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino index 43ce2b576b52..1d8eea980657 100644 --- a/sonoff/xdrv_snfled.ino +++ b/sonoff/xdrv_snfled.ino @@ -207,7 +207,7 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le } } else if (!strcmp_P(type,PSTR("DIMMER"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 100)) { + if ((payload >= 0) && (payload <= 100)) { sysCfg.led_dimmer[0] = payload; coldim = true; } else { @@ -215,7 +215,7 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le } } else if (!strcmp_P(type,PSTR("LEDTABLE"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { + if ((payload >= 0) && (payload <= 2)) { switch (payload) { case 0: // Off case 1: // On @@ -230,27 +230,25 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le snprintf_P(svalue, ssvalue, PSTR("{\"LedTable\":\"%s\"}"), getStateText(sysCfg.led_table)); } else if (!strcmp_P(type,PSTR("FADE"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { - switch (payload) { - case 0: // Off - case 1: // On - sysCfg.led_fade = payload; - break; - case 2: // Toggle - sysCfg.led_fade ^= 1; - break; - } + switch (payload) { + case 0: // Off + case 1: // On + sysCfg.led_fade = payload; + break; + case 2: // Toggle + sysCfg.led_fade ^= 1; + break; } snprintf_P(svalue, ssvalue, PSTR("{\"Fade\":\"%s\"}"), getStateText(sysCfg.led_fade)); } else if (!strcmp_P(type,PSTR("SPEED"))) { // 1 - fast, 8 - slow - if ((data_len > 0) && (payload > 0) && (payload <= 8)) { + if ((payload > 0) && (payload <= 8)) { sysCfg.led_speed = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"Speed\":%d}"), sysCfg.led_speed); } else if (!strcmp_P(type,PSTR("WAKEUPDURATION"))) { - if ((data_len > 0) && (payload > 0) && (payload < 3601)) { + if ((payload > 0) && (payload < 3601)) { sysCfg.led_wakeup = payload; sl_wakeupActive = 0; } diff --git a/sonoff/xdrv_ws2812.ino b/sonoff/xdrv_ws2812.ino index 6979df479a2e..9a236691fb81 100644 --- a/sonoff/xdrv_ws2812.ino +++ b/sonoff/xdrv_ws2812.ino @@ -529,7 +529,7 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_ boolean serviced = true; if (!strcmp_P(type,PSTR("PIXELS"))) { - if ((data_len > 0) && (payload > 0) && (payload <= WS2812_MAX_LEDS)) { + if ((payload > 0) && (payload <= WS2812_MAX_LEDS)) { sysCfg.ws_pixels = payload; ws2812_pixels(); } @@ -549,7 +549,7 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_ ws2812_getColor(0, svalue, ssvalue); } else if (!strcmp_P(type,PSTR("DIMMER"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 100)) { + if ((payload >= 0) && (payload <= 100)) { sysCfg.ws_dimmer = payload; bitSet(power, ws_bit); #ifdef USE_DOMOTICZ @@ -560,7 +560,7 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_ snprintf_P(svalue, ssvalue, PSTR("{\"Dimmer\":%d}"), sysCfg.ws_dimmer); } else if (!strcmp_P(type,PSTR("LEDTABLE"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { + if ((payload >= 0) && (payload <= 2)) { switch (payload) { case 0: // Off case 1: // On @@ -575,33 +575,31 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_ snprintf_P(svalue, ssvalue, PSTR("{\"LedTable\":\"%s\"}"), getStateText(sysCfg.ws_ledtable)); } else if (!strcmp_P(type,PSTR("FADE"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { - switch (payload) { - case 0: // Off - case 1: // On - sysCfg.ws_fade = payload; - break; - case 2: // Toggle - sysCfg.ws_fade ^= 1; - break; - } + switch (payload) { + case 0: // Off + case 1: // On + sysCfg.ws_fade = payload; + break; + case 2: // Toggle + sysCfg.ws_fade ^= 1; + break; } snprintf_P(svalue, ssvalue, PSTR("{\"Fade\":\"%s\"}"), getStateText(sysCfg.ws_fade)); } else if (!strcmp_P(type,PSTR("SPEED"))) { // 1 - fast, 5 - slow - if ((data_len > 0) && (payload > 0) && (payload <= 5)) { + if ((payload > 0) && (payload <= 5)) { sysCfg.ws_speed = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"Speed\":%d}"), sysCfg.ws_speed); } else if (!strcmp_P(type,PSTR("WIDTH"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 4)) { + if ((payload >= 0) && (payload <= 4)) { sysCfg.ws_width = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"Width\":%d}"), sysCfg.ws_width); } else if (!strcmp_P(type,PSTR("WAKEUP"))) { - if ((data_len > 0) && (payload > 0) && (payload < 3601)) { + if ((payload > 0) && (payload < 3601)) { sysCfg.ws_wakeup = payload; if (1 == sysCfg.ws_scheme) { sysCfg.ws_scheme = 0; @@ -610,7 +608,7 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_ snprintf_P(svalue, ssvalue, PSTR("{\"WakeUp\":%d}"), sysCfg.ws_wakeup); } else if (!strcmp_P(type,PSTR("SCHEME"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 9)) { + if ((payload >= 0) && (payload <= 9)) { sysCfg.ws_scheme = payload; if (1 == sysCfg.ws_scheme) { ws2812_resetWakupState(); diff --git a/sonoff/xsns_hlw8012.ino b/sonoff/xsns_hlw8012.ino index 6d840ba3dcf9..a4f92875a8dd 100644 --- a/sonoff/xsns_hlw8012.ino +++ b/sonoff/xsns_hlw8012.ino @@ -439,43 +439,43 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len boolean serviced = true; if (!strcmp_P(type,PSTR("POWERLOW"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_pmin = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("POWERHIGH"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_pmax = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("VOLTAGELOW"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 501)) { + if ((payload >= 0) && (payload < 501)) { sysCfg.hlw_umin = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.flag.value_units) ? " V" : ""); } else if (!strcmp_P(type,PSTR("VOLTAGEHIGH"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 501)) { + if ((payload >= 0) && (payload < 501)) { sysCfg.hlw_umax = payload; } snprintf_P(svalue, ssvalue, PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.flag.value_units) ? " V" : ""); } else if (!strcmp_P(type,PSTR("CURRENTLOW"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 16001)) { + if ((payload >= 0) && (payload < 16001)) { sysCfg.hlw_imin = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.flag.value_units) ? " mA" : ""); } else if (!strcmp_P(type,PSTR("CURRENTHIGH"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 16001)) { + if ((payload >= 0) && (payload < 16001)) { sysCfg.hlw_imax = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.flag.value_units) ? " mA" : ""); } else if (!strcmp_P(type,PSTR("ENERGYRESET"))) { - if ((data_len > 0) && (payload >= 1) && (payload <= 3)) { + if ((payload >= 1) && (payload <= 3)) { switch (payload) { case 1: hlw_kWhtoday = 0; @@ -500,69 +500,69 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len snprintf_P(svalue, ssvalue, PSTR("{\"EnergyReset\":{\"Total\":%s, \"Yesterday\":%s, \"Today\":%s}}"), stemp2, stemp0, stemp1); } else if (!strcmp_P(type,PSTR("HLWPCAL"))) { - if ((data_len > 0) && (payload > 0) && (payload < 32001)) { + if ((payload > 0) && (payload < 32001)) { sysCfg.hlw_pcal = (payload > 9999) ? payload : HLW_PREF_PULSE; // 12530 } snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.flag.value_units) ? " uS" : ""); } else if (!strcmp_P(type,PSTR("HLWUCAL"))) { - if ((data_len > 0) && (payload > 0) && (payload < 32001)) { + if ((payload > 0) && (payload < 32001)) { sysCfg.hlw_ucal = (payload > 999) ? payload : HLW_UREF_PULSE; // 1950 } snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.flag.value_units) ? " uS" : ""); } else if (!strcmp_P(type,PSTR("HLWICAL"))) { - if ((data_len > 0) && (payload > 0) && (payload < 32001)) { + if ((payload > 0) && (payload < 32001)) { sysCfg.hlw_ical = (payload > 2499) ? payload : HLW_IREF_PULSE; // 3500 } snprintf_P(svalue, ssvalue, PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.flag.value_units) ? " uS" : ""); } #if FEATURE_POWER_LIMIT else if (!strcmp_P(type,PSTR("MAXPOWER"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mpl = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("MAXPOWERHOLD"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mplh = (1 == payload) ? MAX_POWER_HOLD : payload; } snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.flag.value_units) ? " Sec" : ""); } else if (!strcmp_P(type,PSTR("MAXPOWERWINDOW"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mplw = (1 == payload) ? MAX_POWER_WINDOW : payload; } snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.flag.value_units) ? " Sec" : ""); } else if (!strcmp_P(type,PSTR("SAFEPOWER"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mspl = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("SAFEPOWERHOLD"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_msplh = (1 == payload) ? SAFE_POWER_HOLD : payload; } snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.flag.value_units) ? " Sec" : ""); } else if (!strcmp_P(type,PSTR("SAFEPOWERWINDOW"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 1440)) { + if ((payload >= 0) && (payload < 1440)) { sysCfg.hlw_msplw = (1 == payload) ? SAFE_POWER_WINDOW : payload; } snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.flag.value_units) ? " Min" : ""); } else if (!strcmp_P(type,PSTR("MAXENERGY"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { + if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mkwh = payload; hlw_mkwh_state = 3; } snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.flag.value_units) ? " Wh" : ""); } else if (!strcmp_P(type,PSTR("MAXENERGYSTART"))) { - if ((data_len > 0) && (payload >= 0) && (payload < 24)) { + if ((payload >= 0) && (payload < 24)) { sysCfg.hlw_mkwhs = payload; } snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.flag.value_units) ? " Hr" : "");
Idx {1
Idx {1
Key idx {1
Switch idx {1
Switch idx {1
Sensor idx {1 - {2
Sensor idx {1 - {2
Update timer (" STR(DOMOTICZ_UPDATE_TIMER) ")