Add initial support for optional for template specific commands

Add initial support for optional ``Template`` JSON fieldpair ``"CMND":"<any template related command>;<any template related command>;..."`` (#11788)
This commit is contained in:
Theo Arends 2021-04-25 16:51:18 +02:00
parent 8c42b5065d
commit b44c16d861
8 changed files with 60 additions and 25 deletions

View File

@ -3,7 +3,16 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
## [9.4.0.1]
## [9.4.0.2]
### Added
- Initial support for optional ``Template`` JSON fieldpair ``"CMND":"<any template related command>;<any template related command>;..."`` (#11788)
## [Released]
## [9.4.0] 20210423
- Release Leslie
## [9.4.0.1] 20210423
### Added
- Command ``Wifi 0/1`` for ESP8266 to turn wifi Off and On. When wifi is Off it is always returned On after a restart except for a wake-up from deepsleep (#11839)
@ -14,11 +23,6 @@ All notable changes to this project will be documented in this file.
- Command ``Power`` should not reset pulsetime (#11805)
- Teleperiod rule handling regression from v9.3.1.2 (#11851)
## [Released]
## [9.4.0] 20210422
- Release Leslie
## [9.3.1.4] 20210422
### Added
- Command ``TuyaTempSetRes 0..3`` to control Tuya Temperature Set Resolution (#11781)

View File

@ -76,18 +76,15 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
[Complete list](BUILDS.md) of available feature and sensors.
## Changelog v9.4.0.1
## Changelog v9.4.0.2
### Added
- Command ``Wifi 0/1`` for ESP8266 to turn wifi Off and On. When wifi is Off it is always returned On after a restart except for a wake-up from deepsleep [#11839](https://github.com/arendst/Tasmota/issues/11839)
- Initial support for optional ``Template`` JSON fieldpair ``"CMND":"<any template related command>;<any template related command>;..."`` [#11788](https://github.com/arendst/Tasmota/issues/11788)
### Breaking Changed
### Changed
- Zigbee refactored storage for device configuration and device last known data [#11838](https://github.com/arendst/Tasmota/issues/11838)
### Fixed
- Command ``Power`` should not reset pulsetime [#11805](https://github.com/arendst/Tasmota/issues/11805)
- Teleperiod rule handling regression from v9.3.1.2 [#11851](https://github.com/arendst/Tasmota/issues/11851)
### Noted
- ESP32 single core **tasmota32solo1.bin** binary can only be uploaded using the GUI as OTA upload will trigger the watchdog timer

View File

@ -345,6 +345,7 @@
#define D_JSON_GPIO "GPIO"
#define D_JSON_FLAG "FLAG"
#define D_JSON_BASE "BASE"
#define D_JSON_CMND "CMND"
#define D_CMND_TEMPOFFSET "TempOffset"
#define D_CMND_HUMOFFSET "HumOffset"
#define D_CMND_GLOBAL_TEMP "GlobalTemp"

View File

@ -1077,16 +1077,16 @@ void SettingsDefaultSet2(void) {
flag4.mqtt_tls |= MQTT_TLS_ENABLED;
flag4.mqtt_no_retain |= MQTT_NO_RETAIN;
#ifdef USER_TEMPLATE
String user_template = USER_TEMPLATE;
JsonTemplate((char*)user_template.c_str());
#endif
Settings.flag = flag;
Settings.flag2 = flag2;
Settings.flag3 = flag3;
Settings.flag4 = flag4;
Settings.flag5 = flag5;
#ifdef USER_TEMPLATE
String user_template = USER_TEMPLATE;
JsonTemplate((char*)user_template.c_str());
#endif
}
/********************************************************************************************/

View File

@ -515,6 +515,14 @@ char* UpperCase_P(char* dest, const char* source)
return dest;
}
char* StrStr_P(const char* source, const char* search) {
char case_source[strlen(source) +1];
UpperCase_P(case_source, source);
char case_search[strlen(search) +1];
UpperCase_P(case_search, search);
return strstr(case_source, case_search);
}
char* Trim(char* p)
{
if (*p != '\0') {
@ -1645,6 +1653,22 @@ bool JsonTemplate(char* dataBuf)
Settings.user_template_base = base -1; // Default WEMOS
}
val = root[PSTR(D_JSON_CMND)];
if (val) {
if ((USER_MODULE == Settings.module) || (StrStr_P(val.getStr(), PSTR(D_CMND_MODULE " 0")))) { // Only execute if current module = USER_MODULE = this template
char* backup_data = XdrvMailbox.data;
XdrvMailbox.data = (char*)val.getStr(); // Backlog commands
uint32_t backup_data_len = XdrvMailbox.data_len;
XdrvMailbox.data_len = 1; // Any data
uint32_t backup_index = XdrvMailbox.index;
XdrvMailbox.index = 0; // Backlog0 - no delay
CmndBacklog();
XdrvMailbox.index = backup_index;
XdrvMailbox.data_len = backup_data_len;
XdrvMailbox.data = backup_data;
}
}
// AddLog(LOG_LEVEL_DEBUG, PSTR("TPL: Converted"));
// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)&Settings.user_template, sizeof(Settings.user_template) / 2, 2);

View File

@ -326,20 +326,27 @@ void CmndBacklog(void) {
TasmotaGlobal.backlog_nodelay = true;
}
#ifdef SUPPORT_IF_STATEMENT
char *blcommand = strtok(XdrvMailbox.data, ";");
#ifdef SUPPORT_IF_STATEMENT
while ((blcommand != nullptr) && (backlog.size() < MAX_BACKLOG))
#else
uint32_t bl_pointer = (!TasmotaGlobal.backlog_pointer) ? MAX_BACKLOG -1 : TasmotaGlobal.backlog_pointer;
bl_pointer--;
char *blcommand = strtok(XdrvMailbox.data, ";");
while ((blcommand != nullptr) && (TasmotaGlobal.backlog_index != bl_pointer))
#endif
{
// Ignore ; within double quotes (") but find ; after first even quote
char *next = strchr(blcommand, '\0') +1; // Prepare for next ;
while ((next != nullptr) && (ChrCount(blcommand, "\"") % 2)) { // Check for even quote count
next--; // Select end of line
*next = ';'; // Restore ; removed by strtok()
next = strtok(nullptr, ";"); // Point to begin of next string up to next ; or nullptr
}
// Skip unnecessary command Backlog at start of blcommand
while(true) {
blcommand = Trim(blcommand);
if (!strncasecmp_P(blcommand, PSTR(D_CMND_BACKLOG), strlen(D_CMND_BACKLOG))) {
blcommand += strlen(D_CMND_BACKLOG); // Skip unnecessary command Backlog
blcommand += strlen(D_CMND_BACKLOG);
} else {
break;
}
@ -352,7 +359,9 @@ void CmndBacklog(void) {
#else
TasmotaGlobal.backlog[TasmotaGlobal.backlog_index] = blcommand;
TasmotaGlobal.backlog_index++;
if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) TasmotaGlobal.backlog_index = 0;
if (TasmotaGlobal.backlog_index >= MAX_BACKLOG) {
TasmotaGlobal.backlog_index = 0;
}
#endif
}
blcommand = strtok(nullptr, ";");

View File

@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
const uint32_t VERSION = 0x09040001;
const uint32_t VERSION = 0x09040002;
#endif // _TASMOTA_VERSION_H_

View File

@ -2130,11 +2130,11 @@ void HandleOtherConfiguration(void) {
}
void OtherSaveSettings(void) {
char tmp1[300]; // Needs to hold complete ESP32 template of minimal 230 chars
char tmp1[400]; // Needs to hold complete ESP32 template of minimal 230 chars
WebGetArg(PSTR("dn"), tmp1, sizeof(tmp1)); // Device name
char tmp2[TOPSZ];
WebGetArg(PSTR("wp"), tmp2, sizeof(tmp2)); // Web password
char command[500];
char command[600];
snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_WEBPASSWORD "2 %s;" D_CMND_SO "3 %d;" D_CMND_DEVICENAME " %s"),
(!strlen(tmp2)) ? "\"" : (strlen(tmp2) < 5) ? "" : tmp2,
Webserver->hasArg(F("b1")), // SetOption3 - Enable MQTT
@ -2155,8 +2155,8 @@ void OtherSaveSettings(void) {
#endif // USE_EMULATION
WebGetArg(PSTR("t1"), tmp1, sizeof(tmp1)); // Template
if (strlen(tmp1)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255}
snprintf_P(command, sizeof(command), PSTR("%s;" D_CMND_TEMPLATE " %s%s"), command, tmp1, (Webserver->hasArg(F("t2"))) ? PSTR("; " D_CMND_MODULE " 0") : "");
if (strlen(tmp1)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255,"CMND":"SO123 1;SO99 0"}
snprintf_P(command, sizeof(command), PSTR("%s;%s" D_CMND_TEMPLATE " %s"), command, (Webserver->hasArg(F("t2"))) ? PSTR(D_CMND_MODULE " 0;") : "", tmp1);
}
ExecuteWebCommand(command);
}