diff --git a/code/espurna/button.ino b/code/espurna/button.ino index 72f25501..4479ef51 100644 --- a/code/espurna/button.ino +++ b/code/espurna/button.ino @@ -24,12 +24,9 @@ std::vector _buttons; #ifdef MQTT_BUTTON_TOPIC void buttonMQTT(unsigned char id, uint8_t event) { if (id >= _buttons.size()) return; - String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); - char buffer[strlen(MQTT_BUTTON_TOPIC) + mqttGetter.length() + 3]; - sprintf(buffer, "%s/%d%s", MQTT_BUTTON_TOPIC, id, mqttGetter.c_str()); char payload[2]; sprintf(payload, "%d", event); - mqttSend(buffer, payload); + mqttSend(MQTT_BUTTON_TOPIC, id, payload); } #endif diff --git a/code/espurna/config/prototypes.h b/code/espurna/config/prototypes.h index c9373597..c9947441 100644 --- a/code/espurna/config/prototypes.h +++ b/code/espurna/config/prototypes.h @@ -9,7 +9,7 @@ typedef std::function apiGetCallbackFunction; typedef std::function apiPutCallbackFunction; void apiRegister(const char * url, const char * key, apiGetCallbackFunction getFn, apiPutCallbackFunction putFn = NULL); void mqttRegister(void (*callback)(unsigned int, const char *, const char *)); -char * mqttSubtopic(char * topic); +String mqttSubtopic(char * topic); template bool setSetting(const String& key, T value); template String getSetting(const String& key, T defaultValue); template void domoticzSend(const char * key, T value); diff --git a/code/espurna/led.ino b/code/espurna/led.ino index d3a02d0d..210f3169 100644 --- a/code/espurna/led.ino +++ b/code/espurna/led.ino @@ -62,24 +62,20 @@ void ledMQTTCallback(unsigned int type, const char * topic, const char * payload static bool isFirstMessage = true; - String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); - if (type == MQTT_CONNECT_EVENT) { - char buffer[strlen(MQTT_LED_TOPIC) + mqttSetter.length() + 3]; - sprintf(buffer, "%s/+%s", MQTT_LED_TOPIC, mqttSetter.c_str()); + char buffer[strlen(MQTT_LED_TOPIC) + 3]; + sprintf(buffer, "%s/+", MQTT_LED_TOPIC); mqttSubscribe(buffer); } if (type == MQTT_MESSAGE_EVENT) { // Match topic - char * t = mqttSubtopic((char *) topic); - if (strncmp(t, MQTT_LED_TOPIC, strlen(MQTT_LED_TOPIC)) != 0) return; - int len = mqttSetter.length(); - if (strncmp(t + strlen(t) - len, mqttSetter.c_str(), len) != 0) return; + String t = mqttSubtopic((char *) topic); + if (!t.startsWith(MQTT_LED_TOPIC)) return; // Get led ID - unsigned int ledID = topic[strlen(topic) - mqttSetter.length() - 1] - '0'; + unsigned int ledID = t.substring(strlen(MQTT_LED_TOPIC)+1).toInt(); if (ledID >= ledCount()) { DEBUG_MSG("[LED] Wrong ledID (%d)\n", ledID); return; diff --git a/code/espurna/light.ino b/code/espurna/light.ino index 59a5b50e..2b4bd0a6 100644 --- a/code/espurna/light.ino +++ b/code/espurna/light.ino @@ -9,12 +9,11 @@ Copyright (C) 2016-2017 by Xose PĂ©rez #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #include +Ticker colorTicker; #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 #include my9291 * _my9291; -Ticker colorTicker; -bool _mqttSkipColor = false; #endif // ----------------------------------------------------------------------------- @@ -44,7 +43,7 @@ void color_array2rgb(unsigned int * array, char * rgb) { // LIGHT MANAGEMENT // ----------------------------------------------------------------------------- -void lightColor(const char * rgb, bool save) { +void lightColor(const char * rgb, bool save, bool forward) { #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 @@ -63,13 +62,10 @@ void lightColor(const char * rgb, bool save) { #endif // Delay saving to EEPROM 5 seconds to avoid wearing it out unnecessarily - if (save) { - colorTicker.once(LIGHT_SAVE_DELAY, lightColorSave); - } + if (save) colorTicker.once(LIGHT_SAVE_DELAY, lightColorSave); // Report color to MQTT broker - _mqttSkipColor = true; - mqttSend(MQTT_COLOR_TOPIC, rgb); + if (forward) mqttSend(MQTT_COLOR_TOPIC, rgb); // Report color to WS clients char message[20]; @@ -79,10 +75,6 @@ void lightColor(const char * rgb, bool save) { } -void lightColor(const char * rgb) { - lightColor(rgb, true); -} - String lightColor() { String response; @@ -130,7 +122,7 @@ void lightColorSave() { } void lightColorRetrieve() { - lightColor(getSetting("color", LIGHT_DEFAULT_COLOR).c_str(), false); + lightColor(getSetting("color", LIGHT_DEFAULT_COLOR).c_str(), false, true); } // ----------------------------------------------------------------------------- @@ -139,31 +131,18 @@ void lightColorRetrieve() { void lightMQTTCallback(unsigned int type, const char * topic, const char * payload) { - String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); - String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); - bool sameSetGet = mqttGetter.compareTo(mqttSetter) == 0; if (type == MQTT_CONNECT_EVENT) { - char buffer[strlen(MQTT_COLOR_TOPIC) + mqttSetter.length() + 20]; - sprintf(buffer, "%s%s", MQTT_COLOR_TOPIC, mqttSetter.c_str()); - mqttSubscribe(buffer); + mqttSubscribe(MQTT_COLOR_TOPIC); } if (type == MQTT_MESSAGE_EVENT) { // Match topic - char * t = mqttSubtopic((char *) topic); - int len = mqttSetter.length(); - if (strncmp(t + strlen(t) - len, mqttSetter.c_str(), len) != 0) return; - - if (strncmp(t, MQTT_COLOR_TOPIC, strlen(MQTT_COLOR_TOPIC)) == 0) { - if (_mqttSkipColor) { - _mqttSkipColor = false; - } else { - lightColor(payload, true); - } - return; - } + String t = mqttSubtopic((char *) topic); + if (!t.equals(MQTT_COLOR_TOPIC)) return; + + lightColor(payload, true, mqttForward()); } diff --git a/code/espurna/mqtt.ino b/code/espurna/mqtt.ino index 2db6259f..13bf08d9 100644 --- a/code/espurna/mqtt.ino +++ b/code/espurna/mqtt.ino @@ -20,6 +20,7 @@ bool _mqttConnected = false; #endif String mqttTopic; +bool _mqttForward; std::vector _mqtt_callbacks; #if MQTT_SKIP_RETAINED unsigned long mqttConnectedAt = 0; @@ -43,9 +44,23 @@ void buildTopics() { mqttTopic.replace("{identifier}", getSetting("hostname")); } -char * mqttSubtopic(char * topic) { - int pos = min(mqttTopic.length(), strlen(topic)); - return topic + pos; +bool mqttForward() { + return _mqttForward; +} + +String mqttSubtopic(char * topic) { + + String response; + + String t = String(topic); + String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); + + if (t.startsWith(mqttTopic) && t.endsWith(mqttSetter)) { + response = t.substring(mqttTopic.length(), t.length() - mqttSetter.length()); + } + + return response; + } void mqttSendRaw(const char * topic, const char * message) { @@ -60,7 +75,14 @@ void mqttSendRaw(const char * topic, const char * message) { } void mqttSend(const char * topic, const char * message) { - String path = mqttTopic + String(topic); + String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); + String path = mqttTopic + String(topic) + mqttGetter; + mqttSendRaw(path.c_str(), message); +} + +void mqttSend(const char * topic, unsigned int index, const char * message) { + String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); + String path = mqttTopic + String(topic) + String ("/") + String(index) + mqttGetter;; mqttSendRaw(path.c_str(), message); } @@ -72,7 +94,8 @@ void mqttSubscribeRaw(const char * topic) { } void mqttSubscribe(const char * topic) { - String path = mqttTopic + String(topic); + String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); + String path = mqttTopic + String(topic) + mqttSetter; mqttSubscribeRaw(path.c_str()); } @@ -136,8 +159,8 @@ void _mqttOnMessage(char* topic, char* payload, unsigned int len) { DEBUG_MSG("\n"); // Check system topics - char * p = mqttSubtopic(topic); - if (strcmp(p, MQTT_ACTION_TOPIC) == 0) { + String t = mqttSubtopic((char *) topic); + if (t.equals(MQTT_ACTION_TOPIC)) { if (strcmp(message, MQTT_ACTION_RESET) == 0) { ESP.restart(); } @@ -219,6 +242,10 @@ void mqttConnect() { free(user); free(pass); + String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); + String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); + bool _mqttForward = !mqttGetter.equals(mqttSetter); + } } diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index 6de6ede9..714c529c 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -121,9 +121,8 @@ void relayPulseMode(unsigned int value, bool report) { /* if (report) { - String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); - char topic[strlen(MQTT_RELAY_TOPIC) + mqttGetter.length() + 10]; - sprintf(topic, "%s/pulse%s", MQTT_RELAY_TOPIC, mqttGetter.c_str()); + char topic[strlen(MQTT_RELAY_TOPIC) + 10]; + sprintf(topic, "%s/pulse", MQTT_RELAY_TOPIC); char value[2]; sprintf(value, "%d", value); mqttSend(topic, value); @@ -374,10 +373,7 @@ void relayDomoticzSetup() { void relayMQTT(unsigned char id) { if (id >= _relays.size()) return; - String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); - char buffer[strlen(MQTT_RELAY_TOPIC) + mqttGetter.length() + 3]; - sprintf(buffer, "%s/%d%s", MQTT_RELAY_TOPIC, id, mqttGetter.c_str()); - mqttSend(buffer, relayStatus(id) ? "1" : "0"); + mqttSend(MQTT_RELAY_TOPIC, id, relayStatus(id) ? "1" : "0"); } void relayMQTT() { @@ -388,16 +384,12 @@ void relayMQTT() { void relayMQTTCallback(unsigned int type, const char * topic, const char * payload) { - String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); - String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); - bool sameSetGet = mqttGetter.compareTo(mqttSetter) == 0; - if (type == MQTT_CONNECT_EVENT) { relayMQTT(); - char buffer[strlen(MQTT_RELAY_TOPIC) + mqttSetter.length() + 20]; - sprintf(buffer, "%s/+%s", MQTT_RELAY_TOPIC, mqttSetter.c_str()); + char buffer[strlen(MQTT_RELAY_TOPIC) + 3]; + sprintf(buffer, "%s/+", MQTT_RELAY_TOPIC); mqttSubscribe(buffer); } @@ -405,36 +397,30 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo if (type == MQTT_MESSAGE_EVENT) { // Match topic - char * t = mqttSubtopic((char *) topic); - int len = mqttSetter.length(); - if (strncmp(t + strlen(t) - len, mqttSetter.c_str(), len) != 0) return; - - // Relay topic - if (strncmp(t, MQTT_RELAY_TOPIC, strlen(MQTT_RELAY_TOPIC)) == 0) { + String t = mqttSubtopic((char *) topic); + if (!t.startsWith(MQTT_RELAY_TOPIC)) return; - // Get value - unsigned int value = (char)payload[0] - '0'; + // Get value + unsigned int value = (char)payload[0] - '0'; - // Pulse topic - if (strncmp(t + strlen(MQTT_RELAY_TOPIC) + 1, "pulse", 5) == 0) { - relayPulseMode(value, !sameSetGet); - return; - } - - // Get relay ID - unsigned int relayID = topic[strlen(topic) - mqttSetter.length() - 1] - '0'; - if (relayID >= relayCount()) { - DEBUG_MSG("[RELAY] Wrong relayID (%d)\n", relayID); - return; - } + // Pulse topic + if (t.endsWith("pulse")) { + relayPulseMode(value, mqttForward()); + return; + } - // Action to perform - if (value == 2) { - relayToggle(relayID); - } else { - relayStatus(relayID, value > 0, !sameSetGet); - } + // Get relay ID + unsigned int relayID = t.substring(strlen(MQTT_RELAY_TOPIC)+1).toInt(); + if (relayID >= relayCount()) { + DEBUG_MSG("[RELAY] Wrong relayID (%d)\n", relayID); + return; + } + // Action to perform + if (value == 2) { + relayToggle(relayID); + } else { + relayStatus(relayID, value > 0, mqttForward()); } } diff --git a/code/espurna/web.ino b/code/espurna/web.ino index 30c3814e..bb79279f 100644 --- a/code/espurna/web.ino +++ b/code/espurna/web.ino @@ -123,7 +123,7 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) { #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE if (action.equals("color") && root.containsKey("data")) { - lightColor(root["data"], true); + lightColor(root["data"], true, true); } #endif