Refactor MQTT commands

Refactor MQTT commands
This commit is contained in:
Theo Arends 2019-07-28 17:14:20 +02:00
parent a3e12dd3c8
commit 13a618634e
4 changed files with 369 additions and 329 deletions

View File

@ -452,23 +452,23 @@ char IndexSeparator()
} }
} }
void SetShortcut(char* str, uint8_t action) void SetShortcutDefault(void)
{ {
if ('\0' != str[0]) { // There must be at least one character in the buffer if ('\0' != XdrvMailbox.data[0]) { // There must be at least one character in the buffer
str[0] = '0' + action; // SC_CLEAR, SC_DEFAULT, SC_USER XdrvMailbox.data[0] = '0' + SC_DEFAULT; // SC_CLEAR, SC_DEFAULT, SC_USER
str[1] = '\0'; XdrvMailbox.data[1] = '\0';
} }
} }
uint8_t Shortcut(const char* str) uint8_t Shortcut()
{ {
uint8_t result = 10; uint8_t result = 10;
if ('\0' == str[1]) { // Only allow single character input for shortcut if ('\0' == XdrvMailbox.data[1]) { // Only allow single character input for shortcut
if (('"' == str[0]) || ('0' == str[0])) { if (('"' == XdrvMailbox.data[0]) || ('0' == XdrvMailbox.data[0])) {
result = SC_CLEAR; result = SC_CLEAR;
} else { } else {
result = atoi(str); // 1 = SC_DEFAULT, 2 = SC_USER result = atoi(XdrvMailbox.data); // 1 = SC_DEFAULT, 2 = SC_USER
if (0 == result) { if (0 == result) {
result = 10; result = 10;
} }
@ -502,29 +502,6 @@ bool ParseIp(uint32_t* addr, const char* str)
return (3 == i); return (3 == i);
} }
void MakeValidMqtt(uint32_t option, char* str)
{
// option 0 = replace by underscore
// option 1 = delete character
uint32_t i = 0;
while (str[i] > 0) {
// if ((str[i] == '/') || (str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if ((str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if (option) {
uint32_t j = i;
while (str[j] > 0) {
str[j] = str[j +1];
j++;
}
i--;
} else {
str[i] = '_';
}
}
i++;
}
}
// Function to parse & check if version_str is newer than our currently installed version. // Function to parse & check if version_str is newer than our currently installed version.
bool NewerVersion(char* version_str) bool NewerVersion(char* version_str)
{ {

View File

@ -143,6 +143,7 @@ void CommandHandler(char* topic, uint8_t* data, uint32_t data_len)
backlog_delay = millis() + (100 * MIN_BACKLOG_DELAY); backlog_delay = millis() + (100 * MIN_BACKLOG_DELAY);
char command[CMDSZ]; char command[CMDSZ];
XdrvMailbox.command = command;
XdrvMailbox.index = index; XdrvMailbox.index = index;
XdrvMailbox.data_len = data_len; XdrvMailbox.data_len = data_len;
XdrvMailbox.payload = payload; XdrvMailbox.payload = payload;
@ -150,9 +151,8 @@ void CommandHandler(char* topic, uint8_t* data, uint32_t data_len)
XdrvMailbox.usridx = user_index; XdrvMailbox.usridx = user_index;
XdrvMailbox.topic = type; XdrvMailbox.topic = type;
XdrvMailbox.data = dataBuf; XdrvMailbox.data = dataBuf;
XdrvMailbox.command = command;
int command_code = GetCommandCode(command, sizeof(command), type, kTasmotaCommands); int command_code = GetCommandCode(XdrvMailbox.command, CMDSZ, type, kTasmotaCommands);
if (command_code >= 0) { if (command_code >= 0) {
TasmotaCommand[command_code](); TasmotaCommand[command_code]();
} else { } else {
@ -398,7 +398,7 @@ void CmndUpgrade(void)
void CmndOtaUrl(void) void CmndOtaUrl(void)
{ {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.ota_url))) { if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.ota_url))) {
strlcpy(Settings.ota_url, (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? OTA_URL : XdrvMailbox.data, sizeof(Settings.ota_url)); strlcpy(Settings.ota_url, (SC_DEFAULT == Shortcut()) ? OTA_URL : XdrvMailbox.data, sizeof(Settings.ota_url));
} }
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.ota_url); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.ota_url);
} }
@ -946,7 +946,7 @@ void CmndSyslog(void)
void CmndLoghost(void) void CmndLoghost(void)
{ {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.syslog_host))) { if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.syslog_host))) {
strlcpy(Settings.syslog_host, (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? SYS_LOG_HOST : XdrvMailbox.data, sizeof(Settings.syslog_host)); strlcpy(Settings.syslog_host, (SC_DEFAULT == Shortcut()) ? SYS_LOG_HOST : XdrvMailbox.data, sizeof(Settings.syslog_host));
} }
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.syslog_host); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.syslog_host);
} }
@ -978,7 +978,7 @@ void CmndNtpServer(void)
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.ntp_server[0]))) { if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.ntp_server[0]))) {
strlcpy(Settings.ntp_server[XdrvMailbox.index -1], strlcpy(Settings.ntp_server[XdrvMailbox.index -1],
(SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? (1==XdrvMailbox.index)?NTP_SERVER1:(2==XdrvMailbox.index)?NTP_SERVER2:NTP_SERVER3 : XdrvMailbox.data, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1==XdrvMailbox.index)?NTP_SERVER1:(2==XdrvMailbox.index)?NTP_SERVER2:NTP_SERVER3 : XdrvMailbox.data,
sizeof(Settings.ntp_server[0])); sizeof(Settings.ntp_server[0]));
for (uint32_t i = 0; i < strlen(Settings.ntp_server[XdrvMailbox.index -1]); i++) { for (uint32_t i = 0; i < strlen(Settings.ntp_server[XdrvMailbox.index -1]); i++) {
if (Settings.ntp_server[XdrvMailbox.index -1][i] == ',') Settings.ntp_server[XdrvMailbox.index -1][i] = '.'; if (Settings.ntp_server[XdrvMailbox.index -1][i] == ',') Settings.ntp_server[XdrvMailbox.index -1][i] = '.';
@ -1011,7 +1011,7 @@ void CmndSsid(void)
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.sta_ssid[0]))) { if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.sta_ssid[0]))) {
strlcpy(Settings.sta_ssid[XdrvMailbox.index -1], strlcpy(Settings.sta_ssid[XdrvMailbox.index -1],
(SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? (1 == XdrvMailbox.index) ? STA_SSID1 : STA_SSID2 : XdrvMailbox.data, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? STA_SSID1 : STA_SSID2 : XdrvMailbox.data,
sizeof(Settings.sta_ssid[0])); sizeof(Settings.sta_ssid[0]));
Settings.sta_active = XdrvMailbox.index -1; Settings.sta_active = XdrvMailbox.index -1;
restart_flag = 2; restart_flag = 2;
@ -1023,9 +1023,9 @@ void CmndSsid(void)
void CmndPassword(void) void CmndPassword(void)
{ {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
if ((XdrvMailbox.data_len > 4 || SC_CLEAR == Shortcut(XdrvMailbox.data) || SC_DEFAULT == Shortcut(XdrvMailbox.data)) && (XdrvMailbox.data_len < sizeof(Settings.sta_pwd[0]))) { if ((XdrvMailbox.data_len > 4 || SC_CLEAR == Shortcut() || SC_DEFAULT == Shortcut()) && (XdrvMailbox.data_len < sizeof(Settings.sta_pwd[0]))) {
strlcpy(Settings.sta_pwd[XdrvMailbox.index -1], strlcpy(Settings.sta_pwd[XdrvMailbox.index -1],
(SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? (1 == XdrvMailbox.index) ? STA_PASS1 : STA_PASS2 : XdrvMailbox.data, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? STA_PASS1 : STA_PASS2 : XdrvMailbox.data,
sizeof(Settings.sta_pwd[0])); sizeof(Settings.sta_pwd[0]));
Settings.sta_active = XdrvMailbox.index -1; Settings.sta_active = XdrvMailbox.index -1;
restart_flag = 2; restart_flag = 2;
@ -1039,7 +1039,7 @@ void CmndPassword(void)
void CmndHostname(void) void CmndHostname(void)
{ {
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.hostname))) { if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.hostname))) {
strlcpy(Settings.hostname, (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? WIFI_HOSTNAME : XdrvMailbox.data, sizeof(Settings.hostname)); strlcpy(Settings.hostname, (SC_DEFAULT == Shortcut()) ? WIFI_HOSTNAME : XdrvMailbox.data, sizeof(Settings.hostname));
if (strstr(Settings.hostname, "%") != nullptr) { if (strstr(Settings.hostname, "%") != nullptr) {
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname)); strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname));
} }
@ -1076,7 +1076,7 @@ void CmndFriendlyname(void)
} else { } else {
snprintf_P(stemp1, sizeof(stemp1), PSTR(FRIENDLY_NAME "%d"), XdrvMailbox.index); snprintf_P(stemp1, sizeof(stemp1), PSTR(FRIENDLY_NAME "%d"), XdrvMailbox.index);
} }
strlcpy(Settings.friendlyname[XdrvMailbox.index -1], (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? stemp1 : XdrvMailbox.data, sizeof(Settings.friendlyname[XdrvMailbox.index -1])); strlcpy(Settings.friendlyname[XdrvMailbox.index -1], (SC_DEFAULT == Shortcut()) ? stemp1 : XdrvMailbox.data, sizeof(Settings.friendlyname[XdrvMailbox.index -1]));
} }
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, Settings.friendlyname[XdrvMailbox.index -1]); Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, Settings.friendlyname[XdrvMailbox.index -1]);
} }

View File

@ -2479,7 +2479,7 @@ bool WebCommand(void)
} }
else if (CMND_WEBPASSWORD == command_code) { else if (CMND_WEBPASSWORD == command_code) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.web_password))) { if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.web_password))) {
strlcpy(Settings.web_password, (SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? WEB_PASSWORD : XdrvMailbox.data, sizeof(Settings.web_password)); strlcpy(Settings.web_password, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? WEB_PASSWORD : XdrvMailbox.data, sizeof(Settings.web_password));
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.web_password); Response_P(S_JSON_COMMAND_SVALUE, command, Settings.web_password);
} else { } else {
Response_P(S_JSON_COMMAND_ASTERISK, command); Response_P(S_JSON_COMMAND_ASTERISK, command);

View File

@ -26,14 +26,26 @@
WiFiClient EspClient; // Wifi Client WiFiClient EspClient; // Wifi Client
#endif #endif
enum MqttCommands {
CMND_MQTTHOST, CMND_MQTTPORT, CMND_MQTTRETRY, CMND_STATETEXT, CMND_MQTTFINGERPRINT, CMND_MQTTCLIENT,
CMND_MQTTUSER, CMND_MQTTPASSWORD, CMND_FULLTOPIC, CMND_PREFIX, CMND_GROUPTOPIC, CMND_TOPIC, CMND_PUBLISH,
CMND_BUTTONTOPIC, CMND_SWITCHTOPIC, CMND_BUTTONRETAIN, CMND_SWITCHRETAIN, CMND_POWERRETAIN, CMND_SENSORRETAIN };
const char kMqttCommands[] PROGMEM = const char kMqttCommands[] PROGMEM =
D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTFINGERPRINT "|" D_CMND_MQTTCLIENT "|" #if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|" D_CMND_MQTTFINGERPRINT "|"
#endif
#if !defined(USE_MQTT_TLS) || !defined(USE_MQTT_AWS_IOT) // user and password are disabled with AWS IoT
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|"
#endif
D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTCLIENT "|"
D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|"
D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ; D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ;
void (* const MqttCommand[])(void) PROGMEM = {
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
&CmndMqttFingerprint,
#endif
#if !defined(USE_MQTT_TLS) || !defined(USE_MQTT_AWS_IOT) // user and password are disabled with AWS IoT
&CmndMqttUser, &CmndMqttPassword,
#endif
&CmndMqttHost, &CmndMqttPort, &CmndMqttRetry, &CmndStateText, &CmndMqttClient,
&CmndFullTopic, &CmndPrefix, &CmndGroupTopic, &CmndTopic, &CmndPublish,
&CmndButtonTopic, &CmndSwitchTopic, &CmndButtonRetain, &CmndSwitchRetain, &CmndPowerRetain, &CmndSensorRetain };
IPAddress mqtt_host_addr; // MQTT host IP address IPAddress mqtt_host_addr; // MQTT host IP address
uint32_t mqtt_host_hash = 0; // MQTT host name hash uint32_t mqtt_host_hash = 0; // MQTT host name hash
@ -45,8 +57,6 @@ bool mqtt_connected = false; // MQTT virtual connection status
bool mqtt_allowed = false; // MQTT enabled and parameters valid bool mqtt_allowed = false; // MQTT enabled and parameters valid
#ifdef USE_MQTT_TLS #ifdef USE_MQTT_TLS
// see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c // see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c
void to_hex(unsigned char * in, size_t insz, char * out, size_t outsz) { void to_hex(unsigned char * in, size_t insz, char * out, size_t outsz) {
unsigned char * pin = in; unsigned char * pin = in;
@ -90,8 +100,73 @@ bool is_fingerprint_mono_value(uint8_t finger[20], uint8_t value) {
return true; return true;
} }
#ifdef USE_MQTT_AWS_IOT
void setLongMqttHost(const char *mqtt_host) {
if (strlen(mqtt_host) <= sizeof(Settings.mqtt_host)) {
strlcpy(Settings.mqtt_host, mqtt_host, sizeof(Settings.mqtt_host));
Settings.mqtt_user[0] = 0;
} else {
// need to split in mqtt_user first then mqtt_host
strlcpy(Settings.mqtt_user, mqtt_host, sizeof(Settings.mqtt_user));
strlcpy(Settings.mqtt_host, &mqtt_host[sizeof(Settings.mqtt_user)-1], sizeof(Settings.mqtt_host));
}
strlcpy(AWS_endpoint, mqtt_host, sizeof(AWS_endpoint));
}
#endif // USE_MQTT_AWS_IOT
#endif // USE_MQTT_TLS #endif // USE_MQTT_TLS
void MakeValidMqtt(uint32_t option, char* str)
{
// option 0 = replace by underscore
// option 1 = delete character
uint32_t i = 0;
while (str[i] > 0) {
// if ((str[i] == '/') || (str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if ((str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if (option) {
uint32_t j = i;
while (str[j] > 0) {
str[j] = str[j +1];
j++;
}
i--;
} else {
str[i] = '_';
}
}
i++;
}
}
#ifdef USE_DISCOVERY
#ifdef MQTT_HOST_DISCOVERY
void MqttDiscoverServer(void)
{
if (!mdns_begun) { return; }
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
if (n > 0) {
uint32_t i = 0; // If the hostname isn't set, use the first record found.
#ifdef MDNS_HOSTNAME
for (i = n; i > 0; i--) { // Search from last to first and use first if not found
if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) {
break; // Stop at matching record
}
}
#endif // MDNS_HOSTNAME
snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(i).toString().c_str());
Settings.mqtt_port = MDNS.port(i);
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), Settings.mqtt_host, Settings.mqtt_port);
}
}
#endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY
/*********************************************************************************************\ /*********************************************************************************************\
* MQTT driver specific code need to provide the following functions: * MQTT driver specific code need to provide the following functions:
* *
@ -114,8 +189,8 @@ PubSubClient MqttClient;
PubSubClient MqttClient(EspClient); PubSubClient MqttClient(EspClient);
#endif #endif
void MqttInit(void)
void MqttInit(void) { {
#ifdef USE_MQTT_TLS #ifdef USE_MQTT_TLS
tlsClient = new BearSSL::WiFiClientSecure_light(1024,1024); tlsClient = new BearSSL::WiFiClientSecure_light(1024,1024);
@ -139,7 +214,6 @@ void MqttInit(void) {
#endif // USE_MQTT_TLS #endif // USE_MQTT_TLS
} }
bool MqttIsConnected(void) bool MqttIsConnected(void)
{ {
return MqttClient.connected(); return MqttClient.connected();
@ -206,34 +280,6 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
/*********************************************************************************************/ /*********************************************************************************************/
#ifdef USE_DISCOVERY
#ifdef MQTT_HOST_DISCOVERY
void MqttDiscoverServer(void)
{
if (!mdns_begun) { return; }
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
if (n > 0) {
uint32_t i = 0; // If the hostname isn't set, use the first record found.
#ifdef MDNS_HOSTNAME
for (i = n; i > 0; i--) { // Search from last to first and use first if not found
if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) {
break; // Stop at matching record
}
}
#endif // MDNS_HOSTNAME
snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(i).toString().c_str());
Settings.mqtt_port = MDNS.port(i);
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), Settings.mqtt_host, Settings.mqtt_port);
}
}
#endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY
void MqttRetryCounter(uint8_t value) void MqttRetryCounter(uint8_t value)
{ {
mqtt_retry_counter = value; mqtt_retry_counter = value;
@ -311,7 +357,7 @@ void MqttPublish(const char* topic)
MqttPublish(topic, false); MqttPublish(topic, false);
} }
void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic, bool retained) void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retained)
{ {
/* prefix 0 = cmnd using subtopic /* prefix 0 = cmnd using subtopic
* prefix 1 = stat using subtopic * prefix 1 = stat using subtopic
@ -332,12 +378,12 @@ void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic, bool retaine
MqttPublish(stopic, retained); MqttPublish(stopic, retained);
} }
void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic) void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic)
{ {
MqttPublishPrefixTopic_P(prefix, subtopic, false); MqttPublishPrefixTopic_P(prefix, subtopic, false);
} }
void MqttPublishPowerState(uint8_t device) void MqttPublishPowerState(uint32_t device)
{ {
char stopic[TOPSZ]; char stopic[TOPSZ];
char scommand[33]; char scommand[33];
@ -380,7 +426,7 @@ void MqttPublishAllPowerState()
} }
} }
void MqttPublishPowerBlinkState(uint8_t device) void MqttPublishPowerBlinkState(uint32_t device)
{ {
char scommand[33]; char scommand[33];
@ -518,7 +564,6 @@ void MqttReconnect(void)
#endif #endif
if (2 == mqtt_initial_connection_state) { // Executed once just after power on and wifi is connected if (2 == mqtt_initial_connection_state) { // Executed once just after power on and wifi is connected
mqtt_initial_connection_state = 1; mqtt_initial_connection_state = 1;
} }
@ -617,126 +662,118 @@ void MqttCheck(void)
} }
} }
/*********************************************************************************************/ /*********************************************************************************************\
* Commands
\*********************************************************************************************/
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
void setLongMqttHost(const char *mqtt_host) {
if (strlen(mqtt_host) <= sizeof(Settings.mqtt_host)) {
strlcpy(Settings.mqtt_host, mqtt_host, sizeof(Settings.mqtt_host));
Settings.mqtt_user[0] = 0;
} else {
// need to split in mqtt_user first then mqtt_host
strlcpy(Settings.mqtt_user, mqtt_host, sizeof(Settings.mqtt_user));
strlcpy(Settings.mqtt_host, &mqtt_host[sizeof(Settings.mqtt_user)-1], sizeof(Settings.mqtt_host));
}
strlcpy(AWS_endpoint, mqtt_host, sizeof(AWS_endpoint));
}
#endif // USE_MQTT_AWS_IOT
bool MqttCommand(void)
{
char command [CMDSZ];
bool serviced = true;
char stemp1[TOPSZ];
char scommand[CMDSZ];
uint32_t index = XdrvMailbox.index;
uint32_t data_len = XdrvMailbox.data_len;
int32_t payload = XdrvMailbox.payload;
bool grpflg = XdrvMailbox.grpflg;
char *type = XdrvMailbox.topic;
char *dataBuf = XdrvMailbox.data;
int command_code = GetCommandCode(command, sizeof(command), type, kMqttCommands);
if (-1 == command_code) {
serviced = false; // Unknown command
}
else if (CMND_MQTTHOST == command_code) {
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
if ((data_len > 0) && (data_len <= sizeof(Settings.mqtt_host) + sizeof(Settings.mqtt_user) - 2)) {
setLongMqttHost((SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_HOST : dataBuf);
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, AWS_endpoint);
#else
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_host))) {
strlcpy(Settings.mqtt_host, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_host);
#endif
}
else if (CMND_MQTTPORT == command_code) {
if ((payload > 0) && (payload < 65536)) {
Settings.mqtt_port = (1 == payload) ? MQTT_PORT : payload;
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.mqtt_port);
}
else if (CMND_MQTTRETRY == command_code) {
if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) {
Settings.mqtt_retry = payload;
mqtt_retry_counter = Settings.mqtt_retry;
}
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.mqtt_retry);
}
else if ((CMND_STATETEXT == command_code) && (index > 0) && (index <= 4)) {
if ((data_len > 0) && (data_len < sizeof(Settings.state_text[0]))) {
for (uint32_t i = 0; i <= data_len; i++) {
if (dataBuf[i] == ' ') dataBuf[i] = '_';
}
strlcpy(Settings.state_text[index -1], dataBuf, sizeof(Settings.state_text[0]));
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, GetStateText(index -1));
}
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT) #if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
else if ((CMND_MQTTFINGERPRINT == command_code) && (index > 0) && (index <= 2)) { void CmndMqttFingerprint(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
char fingerprint[60]; char fingerprint[60];
if ((data_len > 0) && (data_len < sizeof(fingerprint))) { if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(fingerprint))) {
strlcpy(fingerprint, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? (1 == index) ? MQTT_FINGERPRINT1 : MQTT_FINGERPRINT2 : dataBuf, sizeof(fingerprint)); strlcpy(fingerprint, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? MQTT_FINGERPRINT1 : MQTT_FINGERPRINT2 : XdrvMailbox.data, sizeof(fingerprint));
char *p = fingerprint; char *p = fingerprint;
for (uint32_t i = 0; i < 20; i++) { for (uint32_t i = 0; i < 20; i++) {
Settings.mqtt_fingerprint[index -1][i] = strtol(p, &p, 16); Settings.mqtt_fingerprint[XdrvMailbox.index -1][i] = strtol(p, &p, 16);
} }
restart_flag = 2; restart_flag = 2;
} }
fingerprint[0] = '\0'; fingerprint[0] = '\0';
for (uint32_t i = 0; i < sizeof(Settings.mqtt_fingerprint[index -1]); i++) { for (uint32_t i = 0; i < sizeof(Settings.mqtt_fingerprint[XdrvMailbox.index -1]); i++) {
snprintf_P(fingerprint, sizeof(fingerprint), PSTR("%s%s%02X"), fingerprint, (i) ? " " : "", Settings.mqtt_fingerprint[index -1][i]); snprintf_P(fingerprint, sizeof(fingerprint), PSTR("%s%s%02X"), fingerprint, (i) ? " " : "", Settings.mqtt_fingerprint[XdrvMailbox.index -1][i]);
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, fingerprint);
} }
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, fingerprint);
} }
#endif #endif
else if (CMND_MQTTCLIENT == command_code) {
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.mqtt_client))) {
strlcpy(Settings.mqtt_client, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_CLIENT_ID : dataBuf, sizeof(Settings.mqtt_client));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_client);
}
#if !defined(USE_MQTT_TLS) || !defined(USE_MQTT_AWS_IOT) // user and password are disabled with AWS IoT #if !defined(USE_MQTT_TLS) || !defined(USE_MQTT_AWS_IOT) // user and password are disabled with AWS IoT
else if (CMND_MQTTUSER == command_code) { void CmndMqttUser(void)
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_user))) { {
strlcpy(Settings.mqtt_user, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_USER : dataBuf, sizeof(Settings.mqtt_user)); if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_user))) {
strlcpy(Settings.mqtt_user, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_USER : XdrvMailbox.data, sizeof(Settings.mqtt_user));
restart_flag = 2; restart_flag = 2;
} }
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_user); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_user);
} }
else if (CMND_MQTTPASSWORD == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_pwd))) { void CmndMqttPassword(void)
strlcpy(Settings.mqtt_pwd, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_PASS : dataBuf, sizeof(Settings.mqtt_pwd)); {
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_pwd); if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_pwd))) {
strlcpy(Settings.mqtt_pwd, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_PASS : XdrvMailbox.data, sizeof(Settings.mqtt_pwd));
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_pwd);
restart_flag = 2; restart_flag = 2;
} else { } else {
Response_P(S_JSON_COMMAND_ASTERISK, command); Response_P(S_JSON_COMMAND_ASTERISK, XdrvMailbox.command);
} }
} }
#endif // USE_MQTT_AWS_IOT #endif // USE_MQTT_AWS_IOT
else if (CMND_FULLTOPIC == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_fulltopic))) { void CmndMqttHost(void)
MakeValidMqtt(1, dataBuf); {
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT); #if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1)); if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len <= sizeof(Settings.mqtt_host) + sizeof(Settings.mqtt_user) - 2)) {
setLongMqttHost((SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_HOST : XdrvMailbox.data);
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, AWS_endpoint);
#else
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_host))) {
strlcpy(Settings.mqtt_host, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_HOST : XdrvMailbox.data, sizeof(Settings.mqtt_host));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_host);
#endif
}
void CmndMqttPort(void)
{
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 65536)) {
Settings.mqtt_port = (1 == XdrvMailbox.payload) ? MQTT_PORT : XdrvMailbox.payload;
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_NVALUE, XdrvMailbox.command, Settings.mqtt_port);
}
void CmndMqttRetry(void)
{
if ((XdrvMailbox.payload >= MQTT_RETRY_SECS) && (XdrvMailbox.payload < 32001)) {
Settings.mqtt_retry = XdrvMailbox.payload;
mqtt_retry_counter = Settings.mqtt_retry;
}
Response_P(S_JSON_COMMAND_NVALUE, XdrvMailbox.command, Settings.mqtt_retry);
}
void CmndStateText(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.state_text[0]))) {
for (uint32_t i = 0; i <= XdrvMailbox.data_len; i++) {
if (XdrvMailbox.data[i] == ' ') XdrvMailbox.data[i] = '_';
}
strlcpy(Settings.state_text[XdrvMailbox.index -1], XdrvMailbox.data, sizeof(Settings.state_text[0]));
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, GetStateText(XdrvMailbox.index -1));
}
}
void CmndMqttClient(void)
{
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_client))) {
strlcpy(Settings.mqtt_client, (SC_DEFAULT == Shortcut()) ? MQTT_CLIENT_ID : XdrvMailbox.data, sizeof(Settings.mqtt_client));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_client);
}
void CmndFullTopic(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_fulltopic))) {
MakeValidMqtt(1, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
char stemp1[TOPSZ];
strlcpy(stemp1, (SC_DEFAULT == Shortcut()) ? MQTT_FULLTOPIC : XdrvMailbox.data, sizeof(stemp1));
if (strcmp(stemp1, Settings.mqtt_fulltopic)) { if (strcmp(stemp1, Settings.mqtt_fulltopic)) {
Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : ""); Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : "");
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
@ -744,21 +781,28 @@ bool MqttCommand(void)
restart_flag = 2; restart_flag = 2;
} }
} }
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fulltopic); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_fulltopic);
} }
else if ((CMND_PREFIX == command_code) && (index > 0) && (index <= 3)) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_prefix[0]))) { void CmndPrefix(void)
MakeValidMqtt(0, dataBuf); {
strlcpy(Settings.mqtt_prefix[index -1], (SC_DEFAULT == Shortcut(dataBuf)) ? (1==index)?SUB_PREFIX:(2==index)?PUB_PREFIX:PUB_PREFIX2 : dataBuf, sizeof(Settings.mqtt_prefix[0])); if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
// if (Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] == '/') Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] = 0; if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_prefix[0]))) {
MakeValidMqtt(0, XdrvMailbox.data);
strlcpy(Settings.mqtt_prefix[XdrvMailbox.index -1], (SC_DEFAULT == Shortcut()) ? (1==XdrvMailbox.index)?SUB_PREFIX:(2==XdrvMailbox.index)?PUB_PREFIX:PUB_PREFIX2 : XdrvMailbox.data, sizeof(Settings.mqtt_prefix[0]));
// if (Settings.mqtt_prefix[XdrvMailbox.index -1][strlen(Settings.mqtt_prefix[XdrvMailbox.index -1])] == '/') Settings.mqtt_prefix[XdrvMailbox.index -1][strlen(Settings.mqtt_prefix[XdrvMailbox.index -1])] = 0;
restart_flag = 2; restart_flag = 2;
} }
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mqtt_prefix[index -1]); Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, Settings.mqtt_prefix[XdrvMailbox.index -1]);
} }
else if (CMND_PUBLISH == command_code) { }
if (data_len > 0) {
char *mqtt_part = strtok(dataBuf, " "); void CmndPublish(void)
{
if (XdrvMailbox.data_len > 0) {
char *mqtt_part = strtok(XdrvMailbox.data, " ");
if (mqtt_part) { if (mqtt_part) {
char stemp1[TOPSZ];
strlcpy(stemp1, mqtt_part, sizeof(stemp1)); strlcpy(stemp1, mqtt_part, sizeof(stemp1));
mqtt_part = strtok(nullptr, " "); mqtt_part = strtok(nullptr, " ");
if (mqtt_part) { if (mqtt_part) {
@ -766,26 +810,31 @@ bool MqttCommand(void)
} else { } else {
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';
} }
MqttPublishDirect(stemp1, (index == 2)); MqttPublishDirect(stemp1, (XdrvMailbox.index == 2));
// Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE); // Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';
} }
} }
} }
else if (CMND_GROUPTOPIC == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_grptopic))) { void CmndGroupTopic(void)
MakeValidMqtt(0, dataBuf); {
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT); if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_grptopic))) {
strlcpy(Settings.mqtt_grptopic, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_GRPTOPIC : dataBuf, sizeof(Settings.mqtt_grptopic)); MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
strlcpy(Settings.mqtt_grptopic, (SC_DEFAULT == Shortcut()) ? MQTT_GRPTOPIC : XdrvMailbox.data, sizeof(Settings.mqtt_grptopic));
restart_flag = 2; restart_flag = 2;
} }
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_grptopic); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_grptopic);
} }
else if (CMND_TOPIC == command_code) {
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.mqtt_topic))) { void CmndTopic(void)
MakeValidMqtt(0, dataBuf); {
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT); if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_topic))) {
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_TOPIC : dataBuf, sizeof(stemp1)); MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
char stemp1[TOPSZ];
strlcpy(stemp1, (SC_DEFAULT == Shortcut()) ? MQTT_TOPIC : XdrvMailbox.data, sizeof(stemp1));
if (strcmp(stemp1, Settings.mqtt_topic)) { if (strcmp(stemp1, Settings.mqtt_topic)) {
Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : ""); Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : "");
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
@ -793,83 +842,93 @@ bool MqttCommand(void)
restart_flag = 2; restart_flag = 2;
} }
} }
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_topic); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_topic);
} }
else if (CMND_BUTTONTOPIC == command_code) {
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.button_topic))) { void CmndButtonTopic(void)
MakeValidMqtt(0, dataBuf); {
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT); if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.button_topic))) {
switch (Shortcut(dataBuf)) { MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
switch (Shortcut()) {
case SC_CLEAR: strlcpy(Settings.button_topic, "", sizeof(Settings.button_topic)); break; case SC_CLEAR: strlcpy(Settings.button_topic, "", sizeof(Settings.button_topic)); break;
case SC_DEFAULT: strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); break; case SC_DEFAULT: strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); break;
case SC_USER: strlcpy(Settings.button_topic, MQTT_BUTTON_TOPIC, sizeof(Settings.button_topic)); break; case SC_USER: strlcpy(Settings.button_topic, MQTT_BUTTON_TOPIC, sizeof(Settings.button_topic)); break;
default: strlcpy(Settings.button_topic, dataBuf, sizeof(Settings.button_topic)); default: strlcpy(Settings.button_topic, XdrvMailbox.data, sizeof(Settings.button_topic));
} }
} }
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.button_topic); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.button_topic);
} }
else if (CMND_SWITCHTOPIC == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.switch_topic))) { void CmndSwitchTopic(void)
MakeValidMqtt(0, dataBuf); {
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT); if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.switch_topic))) {
switch (Shortcut(dataBuf)) { MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
switch (Shortcut()) {
case SC_CLEAR: strlcpy(Settings.switch_topic, "", sizeof(Settings.switch_topic)); break; case SC_CLEAR: strlcpy(Settings.switch_topic, "", sizeof(Settings.switch_topic)); break;
case SC_DEFAULT: strlcpy(Settings.switch_topic, mqtt_topic, sizeof(Settings.switch_topic)); break; case SC_DEFAULT: strlcpy(Settings.switch_topic, mqtt_topic, sizeof(Settings.switch_topic)); break;
case SC_USER: strlcpy(Settings.switch_topic, MQTT_SWITCH_TOPIC, sizeof(Settings.switch_topic)); break; case SC_USER: strlcpy(Settings.switch_topic, MQTT_SWITCH_TOPIC, sizeof(Settings.switch_topic)); break;
default: strlcpy(Settings.switch_topic, dataBuf, sizeof(Settings.switch_topic)); default: strlcpy(Settings.switch_topic, XdrvMailbox.data, sizeof(Settings.switch_topic));
} }
} }
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.switch_topic); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.switch_topic);
} }
else if (CMND_BUTTONRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) { void CmndButtonRetain(void)
if (!payload) { {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
for (uint32_t i = 1; i <= MAX_KEYS; i++) { for (uint32_t i = 1; i <= MAX_KEYS; i++) {
SendKey(0, i, 9); // Clear MQTT retain in broker SendKey(0, i, 9); // Clear MQTT retain in broker
} }
} }
Settings.flag.mqtt_button_retain = payload; Settings.flag.mqtt_button_retain = XdrvMailbox.payload;
} }
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_button_retain)); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_button_retain));
} }
else if (CMND_SWITCHRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) { void CmndSwitchRetain(void)
if (!payload) { {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
for (uint32_t i = 1; i <= MAX_SWITCHES; i++) { for (uint32_t i = 1; i <= MAX_SWITCHES; i++) {
SendKey(1, i, 9); // Clear MQTT retain in broker SendKey(1, i, 9); // Clear MQTT retain in broker
} }
} }
Settings.flag.mqtt_switch_retain = payload; Settings.flag.mqtt_switch_retain = XdrvMailbox.payload;
} }
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_switch_retain)); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_switch_retain));
} }
else if (CMND_POWERRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) { void CmndPowerRetain(void)
if (!payload) { {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
char stemp1[TOPSZ];
char scommand[CMDSZ];
for (uint32_t i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker for (uint32_t i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker
GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand), Settings.flag.device_index_enable)); GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand), Settings.flag.device_index_enable));
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';
MqttPublish(stemp1, Settings.flag.mqtt_power_retain); MqttPublish(stemp1, Settings.flag.mqtt_power_retain);
} }
} }
Settings.flag.mqtt_power_retain = payload; Settings.flag.mqtt_power_retain = XdrvMailbox.payload;
} }
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_power_retain)); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_power_retain));
} }
else if (CMND_SENSORRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) { void CmndSensorRetain(void)
if (!payload) { {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
} }
Settings.flag.mqtt_sensor_retain = payload; Settings.flag.mqtt_sensor_retain = XdrvMailbox.payload;
} }
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain)); Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_sensor_retain));
}
else serviced = false; // Unknown command
return serviced;
} }
/*********************************************************************************************\ /*********************************************************************************************\
@ -999,7 +1058,11 @@ bool Xdrv02(uint8_t function)
break; break;
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
case FUNC_COMMAND: case FUNC_COMMAND:
result = MqttCommand(); int command_code = GetCommandCode(XdrvMailbox.command, CMDSZ, XdrvMailbox.topic, kMqttCommands);
if (command_code >= 0) {
MqttCommand[command_code]();
result = true;
}
break; break;
} }
} }