mirror of https://github.com/arendst/Tasmota.git
v5.0.5
5.0.5 20170508 * Add command FullTopic with tokens %topic% (replaced by command Topic value) and * %prefix% (replaced by command Prefix<x> values) for more flexible topic definitions (#244) * See wiki > MQTT Features https://github.com/arendst/Sonoff-Tasmota/wiki/MQTT-Features for more information
This commit is contained in:
parent
09acb77277
commit
bc9d44d74a
|
@ -1,7 +1,7 @@
|
||||||
## Sonoff-Tasmota
|
## 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.
|
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.4** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
Current version is **5.0.5** - 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 ****
|
### **** ATTENTION Version 5.0.x specific information ****
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1,4 +1,9 @@
|
||||||
/* 5.0.4 20170505
|
/* 5.0.5 20170508
|
||||||
|
* Add command FullTopic with tokens %topic% (replaced by command Topic value) and
|
||||||
|
* %prefix% (replaced by command Prefix<x> values) for more flexible topic definitions (#244)
|
||||||
|
* See wiki > MQTT Features https://github.com/arendst/Sonoff-Tasmota/wiki/MQTT-Features for more information
|
||||||
|
*
|
||||||
|
* 5.0.4 20170505
|
||||||
* Add Sonoff Pow Energy Total up to 40 MWh
|
* Add Sonoff Pow Energy Total up to 40 MWh
|
||||||
* Add command EnergyReset 1|2|3 to reset Energy counters (#406)
|
* Add command EnergyReset 1|2|3 to reset Energy counters (#406)
|
||||||
* Fix Domoticz Energy logging (#411)
|
* Fix Domoticz Energy logging (#411)
|
||||||
|
|
|
@ -175,6 +175,9 @@ struct SYSCFG {
|
||||||
// 5.0.4
|
// 5.0.4
|
||||||
unsigned long hlw_kWhtotal;
|
unsigned long hlw_kWhtotal;
|
||||||
|
|
||||||
|
// 5.0.4a
|
||||||
|
char mqtt_fulltopic[101];
|
||||||
|
|
||||||
} sysCfg;
|
} sysCfg;
|
||||||
|
|
||||||
struct RTCMEM {
|
struct RTCMEM {
|
||||||
|
|
|
@ -452,6 +452,10 @@ void CFG_DefaultSet2()
|
||||||
// 5.0.4
|
// 5.0.4
|
||||||
// sysCfg.hlw_kWhtotal = 0;
|
// sysCfg.hlw_kWhtotal = 0;
|
||||||
rtcMem.hlw_kWhtotal = 0;
|
rtcMem.hlw_kWhtotal = 0;
|
||||||
|
|
||||||
|
// 5.0.4a
|
||||||
|
strlcpy(sysCfg.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(sysCfg.mqtt_fulltopic));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
@ -630,6 +634,9 @@ void CFG_Delta()
|
||||||
sysCfg.hlw_kWhtotal = 0;
|
sysCfg.hlw_kWhtotal = 0;
|
||||||
rtcMem.hlw_kWhtotal = 0;
|
rtcMem.hlw_kWhtotal = 0;
|
||||||
}
|
}
|
||||||
|
if (sysCfg.version < 0x05000500) {
|
||||||
|
strlcpy(sysCfg.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(sysCfg.mqtt_fulltopic));
|
||||||
|
}
|
||||||
sysCfg.version = VERSION;
|
sysCfg.version = VERSION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* ====================================================
|
* ====================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VERSION 0x05000400 // 5.0.4
|
#define VERSION 0x05000500 // 5.0.5
|
||||||
|
|
||||||
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
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};
|
enum week_t {Last, First, Second, Third, Fourth};
|
||||||
|
@ -119,7 +119,8 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
||||||
#define OTA_ATTEMPTS 10 // Number of times to try fetching the new firmware
|
#define OTA_ATTEMPTS 10 // Number of times to try fetching the new firmware
|
||||||
|
|
||||||
#define INPUT_BUFFER_SIZE 100 // Max number of characters in serial buffer
|
#define INPUT_BUFFER_SIZE 100 // Max number of characters in serial buffer
|
||||||
#define TOPSZ 60 // Max number of characters in topic string
|
#define CMDSZ 20 // Max number of characters in command
|
||||||
|
#define TOPSZ 100 // Max number of characters in topic string
|
||||||
#define LOGSZ 128 // Max number of characters in log string
|
#define LOGSZ 128 // Max number of characters in log string
|
||||||
#ifdef USE_MQTT_TLS
|
#ifdef USE_MQTT_TLS
|
||||||
#define MAX_LOG_LINES 10 // Max number of lines in weblog
|
#define MAX_LOG_LINES 10 // Max number of lines in weblog
|
||||||
|
@ -173,6 +174,8 @@ const char commands[MAX_BUTTON_COMMANDS][14] PROGMEM = {
|
||||||
|
|
||||||
const char wificfg[5][12] PROGMEM = { "Restart", "Smartconfig", "Wifimanager", "WPSconfig", "Retry" };
|
const char wificfg[5][12] PROGMEM = { "Restart", "Smartconfig", "Wifimanager", "WPSconfig", "Retry" };
|
||||||
|
|
||||||
|
const char PREFIXES[3][5] PROGMEM = { "cmnd", "stat", "tele" };
|
||||||
|
|
||||||
struct TIME_T {
|
struct TIME_T {
|
||||||
uint8_t Second;
|
uint8_t Second;
|
||||||
uint8_t Minute;
|
uint8_t Minute;
|
||||||
|
@ -363,59 +366,36 @@ void setLed(uint8_t state)
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
void json2legacy(char* stopic, char* svalue)
|
void getTopic_P(char *stopic, byte idx, char *topic, const char* subtopic)
|
||||||
{
|
{
|
||||||
char *p;
|
char romram[CMDSZ];
|
||||||
char *token;
|
|
||||||
uint16_t i;
|
|
||||||
uint16_t j;
|
|
||||||
|
|
||||||
if (!strstr(svalue, "{\"")) {
|
snprintf_P(romram, sizeof(romram), subtopic);
|
||||||
return; // No JSON
|
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++) {
|
||||||
// stopic = stat/sonoff/RESULT
|
if ('\0' == sysCfg.mqtt_prefix[i][0]) {
|
||||||
// svalue = {"POWER2":"ON"}
|
snprintf_P(sysCfg.mqtt_prefix[i], sizeof(sysCfg.mqtt_prefix[i]), PREFIXES[i]);
|
||||||
// --> stopic = "stat/sonoff/POWER2", svalue = "ON"
|
|
||||||
// svalue = {"Upgrade":{"Version":"2.1.2", "OtaUrl":"%s"}}
|
|
||||||
// --> stopic = "stat/sonoff/UPGRADE", svalue = "2.1.2"
|
|
||||||
// svalue = {"SerialLog":2}
|
|
||||||
// --> stopic = "stat/sonoff/SERIALLOG", svalue = "2"
|
|
||||||
// svalue = {"POWER":""}
|
|
||||||
// --> stopic = "stat/sonoff/POWER", svalue = ""
|
|
||||||
|
|
||||||
token = strtok(svalue, "{\""); // Topic
|
|
||||||
p = strrchr(stopic, '/') +1;
|
|
||||||
i = p - stopic;
|
|
||||||
for (j = 0; j < strlen(token)+1; j++) {
|
|
||||||
stopic[i+j] = toupper(token[j]);
|
|
||||||
}
|
|
||||||
token = strtok(NULL, "\""); // : or :3} or :3, or :{
|
|
||||||
if (strstr(token, ":{")) {
|
|
||||||
token = strtok(NULL, "\""); // Subtopic
|
|
||||||
token = strtok(NULL, "\""); // : or :3} or :3,
|
|
||||||
}
|
|
||||||
if (strlen(token) > 1) {
|
|
||||||
token++;
|
|
||||||
p = strchr(token, ',');
|
|
||||||
if (!p) {
|
|
||||||
p = strchr(token, '}');
|
|
||||||
}
|
|
||||||
i = p - token;
|
|
||||||
token[i] = '\0'; // Value
|
|
||||||
} else {
|
|
||||||
token = strtok(NULL, "\""); // Value or , or }
|
|
||||||
if ((token[0] == ',') || (token[0] == '}')) { // Empty parameter
|
|
||||||
token = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (token == NULL) {
|
fulltopic.replace(F("%prefix%"), sysCfg.mqtt_prefix[idx]);
|
||||||
svalue[0] = '\0';
|
fulltopic.replace(F("%topic%"), topic);
|
||||||
} else {
|
fulltopic.replace(F("#"), "");
|
||||||
memcpy(svalue, token, strlen(token)+1);
|
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)
|
char* getStateText(byte state)
|
||||||
{
|
{
|
||||||
if (state > 2) {
|
if (state > 2) {
|
||||||
|
@ -472,7 +452,7 @@ void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data
|
||||||
|
|
||||||
snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.flag.mqtt_response) ? PSTR("RESULT") : subtopic);
|
snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.flag.mqtt_response) ? PSTR("RESULT") : subtopic);
|
||||||
prefix &= 1;
|
prefix &= 1;
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), sysCfg.mqtt_prefix[prefix +1], sysCfg.mqtt_topic, romram);
|
getTopic_P(stopic, prefix +1, sysCfg.mqtt_topic, romram);
|
||||||
mqtt_publish(stopic, data, retained);
|
mqtt_publish(stopic, data, retained);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,18 +465,21 @@ void mqtt_publishPowerState(byte device)
|
||||||
{
|
{
|
||||||
char stopic[TOPSZ];
|
char stopic[TOPSZ];
|
||||||
char sdevice[10];
|
char sdevice[10];
|
||||||
|
char scommand[10];
|
||||||
char svalue[64]; // was MESSZ
|
char svalue[64]; // was MESSZ
|
||||||
|
|
||||||
if ((device < 1) || (device > Maxdevice)) {
|
if ((device < 1) || (device > Maxdevice)) {
|
||||||
device = 1;
|
device = 1;
|
||||||
}
|
}
|
||||||
snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device);
|
snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device);
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"),
|
snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (Maxdevice > 1) ? sdevice : "");
|
||||||
sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (sysCfg.flag.mqtt_response)?"POWER":"RESULT");
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"POWER%s\":\"%s\"}"),
|
getTopic_P(stopic, 1, sysCfg.mqtt_topic, (sysCfg.flag.mqtt_response)?"POWER":"RESULT");
|
||||||
(Maxdevice > 1) ? sdevice : "", getStateText(bitRead(power, device -1)));
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"%s\":\"%s\"}"), scommand, getStateText(bitRead(power, device -1)));
|
||||||
mqtt_publish(stopic, svalue);
|
mqtt_publish(stopic, svalue);
|
||||||
json2legacy(stopic, svalue);
|
|
||||||
|
getTopic_P(stopic, 1, sysCfg.mqtt_topic, scommand);
|
||||||
|
snprintf_P(svalue, sizeof(svalue), PSTR("%s"), getStateText(bitRead(power, device -1)));
|
||||||
mqtt_publish(stopic, svalue, sysCfg.flag.mqtt_power_retain);
|
mqtt_publish(stopic, svalue, sysCfg.flag.mqtt_power_retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,17 +505,19 @@ void mqtt_connected()
|
||||||
if (sysCfg.flag.mqtt_enabled) {
|
if (sysCfg.flag.mqtt_enabled) {
|
||||||
|
|
||||||
// Satisfy iobroker (#299)
|
// Satisfy iobroker (#299)
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/POWER"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic);
|
getTopic_P(stopic, 0, sysCfg.mqtt_topic, PSTR("POWER"));
|
||||||
svalue[0] ='\0';
|
svalue[0] ='\0';
|
||||||
mqtt_publish(stopic, svalue);
|
mqtt_publish(stopic, svalue);
|
||||||
|
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic);
|
getTopic_P(stopic, 0, sysCfg.mqtt_topic, PSTR("#"));
|
||||||
mqttClient.subscribe(stopic);
|
mqttClient.subscribe(stopic);
|
||||||
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_grptopic);
|
|
||||||
|
getTopic_P(stopic, 0, sysCfg.mqtt_grptopic, PSTR("#"));
|
||||||
mqttClient.subscribe(stopic);
|
mqttClient.subscribe(stopic);
|
||||||
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), sysCfg.mqtt_prefix[0], MQTTClient); // Fall back topic
|
|
||||||
|
getTopic_P(stopic, 0, MQTTClient, PSTR("#"));
|
||||||
mqttClient.subscribe(stopic);
|
mqttClient.subscribe(stopic);
|
||||||
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
|
@ -610,7 +595,8 @@ void mqtt_reconnect()
|
||||||
#endif // USE_DISCOVERY
|
#endif // USE_DISCOVERY
|
||||||
#endif // USE_MQTT_TLS
|
#endif // USE_MQTT_TLS
|
||||||
mqttClient.setServer(sysCfg.mqtt_host, sysCfg.mqtt_port);
|
mqttClient.setServer(sysCfg.mqtt_host, sysCfg.mqtt_port);
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/LWT"), sysCfg.mqtt_prefix[2], sysCfg.mqtt_topic);
|
|
||||||
|
getTopic_P(stopic, 2, sysCfg.mqtt_topic, PSTR("LWT"));
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("Offline"));
|
snprintf_P(svalue, sizeof(svalue), PSTR("Offline"));
|
||||||
if (mqttClient.connect(MQTTClient, sysCfg.mqtt_user, sysCfg.mqtt_pwd, stopic, 1, true, svalue)) {
|
if (mqttClient.connect(MQTTClient, sysCfg.mqtt_user, sysCfg.mqtt_pwd, stopic, 1, true, svalue)) {
|
||||||
addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Connected"));
|
addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Connected"));
|
||||||
|
@ -632,6 +618,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
||||||
boolean serviced = true;
|
boolean serviced = true;
|
||||||
char stemp1[TOPSZ];
|
char stemp1[TOPSZ];
|
||||||
char stemp2[10];
|
char stemp2[10];
|
||||||
|
char scommand[CMDSZ];
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
if (!strcmp_P(type,PSTR("MQTTHOST"))) {
|
if (!strcmp_P(type,PSTR("MQTTHOST"))) {
|
||||||
|
@ -695,6 +682,23 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
|
snprintf_P(svalue, ssvalue, PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
|
||||||
}
|
}
|
||||||
|
else if (!grpflg && !strcmp_P(type,PSTR("FULLTOPIC"))) {
|
||||||
|
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_fulltopic))) {
|
||||||
|
for (i = 0; i <= data_len; i++) {
|
||||||
|
if ((dataBuf[i] == '+') || (dataBuf[i] == '#') || (dataBuf[i] == ' ')) {
|
||||||
|
for (byte j = i; j <= data_len; j++) {
|
||||||
|
dataBuf[j] = dataBuf[j +1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!strcmp(dataBuf, MQTTClient)) {
|
||||||
|
payload = 1;
|
||||||
|
}
|
||||||
|
strlcpy(sysCfg.mqtt_fulltopic, (1 == payload) ? MQTT_FULLTOPIC : dataBuf, sizeof(sysCfg.mqtt_fulltopic));
|
||||||
|
restartflag = 2;
|
||||||
|
}
|
||||||
|
snprintf_P(svalue, ssvalue, PSTR("{\"FullTopic\":\"%s\"}"), sysCfg.mqtt_fulltopic);
|
||||||
|
}
|
||||||
else if (!strcmp_P(type,PSTR("PREFIX")) && (index > 0) && (index <= 3)) {
|
else if (!strcmp_P(type,PSTR("PREFIX")) && (index > 0) && (index <= 3)) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_prefix[0]))) {
|
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_prefix[0]))) {
|
||||||
for(i = 0; i <= data_len; i++) {
|
for(i = 0; i <= data_len; i++) {
|
||||||
|
@ -795,7 +799,12 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
for(i = 1; i <= Maxdevice; i++) { // Clear MQTT retain in broker
|
for(i = 1; i <= Maxdevice; i++) { // Clear MQTT retain in broker
|
||||||
snprintf_P(stemp2, sizeof(stemp2), PSTR("%d"), i);
|
snprintf_P(stemp2, sizeof(stemp2), PSTR("%d"), i);
|
||||||
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/POWER%s"), sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
|
|
||||||
|
snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (Maxdevice > 1) ? stemp2 : "");
|
||||||
|
getTopic_P(stemp1, 1, sysCfg.mqtt_topic, scommand);
|
||||||
|
|
||||||
|
// snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/POWER%s"), sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
|
||||||
|
|
||||||
mqtt_publish(stemp1, "", sysCfg.flag.mqtt_power_retain);
|
mqtt_publish(stemp1, "", sysCfg.flag.mqtt_power_retain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -872,21 +881,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
}
|
}
|
||||||
#endif // USE_DOMOTICZ
|
#endif // USE_DOMOTICZ
|
||||||
|
|
||||||
memmove(topicBuf, topicBuf+strlen(sysCfg.mqtt_prefix[0]), sizeof(topicBuf)-strlen(sysCfg.mqtt_prefix[0])); // Remove SUB_PREFIX
|
grpflg = (strstr(topicBuf, sysCfg.mqtt_grptopic) != NULL);
|
||||||
|
type = strrchr(topicBuf, '/') +1;
|
||||||
i = 0;
|
|
||||||
for (str = strtok_r(topicBuf, "/", &p); str && i < 2; str = strtok_r(NULL, "/", &p)) {
|
|
||||||
switch (i++) {
|
|
||||||
case 0: // Topic / GroupTopic / DVES_123456
|
|
||||||
mtopic = str;
|
|
||||||
break;
|
|
||||||
case 1: // TopicIndex / Text
|
|
||||||
type = str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!strcmp(mtopic, sysCfg.mqtt_grptopic)) {
|
|
||||||
grpflg = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = 1;
|
index = 1;
|
||||||
if (type != NULL) {
|
if (type != NULL) {
|
||||||
|
@ -906,8 +902,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
dataBufUc[i] = toupper(dataBuf[i]);
|
dataBufUc[i] = toupper(dataBuf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("RSLT: DataCb Topic %s, Group %d, Index %d, Type %s, Data %s (%s)"),
|
snprintf_P(svalue, sizeof(svalue), PSTR("RSLT: DataCb Group %d, Index %d, Type %s, Data %s (%s)"),
|
||||||
mtopic, grpflg, index, type, dataBuf, dataBufUc);
|
grpflg, index, type, dataBuf, dataBufUc);
|
||||||
addLog(LOG_LEVEL_DEBUG, svalue);
|
addLog(LOG_LEVEL_DEBUG, svalue);
|
||||||
|
|
||||||
// snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/RESULT"), PUB_PREFIX, sysCfg.mqtt_topic);
|
// snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/RESULT"), PUB_PREFIX, sysCfg.mqtt_topic);
|
||||||
|
@ -1496,6 +1492,7 @@ void send_button_power(byte key, byte device, byte state)
|
||||||
// key 1 = switch_topic
|
// key 1 = switch_topic
|
||||||
|
|
||||||
char stopic[TOPSZ];
|
char stopic[TOPSZ];
|
||||||
|
char scommand[CMDSZ];
|
||||||
char svalue[TOPSZ];
|
char svalue[TOPSZ];
|
||||||
char stemp1[10];
|
char stemp1[10];
|
||||||
|
|
||||||
|
@ -1503,8 +1500,8 @@ void send_button_power(byte key, byte device, byte state)
|
||||||
device = 1;
|
device = 1;
|
||||||
}
|
}
|
||||||
snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device);
|
snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device);
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/POWER%s"),
|
snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (key || (Maxdevice > 1)) ? stemp1 : "");
|
||||||
sysCfg.mqtt_prefix[0], (key) ? sysCfg.switch_topic : sysCfg.button_topic, (key || (Maxdevice > 1)) ? stemp1 : "");
|
getTopic_P(stopic, 0, (key) ? sysCfg.switch_topic : sysCfg.button_topic, scommand);
|
||||||
|
|
||||||
if (3 == state) {
|
if (3 == state) {
|
||||||
svalue[0] = '\0';
|
svalue[0] = '\0';
|
||||||
|
@ -1598,7 +1595,7 @@ void stop_all_power_blink()
|
||||||
|
|
||||||
void do_cmnd(char *cmnd)
|
void do_cmnd(char *cmnd)
|
||||||
{
|
{
|
||||||
char stopic[TOPSZ];
|
char stopic[CMDSZ];
|
||||||
char svalue[128];
|
char svalue[128];
|
||||||
char *start;
|
char *start;
|
||||||
char *token;
|
char *token;
|
||||||
|
@ -1607,10 +1604,10 @@ void do_cmnd(char *cmnd)
|
||||||
if (token != NULL) {
|
if (token != NULL) {
|
||||||
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
|
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
|
||||||
if (start) {
|
if (start) {
|
||||||
token = start;
|
token = start +1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic, token);
|
snprintf_P(stopic, sizeof(stopic), PSTR("/%s"), token);
|
||||||
token = strtok(NULL, "");
|
token = strtok(NULL, "");
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s"), (token == NULL) ? "" : token);
|
snprintf_P(svalue, sizeof(svalue), PSTR("%s"), (token == NULL) ? "" : token);
|
||||||
mqttDataCb(stopic, (byte*)svalue, strlen(svalue));
|
mqttDataCb(stopic, (byte*)svalue, strlen(svalue));
|
||||||
|
|
|
@ -57,14 +57,6 @@
|
||||||
#define MQTT_PASS "DVES_PASS" // [MqttPassword] Optional password
|
#define MQTT_PASS "DVES_PASS" // [MqttPassword] Optional password
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MQTT_CLIENT_ID "DVES_%06X" // [MqttClient] Also fall back topic using Chip Id = last 6 characters of MAC address
|
|
||||||
|
|
||||||
#define SUB_PREFIX "cmnd" // [Prefix1] Sonoff devices subscribe to:- SUB_PREFIX/MQTT_TOPIC and SUB_PREFIX/MQTT_GRPTOPIC
|
|
||||||
#define PUB_PREFIX "stat" // [Prefix2] Sonoff devices publish to:- PUB_PREFIX/MQTT_TOPIC
|
|
||||||
#define PUB_PREFIX2 "tele" // [Prefix3] Sonoff devices publish telemetry data to:- PUB_PREFIX2/MQTT_TOPIC/UPTIME, POWER/LIGHT and TIME
|
|
||||||
// May be named the same as PUB_PREFIX
|
|
||||||
#define MQTT_TOPIC PROJECT // [Topic] (unique) MQTT device topic
|
|
||||||
#define MQTT_GRPTOPIC "sonoffs" // [GroupTopic] MQTT Group topic
|
|
||||||
#define MQTT_BUTTON_RETAIN 0 // [ButtonRetain] Button may send retain flag (0 = off, 1 = on)
|
#define MQTT_BUTTON_RETAIN 0 // [ButtonRetain] Button may send retain flag (0 = off, 1 = on)
|
||||||
#define MQTT_POWER_RETAIN 0 // [PowerRetain] Power status message may send retain flag (0 = off, 1 = on)
|
#define MQTT_POWER_RETAIN 0 // [PowerRetain] Power status message may send retain flag (0 = off, 1 = on)
|
||||||
#define MQTT_SWITCH_RETAIN 0 // [SwitchRetain] Switch may send retain flag (0 = off, 1 = on)
|
#define MQTT_SWITCH_RETAIN 0 // [SwitchRetain] Switch may send retain flag (0 = off, 1 = on)
|
||||||
|
@ -73,6 +65,20 @@
|
||||||
#define MQTT_STATUS_ON "ON" // [StateText2] Command or Status result when turned on (needs to be a string like "1" or "On")
|
#define MQTT_STATUS_ON "ON" // [StateText2] Command or Status result when turned on (needs to be a string like "1" or "On")
|
||||||
#define MQTT_CMND_TOGGLE "TOGGLE" // [StateText3] Command to send when toggling (needs to be a string like "2" or "Toggle")
|
#define MQTT_CMND_TOGGLE "TOGGLE" // [StateText3] Command to send when toggling (needs to be a string like "2" or "Toggle")
|
||||||
|
|
||||||
|
// -- MQTT topics ---------------------------------
|
||||||
|
//#define MQTT_FULLTOPIC "tasmota/bedroom/%topic%/%prefix%/" // Up to max 80 characers
|
||||||
|
#define MQTT_FULLTOPIC "%prefix%/%topic%/" // [FullTopic] Subscribe and Publish full topic name - Legacy topic
|
||||||
|
|
||||||
|
// %prefix% token options
|
||||||
|
#define SUB_PREFIX "cmnd" // [Prefix1] Sonoff devices subscribe to %prefix%/%topic% being SUB_PREFIX/MQTT_TOPIC and SUB_PREFIX/MQTT_GRPTOPIC
|
||||||
|
#define PUB_PREFIX "stat" // [Prefix2] Sonoff devices publish to %prefix%/%topic% being PUB_PREFIX/MQTT_TOPIC
|
||||||
|
#define PUB_PREFIX2 "tele" // [Prefix3] Sonoff devices publish telemetry data to %prefix%/%topic% being PUB_PREFIX2/MQTT_TOPIC/UPTIME, POWER and TIME
|
||||||
|
// May be named the same as PUB_PREFIX
|
||||||
|
// %topic% token options (also ButtonTopic and SwitchTopic)
|
||||||
|
#define MQTT_TOPIC PROJECT // [Topic] (unique) MQTT device topic
|
||||||
|
#define MQTT_GRPTOPIC "sonoffs" // [GroupTopic] MQTT Group topic
|
||||||
|
#define MQTT_CLIENT_ID "DVES_%06X" // [MqttClient] Also fall back topic using Chip Id = last 6 characters of MAC address
|
||||||
|
|
||||||
// -- MQTT - Telemetry ----------------------------
|
// -- MQTT - Telemetry ----------------------------
|
||||||
#define TELE_PERIOD 300 // [TelePeriod] Telemetry (0 = disable, 10 - 3600 seconds)
|
#define TELE_PERIOD 300 // [TelePeriod] Telemetry (0 = disable, 10 - 3600 seconds)
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,7 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
|
||||||
{
|
{
|
||||||
char log[LOGSZ];
|
char log[LOGSZ];
|
||||||
char stemp1[10];
|
char stemp1[10];
|
||||||
|
char scommand[10];
|
||||||
unsigned long idx = 0;
|
unsigned long idx = 0;
|
||||||
int16_t nvalue;
|
int16_t nvalue;
|
||||||
int16_t found = 0;
|
int16_t found = 0;
|
||||||
|
@ -173,16 +174,14 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
|
||||||
if ((SONOFF_LED == sysCfg.module) && (sysCfg.led_dimmer[i] == nvalue)) {
|
if ((SONOFF_LED == sysCfg.module) && (sysCfg.led_dimmer[i] == nvalue)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
snprintf_P(topicBuf, stopicBuf, PSTR("%s/%s/DIMMER%s"),
|
snprintf_P(topicBuf, stopicBuf, PSTR("/DIMMER%s"), (Maxdevice > 1) ? stemp1 : "");
|
||||||
sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp1 : "");
|
|
||||||
snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
|
snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
|
||||||
found = 1;
|
found = 1;
|
||||||
} else {
|
} else {
|
||||||
if (((power >> i) &1) == nvalue) {
|
if (((power >> i) &1) == nvalue) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
snprintf_P(topicBuf, stopicBuf, PSTR("%s/%s/POWER%s"),
|
snprintf_P(topicBuf, stopicBuf, PSTR("/POWER%s"), (Maxdevice > 1) ? stemp1 : "");
|
||||||
sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp1 : "");
|
|
||||||
snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
|
snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue