diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 1804b32c58b3..da5dd225f2ae 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,9 +52,13 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.2.0.1 +### Version 8.2.0.2 - Change HM-10 sensor type detection and add features (#7962) -- Change GPIO initialization solving possible Relay toggle on (OTA) restart +- Fix possible Relay toggle on (OTA) restart - Fix Zigbee sending wrong Sat value with Hue emulation -- Add command ``ZbRestore`` to restore device configuration dumped with ``ZbStatus 2`` +- Add Zigbee command ``ZbRestore`` to restore device configuration dumped with ``ZbStatus 2`` +- Add Zigbee command ``ZbUnbind`` +- Add support for unreachable (unplugged) Zigbee devices in Philips Hue emulation and Alexa +- Add support for 64x48 SSD1306 OLED (#6740) +- Add support for up to four MQTT GroupTopics using the same optional Device Group names (#8014) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index c874a0ef4b85..fa969d778c29 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,13 +1,17 @@ ## Unreleased (development) +### 8.2.0.2 20200328 + +- Add support for up to four MQTT GroupTopics using the same optional Device Group names (#8014) + ### 8.2.0.1 20200321 - Change HM-10 sensor type detection and add features (#7962) -- Change GPIO initialization solving possible Relay toggle on (OTA) restart +- Fix possible Relay toggle on (OTA) restart - Fix Zigbee sending wrong Sat value with Hue emulation -- Add command ``ZbRestore`` to restore device configuration dumped with ``ZbStatus 2`` +- Add ZIgbee command ``ZbRestore`` to restore device configuration dumped with ``ZbStatus 2`` +- Add Zigbee command ``ZbUnbind`` - Add support for unreachable (unplugged) Zigbee devices in Philips Hue emulation and Alexa -- Add Zigbee ``ZbUnbind``command - Add support for 64x48 SSD1306 OLED (#6740) ## Released diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 910d4c7fed66..ab80c4cf6072 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -344,7 +344,6 @@ // -- MQTT ---------------------------------------- #define MQTT_TELE_RETAIN 0 // Tele messages may send retain flag (0 = off, 1 = on) #define MQTT_CLEAN_SESSION 1 // Mqtt clean session connection (0 = No clean session, 1 = Clean session (default)) -//#define USE_GROUPTOPIC_SET // Enable multiple GROUPTOPIC, x=1-4 (+0k1 code) // -- MQTT - Domoticz ----------------------------- #define USE_DOMOTICZ // Enable Domoticz (+6k code, +0.3k mem) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index e1cc9e812c3a..133203a3ef85 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -107,9 +107,11 @@ void ResponseCmndIdxChar(const char* value) void ResponseCmndAll(uint32_t text_index, uint32_t count) { + uint32_t real_index = text_index; mqtt_data[0] = '\0'; for (uint32_t i = 0; i < count; i++) { - ResponseAppend_P(PSTR("%c\"%s%d\":\"%s\""), (i) ? ',' : '{', XdrvMailbox.command, i +1, SettingsText(text_index +i)); + if ((SET_MQTT_GRP_TOPIC == text_index) && (1 == i)) { real_index = SET_MQTT_GRP_TOPIC2 -1; } + ResponseAppend_P(PSTR("%c\"%s%d\":\"%s\""), (i) ? ',' : '{', XdrvMailbox.command, i +1, SettingsText(real_index +i)); } ResponseJsonEnd(); } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index a42515899d48..23a4caad7c78 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -130,7 +130,7 @@ char* GetTopic_P(char *stopic, uint32_t prefix, char *topic, const char* subtopi return stopic; } -char* GetGroupTopic_P(char *stopic, const char* subtopic, int itopic) +char* GetGroupTopic_P(char *stopic, const char* subtopic, uint32_t itopic) { // SetOption75 0: %prefix%/nothing/%topic% = cmnd/nothing//# // SetOption75 1: cmnd/ diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index a1c7d1082038..033b8d783aad 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -81,6 +81,7 @@ const uint8_t MAX_NTP_SERVERS = 3; // Max number of NTP servers const uint8_t MAX_RULE_MEMS = 16; // Max number of saved vars const uint8_t MAX_FRIENDLYNAMES = 8; // Max number of Friendly names const uint8_t MAX_BUTTON_TEXT = 16; // Max number of GUI button labels +const uint8_t MAX_GROUP_TOPICS = 4; // Max number of Group Topics const uint8_t MAX_HUE_DEVICES = 15; // Max number of Philips Hue device per emulation diff --git a/tasmota/tasmota_post.h b/tasmota/tasmota_post.h index d7a36f160ac1..1bba02172bf2 100644 --- a/tasmota/tasmota_post.h +++ b/tasmota/tasmota_post.h @@ -98,7 +98,6 @@ extern "C" void resetPins(); #define CODE_IMAGE_STR "sensors" #undef USE_DISCOVERY // Disable mDNS (+8k code or +23.5k code with core 2_5_x, +0.3k mem) -#undef USE_GROUPTOPIC_SET // Disable multiple GROUPTOPIC, x=1-4 (+0k1 code) // -- Optional modules ---------------------------- //#define ROTARY_V1 // Add support for MI Desk Lamp @@ -274,7 +273,6 @@ extern "C" void resetPins(); #undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#undef USE_GROUPTOPIC_SET // Disable multiple GROUPTOPIC, x=1-4 (+0k1 code) #endif // FIRMWARE_KNX_NO_EMULATION /*********************************************************************************************\ @@ -294,7 +292,6 @@ extern "C" void resetPins(); #undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common) #undef USE_DOMOTICZ // Disable Domoticz #undef USE_HOME_ASSISTANT // Disable Home Assistant -#undef USE_GROUPTOPIC_SET // Disable multiple GROUPTOPIC, x=1-4 (+0k1 code) // -- Optional modules ---------------------------- #undef ROTARY_V1 // Disable support for MI Desk Lamp @@ -376,7 +373,6 @@ extern "C" void resetPins(); //#undef USE_SUNRISE // Disable support for Sunrise and sunset tools //#undef USE_RULES // Disable support for rules #undef USE_DISCOVERY // Disable mDNS for the following services (+8k code or +23.5k code with core 2_5_x, +0.3k mem) -#undef USE_GROUPTOPIC_SET // Disable multiple GROUPTOPIC, x=1-4 (+0k1 code) // -- Optional modules ---------------------------- #undef ROTARY_V1 // Disable support for MI Desk Lamp @@ -478,7 +474,6 @@ extern "C" void resetPins(); #undef USE_DOMOTICZ // Disable Domoticz #undef USE_HOME_ASSISTANT // Disable Home Assistant #undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set -#undef USE_GROUPTOPIC_SET // Disable multiple GROUPTOPIC, x=1-4 (+0k1 code) #undef USE_KNX // Disable KNX IP Protocol Support //#undef USE_WEBSERVER // Disable Webserver #undef USE_WEBSEND_RESPONSE // Disable command WebSend response message (+1k code) @@ -600,7 +595,6 @@ extern "C" void resetPins(); #undef USE_DOMOTICZ // Disable Domoticz #undef USE_HOME_ASSISTANT // Disable Home Assistant //#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set -#undef USE_GROUPTOPIC_SET // Disable multiple GROUPTOPIC, x=1-4 (+0k1 code) #undef USE_KNX // Disable KNX IP Protocol Support //#undef USE_WEBSERVER // Disable Webserver #undef USE_WEBSEND_RESPONSE // Disable command WebSend response message (+1k code) diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 3bc994c67079..47879d1fe4e3 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08020001; +const uint32_t VERSION = 0x08020002; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 31531af88841..f48ce94319c8 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2126,17 +2126,13 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1" D_MQTT_USER "}2%s"), SettingsText(SET_MQTT_USER)); WSContentSend_P(PSTR("}1" D_MQTT_CLIENT "}2%s"), mqtt_client); WSContentSend_P(PSTR("}1" D_MQTT_TOPIC "}2%s"), SettingsText(SET_MQTT_TOPIC)); -// WSContentSend_P(PSTR("}1" D_MQTT_GROUP_TOPIC "}2%s"), SettingsText(SET_MQTT_GRP_TOPIC)); -#ifdef USE_GROUPTOPIC_SET - WSContentSend_P(PSTR("}1" D_MQTT_GROUP_TOPIC " 1}2%s"), GetGroupTopic_P(stopic, "", SET_MQTT_GRP_TOPIC)); - for(uint32_t i=0; i < 3; i++) { - if (strlen(SettingsText(SET_MQTT_GRP_TOPIC2+i))) { - WSContentSend_P(PSTR("}1" D_MQTT_GROUP_TOPIC " %d}2%s"), 2+i, GetGroupTopic_P(stopic, "", SET_MQTT_GRP_TOPIC2+i)); + uint32_t real_index = SET_MQTT_GRP_TOPIC; + for (uint32_t i = 0; i < MAX_GROUP_TOPICS; i++) { + if (1 == i) { real_index = SET_MQTT_GRP_TOPIC2 -1; } + if (strlen(SettingsText(real_index +i))) { + WSContentSend_P(PSTR("}1" D_MQTT_GROUP_TOPIC " %d}2%s"), 1 +i, GetGroupTopic_P(stopic, "", real_index +i)); } } -#else // USE_GROUPTOPIC_SET - WSContentSend_P(PSTR("}1" D_MQTT_GROUP_TOPIC "}2%s"), GetGroupTopic_P(stopic, "", SET_MQTT_GRP_TOPIC)); -#endif // USE_GROUPTOPIC_SET WSContentSend_P(PSTR("}1" D_MQTT_FULL_TOPIC "}2%s"), GetTopic_P(stopic, CMND, mqtt_topic, "")); WSContentSend_P(PSTR("}1" D_MQTT " " D_FALLBACK_TOPIC "}2%s"), GetFallbackTopic_P(stopic, "")); } else { diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 22fcb2d9daaa..ac3065fe8c82 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -510,16 +510,14 @@ void MqttConnected(void) GetTopic_P(stopic, CMND, mqtt_topic, PSTR("#")); MqttSubscribe(stopic); if (strstr_P(SettingsText(SET_MQTT_FULLTOPIC), MQTT_TOKEN_TOPIC) != nullptr) { - GetGroupTopic_P(stopic, PSTR("#"), SET_MQTT_GRP_TOPIC); // SetOption75 0: %prefix%/nothing/%topic% = cmnd/nothing//# or SetOption75 1: cmnd/ - MqttSubscribe(stopic); -#ifdef USE_GROUPTOPIC_SET - for(uint32_t i=0; i < 3; i++) { - if (strlen(SettingsText(SET_MQTT_GRP_TOPIC2+i))) { - GetGroupTopic_P(stopic, PSTR("#"), SET_MQTT_GRP_TOPIC2+i); + uint32_t real_index = SET_MQTT_GRP_TOPIC; + for (uint32_t i = 0; i < MAX_GROUP_TOPICS; i++) { + if (1 == i) { real_index = SET_MQTT_GRP_TOPIC2 -1; } + if (strlen(SettingsText(real_index +i))) { + GetGroupTopic_P(stopic, PSTR("#"), real_index +i); // SetOption75 0: %prefix%/nothing/%topic% = cmnd/nothing//# or SetOption75 1: cmnd/ MqttSubscribe(stopic); } } -#endif GetFallbackTopic_P(stopic, PSTR("#")); MqttSubscribe(stopic); } @@ -889,26 +887,52 @@ void CmndPublish(void) void CmndGroupTopic(void) { -#if defined(USE_DEVICE_GROUPS ) || defined(USE_GROUPTOPIC_SET) - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) { - uint32_t settings_text_index = (XdrvMailbox.index <= 1 ? SET_MQTT_GRP_TOPIC : SET_MQTT_GRP_TOPIC2 + XdrvMailbox.index - 2); -#endif // USE_DEVICE_GROUPS || USE_GROUPTOPIC_SET - if (XdrvMailbox.data_len > 0) { - MakeValidMqtt(0, XdrvMailbox.data); - if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); } -#if defined(USE_DEVICE_GROUPS ) || defined(USE_GROUPTOPIC_SET) - SettingsUpdateText(settings_text_index, (SC_DEFAULT == Shortcut()) ? MQTT_GRPTOPIC : XdrvMailbox.data); -#else // USE_DEVICE_GROUPS || USE_GROUPTOPIC_SET - SettingsUpdateText(SET_MQTT_GRP_TOPIC, (SC_DEFAULT == Shortcut()) ? MQTT_GRPTOPIC : XdrvMailbox.data); -#endif // USE_DEVICE_GROUPS || USE_GROUPTOPIC_SET - restart_flag = 2; - } -#if defined(USE_DEVICE_GROUPS ) || defined(USE_GROUPTOPIC_SET) - ResponseCmndChar(SettingsText(settings_text_index)); + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_GROUP_TOPICS)) { + if (XdrvMailbox.data_len > 0) { + uint32_t settings_text_index = (1 == XdrvMailbox.index) ? SET_MQTT_GRP_TOPIC : SET_MQTT_GRP_TOPIC2 + XdrvMailbox.index - 2; + MakeValidMqtt(0, XdrvMailbox.data); + if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); } + SettingsUpdateText(settings_text_index, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_GRPTOPIC : XdrvMailbox.data); + + // Eliminate duplicates, have at least one and fill from index 1 + char stemp[MAX_GROUP_TOPICS][TOPSZ]; + uint32_t read_index = 0; + uint32_t real_index = SET_MQTT_GRP_TOPIC; + for (uint32_t i = 0; i < MAX_GROUP_TOPICS; i++) { + if (1 == i) { real_index = SET_MQTT_GRP_TOPIC2 -1; } + if (strlen(SettingsText(real_index +i))) { + bool not_equal = true; + for (uint32_t j = 0; j < read_index; j++) { + if (!strcmp(SettingsText(real_index +i), stemp[j])) { // Topics are case-sensitive + not_equal = false; + } + } + if (not_equal) { + strncpy(stemp[read_index], SettingsText(real_index +i), sizeof(stemp[read_index])); + read_index++; + } + } + } + if (0 == read_index) { + SettingsUpdateText(SET_MQTT_GRP_TOPIC, MQTT_GRPTOPIC); + } else { + uint32_t write_index = 0; + uint32_t real_index = SET_MQTT_GRP_TOPIC; + for (uint32_t i = 0; i < MAX_GROUP_TOPICS; i++) { + if (1 == i) { real_index = SET_MQTT_GRP_TOPIC2 -1; } + if (write_index < read_index) { + SettingsUpdateText(real_index +i, stemp[write_index]); + write_index++; + } else { + SettingsUpdateText(real_index +i, ""); + } + } + } + + restart_flag = 2; + } + ResponseCmndAll(SET_MQTT_GRP_TOPIC, MAX_GROUP_TOPICS); } -#else // USE_DEVICE_GROUPS || USE_GROUPTOPIC_SET - ResponseCmndChar(SettingsText(SET_MQTT_GRP_TOPIC)); -#endif // USE_DEVICE_GROUPS || USE_GROUPTOPIC_SET } void CmndTopic(void)