mirror of https://github.com/arendst/Tasmota.git
Change command handling
* Change command SetOption43 to make it more general. Now supports PS_16_DZ driver too (#6547) * Change command handling by moving buffers up in chain solving MQTTlog support (#6524) * Change detection of non-MQTT commands by allowing non-space characters as delimiter (#6540)
This commit is contained in:
parent
97de80bba1
commit
8c34b9edbd
|
@ -8,6 +8,9 @@
|
||||||
* Add command to MCP230xx: sensor29 pin,0/1/2 for OFF/ON/TOGGLE
|
* Add command to MCP230xx: sensor29 pin,0/1/2 for OFF/ON/TOGGLE
|
||||||
* Add initial support for PCF8574 I2C I/O Expander (currently output only) by Stefan Bode
|
* Add initial support for PCF8574 I2C I/O Expander (currently output only) by Stefan Bode
|
||||||
* Add command SetOption71 0/1 to switch between different Modbus Active Energy registers on DDS238-2 energy meters (#6531)
|
* Add command SetOption71 0/1 to switch between different Modbus Active Energy registers on DDS238-2 energy meters (#6531)
|
||||||
|
* Change command SetOption43 to make it more general. Now supports PS_16_DZ driver too (#6547)
|
||||||
|
* Change command handling by moving buffers up in chain solving MQTTlog support (#6524)
|
||||||
|
* Change detection of non-MQTT commands by allowing non-space characters as delimiter (#6540)
|
||||||
*
|
*
|
||||||
* 6.6.0.13 20190922
|
* 6.6.0.13 20190922
|
||||||
* Add command EnergyReset4 x,x to initialize total usage for two tarrifs
|
* Add command EnergyReset4 x,x to initialize total usage for two tarrifs
|
||||||
|
|
|
@ -81,55 +81,61 @@ void ResponseCmndIdxChar(const char* value)
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
void ExecuteCommand(char *cmnd, uint32_t source)
|
void ExecuteCommand(const char *cmnd, uint32_t source)
|
||||||
{
|
{
|
||||||
char *start;
|
// cmnd: "status 0" = stopic "status" and svalue " 0"
|
||||||
char *token;
|
// cmnd: "var1 =1" = stopic "var1" and svalue " =1"
|
||||||
|
// cmnd: "var1=1" = stopic "var1" and svalue "=1"
|
||||||
#ifdef USE_DEBUG_DRIVER
|
#ifdef USE_DEBUG_DRIVER
|
||||||
ShowFreeMem(PSTR("ExecuteCommand"));
|
ShowFreeMem(PSTR("ExecuteCommand"));
|
||||||
#endif
|
#endif
|
||||||
ShowSource(source);
|
ShowSource(source);
|
||||||
|
|
||||||
token = strtok(cmnd, " ");
|
const char *pos = cmnd;
|
||||||
if (token != nullptr) {
|
while (*pos && isspace(*pos)) {
|
||||||
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
|
pos++; // Skip all spaces
|
||||||
if (start) { token = start +1; }
|
|
||||||
}
|
}
|
||||||
uint32_t size = (token != nullptr) ? strlen(token) : 0;
|
|
||||||
char stopic[size +2]; // / + \0
|
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("/%s"), (token == nullptr) ? "" : token);
|
|
||||||
|
|
||||||
token = strtok(nullptr, "");
|
const char *start = pos;
|
||||||
size = (token != nullptr) ? strlen(token) : 0;
|
// Get a command. Commands can only use letters, digits and underscores
|
||||||
char svalue[size +1];
|
while (*pos && (isalpha(*pos) || isdigit(*pos) || '_' == *pos || '/' == *pos)) {
|
||||||
strlcpy(svalue, (token == nullptr) ? "" : token, sizeof(svalue)); // Fixed 5.8.0b
|
if ('/' == *pos) { // Skip possible cmnd/sonoff/ preamble
|
||||||
CommandHandler(stopic, (uint8_t*)svalue, strlen(svalue));
|
start = pos + 1;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
if ('\0' == *start || pos <= start) {
|
||||||
|
return; // Did not find any command to execute
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size = pos - start;
|
||||||
|
char stopic[size + 2]; // with leader '/' and end '\0'
|
||||||
|
stopic[0] = '/';
|
||||||
|
memcpy(stopic+1, start, size);
|
||||||
|
stopic[size+1] = '\0';
|
||||||
|
|
||||||
|
char svalue[strlen(pos) +1]; // pos point to the start of parameters
|
||||||
|
strlcpy(svalue, pos, sizeof(svalue));
|
||||||
|
CommandHandler(stopic, svalue, strlen(svalue));
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
// topic: /power1 data: toggle = Console command
|
// topicBuf: /power1 dataBuf: toggle = Console command
|
||||||
// topic: cmnd/sonoff/power1 data: toggle = Mqtt command using topic
|
// topicBuf: cmnd/sonoff/power1 dataBuf: toggle = Mqtt command using topic
|
||||||
// topic: cmnd/sonoffs/power1 data: toggle = Mqtt command using a group topic
|
// topicBuf: cmnd/sonoffs/power1 dataBuf: toggle = Mqtt command using a group topic
|
||||||
// topic: cmnd/DVES_83BB10_fb/power1 data: toggle = Mqtt command using fallback topic
|
// topicBuf: cmnd/DVES_83BB10_fb/power1 dataBuf: toggle = Mqtt command using fallback topic
|
||||||
|
|
||||||
void CommandHandler(char* topic, uint8_t* data, uint32_t data_len)
|
void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len)
|
||||||
{
|
{
|
||||||
#ifdef USE_DEBUG_DRIVER
|
#ifdef USE_DEBUG_DRIVER
|
||||||
ShowFreeMem(PSTR("CommandHandler"));
|
ShowFreeMem(PSTR("CommandHandler"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char topicBuf[TOPSZ];
|
while (*dataBuf && isspace(*dataBuf)) {
|
||||||
strlcpy(topicBuf, topic, sizeof(topicBuf));
|
dataBuf++; // Skip leading spaces in data
|
||||||
|
data_len--;
|
||||||
uint32_t i = 0;
|
|
||||||
for (i = 0; i < data_len; i++) {
|
|
||||||
if (!isspace(data[i])) { break; } // Skip leading spaces in data
|
|
||||||
}
|
}
|
||||||
data_len -= i;
|
|
||||||
char dataBuf[data_len+1];
|
|
||||||
memcpy(dataBuf, data +i, sizeof(dataBuf));
|
|
||||||
|
|
||||||
bool grpflg = (strstr(topicBuf, Settings.mqtt_grptopic) != nullptr);
|
bool grpflg = (strstr(topicBuf, Settings.mqtt_grptopic) != nullptr);
|
||||||
|
|
||||||
|
@ -137,8 +143,9 @@ void CommandHandler(char* topic, uint8_t* data, uint32_t data_len)
|
||||||
GetFallbackTopic_P(stemp1, CMND, ""); // Full Fallback topic = cmnd/DVES_xxxxxxxx_fb/
|
GetFallbackTopic_P(stemp1, CMND, ""); // Full Fallback topic = cmnd/DVES_xxxxxxxx_fb/
|
||||||
fallback_topic_flag = (!strncmp(topicBuf, stemp1, strlen(stemp1)));
|
fallback_topic_flag = (!strncmp(topicBuf, stemp1, strlen(stemp1)));
|
||||||
|
|
||||||
char *type = strrchr(topicBuf, '/'); // Last part of received topic is always the command (type)
|
char *type = strrchr(topicBuf, '/'); // Last part of received topic is always the command (type)
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
uint32_t index = 1;
|
uint32_t index = 1;
|
||||||
bool user_index = false;
|
bool user_index = false;
|
||||||
if (type != nullptr) {
|
if (type != nullptr) {
|
||||||
|
@ -156,7 +163,7 @@ void CommandHandler(char* topic, uint8_t* data, uint32_t data_len)
|
||||||
type[i] = '\0';
|
type[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_CORE_LOG(PSTR("CMD: " D_GROUP " %d, " D_INDEX " %d, " D_COMMAND " \"%s\", " D_DATA " \"%s\""), grpflg, index, type, dataBuf);
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CMD: " D_GROUP " %d, " D_INDEX " %d, " D_COMMAND " \"%s\", " D_DATA " \"%s\""), grpflg, index, type, dataBuf);
|
||||||
|
|
||||||
if (type != nullptr) {
|
if (type != nullptr) {
|
||||||
Response_P(PSTR("{\"" D_JSON_COMMAND "\":\"" D_JSON_ERROR "\"}"));
|
Response_P(PSTR("{\"" D_JSON_COMMAND "\":\"" D_JSON_ERROR "\"}"));
|
||||||
|
@ -686,11 +693,9 @@ void CmndSetoption(void)
|
||||||
IrReceiveUpdateThreshold();
|
IrReceiveUpdateThreshold();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TUYA_MCU
|
|
||||||
case P_DIMMER_MAX:
|
case P_DIMMER_MAX:
|
||||||
restart_flag = 2; // Need a restart to update GUI
|
restart_flag = 2; // Need a restart to update GUI
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,7 +251,7 @@ bool MqttPublishLib(const char* topic, bool retained)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len)
|
||||||
{
|
{
|
||||||
#ifdef USE_DEBUG_DRIVER
|
#ifdef USE_DEBUG_DRIVER
|
||||||
ShowFreeMem(PSTR("MqttDataHandler"));
|
ShowFreeMem(PSTR("MqttDataHandler"));
|
||||||
|
@ -262,8 +262,8 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
||||||
|
|
||||||
// Do not execute multiple times if Prefix1 equals Prefix2
|
// Do not execute multiple times if Prefix1 equals Prefix2
|
||||||
if (!strcmp(Settings.mqtt_prefix[0], Settings.mqtt_prefix[1])) {
|
if (!strcmp(Settings.mqtt_prefix[0], Settings.mqtt_prefix[1])) {
|
||||||
char *str = strstr(topic, Settings.mqtt_prefix[0]);
|
char *str = strstr(mqtt_topic, Settings.mqtt_prefix[0]);
|
||||||
if ((str == topic) && mqtt_cmnd_publish) {
|
if ((str == mqtt_topic) && mqtt_cmnd_publish) {
|
||||||
if (mqtt_cmnd_publish > 3) {
|
if (mqtt_cmnd_publish > 3) {
|
||||||
mqtt_cmnd_publish -= 3;
|
mqtt_cmnd_publish -= 3;
|
||||||
} else {
|
} else {
|
||||||
|
@ -273,10 +273,15 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data[data_len] = 0;
|
// Save MQTT data ASAP as it's data is discarded by PubSubClient with next publish as used in MQTTlog
|
||||||
|
char topic[TOPSZ];
|
||||||
|
strlcpy(topic, mqtt_topic, sizeof(topic));
|
||||||
|
mqtt_data[data_len] = 0;
|
||||||
|
char data[data_len +1];
|
||||||
|
memcpy(data, mqtt_data, sizeof(data));
|
||||||
|
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_MQTT D_RECEIVED_TOPIC " %s, " D_DATA_SIZE " %d, " D_DATA " %s"), topic, data_len, data);
|
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_MQTT D_RECEIVED_TOPIC " \"%s\", " D_DATA_SIZE " %d, " D_DATA " \"%s\""), topic, data_len, data);
|
||||||
// if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) { Serial.println(dataBuf); }
|
// if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) { Serial.println(data); }
|
||||||
|
|
||||||
// MQTT pre-processing
|
// MQTT pre-processing
|
||||||
XdrvMailbox.index = strlen(topic);
|
XdrvMailbox.index = strlen(topic);
|
||||||
|
|
Loading…
Reference in New Issue