Browse Source

Added hostname and mac placeholders for MQTT base topic

i18n
Xose Pérez 6 years ago
parent
commit
ff56e38254
11 changed files with 3234 additions and 3219 deletions
  1. +23
    -23
      code/espurna/config/general.h
  2. +1
    -1
      code/espurna/config/prototypes.h
  3. BIN
      code/espurna/data/index.html.gz
  4. +10
    -10
      code/espurna/homeassitant.ino
  5. +1
    -1
      code/espurna/led.ino
  6. +1
    -1
      code/espurna/light.ino
  7. +37
    -22
      code/espurna/mqtt.ino
  8. +1
    -1
      code/espurna/relay.ino
  9. +1
    -1
      code/espurna/rfbridge.ino
  10. +3158
    -3158
      code/espurna/static/index.html.gz.h
  11. +1
    -1
      code/html/index.html

+ 23
- 23
code/espurna/config/general.h View File

@ -453,31 +453,31 @@ PROGMEM const char* const custom_reset_string[] = {
// $ echo -n | openssl s_client -connect m11.cloudmqtt.com:24055 > cloudmqtt.pem // $ echo -n | openssl s_client -connect m11.cloudmqtt.com:24055 > cloudmqtt.pem
// $ openssl x509 -noout -in cloudmqtt.pem -fingerprint -sha1 // $ openssl x509 -noout -in cloudmqtt.pem -fingerprint -sha1
#define MQTT_SSL_ENABLED 0 // By default MQTT over SSL will not be enabled
#define MQTT_SSL_FINGERPRINT "" // SSL fingerprint of the server
#define MQTT_SSL_ENABLED 0 // By default MQTT over SSL will not be enabled
#define MQTT_SSL_FINGERPRINT "" // SSL fingerprint of the server
#define MQTT_ENABLED 0 // Do not enable MQTT connection by default
#define MQTT_AUTOCONNECT 1 // If enabled and MDNS_SERVER_SUPPORT=1 will perform an autodiscover and
// autoconnect to the first MQTT broker found if none defined
#define MQTT_SERVER "" // Default MQTT broker address
#define MQTT_USER "" // Default MQTT broker usename
#define MQTT_PASS "" // Default MQTT broker password
#define MQTT_PORT 1883 // MQTT broker port
#define MQTT_TOPIC "{identifier}" // Default MQTT base topic
#define MQTT_RETAIN true // MQTT retain flag
#define MQTT_QOS 0 // MQTT QoS value for all messages
#define MQTT_KEEPALIVE 30 // MQTT keepalive value
#define MQTT_ENABLED 0 // Do not enable MQTT connection by default
#define MQTT_AUTOCONNECT 1 // If enabled and MDNS_SERVER_SUPPORT=1 will perform an autodiscover and
// autoconnect to the first MQTT broker found if none defined
#define MQTT_SERVER "" // Default MQTT broker address
#define MQTT_USER "" // Default MQTT broker usename
#define MQTT_PASS "" // Default MQTT broker password
#define MQTT_PORT 1883 // MQTT broker port
#define MQTT_TOPIC "{hostname}" // Default MQTT base topic
#define MQTT_RETAIN true // MQTT retain flag
#define MQTT_QOS 0 // MQTT QoS value for all messages
#define MQTT_KEEPALIVE 30 // MQTT keepalive value
#define MQTT_RECONNECT_DELAY_MIN 5000 // Try to reconnect in 5 seconds upon disconnection
#define MQTT_RECONNECT_DELAY_STEP 5000 // Increase the reconnect delay in 5 seconds after each failed attempt
#define MQTT_RECONNECT_DELAY_MAX 120000 // Set reconnect time to 2 minutes at most
#define MQTT_RECONNECT_DELAY_MIN 5000 // Try to reconnect in 5 seconds upon disconnection
#define MQTT_RECONNECT_DELAY_STEP 5000 // Increase the reconnect delay in 5 seconds after each failed attempt
#define MQTT_RECONNECT_DELAY_MAX 120000 // Set reconnect time to 2 minutes at most
#define MQTT_SKIP_RETAINED 1 // Skip retained messages on connection
#define MQTT_SKIP_TIME 1000 // Skip messages for 1 second anter connection
#define MQTT_SKIP_RETAINED 1 // Skip retained messages on connection
#define MQTT_SKIP_TIME 1000 // Skip messages for 1 second anter connection
#define MQTT_USE_JSON 0 // Group messages in a JSON body
#define MQTT_USE_JSON_DELAY 100 // Wait this many ms before grouping messages
#define MQTT_QUEUE_MAX_SIZE 10 // Size of the MQTT queue when MQTT_USE_JSON is enabled
#define MQTT_USE_JSON 0 // Group messages in a JSON body
#define MQTT_USE_JSON_DELAY 100 // Wait this many ms before grouping messages
#define MQTT_QUEUE_MAX_SIZE 10 // Size of the MQTT queue when MQTT_USE_JSON is enabled
// These particles will be concatenated to the MQTT_TOPIC base to form the actual topic // These particles will be concatenated to the MQTT_TOPIC base to form the actual topic
@ -527,8 +527,8 @@ PROGMEM const char* const custom_reset_string[] = {
// Custom get and set postfixes // Custom get and set postfixes
// Use something like "/status" or "/set", with leading slash // Use something like "/status" or "/set", with leading slash
// Since 1.9.0 the default value is "" for getter and "/set" for setter // Since 1.9.0 the default value is "" for getter and "/set" for setter
#define MQTT_USE_GETTER ""
#define MQTT_USE_SETTER "/set"
#define MQTT_GETTER ""
#define MQTT_SETTER "/set"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// SETTINGS // SETTINGS


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

@ -45,7 +45,7 @@ void wifiRegister(wifi_callback_f callback);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef std::function<void(unsigned int, const char *, const char *)> mqtt_callback_f; typedef std::function<void(unsigned int, const char *, const char *)> mqtt_callback_f;
void mqttRegister(mqtt_callback_f callback); void mqttRegister(mqtt_callback_f callback);
String mqttSubtopic(char * topic);
String mqttTopicKey(char * topic);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Settings // Settings


BIN
code/espurna/data/index.html.gz View File


+ 10
- 10
code/espurna/homeassitant.ino View File

@ -41,11 +41,11 @@ void _haSend() {
root["platform"] = "mqtt"; root["platform"] = "mqtt";
if (relayCount()) { if (relayCount()) {
root["state_topic"] = mqttGetTopic(MQTT_TOPIC_RELAY, 0, false);
root["command_topic"] = mqttGetTopic(MQTT_TOPIC_RELAY, 0, true);
root["state_topic"] = mqttTopic(MQTT_TOPIC_RELAY, 0, false);
root["command_topic"] = mqttTopic(MQTT_TOPIC_RELAY, 0, true);
root["payload_on"] = String("1"); root["payload_on"] = String("1");
root["payload_off"] = String("0"); root["payload_off"] = String("0");
root["availability_topic"] = mqttGetTopic(MQTT_TOPIC_STATUS, false);
root["availability_topic"] = mqttTopic(MQTT_TOPIC_STATUS, false);
root["payload_available"] = String("1"); root["payload_available"] = String("1");
root["payload_not_available"] = String("0"); root["payload_not_available"] = String("0");
} }
@ -53,16 +53,16 @@ void _haSend() {
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
if (lightHasColor()) { if (lightHasColor()) {
root["brightness_state_topic"] = mqttGetTopic(MQTT_TOPIC_BRIGHTNESS, false);
root["brightness_command_topic"] = mqttGetTopic(MQTT_TOPIC_BRIGHTNESS, true);
root["rgb_state_topic"] = mqttGetTopic(MQTT_TOPIC_COLOR_RGB, false);
root["rgb_command_topic"] = mqttGetTopic(MQTT_TOPIC_COLOR_RGB, true);
root["color_temp_command_topic"] = mqttGetTopic(MQTT_TOPIC_MIRED, true);
root["brightness_state_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, false);
root["brightness_command_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, true);
root["rgb_state_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, false);
root["rgb_command_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, true);
root["color_temp_command_topic"] = mqttTopic(MQTT_TOPIC_MIRED, true);
} }
if (lightChannels() > 3) { if (lightChannels() > 3) {
root["white_value_state_topic"] = mqttGetTopic(MQTT_TOPIC_CHANNEL, 3, false);
root["white_value_command_topic"] = mqttGetTopic(MQTT_TOPIC_CHANNEL, 3, true);
root["white_value_state_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, false);
root["white_value_command_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, true);
} }
#endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE


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

@ -80,7 +80,7 @@ void _ledMQTTCallback(unsigned int type, const char * topic, const char * payloa
if (type == MQTT_MESSAGE_EVENT) { if (type == MQTT_MESSAGE_EVENT) {
// Match topic // Match topic
String t = mqttSubtopic((char *) topic);
String t = mqttTopicKey((char *) topic);
if (!t.startsWith(MQTT_TOPIC_LED)) return; if (!t.startsWith(MQTT_TOPIC_LED)) return;
// Get led ID // Get led ID


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

@ -495,7 +495,7 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl
} }
// Match topic // Match topic
String t = mqttSubtopic((char *) topic);
String t = mqttTopicKey((char *) topic);
// Color temperature in mireds // Color temperature in mireds
if (t.equals(MQTT_TOPIC_MIRED)) { if (t.equals(MQTT_TOPIC_MIRED)) {


+ 37
- 22
code/espurna/mqtt.ino View File

@ -81,8 +81,7 @@ void _mqttFlush() {
String output; String output;
root.printTo(output); root.printTo(output);
String path = _mqtt_topic + String(MQTT_TOPIC_JSON);
mqttSendRaw(path.c_str(), output.c_str());
mqttSendRaw(mqttTopic(MQTT_TOPIC_JSON, false).c_str(), output.c_str());
for (unsigned char i = 0; i < _mqtt_queue.size(); i++) { for (unsigned char i = 0; i < _mqtt_queue.size(); i++) {
mqtt_message_t element = _mqtt_queue[i]; mqtt_message_t element = _mqtt_queue[i];
@ -127,7 +126,7 @@ void _mqttConnect() {
_mqtt_user = strdup(getSetting("mqttUser", MQTT_USER).c_str()); _mqtt_user = strdup(getSetting("mqttUser", MQTT_USER).c_str());
_mqtt_pass = strdup(getSetting("mqttPassword", MQTT_PASS).c_str()); _mqtt_pass = strdup(getSetting("mqttPassword", MQTT_PASS).c_str());
_mqtt_will = strdup((_mqtt_topic + MQTT_TOPIC_STATUS).c_str());
_mqtt_will = strdup(mqttTopic(MQTT_TOPIC_STATUS, false).c_str());
_mqtt_clientid = strdup(getSetting("mqttClientID", getIdentifier()).c_str()); _mqtt_clientid = strdup(getSetting("mqttClientID", getIdentifier()).c_str());
DEBUG_MSG_P(PSTR("[MQTT] Connecting to broker at %s:%d\n"), host, port); DEBUG_MSG_P(PSTR("[MQTT] Connecting to broker at %s:%d\n"), host, port);
@ -238,14 +237,20 @@ void _mqttConnect() {
void _mqttConfigure() { void _mqttConfigure() {
// Replace identifier
// Get base topic
_mqtt_topic = getSetting("mqttTopic", MQTT_TOPIC); _mqtt_topic = getSetting("mqttTopic", MQTT_TOPIC);
if (_mqtt_topic.indexOf("#") == -1) _mqtt_topic = _mqtt_topic + "/#";
// Placeholders
_mqtt_topic.replace("{identifier}", getSetting("hostname")); _mqtt_topic.replace("{identifier}", getSetting("hostname"));
if (!_mqtt_topic.endsWith("/")) _mqtt_topic = _mqtt_topic + "/";
_mqtt_topic.replace("{hostname}", getSetting("hostname"));
String mac = WiFi.macAddress();
mac.replace(":", "");
_mqtt_topic.replace("{mac}", mac);
// Getters and setters // Getters and setters
_mqtt_setter = getSetting("mqttSetter", MQTT_USE_SETTER);
_mqtt_getter = getSetting("mqttGetter", MQTT_USE_GETTER);
_mqtt_setter = getSetting("mqttSetter", MQTT_SETTER);
_mqtt_getter = getSetting("mqttGetter", MQTT_GETTER);
_mqtt_forward = !_mqtt_getter.equals(_mqtt_setter); _mqtt_forward = !_mqtt_getter.equals(_mqtt_setter);
// MQTT options // MQTT options
@ -332,7 +337,7 @@ void _mqttCallback(unsigned int type, const char * topic, const char * payload)
if (type == MQTT_MESSAGE_EVENT) { if (type == MQTT_MESSAGE_EVENT) {
// Match topic // Match topic
String t = mqttSubtopic((char *) topic);
String t = mqttTopicKey((char *) topic);
// Actions // Actions
if (t.equals(MQTT_TOPIC_ACTION)) { if (t.equals(MQTT_TOPIC_ACTION)) {
@ -425,25 +430,37 @@ bool mqttForward() {
return _mqtt_forward; return _mqtt_forward;
} }
String mqttSubtopic(char * topic) {
String response;
String t = String(topic);
if (t.startsWith(_mqtt_topic) && t.endsWith(_mqtt_setter)) {
response = t.substring(_mqtt_topic.length(), t.length() - _mqtt_setter.length());
String mqttTopicKey(char * topic) {
String pattern = _mqtt_topic + _mqtt_setter;
int position = pattern.indexOf("#");
if (position == -1) return String();
String start = pattern.substring(0, position);
String end = pattern.substring(position + 1);
String response = String(topic);
if (response.startsWith(start) && response.endsWith(end)) {
response.remove(0, position);
response.remove(position + 1);
} else {
response = String();
} }
return response; return response;
} }
String mqttGetTopic(const char * topic, bool set) {
String output = _mqtt_topic + String(topic);
if (set) output += _mqtt_setter;
String mqttTopic(const char * topic, bool is_set) {
String output = _mqtt_topic;
output.replace("#", topic);
output += is_set ? _mqtt_setter : _mqtt_getter;
return output; return output;
} }
String mqttGetTopic(const char * topic, unsigned int index, bool set) {
String mqttTopic(const char * topic, unsigned int index, bool is_set) {
char buffer[strlen(topic)+5]; char buffer[strlen(topic)+5];
snprintf_P(buffer, sizeof(buffer), PSTR("%s/%d"), topic, index); snprintf_P(buffer, sizeof(buffer), PSTR("%s/%d"), topic, index);
return mqttGetTopic(buffer, set);
return mqttTopic(buffer, is_set);
} }
void mqttSendRaw(const char * topic, const char * message) { void mqttSendRaw(const char * topic, const char * message) {
@ -471,8 +488,7 @@ void mqttSend(const char * topic, const char * message, bool force) {
_mqtt_flush_ticker.once_ms(MQTT_USE_JSON_DELAY, _mqttFlush); _mqtt_flush_ticker.once_ms(MQTT_USE_JSON_DELAY, _mqttFlush);
} else { } else {
String path = _mqtt_topic + String(topic) + _mqtt_getter;
mqttSendRaw(path.c_str(), message);
mqttSendRaw(mqttTopic(topic, false).c_str(), message);
} }
} }
@ -503,8 +519,7 @@ void mqttSubscribeRaw(const char * topic) {
} }
void mqttSubscribe(const char * topic) { void mqttSubscribe(const char * topic) {
String path = _mqtt_topic + String(topic) + _mqtt_setter;
mqttSubscribeRaw(path.c_str());
mqttSubscribeRaw(mqttTopic(topic, true).c_str());
} }
void mqttUnsubscribeRaw(const char * topic) { void mqttUnsubscribeRaw(const char * topic) {


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

@ -586,7 +586,7 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo
if (type == MQTT_MESSAGE_EVENT) { if (type == MQTT_MESSAGE_EVENT) {
// Check relay topic // Check relay topic
String t = mqttSubtopic((char *) topic);
String t = mqttTopicKey((char *) topic);
if (t.startsWith(MQTT_TOPIC_RELAY)) { if (t.startsWith(MQTT_TOPIC_RELAY)) {
// Get value // Get value


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

@ -315,7 +315,7 @@ void _rfbMqttCallback(unsigned int type, const char * topic, const char * payloa
if (type == MQTT_MESSAGE_EVENT) { if (type == MQTT_MESSAGE_EVENT) {
// Match topic // Match topic
String t = mqttSubtopic((char *) topic);
String t = mqttTopicKey((char *) topic);
// Check if should go into learn mode // Check if should go into learn mode
if (t.startsWith(MQTT_TOPIC_RFLEARN)) { if (t.startsWith(MQTT_TOPIC_RFLEARN)) {


+ 3158
- 3158
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 1
- 1
code/html/index.html View File

@ -685,7 +685,7 @@
<input class="pure-u-1 pure-u-lg-3-4" name="mqttTopic" type="text" tabindex="31" /> <input class="pure-u-1 pure-u-lg-3-4" name="mqttTopic" type="text" tabindex="31" />
<div class="pure-u-0 pure-u-lg-1-4"></div> <div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint"> <div class="pure-u-1 pure-u-lg-3-4 hint">
This is the root topic for this device. A trailing slash will be added if not preset. The {identifier} placeholder will be replaced by the device hostname.<br />
This is the root topic for this device. A trailing slash will be added if not preset. The {hostname} and {mac} placeholders will be replaced by the device hostname and MAC address.<br />
- <strong>&lt;root&gt;/relay/#/set</strong> Send a 0 or a 1 as a payload to this topic to switch it on or off. You can also send a 2 to toggle its current state. Replace # with the switch ID (starting from 0). If the board has only one switch it will be 0.<br /> - <strong>&lt;root&gt;/relay/#/set</strong> Send a 0 or a 1 as a payload to this topic to switch it on or off. You can also send a 2 to toggle its current state. Replace # with the switch ID (starting from 0). If the board has only one switch it will be 0.<br />
<span class="module module-color">- <strong>&lt;root&gt;/color/set</strong> Set the color using this topic, your can either send an "#RRGGBB" value or "RRR,GGG,BBB".<br /></span> <span class="module module-color">- <strong>&lt;root&gt;/color/set</strong> Set the color using this topic, your can either send an "#RRGGBB" value or "RRR,GGG,BBB".<br /></span>
<span class="module module-color">- <strong>&lt;root&gt;/brightness/set</strong> Set the brighness using a value from 0 to 255.<br /></span> <span class="module module-color">- <strong>&lt;root&gt;/brightness/set</strong> Set the brighness using a value from 0 to 255.<br /></span>


Loading…
Cancel
Save