mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-27 05:06:44 +00:00
Configurable MQTT Topic #428
This commit is contained in:
parent
59bc01be04
commit
c296a5e568
@ -22,16 +22,21 @@ bool nvs_user_begin(Preferences& preferences, const char* key, bool readonly)
|
||||
|
||||
bool nvs_clear_user_config()
|
||||
{
|
||||
const char* name[8] = {FP_TIME, FP_OTA, FP_HTTP, FP_FTP, FP_MQTT, FP_WIFI};
|
||||
const char* name[] = {FP_TIME, FP_OTA, FP_HTTP, FP_FTP, FP_MQTT, FP_WIFI};
|
||||
Preferences preferences;
|
||||
bool state = true;
|
||||
|
||||
for(int i = 0; i < 6; i++) {
|
||||
if(!preferences.begin(name[i], false)) return false;
|
||||
if(!preferences.clear()) return false;
|
||||
for(int i = 0; i < sizeof(name) / sizeof(name[0]); i++) {
|
||||
if(preferences.begin(name[i], false) && !preferences.clear()) state = false;
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
return true;
|
||||
for(int i = 0; i < sizeof(name) / sizeof(name[0]); i++) {
|
||||
if(preferences.begin(name[i], false, "config") && !preferences.clear()) state = false;
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
bool nvsUpdateString(Preferences& preferences, const char* key, JsonVariant value)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
/* MIT License - Copyright (c) 2019-2023 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#include "hasp_conf.h"
|
||||
@ -22,6 +22,14 @@
|
||||
#include "../hasp/hasp_dispatch.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#include "esp_http_server.h"
|
||||
#include "esp_tls.h"
|
||||
|
||||
#define MQTT_DEFAULT_NODE_TOPIC MQTT_PREFIX "/%hostname%/%topic%"
|
||||
#define MQTT_DEFAULT_GROUP_TOPIC MQTT_PREFIX "/plates/%topic%"
|
||||
#define MQTT_DEFAULT_BROADCAST_TOPIC MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/%topic%"
|
||||
#define MQTT_DEFAULT_HASS_TOPIC "homeassistant/status"
|
||||
|
||||
QueueHandle_t queue;
|
||||
typedef struct
|
||||
{
|
||||
@ -29,22 +37,30 @@ typedef struct
|
||||
char* payload; //[512];
|
||||
} mqtt_message_t;
|
||||
|
||||
char mqttLwtTopic[28];
|
||||
char mqttNodeTopic[24];
|
||||
char mqttClientId[64];
|
||||
char mqttGroupTopic[24];
|
||||
String mqttNodeLwtTopic;
|
||||
String mqttHassLwtTopic;
|
||||
String mqttNodeStateTopic;
|
||||
String mqttNodeCommandTopic;
|
||||
String mqttGroupCommandTopic;
|
||||
String mqttBroadcastCommandTopic;
|
||||
bool mqttEnabled = false;
|
||||
bool mqttHAautodiscover = true;
|
||||
uint32_t mqttPublishCount;
|
||||
uint32_t mqttReceiveCount;
|
||||
uint32_t mqttFailedCount;
|
||||
|
||||
char mqttServer[MAX_HOSTNAME_LENGTH] = MQTT_HOSTNAME;
|
||||
char mqttUsername[MAX_USERNAME_LENGTH] = MQTT_USERNAME;
|
||||
char mqttPassword[MAX_PASSWORD_LENGTH] = MQTT_PASSWORD;
|
||||
String mqttServer = MQTT_HOSTNAME;
|
||||
String mqttUsername = MQTT_USERNAME;
|
||||
String mqttPassword = MQTT_PASSWORD;
|
||||
|
||||
// char mqttServer[MAX_HOSTNAME_LENGTH] = MQTT_HOSTNAME;
|
||||
// char mqttUsername[MAX_USERNAME_LENGTH] = MQTT_USERNAME;
|
||||
// char mqttPassword[MAX_PASSWORD_LENGTH] = MQTT_PASSWORD;
|
||||
// char mqttNodeName[16] = MQTT_NODENAME;
|
||||
char mqttGroupName[16] = MQTT_GROUPNAME;
|
||||
uint16_t mqttPort = MQTT_PORT;
|
||||
// char mqttGroupName[16] = MQTT_GROUPNAME;
|
||||
uint16_t mqttPort = MQTT_PORT;
|
||||
int mqttQos = 0;
|
||||
esp_mqtt_client_handle_t mqttClient;
|
||||
static esp_mqtt_client_config_t mqtt_cfg;
|
||||
|
||||
@ -107,7 +123,7 @@ int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
|
||||
if(!mqttEnabled) return MQTT_ERR_DISABLED;
|
||||
|
||||
// Write directly to the client, don't use the buffer
|
||||
if(current_mqtt_state && esp_mqtt_client_publish(mqttClient, topic, payload, len, 0, retain) != ESP_FAIL) {
|
||||
if(current_mqtt_state && esp_mqtt_client_publish(mqttClient, topic, payload, len, mqttQos, retain) != ESP_FAIL) {
|
||||
|
||||
// Enqueue a message to the outbox, to be sent later
|
||||
// if(current_mqtt_state && esp_mqtt_client_enqueue(mqttClient, topic, payload, len, 0, retain, true) !=
|
||||
@ -136,29 +152,29 @@ bool mqttIsConnected()
|
||||
bool mqtt_send_lwt(bool online)
|
||||
{
|
||||
char tmp_payload[8];
|
||||
// char tmp_topic[strlen(mqttNodeTopic) + 4];
|
||||
|
||||
// strncpy(tmp_topic, mqttNodeTopic, sizeof(tmp_topic));
|
||||
// strncat_P(tmp_topic, PSTR(MQTT_TOPIC_LWT), sizeof(tmp_topic));
|
||||
|
||||
size_t len = snprintf_P(tmp_payload, sizeof(tmp_payload), online ? PSTR("online") : PSTR("offline"));
|
||||
bool res = mqttPublish(mqttLwtTopic, tmp_payload, len, true);
|
||||
bool res = mqttPublish(mqttNodeLwtTopic.c_str(), tmp_payload, len, true);
|
||||
return res;
|
||||
}
|
||||
|
||||
int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
|
||||
{
|
||||
char tmp_topic[strlen(mqttNodeTopic) + 16];
|
||||
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/" HASP_OBJECT_NOTATION), mqttNodeTopic,
|
||||
pageid, btnid);
|
||||
return mqttPublish(tmp_topic, payload, false);
|
||||
}
|
||||
// int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
|
||||
// {
|
||||
// char tmp_topic[strlen(mqttNodeTopic) + 16];
|
||||
// snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/" HASP_OBJECT_NOTATION), mqttNodeTopic,
|
||||
// pageid, btnid);
|
||||
// return mqttPublish(tmp_topic, payload, false);
|
||||
// }
|
||||
|
||||
int mqtt_send_state(const char* subtopic, const char* payload)
|
||||
{
|
||||
char tmp_topic[strlen(mqttNodeTopic) + strlen(subtopic) + 16];
|
||||
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic, subtopic);
|
||||
return mqttPublish(tmp_topic, payload, false);
|
||||
String tmp_topic((char*)0);
|
||||
tmp_topic.reserve(128);
|
||||
tmp_topic = mqttNodeStateTopic;
|
||||
// tmp_topic += MQTT_TOPIC_STATE;
|
||||
// tmp_topic += "/";
|
||||
tmp_topic += subtopic;
|
||||
|
||||
return mqttPublish(tmp_topic.c_str(), payload, false);
|
||||
}
|
||||
|
||||
int mqtt_send_discovery(const char* payload, size_t len)
|
||||
@ -216,21 +232,15 @@ static void mqtt_message_cb(const char* topic, byte* payload, unsigned int lengt
|
||||
mqttReceiveCount++;
|
||||
// LOG_TRACE(TAG_MQTT_RCV, F("%s = %s"), topic, (char*)payload);
|
||||
|
||||
if(topic == strstr(topic, mqttNodeTopic)) { // startsWith mqttNodeTopic
|
||||
if(topic == strstr(topic, mqttNodeCommandTopic.c_str())) { // startsWith mqttNodeCommandTopic
|
||||
topic += strlen(mqttNodeCommandTopic.c_str()); // shorten Node topic
|
||||
|
||||
// Node topic
|
||||
topic += strlen(mqttNodeTopic); // shorten topic
|
||||
|
||||
} else if(topic == strstr(topic, mqttGroupTopic)) { // startsWith mqttGroupTopic
|
||||
|
||||
// Group topic
|
||||
topic += strlen(mqttGroupTopic); // shorten topic
|
||||
} else if(topic == strstr(topic, mqttGroupCommandTopic.c_str())) { // startsWith mqttGroupCommandTopic
|
||||
topic += strlen(mqttGroupCommandTopic.c_str()); // shorten Group topic
|
||||
|
||||
#ifdef HASP_USE_BROADCAST
|
||||
} else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/"))) { // broadcast topic
|
||||
|
||||
// Broadcast topic
|
||||
topic += strlen_P(PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/")); // shorten topic
|
||||
} else if(topic == strstr_P(topic, mqttBroadcastCommandTopic.c_str())) { // broadcast topic
|
||||
topic += strlen_P(mqttBroadcastCommandTopic.c_str()); // shorten Broadcast topic
|
||||
#endif
|
||||
|
||||
#ifdef HASP_USE_HA
|
||||
@ -241,10 +251,14 @@ static void mqtt_message_cb(const char* topic, byte* payload, unsigned int lengt
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
} else if(topic == strstr(topic, mqttHassLwtTopic.c_str())) { // startsWith mqttGroupCommandTopic
|
||||
String state = String((const char*)payload);
|
||||
state.toLowerCase();
|
||||
LOG_VERBOSE(TAG_MQTT, "Home Automation System: %s", state);
|
||||
return;
|
||||
|
||||
} else {
|
||||
// Other topic
|
||||
LOG_ERROR(TAG_MQTT, F(D_MQTT_INVALID_TOPIC));
|
||||
LOG_ERROR(TAG_MQTT, F(D_MQTT_INVALID_TOPIC ": %s"), topic); // Other topic
|
||||
return;
|
||||
}
|
||||
|
||||
@ -270,6 +284,7 @@ static void mqtt_message_cb(const char* topic, byte* payload, unsigned int lengt
|
||||
else */
|
||||
|
||||
{
|
||||
if(topic[0] == '/') topic++;
|
||||
mqtt_process_topic_payload(topic, (const char*)payload, length);
|
||||
}
|
||||
|
||||
@ -286,41 +301,58 @@ static void mqtt_message_cb(const char* topic, byte* payload, unsigned int lengt
|
||||
} */
|
||||
}
|
||||
|
||||
static void mqttSubscribeTo(const char* topic)
|
||||
static int mqttSubscribeTo(String topic)
|
||||
{
|
||||
if(esp_mqtt_client_subscribe(mqttClient, topic, 0) == ESP_FAIL) {
|
||||
LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_SUBSCRIBED), topic);
|
||||
int err = esp_mqtt_client_subscribe(mqttClient, topic.c_str(), mqttQos);
|
||||
if(err == ESP_FAIL) {
|
||||
LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_SUBSCRIBED), topic.c_str());
|
||||
mqttFailedCount++;
|
||||
} else {
|
||||
LOG_VERBOSE(TAG_MQTT, F(D_BULLET D_MQTT_SUBSCRIBED), topic);
|
||||
LOG_VERBOSE(TAG_MQTT, F(D_BULLET D_MQTT_SUBSCRIBED), topic.c_str());
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
String mqttGetTopic(Preferences preferences, String subtopic, String key, String value, bool add_slash)
|
||||
{
|
||||
String topic = preferences.getString(key.c_str(), value);
|
||||
|
||||
topic.replace(F("%hostname%"), haspDevice.get_hostname());
|
||||
topic.replace(F("%hwid%"), haspDevice.get_hardware_id());
|
||||
topic.replace(F("%topic%"), subtopic);
|
||||
topic.replace(F("%prefix%"), MQTT_PREFIX);
|
||||
|
||||
if(add_slash && !topic.endsWith("/")) {
|
||||
topic += "/";
|
||||
}
|
||||
return topic;
|
||||
}
|
||||
|
||||
void onMqttConnect(esp_mqtt_client_handle_t client)
|
||||
{
|
||||
LOG_INFO(TAG_MQTT, F(D_MQTT_CONNECTED), mqttServer, mqttClientId);
|
||||
|
||||
// Subscribe to our incoming topics
|
||||
char topic[64];
|
||||
snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_COMMAND "/#"), mqttGroupTopic);
|
||||
mqttSubscribeTo(topic);
|
||||
snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_COMMAND "/#"), mqttNodeTopic);
|
||||
mqttSubscribeTo(topic);
|
||||
snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_CONFIG "/#"), mqttGroupTopic);
|
||||
mqttSubscribeTo(topic);
|
||||
snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_CONFIG "/#"), mqttNodeTopic);
|
||||
mqttSubscribeTo(topic);
|
||||
LOG_DEBUG(TAG_MQTT, F(D_BULLET "%s"), mqttNodeCommandTopic.c_str());
|
||||
LOG_DEBUG(TAG_MQTT, F(D_BULLET "%s"), mqttGroupCommandTopic.c_str());
|
||||
LOG_DEBUG(TAG_MQTT, F(D_BULLET "%s"), mqttBroadcastCommandTopic.c_str());
|
||||
LOG_DEBUG(TAG_MQTT, F(D_BULLET "%s"), mqttHassLwtTopic.c_str());
|
||||
|
||||
#if defined(HASP_USE_CUSTOM)
|
||||
snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_CUSTOM "/#"), mqttGroupTopic);
|
||||
mqttSubscribeTo(topic);
|
||||
snprintf_P(topic, sizeof(topic), PSTR("%s" MQTT_TOPIC_CUSTOM "/#"), mqttNodeTopic);
|
||||
mqttSubscribeTo(topic);
|
||||
#endif
|
||||
// Subscribe to our incoming topics
|
||||
mqttSubscribeTo(mqttGroupCommandTopic + "/#");
|
||||
mqttSubscribeTo(mqttNodeCommandTopic + "/#");
|
||||
|
||||
#ifdef HASP_USE_BROADCAST
|
||||
snprintf_P(topic, sizeof(topic), PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/" MQTT_TOPIC_COMMAND "/#"));
|
||||
mqttSubscribeTo(topic);
|
||||
mqttSubscribeTo(mqttBroadcastCommandTopic + "/#");
|
||||
#endif
|
||||
|
||||
// subtopic = F(MQTT_TOPIC_CONFIG "/#");
|
||||
// mqttSubscribeTo(mqttGroupTopic + subtopic);
|
||||
// mqttSubscribeTo(mqttNodeTopic + subtopic);
|
||||
|
||||
#if defined(HASP_USE_CUSTOM)
|
||||
subtopic = F(MQTT_TOPIC_CUSTOM "/#");
|
||||
mqttSubscribeTo(mqttGroupTopic + subtopic);
|
||||
mqttSubscribeTo(mqttNodeTopic + subtopic);
|
||||
#endif
|
||||
|
||||
/* Home Assistant auto-configuration */
|
||||
@ -334,6 +366,8 @@ void onMqttConnect(esp_mqtt_client_handle_t client)
|
||||
}
|
||||
#endif
|
||||
|
||||
mqttSubscribeTo(mqttHassLwtTopic);
|
||||
|
||||
// Force any subscribed clients to toggle offline/online when we first connect to
|
||||
// make sure we get a full panel refresh at power on. Sending offline,
|
||||
// "online" will be sent by the mqttStatusTopic subscription action.
|
||||
@ -358,10 +392,10 @@ static void onMqttData(esp_mqtt_event_handle_t event)
|
||||
|
||||
static void onMqttSubscribed(esp_mqtt_event_handle_t event)
|
||||
{
|
||||
String topic = String(event->topic).substring(0, event->topic_len);
|
||||
String msg = String(event->data).substring(0, event->data_len);
|
||||
LOG_VERBOSE(TAG_MQTT, F(D_BULLET D_MQTT_SUBSCRIBED " %d %s %d"), topic.c_str(), event->topic_len, msg.c_str(),
|
||||
event->data_len);
|
||||
// String topic = String(event->topic).substring(0, event->topic_len);
|
||||
String msg = String(event->data).substring(0, event->data_len);
|
||||
const char* topic = "topic";
|
||||
LOG_VERBOSE(TAG_MQTT, F(D_BULLET D_MQTT_SUBSCRIBED "(%d)"), topic, event->msg_id);
|
||||
}
|
||||
|
||||
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
||||
@ -410,8 +444,8 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
||||
case MQTT_CONNECTION_REFUSE_BAD_USERNAME: /*!< MQTT connection refused reason: Wrong user */
|
||||
LOG_WARNING(TAG_MQTT, "Connection refused: Wrong user");
|
||||
break;
|
||||
case MQTT_CONNECTION_REFUSE_NOT_AUTHORIZED: /*!< MQTT connection refused reason: Wrong username
|
||||
or password */
|
||||
case MQTT_CONNECTION_REFUSE_NOT_AUTHORIZED: /*!< MQTT connection refused reason: Wrong
|
||||
username or password */
|
||||
LOG_WARNING(TAG_MQTT, "Connection refused: Authentication error");
|
||||
break;
|
||||
default:;
|
||||
@ -430,12 +464,6 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
||||
|
||||
void mqttSetup()
|
||||
{
|
||||
Preferences preferences;
|
||||
preferences.begin("mqtt", true);
|
||||
String password = preferences.getString(FP_CONFIG_PASS, MQTT_PASSWORD);
|
||||
strncpy(mqttPassword, password.c_str(), sizeof(mqttPassword));
|
||||
LOG_DEBUG(TAG_MQTT, F(D_BULLET "Read %s => %s (%d bytes)"), FP_CONFIG_PASS, password.c_str(), password.length());
|
||||
|
||||
queue = xQueueCreate(64, sizeof(mqtt_message_t));
|
||||
esp_crt_bundle_set(rootca_crt_bundle_start);
|
||||
mqttStart();
|
||||
@ -468,10 +496,45 @@ void mqttEvery5Seconds(bool networkIsConnected)
|
||||
|
||||
void mqttStart()
|
||||
{
|
||||
char buffer[64];
|
||||
char lastWillPayload[8];
|
||||
{
|
||||
Preferences preferences;
|
||||
nvs_user_begin(preferences, FP_MQTT, true);
|
||||
mqttServer = preferences.getString(FP_CONFIG_HOST, mqttServer); // Update from NVS if it exists
|
||||
mqttUsername = preferences.getString(FP_CONFIG_USER, mqttUsername); // Update from NVS if it exists
|
||||
mqttPassword = preferences.getString(FP_CONFIG_PASS, mqttPassword); // Update from NVS if it exists
|
||||
mqttPort = preferences.getUShort(FP_CONFIG_PORT, mqttPort); // Update from NVS if it exists
|
||||
|
||||
mqttEnabled = strlen(mqttServer) > 0 && mqttPort > 0;
|
||||
String subtopic((char*)0);
|
||||
subtopic.reserve(64);
|
||||
|
||||
String nvsOldGroup = MQTT_PREFIX "/"; // recover group setting
|
||||
nvsOldGroup += preferences.getString(FP_CONFIG_GROUP, "plates");
|
||||
nvsOldGroup += "/%topic%";
|
||||
|
||||
subtopic = F(MQTT_TOPIC_COMMAND);
|
||||
mqttNodeCommandTopic =
|
||||
mqttGetTopic(preferences, subtopic, FP_CONFIG_NODE_TOPIC, MQTT_DEFAULT_NODE_TOPIC, false);
|
||||
mqttGroupCommandTopic = mqttGetTopic(preferences, subtopic, FP_CONFIG_GROUP_TOPIC, nvsOldGroup.c_str(), false);
|
||||
#ifdef HASP_USE_BROADCAST
|
||||
mqttBroadcastCommandTopic =
|
||||
mqttGetTopic(preferences, subtopic, FP_CONFIG_BROADCAST_TOPIC, MQTT_DEFAULT_BROADCAST_TOPIC, false);
|
||||
#endif
|
||||
|
||||
subtopic = F(MQTT_TOPIC_STATE);
|
||||
mqttNodeStateTopic = mqttGetTopic(preferences, subtopic, FP_CONFIG_NODE_TOPIC, MQTT_DEFAULT_NODE_TOPIC, true);
|
||||
|
||||
subtopic = F(MQTT_TOPIC_LWT);
|
||||
mqttNodeLwtTopic = mqttGetTopic(preferences, subtopic, FP_CONFIG_NODE_TOPIC, MQTT_DEFAULT_NODE_TOPIC, false);
|
||||
LOG_WARNING(TAG_MQTT, mqttNodeLwtTopic.c_str());
|
||||
|
||||
subtopic = F(MQTT_TOPIC_LWT);
|
||||
mqttHassLwtTopic = mqttGetTopic(preferences, subtopic, FP_CONFIG_HASS_TOPIC, MQTT_DEFAULT_HASS_TOPIC, false);
|
||||
LOG_WARNING(TAG_MQTT, mqttNodeLwtTopic.c_str());
|
||||
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
mqttEnabled = mqttServer.length() > 0 && mqttPort > 0;
|
||||
if(!mqttEnabled) {
|
||||
LOG_WARNING(TAG_MQTT, F(D_MQTT_NOT_CONFIGURED));
|
||||
return;
|
||||
@ -488,10 +551,6 @@ void mqttStart()
|
||||
LOG_INFO(TAG_MQTT, mqttClientId);
|
||||
}
|
||||
|
||||
strncpy(mqttLwtTopic, mqttNodeTopic, sizeof(mqttLwtTopic));
|
||||
strncat_P(mqttLwtTopic, PSTR(MQTT_TOPIC_LWT), sizeof(mqttLwtTopic));
|
||||
LOG_WARNING(TAG_MQTT, mqttLwtTopic);
|
||||
|
||||
mqtt_cfg.event_handle = mqtt_event_handler;
|
||||
mqtt_cfg.buffer_size = MQTT_MAX_PACKET_SIZE;
|
||||
mqtt_cfg.out_buffer_size = 512;
|
||||
@ -502,15 +561,15 @@ void mqttStart()
|
||||
|
||||
mqtt_cfg.protocol_ver = MQTT_PROTOCOL_V_3_1_1;
|
||||
mqtt_cfg.transport = MQTT_TRANSPORT_OVER_TCP;
|
||||
mqtt_cfg.host = mqttServer;
|
||||
mqtt_cfg.host = mqttServer.c_str();
|
||||
mqtt_cfg.port = mqttPort;
|
||||
mqtt_cfg.username = mqttUsername;
|
||||
mqtt_cfg.password = mqttPassword;
|
||||
mqtt_cfg.username = mqttUsername.c_str();
|
||||
mqtt_cfg.password = mqttPassword.c_str();
|
||||
mqtt_cfg.client_id = mqttClientId;
|
||||
|
||||
mqtt_cfg.lwt_msg = "offline";
|
||||
mqtt_cfg.lwt_retain = true;
|
||||
mqtt_cfg.lwt_topic = mqttLwtTopic;
|
||||
mqtt_cfg.lwt_topic = mqttNodeLwtTopic.c_str();
|
||||
mqtt_cfg.lwt_qos = 1;
|
||||
|
||||
mqtt_cfg.task_prio = 1;
|
||||
@ -610,27 +669,73 @@ void mqtt_get_info(JsonDocument& doc)
|
||||
bool mqttGetConfig(const JsonObject& settings)
|
||||
{
|
||||
bool changed = false;
|
||||
Preferences preferences;
|
||||
nvs_user_begin(preferences, FP_MQTT, false);
|
||||
|
||||
if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname();
|
||||
{
|
||||
String nvsServer = preferences.getString(FP_CONFIG_HOST, mqttServer); // Read from NVS if it exists
|
||||
if(strcmp(nvsServer.c_str(), settings[FP_CONFIG_HOST].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FP_CONFIG_HOST] = nvsServer;
|
||||
}
|
||||
|
||||
if(strcmp(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName;
|
||||
{
|
||||
String nvsUsername = preferences.getString(FP_CONFIG_USER, mqttUsername); // Read from NVS if it exists
|
||||
if(strcmp(nvsUsername.c_str(), settings[FP_CONFIG_USER].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FP_CONFIG_USER] = nvsUsername;
|
||||
}
|
||||
|
||||
if(strcmp(mqttServer, settings[FPSTR(FP_CONFIG_HOST)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_HOST)] = mqttServer;
|
||||
{
|
||||
String nvsPassword = preferences.getString(FP_CONFIG_PASS, mqttPassword); // Read from NVS if it exists
|
||||
if(strcmp(D_PASSWORD_MASK, settings[FP_CONFIG_PASS].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FP_CONFIG_PASS] = D_PASSWORD_MASK;
|
||||
}
|
||||
|
||||
if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as<uint16_t>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_PORT)] = mqttPort;
|
||||
{
|
||||
String nvsNodeTopic =
|
||||
preferences.getString(FP_CONFIG_NODE_TOPIC, MQTT_DEFAULT_NODE_TOPIC); // Read from NVS if it exists
|
||||
if(strcmp(nvsNodeTopic.c_str(), settings["topic"][FP_CONFIG_NODE].as<String>().c_str()) != 0) changed = true;
|
||||
settings["topic"][FP_CONFIG_NODE] = nvsNodeTopic;
|
||||
}
|
||||
|
||||
if(strcmp(mqttUsername, settings[FPSTR(FP_CONFIG_USER)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_USER)] = mqttUsername;
|
||||
{
|
||||
String nvsOldGroup = MQTT_PREFIX "/"; // recover group setting
|
||||
nvsOldGroup += preferences.getString(FP_CONFIG_GROUP, "plates");
|
||||
nvsOldGroup += "/%topic%";
|
||||
|
||||
String nvsGroupTopic =
|
||||
preferences.getString(FP_CONFIG_GROUP_TOPIC, nvsOldGroup.c_str()); // Read from NVS if it exists
|
||||
if(strcmp(nvsGroupTopic.c_str(), settings["topic"][FP_CONFIG_GROUP].as<String>().c_str()) != 0) changed = true;
|
||||
settings["topic"][FP_CONFIG_GROUP] = nvsGroupTopic;
|
||||
}
|
||||
|
||||
// if(strcmp(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)].as<String>().c_str()) != 0) changed = true;
|
||||
// settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword;
|
||||
if(strcmp(D_PASSWORD_MASK, settings[FPSTR(FP_CONFIG_PASS)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_PASS)] = D_PASSWORD_MASK;
|
||||
{
|
||||
String nvsBroadcastTopic = preferences.getString(FP_CONFIG_BROADCAST_TOPIC,
|
||||
MQTT_DEFAULT_BROADCAST_TOPIC); // Read from NVS if it exists
|
||||
if(strcmp(nvsBroadcastTopic.c_str(), settings["topic"][FP_CONFIG_BROADCAST].as<String>().c_str()) != 0)
|
||||
changed = true;
|
||||
settings["topic"][FP_CONFIG_BROADCAST] = nvsBroadcastTopic;
|
||||
}
|
||||
|
||||
{
|
||||
String nvsHassTopic =
|
||||
preferences.getString(FP_CONFIG_HASS_TOPIC, MQTT_DEFAULT_HASS_TOPIC); // Read from NVS if it exists
|
||||
if(strcmp(nvsHassTopic.c_str(), settings["topic"][FP_CONFIG_HASS].as<String>().c_str()) != 0) changed = true;
|
||||
settings["topic"][FP_CONFIG_HASS] = nvsHassTopic;
|
||||
}
|
||||
|
||||
{
|
||||
uint16_t nvsPort = preferences.getUShort(FP_CONFIG_PORT, mqttPort); // Read from NVS if it exists
|
||||
if(nvsPort != settings[FP_CONFIG_PORT].as<uint16_t>()) changed = true;
|
||||
settings[FP_CONFIG_PORT] = nvsPort;
|
||||
}
|
||||
|
||||
if(strcmp(haspDevice.get_hostname(), settings[FP_CONFIG_NAME].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FP_CONFIG_NAME] = haspDevice.get_hostname();
|
||||
|
||||
// if(strcmp(mqttGroupName, settings[FP_CONFIG_GROUP].as<String>().c_str()) != 0) changed = true;
|
||||
// settings[FP_CONFIG_GROUP] = mqttGroupName;
|
||||
|
||||
preferences.end();
|
||||
if(changed) configOutput(settings, TAG_MQTT);
|
||||
return changed;
|
||||
}
|
||||
@ -646,17 +751,20 @@ bool mqttGetConfig(const JsonObject& settings)
|
||||
bool mqttSetConfig(const JsonObject& settings)
|
||||
{
|
||||
Preferences preferences;
|
||||
preferences.begin("mqtt", false);
|
||||
nvs_user_begin(preferences, FP_MQTT, false);
|
||||
|
||||
configOutput(settings, TAG_MQTT);
|
||||
bool changed = false;
|
||||
|
||||
changed |= configSet(mqttPort, settings[FPSTR(FP_CONFIG_PORT)], F("mqttPort"));
|
||||
if(!settings[FP_CONFIG_PORT].isNull()) {
|
||||
// changed |= configSet(mqttPort, settings[FP_CONFIG_PORT], F("mqttPort"));
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_PORT, settings[FP_CONFIG_PORT]);
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_NAME)].isNull()) {
|
||||
changed |= strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)]) != 0;
|
||||
// strncpy(mqttNodeName, settings[FPSTR(FP_CONFIG_NAME)], sizeof(mqttNodeName));
|
||||
haspDevice.set_hostname(settings[FPSTR(FP_CONFIG_NAME)].as<const char*>());
|
||||
if(!settings[FP_CONFIG_NAME].isNull()) {
|
||||
changed |= strcmp(haspDevice.get_hostname(), settings[FP_CONFIG_NAME]) != 0;
|
||||
// strncpy(mqttNodeName, settings[FP_CONFIG_NAME], sizeof(mqttNodeName));
|
||||
haspDevice.set_hostname(settings[FP_CONFIG_NAME].as<const char*>());
|
||||
}
|
||||
// Prefill node name
|
||||
if(strlen(haspDevice.get_hostname()) == 0) {
|
||||
@ -668,36 +776,57 @@ bool mqttSetConfig(const JsonObject& settings)
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_GROUP)].isNull()) {
|
||||
changed |= strcmp(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)]) != 0;
|
||||
strncpy(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)], sizeof(mqttGroupName));
|
||||
if(!settings[FP_CONFIG_GROUP].isNull()) {
|
||||
// changed |= strcmp(mqttGroupName, settings[FP_CONFIG_GROUP]) != 0;
|
||||
// strncpy(mqttGroupName, settings[FP_CONFIG_GROUP], sizeof(mqttGroupName));
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_GROUP, settings[FP_CONFIG_GROUP]);
|
||||
}
|
||||
|
||||
if(strlen(mqttGroupName) == 0) {
|
||||
strcpy_P(mqttGroupName, PSTR("plates"));
|
||||
changed = true;
|
||||
// if(strlen(mqttGroupName) == 0) {
|
||||
// strcpy_P(mqttGroupName, PSTR("plates"));
|
||||
// changed = true;
|
||||
// }
|
||||
|
||||
if(!settings[FP_CONFIG_HOST].isNull()) {
|
||||
// changed |= strcmp(mqttServer, settings[FP_CONFIG_HOST]) != 0;
|
||||
// strncpy(mqttServer, settings[FP_CONFIG_HOST], sizeof(mqttServer));
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_HOST, settings[FP_CONFIG_HOST]);
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_HOST)].isNull()) {
|
||||
changed |= strcmp(mqttServer, settings[FPSTR(FP_CONFIG_HOST)]) != 0;
|
||||
strncpy(mqttServer, settings[FPSTR(FP_CONFIG_HOST)], sizeof(mqttServer));
|
||||
if(!settings[FP_CONFIG_USER].isNull()) {
|
||||
// changed |= strcmp(mqttUsername, settings[FP_CONFIG_USER]) != 0;
|
||||
// strncpy(mqttUsername, settings[FP_CONFIG_USER], sizeof(mqttUsername));
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_USER, settings[FP_CONFIG_USER]);
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_USER)].isNull()) {
|
||||
changed |= strcmp(mqttUsername, settings[FPSTR(FP_CONFIG_USER)]) != 0;
|
||||
strncpy(mqttUsername, settings[FPSTR(FP_CONFIG_USER)], sizeof(mqttUsername));
|
||||
if(!settings[FP_CONFIG_PASS].isNull() && settings[FP_CONFIG_PASS].as<String>() != String(D_PASSWORD_MASK)) {
|
||||
// changed |= strcmp(mqttPassword, settings[FP_CONFIG_PASS]) != 0;
|
||||
// strncpy(mqttPassword, settings[FP_CONFIG_PASS], sizeof(mqttPassword));
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_PASS, settings[FP_CONFIG_PASS]);
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_PASS)].isNull() &&
|
||||
settings[FPSTR(FP_CONFIG_PASS)].as<String>() != String(FPSTR(D_PASSWORD_MASK))) {
|
||||
changed |= strcmp(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)]) != 0;
|
||||
strncpy(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)], sizeof(mqttPassword));
|
||||
nvsUpdateString(preferences, FP_CONFIG_PASS, settings[FPSTR(FP_CONFIG_PASS)]);
|
||||
JsonVariant topic;
|
||||
topic = settings["topic"][FP_CONFIG_NODE];
|
||||
if(topic.is<const char*>()) {
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_NODE_TOPIC, topic);
|
||||
}
|
||||
topic = settings["topic"][FP_CONFIG_GROUP];
|
||||
if(topic.is<const char*>()) {
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_GROUP_TOPIC, topic);
|
||||
}
|
||||
topic = settings["topic"][FP_CONFIG_BROADCAST];
|
||||
if(topic.is<const char*>()) {
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_BROADCAST_TOPIC, topic);
|
||||
}
|
||||
topic = settings["topic"][FP_CONFIG_HASS];
|
||||
if(topic.is<const char*>()) {
|
||||
changed |= nvsUpdateString(preferences, FP_CONFIG_HASS_TOPIC, topic);
|
||||
}
|
||||
|
||||
snprintf_P(mqttNodeTopic, sizeof(mqttNodeTopic), PSTR(MQTT_PREFIX "/%s/"), haspDevice.get_hostname());
|
||||
snprintf_P(mqttGroupTopic, sizeof(mqttGroupTopic), PSTR(MQTT_PREFIX "/%s/"), mqttGroupName);
|
||||
// snprintf_P(mqttNodeTopic, sizeof(mqttNodeTopic), PSTR(MQTT_PREFIX "/%s/"), haspDevice.get_hostname());
|
||||
// snprintf_P(mqttGroupTopic, sizeof(mqttGroupTopic), PSTR(MQTT_PREFIX "/%s/"), mqttGroupName);
|
||||
|
||||
preferences.end();
|
||||
return changed;
|
||||
}
|
||||
#endif // HASP_USE_CONFIG
|
||||
|
@ -1413,14 +1413,10 @@ static void http_handle_mqtt()
|
||||
<h2 v-t="'mqtt.title'"></h2>
|
||||
<div class="container" v-cloak v-if="config.mqtt">
|
||||
<form @submit.prevent="submitOldConfig('mqtt') ">
|
||||
<div class="row">
|
||||
<div class="row gap">
|
||||
<div class="col-25"><label class="required" for="name" v-t="'mqtt.name'"></label></div>
|
||||
<div class="col-75"><input required="" type="text" id="name" maxlength="63" pattern="[a-z0-9_]*" placeholder="Plate Name" v-model="config.mqtt.name"></div>
|
||||
</div>
|
||||
<div class="row gap">
|
||||
<div class="col-25"><label for="group" v-t="'mqtt.group'"></label></div>
|
||||
<div class="col-75"><input type="text" id="group" maxlength="15" pattern="[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]" placeholder="Group Name" v-model="config.mqtt.group"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-25"><label for="host" v-t="'mqtt.host'"></label></div>
|
||||
<div class="col-75"><input type="text" id="host" maxlength="127" placeholder="Server Name" v-model="config.mqtt.host"></div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user