diff --git a/things.ino b/things.ino index 6056553..a6f08ff 100644 --- a/things.ino +++ b/things.ino @@ -1,5 +1,6 @@ // based on example code from the used libraries +#include // this needs to be first, or it all crashes and burns... extern "C" { #include } @@ -10,6 +11,7 @@ extern "C" { #include #include // https://github.com/knolleary/pubsubclient #include // https://github.com/adafruit/DHT-sensor-library +#include // https://github.com/bblanchon/ArduinoJson // configure DHT sensor #define DHTPIN D4 // what pin the DHT is connected to @@ -17,7 +19,19 @@ extern "C" { //#define DHTTYPE DHT21 // DHT21 (AM2301) #define DHTTYPE DHT22 // DHT22 (AM2302) -const char* mqtt_server = "192.168.0.66"; +//define your default values here, if there are different values in config.json, they are overwritten. +char mqtt_server[40]; +char mqtt_port[6] = "1883"; +char mqtt_topic[34] = "OutTopic"; + +//flag for saving data +bool shouldSaveConfig = false; + +//callback notifying us of the need to save config +void saveConfigCallback () { + Serial.println("Should save config"); + shouldSaveConfig = true; +} // initialize modules ESP8266WebServer server(80); // webserver @@ -82,14 +96,21 @@ void read_sensor() { dtostrf(temperature, 1, 2, str_temperature); dtostrf(heatindex, 1, 2, str_heatindex); + char pub_topic[34]; if (!isEqual(humidity, previousHumidity)) { - client.publish("nodemcu/humidity", str_humidity); + strcpy(pub_topic,mqtt_topic); + strcat(pub_topic,"/humidity"); + client.publish(pub_topic, str_humidity); } if (!isEqual(temperature, previousTemperature)) { - client.publish("nodemcu/temperature", str_temperature); + strcpy(pub_topic,mqtt_topic); + strcat(pub_topic,"/temperature"); + client.publish(pub_topic, str_temperature); } if (!isEqual(heatindex, previousHeatindex)) { - client.publish("nodemcu/heatindex", str_heatindex); + strcpy(pub_topic,mqtt_topic); + strcat(pub_topic,"/heatindex"); + client.publish(pub_topic, str_heatindex); } Serial.print("Humidity: "); @@ -130,10 +151,13 @@ void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect - if (client.connect(wifi_station_get_hostname(), "nodemcu/online", MQTTQOS1, true, "0")) { + char pub_topic[34]; + strcpy(pub_topic,mqtt_topic); + strcat(pub_topic,"/online"); + if (client.connect(wifi_station_get_hostname(), pub_topic, MQTTQOS1, true, "0")) { Serial.println("connected"); // Once connected, publish an announcement... - client.publish("nodemcu/online", "1"); + client.publish(pub_topic, "1"); // ... and resubscribe: client.subscribe("inTopic"); } else { @@ -146,6 +170,18 @@ void reconnect() { } } + int stringToNumber(String thisString) { + int i, value, length; + length = thisString.length(); + char blah[(length + 1)]; + for (i = 0; i < length; i++) { + blah[i] = thisString.charAt(i); + } + blah[i] = 0; + value = atoi(blah); + return value; + } + void setup() { // put your setup code here, to run once: Serial.begin(9600); @@ -155,6 +191,53 @@ void setup() { // start ticker with 0.5 because we start in AP mode and try to connect ticker.attach(0.6, toggle_led); + + //clean FS, for testing + //SPIFFS.format(); + + //read configuration from FS json + Serial.println("mounting FS..."); + + if (SPIFFS.begin()) { + Serial.println("mounted file system"); + if (SPIFFS.exists("/config.json")) { + //file exists, reading and loading + Serial.println("reading config file"); + File configFile = SPIFFS.open("/config.json", "r"); + if (configFile) { + Serial.println("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()); + json.printTo(Serial); + if (json.success()) { + Serial.println("\nparsed json"); + + strcpy(mqtt_server, json["mqtt_server"]); + strcpy(mqtt_port, json["mqtt_port"]); + strcpy(mqtt_topic, json["mqtt_topic"]); + + } else { + Serial.println("failed to load json config"); + } + } + } + } else { + Serial.println("failed to mount FS"); + } + //end read + + // 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 + WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40); + WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 5); + WiFiManagerParameter custom_mqtt_topic("topic", "mqtt topic", mqtt_topic, 32); + //WiFiManager //Local intialization. Once its business is done, there is no need to keep it around WiFiManager wifiManager; @@ -164,6 +247,14 @@ void setup() { //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode wifiManager.setAPCallback(configModeCallback); + //set config save notify callback + wifiManager.setSaveConfigCallback(saveConfigCallback); + + //add all your parameters here + wifiManager.addParameter(&custom_mqtt_server); + wifiManager.addParameter(&custom_mqtt_port); + wifiManager.addParameter(&custom_mqtt_topic); + //fetches ssid and pass and tries to connect //if it does not connect it starts an access point with the specified name //here "AutoConnectAP" @@ -181,16 +272,48 @@ void setup() { //keep LED on digitalWrite(BUILTIN_LED, LOW); - client.setServer(mqtt_server, 1883); + //read updated parameters + strcpy(mqtt_server, custom_mqtt_server.getValue()); + strcpy(mqtt_port, custom_mqtt_port.getValue()); + strcpy(mqtt_topic, custom_mqtt_topic.getValue()); + + //save the custom parameters to FS + if (shouldSaveConfig) { + Serial.println("saving config"); + DynamicJsonBuffer jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + json["mqtt_server"] = mqtt_server; + json["mqtt_port"] = mqtt_port; + json["mqtt_topic"] = mqtt_topic; + + File configFile = SPIFFS.open("/config.json", "w"); + if (!configFile) { + Serial.println("failed to open config file for writing"); + } + + json.printTo(Serial); + json.printTo(configFile); + configFile.close(); + //end save + } + + client.setServer(mqtt_server, stringToNumber(mqtt_port)); client.setCallback(callback); dht.begin(); // Initial read read_sensor(); - client.publish("nodemcu/humidity", str_humidity); - client.publish("nodemcu/temperature", str_temperature); - client.publish("nodemcu/heatindex", str_heatindex); + char pub_topic[34]; + strcpy(pub_topic,mqtt_topic); + strcat(pub_topic,"/humidity"); + client.publish(pub_topic, str_humidity); + strcpy(pub_topic,mqtt_topic); + strcat(pub_topic,"/temperature"); + client.publish(pub_topic, str_temperature); + strcpy(pub_topic,mqtt_topic); + strcat(pub_topic,"/heatindex"); + client.publish(pub_topic, str_heatindex); // Handle http requests server.on("/", [](){