From c296a5e568bb947f711646f4428b64651e63be0f Mon Sep 17 00:00:00 2001 From: fvanroie Date: Wed, 15 Feb 2023 20:09:13 +0100 Subject: [PATCH] Configurable MQTT Topic #428 --- src/hasp/hasp_nvs.cpp | 15 +- src/mqtt/hasp_mqtt_esp.cpp | 377 +++++++++++++++++++++++++------------ src/sys/svc/hasp_http.cpp | 6 +- 3 files changed, 264 insertions(+), 134 deletions(-) diff --git a/src/hasp/hasp_nvs.cpp b/src/hasp/hasp_nvs.cpp index 88039415..439a1bea 100644 --- a/src/hasp/hasp_nvs.cpp +++ b/src/hasp/hasp_nvs.cpp @@ -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) diff --git a/src/mqtt/hasp_mqtt_esp.cpp b/src/mqtt/hasp_mqtt_esp.cpp index a82ec54f..55b910a5 100644 --- a/src/mqtt/hasp_mqtt_esp.cpp +++ b/src/mqtt/hasp_mqtt_esp.cpp @@ -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().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().c_str()) != 0) changed = true; + settings[FP_CONFIG_HOST] = nvsServer; + } - if(strcmp(mqttGroupName, settings[FPSTR(FP_CONFIG_GROUP)].as().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().c_str()) != 0) changed = true; + settings[FP_CONFIG_USER] = nvsUsername; + } - if(strcmp(mqttServer, settings[FPSTR(FP_CONFIG_HOST)].as().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().c_str()) != 0) changed = true; + settings[FP_CONFIG_PASS] = D_PASSWORD_MASK; + } - if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as()) 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().c_str()) != 0) changed = true; + settings["topic"][FP_CONFIG_NODE] = nvsNodeTopic; + } - if(strcmp(mqttUsername, settings[FPSTR(FP_CONFIG_USER)].as().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().c_str()) != 0) changed = true; + settings["topic"][FP_CONFIG_GROUP] = nvsGroupTopic; + } - // if(strcmp(mqttPassword, settings[FPSTR(FP_CONFIG_PASS)].as().c_str()) != 0) changed = true; - // settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword; - if(strcmp(D_PASSWORD_MASK, settings[FPSTR(FP_CONFIG_PASS)].as().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().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().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()) changed = true; + settings[FP_CONFIG_PORT] = nvsPort; + } + + if(strcmp(haspDevice.get_hostname(), settings[FP_CONFIG_NAME].as().c_str()) != 0) changed = true; + settings[FP_CONFIG_NAME] = haspDevice.get_hostname(); + + // if(strcmp(mqttGroupName, settings[FP_CONFIG_GROUP].as().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()); + 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()); } // 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(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(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()) { + changed |= nvsUpdateString(preferences, FP_CONFIG_NODE_TOPIC, topic); + } + topic = settings["topic"][FP_CONFIG_GROUP]; + if(topic.is()) { + changed |= nvsUpdateString(preferences, FP_CONFIG_GROUP_TOPIC, topic); + } + topic = settings["topic"][FP_CONFIG_BROADCAST]; + if(topic.is()) { + changed |= nvsUpdateString(preferences, FP_CONFIG_BROADCAST_TOPIC, topic); + } + topic = settings["topic"][FP_CONFIG_HASS]; + if(topic.is()) { + 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 diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 37047f23..75ccecf2 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1413,14 +1413,10 @@ static void http_handle_mqtt()

-
+
-
-
-
-