From d3193ee5effb89fc7132cd73d17f5fcafa899ebc Mon Sep 17 00:00:00 2001 From: fvanroie Date: Mon, 13 Apr 2020 17:50:45 +0200 Subject: [PATCH] Add config topics --- src/hasp_config.cpp | 28 +++++++------- src/hasp_dispatch.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++ src/hasp_dispatch.h | 2 + src/hasp_mqtt.cpp | 15 ++++++-- 4 files changed, 117 insertions(+), 18 deletions(-) diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 12bcb75e..69649c0c 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -168,32 +168,26 @@ void configWriteConfig() configGetConfig(doc, false); Log.trace(F("CONF: Config LOADED first %s"), configFile.c_str()); - bool writefile = false; - bool changed = false; + // Make sure we have a valid JsonObject to start from JsonObject settings; - if(doc.as().isNull()) { - settings = doc.to(); + settings = doc.to(); // Settings are invalid, force creation of an empty JsonObject } else { - settings = doc.as(); + settings = doc.as(); // Settings are valid, cast as a JsonObject } - if(settings[F("wifi")].as().isNull()) settings.createNestedObject(F("wifi")); - if(settings[F("mqtt")].as().isNull()) settings.createNestedObject(F("mqtt")); - if(settings[F("hasp")].as().isNull()) settings.createNestedObject(F("hasp")); - if(settings[F("mdns")].as().isNull()) settings.createNestedObject(F("mdns")); - if(settings[F("http")].as().isNull()) settings.createNestedObject(F("http")); - if(settings[F("debug")].as().isNull()) settings.createNestedObject(F("debug")); - if(settings[F("telnet")].as().isNull()) settings.createNestedObject(F("telnet")); - if(settings[F("gui")].as().isNull()) settings.createNestedObject(F("gui")); + bool writefile = false; + bool changed = false; #if HASP_USE_WIFI - changed = wifiGetConfig(settings[F("wifi")].as()); + if(settings[F("wifi")].as().isNull()) settings.createNestedObject(F("wifi")); + changed = wifiGetConfig(settings[F("wifi")]); if(changed) { Log.verbose(F("WIFI: Settings changed")); writefile = true; } #if HASP_USE_MQTT + if(settings[F("mqtt")].as().isNull()) settings.createNestedObject(F("mqtt")); changed = mqttGetConfig(settings[F("mqtt")]); if(changed) { Log.verbose(F("MQTT: Settings changed")); @@ -202,6 +196,7 @@ void configWriteConfig() } #endif #if HASP_USE_TELNET + if(settings[F("telnet")].as().isNull()) settings.createNestedObject(F("telnet")); changed = telnetGetConfig(settings[F("telnet")]); if(changed) { Log.verbose(F("TELNET: Settings changed")); @@ -210,6 +205,7 @@ void configWriteConfig() } #endif #if HASP_USE_MDNS + if(settings[F("mdns")].as().isNull()) settings.createNestedObject(F("mdns")); changed = mdnsGetConfig(settings[F("mdns")]); if(changed) { Log.verbose(F("MDNS: Settings changed")); @@ -217,6 +213,7 @@ void configWriteConfig() } #endif #if HASP_USE_HTTP + if(settings[F("http")].as().isNull()) settings.createNestedObject(F("http")); changed = httpGetConfig(settings[F("http")]); if(changed) { Log.verbose(F("HTTP: Settings changed")); @@ -226,18 +223,21 @@ void configWriteConfig() #endif #endif + if(settings[F("debug")].as().isNull()) settings.createNestedObject(F("debug")); changed = debugGetConfig(settings[F("debug")]); if(changed) { Log.verbose(F("DEBUG: Settings changed")); writefile = true; } + if(settings[F("gui")].as().isNull()) settings.createNestedObject(F("gui")); changed = guiGetConfig(settings[F("gui")]); if(changed) { Log.verbose(F("GUI: Settings changed")); writefile = true; } + if(settings[F("hasp")].as().isNull()) settings.createNestedObject(F("hasp")); changed = haspGetConfig(settings[F("hasp")]); if(changed) { Log.verbose(F("HASP: Settings changed")); diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp index 6f79e129..d44f81bc 100644 --- a/src/hasp_dispatch.cpp +++ b/src/hasp_dispatch.cpp @@ -310,3 +310,93 @@ void IRAM_ATTR dispatch_obj_attribute_str(uint8_t pageid, uint8_t btnid, const c mqtt_send_obj_attribute_str(pageid, btnid, attribute, data); #endif } + +void dispatchConfig(const char * topic, const char * payload) +{ + DynamicJsonDocument doc(128 * 2); + char buffer[128 * 2]; + JsonObject settings; + bool update; + + if(strlen(payload) == 0) { + // Make sure we have a valid JsonObject to start from + settings = doc.to().createNestedObject(topic); + update = false; + + } else { + DeserializationError jsonError = deserializeJson(doc, payload); + if(jsonError) { // Couldn't parse incoming JSON command + Log.warning(F("JSON: Failed to parse incoming JSON command with error: %s"), jsonError.c_str()); + return; + } + settings = doc.as(); + update = true; + } + + if(strcmp_P(topic, PSTR("debug")) == 0) { + if(update) + debugSetConfig(settings); + else + debugGetConfig(settings); + } + + else if(strcmp_P(topic, PSTR("gui")) == 0) { + if(update) + guiSetConfig(settings); + else + guiGetConfig(settings); + } + + else if(strcmp_P(topic, PSTR("hasp")) == 0) { + if(update) + haspSetConfig(settings); + else + haspGetConfig(settings); + } + +#if HASP_USE_WIFI + else if(strcmp_P(topic, PSTR("wifi")) == 0) { + if(update) + wifiSetConfig(settings); + else + wifiGetConfig(settings); + } +#if HASP_USE_MQTT + else if(strcmp_P(topic, PSTR("mqtt")) == 0) { + if(update) + mqttSetConfig(settings); + else + mqttGetConfig(settings); + } +#endif +#if HASP_USE_TELNET + // else if(strcmp_P(topic, PSTR("telnet")) == 0) + // telnetGetConfig(settings[F("telnet")]); +#endif +#if HASP_USE_MDNS + else if(strcmp_P(topic, PSTR("mdns")) == 0) { + if(update) + mdnsSetConfig(settings); + else + mdnsGetConfig(settings); + } +#endif +#if HASP_USE_HTTP + else if(strcmp_P(topic, PSTR("http")) == 0) { + if(update) + httpSetConfig(settings); + else + httpGetConfig(settings); + } +#endif +#endif + + // Send output + if(!update) { + settings.remove(F("pass")); // hide password in output + size_t size = serializeJson(doc, buffer, sizeof(buffer)); +#if HASP_USE_MQTT + mqtt_send_state(F("config"), buffer); +#endif + } +} diff --git a/src/hasp_dispatch.h b/src/hasp_dispatch.h index 8b16d138..fabb3d9d 100644 --- a/src/hasp_dispatch.h +++ b/src/hasp_dispatch.h @@ -8,6 +8,8 @@ void dispatchLoop(void); void dispatchAttribute(String strTopic, const char * strPayload); void dispatchCommand(String cmnd); +void dispatchConfig(const char * topic, const char * payload); + void dispatchJson(char * strPayload); void dispatchJsonl(char * strPayload); void dispatchJsonl(Stream & stream); diff --git a/src/hasp_mqtt.cpp b/src/hasp_mqtt.cpp index 48f9b6dd..7eccd9a9 100644 --- a/src/hasp_mqtt.cpp +++ b/src/hasp_mqtt.cpp @@ -131,7 +131,7 @@ void IRAM_ATTR mqtt_send_state(const __FlashStringHelper * subtopic, const char } // Log after char buffers are cleared - Log.notice(F("MQTT OUT: %sstate/%S = %s"), mqttNodeTopic, subtopic, payload); + Log.notice(F("MQTT PUB: %sstate/%S = %s"), mqttNodeTopic, subtopic, payload); } void mqtt_send_input(uint8_t id, const char * payload) @@ -147,7 +147,7 @@ void mqtt_send_input(uint8_t id, const char * payload) } // Log after char buffers are cleared - Log.notice(F("MQTT OUT: %sstate/input%u = %s"), mqttNodeTopic, id, payload); + Log.notice(F("MQTT PUB: %sstate/input%u = %s"), mqttNodeTopic, id, payload); } void IRAM_ATTR mqtt_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data) @@ -166,7 +166,7 @@ void IRAM_ATTR mqtt_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const } // Log after char buffers are cleared - Log.notice(F("MQTT OUT: %sstate/json = {\"p[%u].b[%u].%s\":\"%s\"}"), mqttNodeTopic, pageid, btnid, attribute, + Log.notice(F("MQTT PUB: %sstate/json = {\"p[%u].b[%u].%s\":\"%s\"}"), mqttNodeTopic, pageid, btnid, attribute, data); } @@ -226,6 +226,7 @@ void mqtt_send_statusupdate() // Receive incoming messages static void mqtt_message_cb(char * topic_p, byte * payload, unsigned int length) { // Handle incoming commands from MQTT + if(length >= MQTT_MAX_PACKET_SIZE) return; payload[length] = '\0'; // String strTopic((char *)0); @@ -247,7 +248,7 @@ static void mqtt_message_cb(char * topic_p, byte * payload, unsigned int length) // '[...]/device/command/p[1].b[4].txt' -m '"Lights On"' = nextionSetAttr("p[1].b[4].txt", "\"Lights On\"") char * topic = (char *)topic_p; - Log.notice(F("MQTT IN: %s = %s"), topic, (char *)payload); + Log.notice(F("MQTT RCV: %s = %s"), topic, (char *)payload); if(topic == strstr(topic, mqttNodeTopic)) { // startsWith mqttNodeTopic topic += strlen(mqttNodeTopic); @@ -282,6 +283,12 @@ static void mqtt_message_cb(char * topic_p, byte * payload, unsigned int length) return; } + if(topic == strstr_P(topic, PSTR("config/"))) { // startsWith command/ + topic += 7u; + dispatchConfig(topic, (char *)payload); + return; + } + // catch a dangling LWT from a previous connection if it appears if(!strcmp_P(topic, PSTR("status")) && !strcmp_P((char *)payload, PSTR("OFF"))) { char topicBuffer[128];