diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index 76e504a..935b6f2 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -13,6 +13,7 @@ #include #include #include +#include #include //https://github.com/Links2004/arduinoWebSockets #include @@ -74,6 +75,38 @@ void tick() } +// *************************************************************************** +// EEPROM helper +// *************************************************************************** +String readEEPROM(int offset, int len) { + String res = ""; + for (int i = 0; i < len; ++i) + { + res += char(EEPROM.read(i + offset)); + //DBG_OUTPUT_PORT.println(char(EEPROM.read(i + offset))); + } + + DBG_OUTPUT_PORT.print("Read EEPROM: ["); + DBG_OUTPUT_PORT.print(res); + DBG_OUTPUT_PORT.println("]"); + return res; +} + +void writeEEPROM(int offset, int len, String value) { + for (int i = 0; i < len; ++i) + { + if (i < value.length()) { + EEPROM.write(i + offset, value[i]); + } else { + EEPROM.write(i + offset, NULL); + } + + DBG_OUTPUT_PORT.print("Wrote EEPROM: "); + DBG_OUTPUT_PORT.println(value[i]); + } +} + + // *************************************************************************** // Callback for WiFiManager library when config mode is entered // *************************************************************************** @@ -93,6 +126,11 @@ void configModeCallback (WiFiManager *myWiFiManager) { strip.show(); } +//callback notifying us of the need to save config +void saveConfigCallback () { + DBG_OUTPUT_PORT.println("Should save config"); + shouldSaveConfig = true; +} // *************************************************************************** // Include: Webserver @@ -116,6 +154,7 @@ void configModeCallback (WiFiManager *myWiFiManager) { // *************************************************************************** void setup() { DBG_OUTPUT_PORT.begin(115200); + EEPROM.begin(512); // set builtin led pin as output pinMode(BUILTIN_LED, OUTPUT); @@ -135,6 +174,28 @@ void setup() { // *************************************************************************** // Setup: WiFiManager // *************************************************************************** + // The extra parameters to be configured (can be either global or just in the setup) + // After connecting, parameter.getValue() will get you the configured value + // id/name placeholder/prompt default length + #ifdef ENABLE_MQTT + String settings_available = readEEPROM(134, 1); + if (settings_available == "1") { + readEEPROM(0, 64).toCharArray(mqtt_host, 64); // 0-63 + readEEPROM(64, 6).toCharArray(mqtt_port, 6); // 64-69 + readEEPROM(70, 32).toCharArray(mqtt_user, 32); // 70-101 + readEEPROM(102, 32).toCharArray(mqtt_pass, 32); // 102-133 + DBG_OUTPUT_PORT.printf("MQTT host: %s\n", mqtt_host); + DBG_OUTPUT_PORT.printf("MQTT port: %s\n", mqtt_port); + DBG_OUTPUT_PORT.printf("MQTT user: %s\n", mqtt_user); + DBG_OUTPUT_PORT.printf("MQTT pass: %s\n", mqtt_pass); + } + + WiFiManagerParameter custom_mqtt_host("host", "MQTT hostname", mqtt_host, 64); + WiFiManagerParameter custom_mqtt_port("port", "MQTT port", mqtt_port, 6); + WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32); + WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32); + #endif + //Local intialization. Once its business is done, there is no need to keep it around WiFiManager wifiManager; //reset settings - for testing @@ -143,6 +204,17 @@ void setup() { //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode wifiManager.setAPCallback(configModeCallback); + #ifdef ENABLE_MQTT + //set config save notify callback + wifiManager.setSaveConfigCallback(saveConfigCallback); + + //add all your parameters here + wifiManager.addParameter(&custom_mqtt_host); + wifiManager.addParameter(&custom_mqtt_port); + wifiManager.addParameter(&custom_mqtt_user); + wifiManager.addParameter(&custom_mqtt_pass); + #endif + //fetches ssid and pass and tries to connect //if it does not connect it starts an access point with the specified name //here "AutoConnectAP" @@ -154,6 +226,26 @@ void setup() { delay(1000); } + #ifdef ENABLE_MQTT + //read updated parameters + strcpy(mqtt_host, custom_mqtt_host.getValue()); + strcpy(mqtt_port, custom_mqtt_port.getValue()); + strcpy(mqtt_user, custom_mqtt_user.getValue()); + strcpy(mqtt_pass, custom_mqtt_pass.getValue()); + + //save the custom parameters to FS + if (shouldSaveConfig) { + DBG_OUTPUT_PORT.println("Saving WiFiManager config"); + + writeEEPROM(0, 64, mqtt_host); // 0-63 + writeEEPROM(64, 6, mqtt_port); // 64-69 + writeEEPROM(70, 32, mqtt_user); // 70-101 + writeEEPROM(102, 32, mqtt_pass); // 102-133 + writeEEPROM(134, 1, "1"); // 134 --> alwasy "1" + EEPROM.commit(); + } + #endif + //if you get here you have connected to the WiFi DBG_OUTPUT_PORT.println("connected...yeey :)"); ticker.detach(); @@ -209,8 +301,10 @@ void setup() { #ifdef ENABLE_MQTT String(String(HOSTNAME) + "/in").toCharArray(mqtt_intopic, strlen(HOSTNAME) + 3); String(String(HOSTNAME) + "/out").toCharArray(mqtt_outtopic, strlen(HOSTNAME) + 4); + + DBG_OUTPUT_PORT.printf("Connect %s %d\n", mqtt_host, String(mqtt_port).toInt()); - mqtt_client.setServer(mqtt_server, 1883); + mqtt_client.setServer(mqtt_host, String(mqtt_port).toInt()); mqtt_client.setCallback(mqtt_callback); #endif @@ -225,7 +319,7 @@ void setup() { DBG_OUTPUT_PORT.print("Use http://"); DBG_OUTPUT_PORT.print(HOSTNAME); - DBG_OUTPUT_PORT.println(".local/ when you have Bobjour installed."); + DBG_OUTPUT_PORT.println(".local/ when you have Bonjour installed."); DBG_OUTPUT_PORT.print("New users: Open http://"); DBG_OUTPUT_PORT.print(WiFi.localIP()); diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index 6e3cc1f..97c6cdd 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -14,11 +14,14 @@ const char HOSTNAME[] = "ESP8266_VORONOI"; // Friedly hostname char mqtt_outtopic[strlen(HOSTNAME) + 4]; // Topic out will be: /out const char mqtt_clientid[] = "ESP8266Client"; // MQTT ClientID - const char mqtt_server[] = "raspberrypi2"; // Hostname of the MQTT broker - const char mqtt_username[] = ""; // MQTT Username - const char mqtt_password[] = ""; // MQTT Password + + char mqtt_host[64] = ""; + char mqtt_port[6] = ""; + char mqtt_user[32] = ""; + char mqtt_pass[32] = ""; #endif + // *************************************************************************** // Global variables / definitions // *************************************************************************** @@ -36,6 +39,8 @@ int ws2812fx_mode = 0; // Helper variable to set WS2812FX modes bool exit_func = false; // Global helper variable to get out of the color modes when mode changes +bool shouldSaveConfig = false; // For WiFiManger custom config + struct ledstate // Data structure to store a state of a single led { uint8_t red; diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index f1061e4..eb399ab 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -391,7 +391,7 @@ void checkForRequests() { while (!mqtt_client.connected()) { DBG_OUTPUT_PORT.print("Attempting MQTT connection... "); // Attempt to connect - if (mqtt_client.connect(mqtt_clientid, mqtt_username, mqtt_password)) { + if (mqtt_client.connect(mqtt_clientid, mqtt_user, mqtt_pass)) { DBG_OUTPUT_PORT.println("connected!"); // Once connected, publish an announcement... char * message = new char[18 + strlen(HOSTNAME) + 1];