diff --git a/README.md b/README.md index ad865c067..00eb424bd 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.0.5** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. +Current version is **5.0.6** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. ### **** ATTENTION Version 5.0.x specific information **** diff --git a/api/arduino/sonoff.ino.bin b/api/arduino/sonoff.ino.bin index 610f18bd4..a8f879992 100644 Binary files a/api/arduino/sonoff.ino.bin and b/api/arduino/sonoff.ino.bin differ diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 540f3fb09..c63487736 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,8 @@ -/* 5.0.5 20170508 +/* 5.0.6 20170510 + * Remove hyphen in case of a single DHT sensor connecetd (#427) + * Add command MqttRetry to change default MQTT reconnect retry timer from minimal 10 seconds (#429) + * + * 5.0.5 20170508 * Add command FullTopic with tokens %topic% (replaced by command Topic value) and * %prefix% (replaced by command Prefix values) for more flexible topic definitions (#244) * See wiki > MQTT Features https://github.com/arendst/Sonoff-Tasmota/wiki/MQTT-Features for more information diff --git a/sonoff/settings.h b/sonoff/settings.h index 1f7e21c08..21d98205f 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -105,7 +105,7 @@ struct SYSCFG { uint16_t hlw_mkwhs; // MaxEnergyStart // 3.0.6 - uint16_t ex_pulsetime; // Not used since 4.0.4 + uint16_t mqtt_retry; // was ex_pulsetime until 4.0.4 // 3.1.1 uint8_t poweronstate; @@ -176,7 +176,7 @@ struct SYSCFG { unsigned long hlw_kWhtotal; // 5.0.4a - char mqtt_fulltopic[101]; + char mqtt_fulltopic[101]; } sysCfg; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 877ff6e85..299df8744 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -453,9 +453,11 @@ void CFG_DefaultSet2() // sysCfg.hlw_kWhtotal = 0; rtcMem.hlw_kWhtotal = 0; - // 5.0.4a + // 5.0.5 strlcpy(sysCfg.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(sysCfg.mqtt_fulltopic)); + // 5.0.6 + sysCfg.mqtt_retry = MQTT_RETRY_SECS; } /********************************************************************************************/ @@ -516,7 +518,7 @@ void CFG_DefaultSet_4_0_4() } } } - sysCfg.pulsetime[0] = sysCfg.ex_pulsetime; + sysCfg.pulsetime[0] = APP_PULSETIME; for (byte i = 1; i < MAX_PULSETIMERS; i++) { sysCfg.pulsetime[i] = 0; } @@ -554,9 +556,6 @@ void CFG_DefaultSet_5_0_2() void CFG_Delta() { if (sysCfg.version != VERSION) { // Fix version dependent changes - if (sysCfg.version < 0x03000600) { // 3.0.6 - Add parameter - sysCfg.ex_pulsetime = APP_PULSETIME; - } if (sysCfg.version < 0x03010200) { // 3.1.2 - Add parameter sysCfg.poweronstate = APP_POWERON_STATE; } @@ -637,6 +636,9 @@ void CFG_Delta() if (sysCfg.version < 0x05000500) { strlcpy(sysCfg.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(sysCfg.mqtt_fulltopic)); } + if (sysCfg.version < 0x05000600) { + sysCfg.mqtt_retry = MQTT_RETRY_SECS; + } sysCfg.version = VERSION; } } diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 8704b1965..f982c1b89 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -10,7 +10,7 @@ * ==================================================== */ -#define VERSION 0x05000500 // 5.0.5 +#define VERSION 0x05000600 // 5.0.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}; @@ -89,6 +89,9 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; #define WS2812_LEDS 30 // [Pixels] Number of LEDs #endif +#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x] +#define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic + #define WIFI_HOSTNAME "%s-%04d" // Expands to - #define CONFIG_FILE_SIGN 0xA5 // Configuration file signature #define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor) @@ -97,7 +100,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; #define HLW_UREF_PULSE 1950 // was 1666us = 600Hz = 220V #define HLW_IREF_PULSE 3500 // was 1666us = 600Hz = 4.545A -#define MQTT_RETRY_SECS 10 // Seconds to retry MQTT connection +#define MQTT_RETRY_SECS 10 // Minimum seconds to retry MQTT connection #define APP_POWER 0 // Default saved power state Off #define MAX_DEVICE 1 // Max number of devices #define MAX_PULSETIMERS 4 // Max number of supported pulse timers @@ -139,7 +142,7 @@ enum butt_t {PRESSED, NOT_PRESSED}; #define MESSZ 360 // Max number of characters in JSON message string (4 x DS18x20 sensors) #if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MESSZ // If the max message size is too small, throw an error at compile time // See pubsubclient.c line 359 - #error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 427" + #error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 467" #endif #include // RTC, HLW8012, OSWatch @@ -158,12 +161,10 @@ enum butt_t {PRESSED, NOT_PRESSED}; #include // I2C support library #endif // USE_I2C #ifdef USI_SPI - #include // SPI, TFT + #include // SPI support, TFT #endif // USE_SPI #include "settings.h" -typedef void (*rtcCallback)(); - #define MAX_BUTTON_COMMANDS 5 // Max number of button commands supported const char commands[MAX_BUTTON_COMMANDS][14] PROGMEM = { {"wificonfig 1"}, // Press button three times @@ -173,7 +174,6 @@ const char commands[MAX_BUTTON_COMMANDS][14] PROGMEM = { {"upgrade 1"}}; // Press button seven times const char wificfg[5][12] PROGMEM = { "Restart", "Smartconfig", "Wifimanager", "WPSconfig", "Retry" }; - const char PREFIXES[3][5] PROGMEM = { "cmnd", "stat", "tele" }; struct TIME_T { @@ -305,6 +305,45 @@ void getClient(char* output, const char* input, byte size) } } +void getTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic) +{ + char romram[CMDSZ]; + + snprintf_P(romram, sizeof(romram), subtopic); + String fulltopic = sysCfg.mqtt_fulltopic; + if ((0 == prefix) && (-1 == fulltopic.indexOf(F(MQTT_TOKEN_PREFIX)))) { + fulltopic += F("/" MQTT_TOKEN_PREFIX); // Need prefix for commands to handle mqtt topic loops + } + for (byte i = 0; i < 3; i++) { + if ('\0' == sysCfg.mqtt_prefix[i][0]) { + snprintf_P(sysCfg.mqtt_prefix[i], sizeof(sysCfg.mqtt_prefix[i]), PREFIXES[i]); + } + } + fulltopic.replace(F(MQTT_TOKEN_PREFIX), sysCfg.mqtt_prefix[prefix]); + fulltopic.replace(F(MQTT_TOKEN_TOPIC), topic); + fulltopic.replace(F("#"), ""); + fulltopic.replace(F("//"), "/"); + if (!fulltopic.endsWith("/")) { + fulltopic += "/"; + } + snprintf_P(stopic, TOPSZ, PSTR("%s%s"), fulltopic.c_str(), romram); +/* + char log[LOGSZ]; + snprintf_P(log, sizeof(log), PSTR("MTPC: %s"), stopic); + addLog(LOG_LEVEL_DEBUG, log); +*/ +} + +char* getStateText(byte state) +{ + if (state > 2) { + state = 1; + } + return sysCfg.state_text[state]; +} + +/********************************************************************************************/ + void setLatchingRelay(uint8_t power, uint8_t state) { power &= 1; @@ -366,46 +405,6 @@ void setLed(uint8_t state) /********************************************************************************************/ -void getTopic_P(char *stopic, byte idx, char *topic, const char* subtopic) -{ - char romram[CMDSZ]; - - snprintf_P(romram, sizeof(romram), subtopic); - String fulltopic = sysCfg.mqtt_fulltopic; - if ((0 == idx) && (-1 == fulltopic.indexOf(F("%prefix%")))) { - fulltopic += F("/%prefix%"); // Need prefix for commands to handle mqtt topic loops - } - for (byte i = 0; i < 3; i++) { - if ('\0' == sysCfg.mqtt_prefix[i][0]) { - snprintf_P(sysCfg.mqtt_prefix[i], sizeof(sysCfg.mqtt_prefix[i]), PREFIXES[i]); - } - } - fulltopic.replace(F("%prefix%"), sysCfg.mqtt_prefix[idx]); - fulltopic.replace(F("%topic%"), topic); - fulltopic.replace(F("#"), ""); - fulltopic.replace(F("//"), "/"); - if (!fulltopic.endsWith("/")) { - fulltopic += "/"; - } - snprintf_P(stopic, TOPSZ, PSTR("%s%s"), fulltopic.c_str(), romram); -/* - char log[LOGSZ]; - snprintf_P(log, sizeof(log), PSTR("MTPC: %s"), stopic); - addLog(LOG_LEVEL_DEBUG, log); -*/ -} - - -char* getStateText(byte state) -{ - if (state > 2) { - state = 1; - } - return sysCfg.state_text[state]; -} - -/********************************************************************************************/ - void mqtt_publish_sec(const char* topic, const char* data, boolean retained) { char log[TOPSZ + MESSZ]; @@ -447,12 +446,19 @@ void mqtt_publish(const char* topic, const char* data) void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data, boolean retained) { +/* prefix 0 = cmnd using subtopic + * prefix 1 = stat using subtopic + * prefix 2 = tele using subtopic + * prefix 4 = cmnd using subtopic or RESULT + * prefix 5 = stat using subtopic or RESULT + * prefix 6 = tele using subtopic or RESULT + */ char romram[16]; char stopic[TOPSZ]; snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.flag.mqtt_response) ? PSTR("RESULT") : subtopic); - prefix &= 1; - getTopic_P(stopic, prefix +1, sysCfg.mqtt_topic, romram); + prefix &= 3; + getTopic_P(stopic, prefix, sysCfg.mqtt_topic, romram); mqtt_publish(stopic, data, retained); } @@ -494,7 +500,7 @@ void mqtt_publishPowerBlinkState(byte device) snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device); snprintf_P(svalue, sizeof(svalue), PSTR("{\"POWER%s\":\"BLINK %s\"}"), (Maxdevice > 1) ? sdevice : "", getStateText(bitRead(blink_mask, device -1))); - mqtt_publish_topic_P(4, PSTR("POWER"), svalue); + mqtt_publish_topic_P(5, PSTR("POWER"), svalue); } void mqtt_connected() @@ -505,21 +511,20 @@ void mqtt_connected() if (sysCfg.flag.mqtt_enabled) { // Satisfy iobroker (#299) - getTopic_P(stopic, 0, sysCfg.mqtt_topic, PSTR("POWER")); - svalue[0] ='\0'; - mqtt_publish(stopic, svalue); + svalue[0] = '\0'; + mqtt_publish_topic_P(0, PSTR("POWER"), svalue); getTopic_P(stopic, 0, sysCfg.mqtt_topic, PSTR("#")); mqttClient.subscribe(stopic); mqttClient.loop(); // Solve LmacRxBlk:1 messages - - getTopic_P(stopic, 0, sysCfg.mqtt_grptopic, PSTR("#")); - mqttClient.subscribe(stopic); - mqttClient.loop(); // Solve LmacRxBlk:1 messages - - getTopic_P(stopic, 0, MQTTClient, PSTR("#")); - mqttClient.subscribe(stopic); - mqttClient.loop(); // Solve LmacRxBlk:1 messages + if (strstr(sysCfg.mqtt_fulltopic, MQTT_TOKEN_TOPIC) != NULL) { + getTopic_P(stopic, 0, sysCfg.mqtt_grptopic, PSTR("#")); + mqttClient.subscribe(stopic); + mqttClient.loop(); // Solve LmacRxBlk:1 messages + getTopic_P(stopic, 0, MQTTClient, PSTR("#")); + mqttClient.subscribe(stopic); + mqttClient.loop(); // Solve LmacRxBlk:1 messages + } #ifdef USE_DOMOTICZ domoticz_mqttSubscribe(); #endif // USE_DOMOTICZ @@ -528,17 +533,17 @@ void mqtt_connected() if (mqttflag) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"Module\":\"%s\", \"Version\":\"%s\", \"FallbackTopic\":\"%s\", \"GroupTopic\":\"%s\"}"), my_module.name, Version, MQTTClient, sysCfg.mqtt_grptopic); - mqtt_publish_topic_P(1, PSTR("INFO1"), svalue); + mqtt_publish_topic_P(2, PSTR("INFO1"), svalue); #ifdef USE_WEBSERVER if (sysCfg.webserver) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebserverMode\":\"%s\", \"Hostname\":\"%s\", \"IPaddress\":\"%s\"}"), (2 == sysCfg.webserver) ? "Admin" : "User", Hostname, WiFi.localIP().toString().c_str()); - mqtt_publish_topic_P(1, PSTR("INFO2"), svalue); + mqtt_publish_topic_P(2, PSTR("INFO2"), svalue); } #endif // USE_WEBSERVER snprintf_P(svalue, sizeof(svalue), PSTR("{\"Started\":\"%s\"}"), (getResetReason() == "Exception") ? ESP.getResetInfo().c_str() : getResetReason().c_str()); - mqtt_publish_topic_P(1, PSTR("INFO3"), svalue); + mqtt_publish_topic_P(2, PSTR("INFO3"), svalue); if (sysCfg.tele_period) { tele_period = sysCfg.tele_period -9; } @@ -556,7 +561,7 @@ void mqtt_reconnect() char svalue[TOPSZ]; char log[LOGSZ]; - mqttcounter = MQTT_RETRY_SECS; + mqttcounter = sysCfg.mqtt_retry; if (!sysCfg.flag.mqtt_enabled) { mqtt_connected(); @@ -635,6 +640,13 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } 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)) { + 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)) { sysCfg.flag.mqtt_response = payload; @@ -816,7 +828,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { if (!payload) { svalue[0] = '\0'; - mqtt_publish_topic_P(1, PSTR("SENSOR"), svalue, sysCfg.flag.mqtt_sensor_retain); + mqtt_publish_topic_P(2, PSTR("SENSOR"), svalue, sysCfg.flag.mqtt_sensor_retain); } sysCfg.flag.mqtt_sensor_retain = payload; } @@ -1084,7 +1096,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i +1, stemp1); } snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue); - mqtt_publish_topic_P(4, type, svalue); + mqtt_publish_topic_P(5, type, svalue); snprintf_P(svalue, sizeof(svalue), PSTR("{\"Modules2\":\""), svalue); jsflg = 0; for (byte i = MAXMODULE /2; i < MAXMODULE; i++) { @@ -1139,7 +1151,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i, stemp1); } snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue); - mqtt_publish_topic_P(4, type, svalue); + mqtt_publish_topic_P(5, type, svalue); snprintf_P(svalue, sizeof(svalue), PSTR("{\"GPIOs2\":\""), svalue); jsflg = 0; for (byte i = GPIO_SENSOR_END /2; i < GPIO_SENSOR_END; i++) { @@ -1481,7 +1493,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"Command\":\"Unknown\"}")); type = (char*)topicBuf; } - mqtt_publish_topic_P(4, type, svalue); + mqtt_publish_topic_P(5, type, svalue); } /********************************************************************************************/ @@ -1616,10 +1628,12 @@ void do_cmnd(char *cmnd) void publish_status(uint8_t payload) { char svalue[MESSZ]; - uint8_t option = 0; + uint8_t option = 1; // Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX - option = (!strcmp(sysCfg.mqtt_prefix[0],sysCfg.mqtt_prefix[1]) && (!payload)); + if (!strcmp(sysCfg.mqtt_prefix[0],sysCfg.mqtt_prefix[1]) && (!payload)) { + option++; + } if ((!sysCfg.flag.mqtt_enabled) && (6 == payload)) { payload = 99; @@ -1870,13 +1884,13 @@ void every_second() svalue[0] = '\0'; state_mqttPresent(svalue, sizeof(svalue)); - mqtt_publish_topic_P(1, PSTR("STATE"), svalue); + mqtt_publish_topic_P(2, PSTR("STATE"), svalue); uint8_t djson = 0; svalue[0] = '\0'; sensors_mqttPresent(svalue, sizeof(svalue), &djson); if (djson) { - mqtt_publish_topic_P(1, PSTR("SENSOR"), svalue, sysCfg.flag.mqtt_sensor_retain); + mqtt_publish_topic_P(2, PSTR("SENSOR"), svalue, sysCfg.flag.mqtt_sensor_retain); } if (hlw_flg) { @@ -1893,7 +1907,7 @@ void every_second() uptime_flg = false; uptime++; snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", \"Uptime\":%d}"), getDateTime().c_str(), uptime); - mqtt_publish_topic_P(1, PSTR("UPTIME"), svalue); + mqtt_publish_topic_P(2, PSTR("UPTIME"), svalue); } if ((3 == rtcTime.Minute) && !uptime_flg) { uptime_flg = true; @@ -2134,7 +2148,7 @@ void stateloop() snprintf_P(svalue, sizeof(svalue), PSTR("Failed %s"), ESPhttpUpdate.getLastErrorString().c_str()); } restartflag = 2; // Restart anyway to keep memory clean webserver - mqtt_publish_topic_P(0, PSTR("UPGRADE"), svalue); + mqtt_publish_topic_P(1, PSTR("UPGRADE"), svalue); } } break; diff --git a/sonoff/support.ino b/sonoff/support.ino index ef192664e..974259be2 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -309,8 +309,8 @@ void WIFI_begin(uint8_t flag) #ifdef USE_EMULATION UDP_Disconnect(); #endif // USE_EMULATION - if (!strncmp(ESP.getSdkVersion(),"1.5.3",5)) { - addLog_P(LOG_LEVEL_DEBUG, "Wifi: Patch issue 2186"); + if (!strncmp_P(ESP.getSdkVersion(),PSTR("1.5.3"),5)) { + addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifi: Patch issue 2186")); WiFi.mode(WIFI_OFF); // See https://github.com/esp8266/Arduino/issues/2186 } WiFi.disconnect(); diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index 4a213d62a..f26301eff 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -395,11 +395,11 @@ void showPage(String &page) if((HTTP_ADMIN == _httpflag) && (sysCfg.web_password[0] != 0) && !webServer->authenticate(WEB_USERNAME, sysCfg.web_password)) { return webServer->requestAuthentication(); } - page.replace("{ha}", my_module.name); - page.replace("{h}", sysCfg.friendlyname[0]); + page.replace(F("{ha}"), my_module.name); + page.replace(F("{h}"), sysCfg.friendlyname[0]); if (HTTP_MANAGER == _httpflag) { if (WIFI_configCounter()) { - page.replace("", ""); + page.replace(F(""), F("")); page += FPSTR(HTTP_COUNTER); } } @@ -424,8 +424,8 @@ void handleRoot() } else { char stemp[10], line[100]; String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Main menu"); - page.replace("", ""); + page.replace(F("{v}"), F("Main menu")); + page.replace(F(""), F("")); page += F("
"); if (Maxdevice) { @@ -552,7 +552,7 @@ void handleConfig() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle config")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Configuration"); + page.replace(F("{v}"), F("Configuration")); page += FPSTR(HTTP_BTN_MENU2); if (sysCfg.flag.mqtt_enabled) { page += FPSTR(HTTP_BTN_MENU3); @@ -614,11 +614,11 @@ void handleModule() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Module config")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Config module"); + page.replace(F("{v}"), F("Config module")); page += FPSTR(HTTP_FORM_MODULE); snprintf_P(stemp, sizeof(stemp), modules[MODULE].name); - page.replace("{mt}", stemp); + page.replace(F("{mt}"), stemp); for (byte i = 0; i < MAXMODULE; i++) { snprintf_P(stemp, sizeof(stemp), modules[i].name); @@ -650,8 +650,8 @@ void handleModule() } } func += F("}"); - page.replace("", func); - page.replace("", ""); + page.replace(F(""), func); + page.replace(F(""), F("")); page += FPSTR(HTTP_FORM_END); page += FPSTR(HTTP_BTN_CONF); @@ -678,8 +678,8 @@ void handleWifi(boolean scan) addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Wifi config")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Configure Wifi"); - page.replace("", FPSTR(HTTP_LNK_STYLE)); + page.replace(F("{v}"), F("Configure Wifi")); + page.replace(F(""), FPSTR(HTTP_LNK_STYLE)); if (scan) { #ifdef USE_EMULATION @@ -738,12 +738,12 @@ void handleWifi(boolean scan) String item = FPSTR(HTTP_LNK_ITEM); String rssiQ; rssiQ += quality; - item.replace("{v}", WiFi.SSID(indices[i])); - item.replace("{r}", rssiQ); + item.replace(F("{v}"), WiFi.SSID(indices[i])); + item.replace(F("{r}"), rssiQ); if (WiFi.encryptionType(indices[i]) != ENC_TYPE_NONE) { - item.replace("{i}", "l"); + item.replace(F("{i}"), F("l")); } else { - item.replace("{i}", ""); + item.replace(F("{i}"), ""); } page += item; delay(0); @@ -759,11 +759,11 @@ void handleWifi(boolean scan) } page += FPSTR(HTTP_FORM_WIFI); - page.replace("{h1}", sysCfg.hostname); - page.replace("{s1}", sysCfg.sta_ssid[0]); - page.replace("{p1}", sysCfg.sta_pwd[0]); - page.replace("{s2}", sysCfg.sta_ssid[1]); - page.replace("{p2}", sysCfg.sta_pwd[1]); + page.replace(F("{h1}"), sysCfg.hostname); + page.replace(F("{s1}"), sysCfg.sta_ssid[0]); + page.replace(F("{p1}"), sysCfg.sta_pwd[0]); + page.replace(F("{s2}"), sysCfg.sta_ssid[1]); + page.replace(F("{p2}"), sysCfg.sta_pwd[1]); page += FPSTR(HTTP_FORM_END); if (HTTP_MANAGER == _httpflag) { page += FPSTR(HTTP_BTN_RSTRT); @@ -781,17 +781,17 @@ void handleMqtt() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle MQTT config")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Configure MQTT"); + page.replace(F("{v}"), F("Configure MQTT")); page += FPSTR(HTTP_FORM_MQTT); char str[sizeof(sysCfg.mqtt_client)]; getClient(str, MQTT_CLIENT_ID, sizeof(sysCfg.mqtt_client)); - page.replace("{m0}", str); - page.replace("{m1}", sysCfg.mqtt_host); - page.replace("{m2}", String(sysCfg.mqtt_port)); - page.replace("{m3}", sysCfg.mqtt_client); - page.replace("{m4}", (sysCfg.mqtt_user[0] == '\0')?"0":sysCfg.mqtt_user); - page.replace("{m5}", (sysCfg.mqtt_pwd[0] == '\0')?"0":sysCfg.mqtt_pwd); - page.replace("{m6}", sysCfg.mqtt_topic); + page.replace(F("{m0}"), str); + page.replace(F("{m1}"), sysCfg.mqtt_host); + page.replace(F("{m2}"), String(sysCfg.mqtt_port)); + page.replace(F("{m3}"), sysCfg.mqtt_client); + page.replace(F("{m4}"), (sysCfg.mqtt_user[0] == '\0')?"0":sysCfg.mqtt_user); + page.replace(F("{m5}"), (sysCfg.mqtt_pwd[0] == '\0')?"0":sysCfg.mqtt_pwd); + page.replace(F("{m6}"), sysCfg.mqtt_topic); page += FPSTR(HTTP_FORM_END); page += FPSTR(HTTP_BTN_CONF); showPage(page); @@ -805,41 +805,41 @@ void handleLog() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Log config")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Config logging"); + page.replace(F("{v}"), F("Config logging")); page += FPSTR(HTTP_FORM_LOG1); for (byte idx = 0; idx < 3; idx++) { page += FPSTR(HTTP_FORM_LOG2); switch (idx) { case 0: - page.replace("{b0}", F("Serial ")); - page.replace("{b1}", STR(SERIAL_LOG_LEVEL)); - page.replace("{b2}", "ls"); + page.replace(F("{b0}"), F("Serial ")); + page.replace(F("{b1}"), STR(SERIAL_LOG_LEVEL)); + page.replace(F("{b2}"), F("ls")); for (byte i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) { - page.replace("{a" + String(i), (i == sysCfg.seriallog_level) ? " selected " : " "); + page.replace("{a" + String(i), (i == sysCfg.seriallog_level) ? F(" selected ") : F(" ")); } break; case 1: - page.replace("{b0}", F("Web ")); - page.replace("{b1}", STR(WEB_LOG_LEVEL)); - page.replace("{b2}", "lw"); + page.replace(F("{b0}"), F("Web ")); + page.replace(F("{b1}"), STR(WEB_LOG_LEVEL)); + page.replace(F("{b2}"), F("lw")); for (byte i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) { - page.replace("{a" + String(i), (i == sysCfg.weblog_level) ? " selected " : " "); + page.replace("{a" + String(i), (i == sysCfg.weblog_level) ? F(" selected ") : F(" ")); } break; case 2: - page.replace("{b0}", F("Sys")); - page.replace("{b1}", STR(SYS_LOG_LEVEL)); - page.replace("{b2}", "ll"); + page.replace(F("{b0}"), F("Sys")); + page.replace(F("{b1}"), STR(SYS_LOG_LEVEL)); + page.replace(F("{b2}"), F("ll")); for (byte i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) { - page.replace("{a" + String(i), (i == sysCfg.syslog_level) ? " selected " : " "); + page.replace("{a" + String(i), (i == sysCfg.syslog_level) ? F(" selected ") : F(" ")); } break; } } page += FPSTR(HTTP_FORM_LOG3); - page.replace("{l2}", sysCfg.syslog_host); - page.replace("{l3}", String(sysCfg.syslog_port)); - page.replace("{l4}", String(sysCfg.tele_period)); + page.replace(F("{l2}"), sysCfg.syslog_host); + page.replace(F("{l3}"), String(sysCfg.syslog_port)); + page.replace(F("{l4}"), String(sysCfg.tele_period)); page += FPSTR(HTTP_FORM_END); page += FPSTR(HTTP_BTN_CONF); showPage(page); @@ -854,25 +854,25 @@ void handleOther() char stemp[40]; String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Configure Other"); + page.replace(F("{v}"), F("Configure Other")); page += FPSTR(HTTP_FORM_OTHER); - page.replace("{p1}", sysCfg.web_password); - page.replace("{r1}", (sysCfg.flag.mqtt_enabled) ? " checked" : ""); + page.replace(F("{p1}"), sysCfg.web_password); + page.replace(F("{r1}"), (sysCfg.flag.mqtt_enabled) ? F(" checked") : F("")); page += FPSTR(HTTP_FORM_OTHER2); - page.replace("{1", "1"); - page.replace("{2", FRIENDLY_NAME); - page.replace("{3", sysCfg.friendlyname[0]); + page.replace(F("{1"), F("1")); + page.replace(F("{2"), FRIENDLY_NAME); + page.replace(F("{3"), sysCfg.friendlyname[0]); #ifdef USE_EMULATION page += FPSTR(HTTP_FORM_OTHER3); - page.replace("{r2}", (EMUL_NONE == sysCfg.flag.emulation) ? " checked" : ""); - page.replace("{r3}", (EMUL_WEMO == sysCfg.flag.emulation) ? " checked" : ""); - page.replace("{r4}", (EMUL_HUE == sysCfg.flag.emulation) ? " checked" : ""); + page.replace(F("{r2}"), (EMUL_NONE == sysCfg.flag.emulation) ? F(" checked") : F("")); + page.replace(F("{r3}"), (EMUL_WEMO == sysCfg.flag.emulation) ? F(" checked") : F("")); + page.replace(F("{r4}"), (EMUL_HUE == sysCfg.flag.emulation) ? F(" checked") : F("")); for (int i = 1; i < Maxdevice; i++) { page += FPSTR(HTTP_FORM_OTHER2); - page.replace("{1", String(i +1)); + page.replace(F("{1"), String(i +1)); snprintf_P(stemp, sizeof(stemp), PSTR(FRIENDLY_NAME"%d"), i +1); - page.replace("{2", stemp); - page.replace("{3", sysCfg.friendlyname[i]); + page.replace(F("{2"), stemp); + page.replace(F("{3"), sysCfg.friendlyname[i]); } page += F("
"); #endif // USE_EMULATION @@ -1011,7 +1011,7 @@ void handleSave() restart = (!strlen(webServer->arg("r").c_str())) ? 1 : atoi(webServer->arg("r").c_str()); if (restart) { String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Save parameters"); + page.replace(F("{v}"), F("Save parameters")); page += F("
Parameters saved
"); page += result; page += F("
"); @@ -1040,7 +1040,7 @@ void handleReset() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Reset parameters")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Default parameters"); + page.replace(F("{v}"), F("Default parameters")); page += F("
Parameters reset to default
"); page += FPSTR(HTTP_MSG_RSTRT); page += FPSTR(HTTP_BTN_MAIN); @@ -1058,7 +1058,7 @@ void handleRestore() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle restore")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Restore Configuration"); + page.replace(F("{v}"), F("Restore Configuration")); page += FPSTR(HTTP_FORM_RST); page += FPSTR(HTTP_BTN_CONF); showPage(page); @@ -1075,9 +1075,9 @@ void handleUpgrade() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle upgrade")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Firmware upgrade"); + page.replace(F("{v}"), F("Firmware upgrade")); page += FPSTR(HTTP_FORM_UPG); - page.replace("{o1}", sysCfg.otaUrl); + page.replace(F("{o1}"), sysCfg.otaUrl); page += FPSTR(HTTP_BTN_MAIN); showPage(page); @@ -1101,7 +1101,7 @@ void handleUpgradeStart() } String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Info"); + page.replace(F("{v}"), F("Info")); page += F("
Upgrade started ...
"); page += FPSTR(HTTP_MSG_RSTRT); page += FPSTR(HTTP_BTN_MAIN); @@ -1126,7 +1126,7 @@ void handleUploadDone() mqttcounter = 0; String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Info"); + page.replace(F("{v}"), F("Info")); page += F("
Upload "); if (_uploaderror) { page += F("failed

"); @@ -1356,9 +1356,9 @@ void handleConsole() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle console")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Console"); - page.replace("", FPSTR(HTTP_SCRIPT_CONSOL)); - page.replace("", ""); + page.replace(F("{v}"), F("Console")); + page.replace(F(""), FPSTR(HTTP_SCRIPT_CONSOL)); + page.replace(F(""), F("")); page += FPSTR(HTTP_FORM_CMND); page += FPSTR(HTTP_BTN_MAIN); showPage(page); @@ -1435,7 +1435,7 @@ void handleInfo() int freeMem = ESP.getFreeHeap(); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Information"); + page.replace(F("{v}"), F("Information")); // page += F("
 Information "); page += F(""); page += F(""); @@ -1534,7 +1534,7 @@ void handleRestart() addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Restarting")); String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Info"); + page.replace(F("{v}"), F("Info")); page += FPSTR(HTTP_MSG_RSTRT); if (HTTP_MANAGER == _httpflag) { _httpflag = HTTP_ADMIN; @@ -1561,14 +1561,13 @@ void handleNotFound() } else #endif // USE_EMULATION { - String message = "File Not Found\n\n"; - message += "URI: "; + String message = F("File Not Found\n\nURI: "); message += webServer->uri(); - message += "\nMethod: "; - message += ( webServer->method() == HTTP_GET ) ? "GET" : "POST"; - message += "\nArguments: "; + message += F("\nMethod: "); + message += ( webServer->method() == HTTP_GET ) ? F("GET") : F("POST"); + message += F("\nArguments: "); message += webServer->args(); - message += "\n"; + message += F("\n"); for ( uint8_t i = 0; i < webServer->args(); i++ ) { message += " " + webServer->argName ( i ) + ": " + webServer->arg ( i ) + "\n"; } diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino index a4143751e..7e7291717 100644 --- a/sonoff/xdrv_snfled.ino +++ b/sonoff/xdrv_snfled.ino @@ -156,7 +156,7 @@ void sl_animate() sl_tcolor[1] = sl_dcolor[1]; } else { snprintf_P(svalue, sizeof(svalue), PSTR("{\"Wakeup\":\"Done\"}")); - mqtt_publish_topic_P(1, PSTR("WAKEUP"), svalue); + mqtt_publish_topic_P(2, PSTR("WAKEUP"), svalue); sl_wakeupActive = 0; } } diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino index b7e1b9e2c..20c564d30 100644 --- a/sonoff/xdrv_wemohue.ino +++ b/sonoff/xdrv_wemohue.ino @@ -578,12 +578,11 @@ void hue_lights(String *path) } #endif // USE_WS2812 response += "]"; - webServer->send(200, "application/json", response); } else { response=FPSTR(HUE_ERROR_JSON); - webServer->send(200, "application/json", response); } + webServer->send(200, "application/json", response); } else if(path->indexOf("/lights/") >= 0) { // Got /lights/ID path->remove(0,8); // Remove /lights/ diff --git a/sonoff/xsns_dht.ino b/sonoff/xsns_dht.ino index 3b130b91a..b44e73616 100644 --- a/sonoff/xsns_dht.ino +++ b/sonoff/xsns_dht.ino @@ -202,13 +202,16 @@ void dht_init() dht[i].lastreadtime = -MIN_INTERVAL; switch (dht[i].type) { case GPIO_DHT11: - snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("DHT11-%02d"), dht[i].pin); + strcpy_P(dht[i].stype, PSTR("DHT11")); break; case GPIO_DHT21: - snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("AM2301-%02d"), dht[i].pin); + strcpy_P(dht[i].stype, PSTR("AM2301")); break; case GPIO_DHT22: - snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("DHT22-%02d"), dht[i].pin); + strcpy_P(dht[i].stype, PSTR("DHT22")); + } + if (dht_sensors > 1) { + snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("%s-%02d"), dht[i].stype, dht[i].pin); } } diff --git a/sonoff/xsns_hlw8012.ino b/sonoff/xsns_hlw8012.ino index 47d20d796..8a296b865 100644 --- a/sonoff/xsns_hlw8012.ino +++ b/sonoff/xsns_hlw8012.ino @@ -372,7 +372,7 @@ void hlw_margin_chk() } if (jsonflg) { snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue); - mqtt_publish_topic_P(1, PSTR("MARGINS"), svalue); + mqtt_publish_topic_P(2, PSTR("MARGINS"), svalue); } } @@ -386,7 +386,7 @@ void hlw_margin_chk() hlw_mplh_counter--; if (!hlw_mplh_counter) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pw, (sysCfg.flag.value_units) ? " W" : ""); - mqtt_publish_topic_P(0, PSTR("WARNING"), svalue); + mqtt_publish_topic_P(1, PSTR("WARNING"), svalue); do_cmnd_power(1, 0); if (!hlw_mplr_counter) { hlw_mplr_counter = MAX_POWER_RETRY +1; @@ -408,11 +408,11 @@ void hlw_margin_chk() hlw_mplr_counter--; if (hlw_mplr_counter) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"PowerMonitor\":\"%s\"}"), getStateText(1)); - mqtt_publish_topic_P(4, PSTR("POWERMONITOR"), svalue); + mqtt_publish_topic_P(5, PSTR("POWERMONITOR"), svalue); do_cmnd_power(1, 1); } else { snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReachedRetry\":\"%s\"}"), getStateText(0)); - mqtt_publish_topic_P(0, PSTR("WARNING"), svalue); + mqtt_publish_topic_P(1, PSTR("WARNING"), svalue); } } } @@ -425,14 +425,14 @@ void hlw_margin_chk() if (!hlw_mkwh_state && (rtcTime.Hour == sysCfg.hlw_mkwhs)) { hlw_mkwh_state = 1; snprintf_P(svalue, sizeof(svalue), PSTR("{\"EnergyMonitor\":\"%s\"}"), getStateText(1)); - mqtt_publish_topic_P(4, PSTR("ENERGYMONITOR"), svalue); + mqtt_publish_topic_P(5, PSTR("ENERGYMONITOR"), svalue); do_cmnd_power(1, 1); } else if ((1 == hlw_mkwh_state) && (uped >= sysCfg.hlw_mkwh)) { hlw_mkwh_state = 2; dtostrf(ped, 1, 3, svalue); snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyReached\":\"%s%s\"}"), svalue, (sysCfg.flag.value_units) ? " kWh" : ""); - mqtt_publish_topic_P(0, PSTR("WARNING"), svalue); + mqtt_publish_topic_P(1, PSTR("WARNING"), svalue); do_cmnd_power(1, 0); } } @@ -625,7 +625,7 @@ void hlw_mqttPresent() snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", "), getDateTime().c_str()); hlw_mqttStat(1, svalue, sizeof(svalue)); - mqtt_publish_topic_P(1, PSTR("ENERGY"), svalue); + mqtt_publish_topic_P(2, PSTR("ENERGY"), svalue); } void hlw_mqttStatus(char* svalue, uint16_t ssvalue)