Browse Source

Helper methods for MQTT sending, subscribing and forwarding

fastled
Xose Pérez 7 years ago
parent
commit
e0abce8f0b
7 changed files with 77 additions and 92 deletions
  1. +1
    -4
      code/espurna/button.ino
  2. +1
    -1
      code/espurna/config/prototypes.h
  3. +5
    -9
      code/espurna/led.ino
  4. +10
    -31
      code/espurna/light.ino
  5. +34
    -7
      code/espurna/mqtt.ino
  6. +25
    -39
      code/espurna/relay.ino
  7. +1
    -1
      code/espurna/web.ino

+ 1
- 4
code/espurna/button.ino View File

@ -24,12 +24,9 @@ std::vector<button_t> _buttons;
#ifdef MQTT_BUTTON_TOPIC #ifdef MQTT_BUTTON_TOPIC
void buttonMQTT(unsigned char id, uint8_t event) { void buttonMQTT(unsigned char id, uint8_t event) {
if (id >= _buttons.size()) return; 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]; char payload[2];
sprintf(payload, "%d", event); sprintf(payload, "%d", event);
mqttSend(buffer, payload);
mqttSend(MQTT_BUTTON_TOPIC, id, payload);
} }
#endif #endif


+ 1
- 1
code/espurna/config/prototypes.h View File

@ -9,7 +9,7 @@ typedef std::function<void(char *, size_t)> apiGetCallbackFunction;
typedef std::function<void(const char *)> apiPutCallbackFunction; typedef std::function<void(const char *)> apiPutCallbackFunction;
void apiRegister(const char * url, const char * key, apiGetCallbackFunction getFn, apiPutCallbackFunction putFn = NULL); void apiRegister(const char * url, const char * key, apiGetCallbackFunction getFn, apiPutCallbackFunction putFn = NULL);
void mqttRegister(void (*callback)(unsigned int, const char *, const char *)); void mqttRegister(void (*callback)(unsigned int, const char *, const char *));
char * mqttSubtopic(char * topic);
String mqttSubtopic(char * topic);
template<typename T> bool setSetting(const String& key, T value); template<typename T> bool setSetting(const String& key, T value);
template<typename T> String getSetting(const String& key, T defaultValue); template<typename T> String getSetting(const String& key, T defaultValue);
template<typename T> void domoticzSend(const char * key, T value); template<typename T> void domoticzSend(const char * key, T value);


+ 5
- 9
code/espurna/led.ino View File

@ -62,24 +62,20 @@ void ledMQTTCallback(unsigned int type, const char * topic, const char * payload
static bool isFirstMessage = true; static bool isFirstMessage = true;
String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER);
if (type == MQTT_CONNECT_EVENT) { 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); mqttSubscribe(buffer);
} }
if (type == MQTT_MESSAGE_EVENT) { if (type == MQTT_MESSAGE_EVENT) {
// Match topic // 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 // 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()) { if (ledID >= ledCount()) {
DEBUG_MSG("[LED] Wrong ledID (%d)\n", ledID); DEBUG_MSG("[LED] Wrong ledID (%d)\n", ledID);
return; return;


+ 10
- 31
code/espurna/light.ino View File

@ -9,12 +9,11 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
#include <Ticker.h> #include <Ticker.h>
Ticker colorTicker;
#if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
#include <my9291.h> #include <my9291.h>
my9291 * _my9291; my9291 * _my9291;
Ticker colorTicker;
bool _mqttSkipColor = false;
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -44,7 +43,7 @@ void color_array2rgb(unsigned int * array, char * rgb) {
// LIGHT MANAGEMENT // LIGHT MANAGEMENT
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void lightColor(const char * rgb, bool save) {
void lightColor(const char * rgb, bool save, bool forward) {
#if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
@ -63,13 +62,10 @@ void lightColor(const char * rgb, bool save) {
#endif #endif
// Delay saving to EEPROM 5 seconds to avoid wearing it out unnecessarily // 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 // Report color to MQTT broker
_mqttSkipColor = true;
mqttSend(MQTT_COLOR_TOPIC, rgb);
if (forward) mqttSend(MQTT_COLOR_TOPIC, rgb);
// Report color to WS clients // Report color to WS clients
char message[20]; 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 lightColor() {
String response; String response;
@ -130,7 +122,7 @@ void lightColorSave() {
} }
void lightColorRetrieve() { 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) { 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) { 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) { if (type == MQTT_MESSAGE_EVENT) {
// Match topic // 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());
} }


+ 34
- 7
code/espurna/mqtt.ino View File

@ -20,6 +20,7 @@ bool _mqttConnected = false;
#endif #endif
String mqttTopic; String mqttTopic;
bool _mqttForward;
std::vector<void (*)(unsigned int, const char *, const char *)> _mqtt_callbacks; std::vector<void (*)(unsigned int, const char *, const char *)> _mqtt_callbacks;
#if MQTT_SKIP_RETAINED #if MQTT_SKIP_RETAINED
unsigned long mqttConnectedAt = 0; unsigned long mqttConnectedAt = 0;
@ -43,9 +44,23 @@ void buildTopics() {
mqttTopic.replace("{identifier}", getSetting("hostname")); 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) { 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) { 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); mqttSendRaw(path.c_str(), message);
} }
@ -72,7 +94,8 @@ void mqttSubscribeRaw(const char * topic) {
} }
void mqttSubscribe(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()); mqttSubscribeRaw(path.c_str());
} }
@ -136,8 +159,8 @@ void _mqttOnMessage(char* topic, char* payload, unsigned int len) {
DEBUG_MSG("\n"); DEBUG_MSG("\n");
// Check system topics // 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) { if (strcmp(message, MQTT_ACTION_RESET) == 0) {
ESP.restart(); ESP.restart();
} }
@ -219,6 +242,10 @@ void mqttConnect() {
free(user); free(user);
free(pass); free(pass);
String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER);
String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER);
bool _mqttForward = !mqttGetter.equals(mqttSetter);
} }
} }


+ 25
- 39
code/espurna/relay.ino View File

@ -121,9 +121,8 @@ void relayPulseMode(unsigned int value, bool report) {
/* /*
if (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]; char value[2];
sprintf(value, "%d", value); sprintf(value, "%d", value);
mqttSend(topic, value); mqttSend(topic, value);
@ -374,10 +373,7 @@ void relayDomoticzSetup() {
void relayMQTT(unsigned char id) { void relayMQTT(unsigned char id) {
if (id >= _relays.size()) return; 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() { void relayMQTT() {
@ -388,16 +384,12 @@ void relayMQTT() {
void relayMQTTCallback(unsigned int type, const char * topic, const char * payload) { 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) { if (type == MQTT_CONNECT_EVENT) {
relayMQTT(); 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); mqttSubscribe(buffer);
} }
@ -405,36 +397,30 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo
if (type == MQTT_MESSAGE_EVENT) { if (type == MQTT_MESSAGE_EVENT) {
// Match topic // 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());
} }
} }


+ 1
- 1
code/espurna/web.ino View File

@ -123,7 +123,7 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) {
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
if (action.equals("color") && root.containsKey("data")) { if (action.equals("color") && root.containsKey("data")) {
lightColor(root["data"], true);
lightColor(root["data"], true, true);
} }
#endif #endif


Loading…
Cancel
Save