From 78cd3627a6850c42f723f35d61857a39a8fb1414 Mon Sep 17 00:00:00 2001
From: David
Date: Tue, 23 Apr 2019 03:55:42 +1000
Subject: [PATCH 1/5] Move MQTT server connection parameters to WifiManager
settings. * Add mqtt server, port, username & password to WifiManager
settings. * Save a `/config.json` file into the SPIFFS to store these over
reboots. * Bucketloads of debugging added.
Testing seems to show it works.
Fixes #669
---
examples/IRMQTTServer/IRMQTTServer.ino | 174 +++++++++++++++++++++----
examples/IRMQTTServer/platformio.ini | 1 +
2 files changed, 153 insertions(+), 22 deletions(-)
diff --git a/examples/IRMQTTServer/IRMQTTServer.ino b/examples/IRMQTTServer/IRMQTTServer.ino
index a7234b638..e3aa8e41c 100644
--- a/examples/IRMQTTServer/IRMQTTServer.ino
+++ b/examples/IRMQTTServer/IRMQTTServer.ino
@@ -24,8 +24,9 @@
*
* - Arduino IDE:
* o Install the following libraries via Library Manager
- * - WiFiManager (https://github.com/tzapu/WiFiManager) (Version >= 0.14)
+ * - ArduinoJson (https://arduinojson.org/)
* - PubSubClient (https://pubsubclient.knolleary.net/)
+ * - WiFiManager (https://github.com/tzapu/WiFiManager) (Version >= 0.14)
* o You MUST change to have the following (or larger) value:
* (with REPORT_RAW_UNKNOWNS 1024 or more is recommended)
* #define MQTT_MAX_PACKET_SIZE 768
@@ -228,6 +229,8 @@
#endif // MQTT_ENABLE
#include
+#include
+#include
#include
#include
#include
@@ -301,13 +304,6 @@ const char* kHtmlPassword = "esp8266"; // <=- CHANGE_ME (required)
// ----------------------- MQTT Related Settings -------------------------------
#if MQTT_ENABLE
-// Address of your MQTT server.
-#define MQTT_SERVER "10.0.0.4" // <=- CHANGE_ME
-const uint16_t kMqttPort = 1883; // Default port used by MQTT servers.
-// Set if your MQTT server requires a Username & Password to connect
-// ... and it probably should if you want to be more secure.
-const char* kMqttUsername = ""; // <=- CHANGE_ME (optional)
-const char* kMqttPassword = ""; // <=- CHANGE_ME (optional)
const uint32_t kMqttReconnectTime = 5000; // Delay(ms) between reconnect tries.
#define MQTTprefix HOSTNAME // Change this if you want the MQTT topic to be
@@ -409,7 +405,8 @@ const uint8_t kSendTableSize = sizeof(gpioTable);
// Firmware uploads are blocked until the user changes kHtmlPassword to a
// different value than this.
const char* kDefaultPassword = "esp8266"; // Do NOT change this.
-
+// Name of the json config file in SPIFFS.
+const char* kConfigFile = "/config.json";
// Globals
ESP8266WebServer server(kHttpPort);
#ifdef IR_RX
@@ -418,7 +415,9 @@ decode_results capture; // Somewhere to store inbound IR messages.
#endif // IR_RX
MDNSResponder mdns;
WiFiClient espClient;
+
WiFiManager wifiManager;
+bool flagSaveWifiConfig = false;
uint16_t *codeArray;
uint32_t lastReconnectAttempt = 0; // MQTT last attempt reconnection number
@@ -455,12 +454,21 @@ uint32_t lastDisconnectedTime = 0;
uint32_t mqttDisconnectCounter = 0;
uint32_t mqttSentCounter = 0;
uint32_t mqttRecvCounter = 0;
-
bool wasConnected = true;
+const uint8_t kMaxMqttServerSize = 40;
+char MqttServer[kMaxMqttServerSize + 1] = "";
+const uint8_t kMaxMqttPortSize = 6; // Largest value of uint16_t is "65535".
+uint16_t MqttPort = 1883;
+const uint8_t kMaxMqttUsernameSize = 20;
+char MqttUsername[kMaxMqttUsernameSize + 1] = "";
+const uint8_t kMaxMqttPasswordSize = 40;
+char MqttPassword[kMaxMqttPasswordSize + 1] = "";
+
// MQTT client parameters
void callback(char* topic, byte* payload, unsigned int length);
-PubSubClient mqtt_client(MQTT_SERVER, kMqttPort, callback, espClient);
+PubSubClient mqtt_client(espClient);
+
// Create a unique MQTT client id.
String mqtt_clientid = MQTTprefix + String(ESP.getChipId(), HEX);
@@ -501,6 +509,81 @@ void debug(String str) {
#endif // DEBUG
}
+// callback notifying us of the need to save the wifi config
+void saveWifiConfigCallback(void) {
+ debug("saveWifiConfigCallback called.");
+ flagSaveWifiConfig = true;
+}
+
+void saveWifiConfig() {
+ debug("Saving the wifi config.");
+ DynamicJsonBuffer jsonBuffer;
+ JsonObject& json = jsonBuffer.createObject();
+#if MQTT_ENABLE
+ json["mqtt_server"] = MqttServer;
+ json["mqtt_port"] = String(MqttPort).c_str();
+ json["mqtt_username"] = MqttUsername;
+ json["mqtt_pass"] = MqttPassword;
+#endif // MQTT_ENABLE
+ if (SPIFFS.begin()) {
+ File configFile = SPIFFS.open(kConfigFile, "w");
+ if (!configFile) {
+ debug("Failed to open config file for writing.");
+ } else {
+ debug("Writing out the config file.");
+ json.printTo(configFile);
+ configFile.close();
+ debug("Finished writing config file.");
+ }
+ SPIFFS.end();
+ }
+}
+
+void loadWifiConfigFile() {
+ debug("Trying to mount SPIFFS");
+ if (SPIFFS.begin()) {
+ debug("mounted file system");
+ if (SPIFFS.exists(kConfigFile)) {
+ debug("config file exists");
+
+ File configFile = SPIFFS.open(kConfigFile, "r");
+ if (configFile) {
+ debug("Opened config file");
+ size_t size = configFile.size();
+ // Allocate a buffer to store contents of the file.
+ std::unique_ptr buf(new char[size]);
+
+ configFile.readBytes(buf.get(), size);
+ DynamicJsonBuffer jsonBuffer;
+ JsonObject& json = jsonBuffer.parseObject(buf.get());
+ if (json.success()) {
+ debug("Json config file parsed ok.");
+#if MQTT_ENABLE
+ if (json["mqtt_server"] != NULL)
+ strncpy(MqttServer, json["mqtt_server"], kMaxMqttServerSize);
+ if (json["mqtt_port"] != NULL)
+ MqttPort = atoi(json["mqtt_port"]);
+ if (json["mqtt_username"] != NULL)
+ strncpy(MqttUsername, json["mqtt_username"], kMaxMqttUsernameSize);
+ if (json["mqtt_password"] != NULL)
+ strncpy(MqttPassword, json["mqtt_password"], kMaxMqttPasswordSize);
+#endif // MQTT_ENABLE
+ } else {
+ debug("Failed to load json config");
+ }
+ debug("Closing the config file.");
+ configFile.close();
+ }
+ } else {
+ debug("Config file doesn't exist!");
+ }
+ debug("Unmounting SPIFFS.");
+ SPIFFS.end();
+ } else {
+ debug("Failed to mount SPIFFS");
+ }
+}
+
String msToHumanString(uint32_t const msecs) {
uint32_t totalseconds = msecs / 1000;
if (totalseconds == 0) return "Now";
@@ -1189,7 +1272,7 @@ void handleInfo() {
"
"
#if MQTT_ENABLE
"MQTT Information
"
- "Server: " MQTT_SERVER ":" + String(kMqttPort) + " (" +
+ "
Server: " + String(MqttServer) + ":" + String(MqttPort) + " (" +
(mqtt_client.connected() ? "Connected " + timeSince(lastDisconnectedTime)
: "Disconnected " + timeSince(lastConnectedTime)) +
")
"
@@ -1267,9 +1350,21 @@ void handleReset() {
"
Resetting the WiFiManager config back to defaults.
"
"Device restarting. Try connecting in a few seconds.
"
"