diff --git a/Software/WeatherSensor_D1mini/WeatherSensor_D1mini.ino b/Software/WeatherSensor_D1mini/WeatherSensor_D1mini.ino index d2bc274..f743e3d 100644 --- a/Software/WeatherSensor_D1mini/WeatherSensor_D1mini.ino +++ b/Software/WeatherSensor_D1mini/WeatherSensor_D1mini.ino @@ -3,18 +3,7 @@ // Update these with values suitable for your network. -const int CONFIG_PIN = D0; -const char *ssid = "AcS"; -const char *password = "67993776724373201548"; -const char* mqtt_server = "192.168.1.98"; -const String mqtt_client = "home/S000"; -const String mqtt_topic_t = mqtt_client + String("/temperatur"); -const String mqtt_topic_h = mqtt_client + String("/humidity"); -const String mqtt_topic_p = mqtt_client + String("/pressure"); -const String mqtt_topic_l = mqtt_client + String("/lux"); -const String mqtt_topic_led_state = mqtt_client + String("/led_state"); -const String mqtt_topic_led = mqtt_client + String("/led"); WiFiClient espClient; PubSubClient client(espClient); @@ -44,26 +33,288 @@ Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 1234 unsigned long delayTime; -void setup() { - //pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output - //digitalWrite(BUILTIN_LED, HIGH); - Serial.begin(115200); - setup_wifi(); - setup_sensor(); - client.setServer(mqtt_server, 1883); - //client.setCallback(callback); +//########################################## +// Config +#include +#define CONFIG_MAX_SIZE 1024 +const int CONFIG_PIN = D0; - if (!client.connected()) { - reconnect(); +enum CONFIG_STATE { + CONFIG_NONE = 0x00, + CONFIG_VALID = 0x01, +}; + +///const String mqtt_topic_l = mqtt_client + String("/lux"); +///const String mqtt_topic_led_state = mqtt_client + String("/led_state"); +///const String mqtt_topic_led = mqtt_client + String("/led"); + +struct config_map { + char state; + char version; + char ssid[50]; + char password[50]; + byte mqtt_ip[4]; + unsigned short mqtt_port; + char topic_base[20]; + char topic_temperature[40]; + char topic_pressure[40]; + char topic_humidity[40]; + //char topic_lux[20]; + +}; + +config_map config; +//########################################## + +//########################################## +// Mode +enum RUN_MODE { + MODE_CONFIGURE, + MODE_RUN, + MODE_TEST +}; + +RUN_MODE mode = MODE_RUN; +//########################################## + +//########################################## +// Config Server +#include +ESP8266WebServer server(80); + +#define CONFIG_SSID "WeatherConfig" +#define DISABLE_LOG 1 + +void print_init() { +#ifndef DISABLE_LOG + Serial.begin(115200); +#endif +} + +template +void print(T val, bool newLine = true) { +#ifndef DISABLE_LOG + if (newLine) { + Serial.println(val); + } else { + Serial.print(val); + } +#endif +} + +void setup_access_point() { + print("Configuring access point..."); + /* You can remove the password parameter if you want the AP to be open. */ + WiFi.softAPConfig(IPAddress(192,168,4,1), IPAddress(192,168,4,1), IPAddress(255,255,255,0)); + WiFi.softAP(CONFIG_SSID); + + IPAddress myIP = WiFi.softAPIP(); + print("AP IP address: ", false); + print(myIP); + server.on("/", handleRoot); + server.on("/config", handleWriteConfig); + server.on("/reset", handleReset); + server.begin(); + print("HTTP server started"); +} + +void handleRoot() { + server.send(200, "text/html", "" + "WeatherSensor Config" + "" + "" + "
" + "

Weather Sensor

" + "
" + "
Config Details" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "Firmware Update" + "
" + "
"); +} + +void handleWriteConfig() { + int args = server.args(); + int errors = 0x1F; + if (args > 0) { + /*for(int i=0; i< args; ++i) { + Serial.print(server.argName(i)); + Serial.print(" = "); + Serial.println(server.arg(i)); + }*/ + if (server.hasArg("ssid")) { + const String &ssid = server.arg("ssid"); + ssid.toCharArray(config.ssid, 50); + errors &= ~(0x01); + } + if (server.hasArg("pw")) { + const String &pw = server.arg("pw"); + pw.toCharArray(config.password, 50); + errors &= ~(0x02); + } + if (server.hasArg("dev")) { + const String &device = server.arg("dev"); + device.toCharArray(config.topic_base, 20); + if (server.hasArg("temperature")) { + const String temperature = device + server.arg("temperature"); + temperature.toCharArray(config.topic_temperature, 40); + errors &= ~(0x10); + } + if (server.hasArg("humidity")) { + const String humidity = device + server.arg("humidity"); + humidity.toCharArray(config.topic_humidity, 40); + errors &= ~(0x10); + } + if (server.hasArg("pressure")) { + const String pressure = device + server.arg("pressure"); + pressure.toCharArray(config.topic_pressure, 40); + errors &= ~(0x10); + } + } + if (server.hasArg("port")) { + int port = server.arg("port").toInt(); + if (0 < port && port < 65535) { + config.mqtt_port = port; + errors &= ~(0x04); + } + } + if (server.hasArg("srv")) { + String addr = server.arg("srv"); + for (int i=0; i<4; ++i) { + int val = addr.toInt(); + if (0<=val && val<256) { + config.mqtt_ip[i] = val; + } else { + server.send(500, "text/html", "
" + "

Weather Sensor

" + "
ERROR - 4
" + "
Error while parsing the IP address!
"); + errors &= ~(0x08); + } + int pos = addr.indexOf('.'); + addr = addr.substring(pos+1); + } + errors &= ~(0x08); + } + + print(errors); + if (errors == 0x00) { + EEPROM.begin(CONFIG_MAX_SIZE); + config.state = CONFIG_VALID; + EEPROM.put(0, config); + EEPROM.end(); + server.send(200, "text/html", "
" + "

Weather Sensor

" + "
OK
" + "
Disable config mode and reboot device!
"); + // @todo add reset link to html content + // @todo add current memory content to input boxes + return; + } else { + server.send(500, "text/html", "
" + "

Weather Sensor

" + "
ERROR - 2
" + "
Error while parsing config values! Code: " + String(errors) + "
"); + } + } + server.send(500, "text/html", "
" + "

Weather Sensor

" + "
ERROR - 1
" + "
Disable config mode and reboot device!
"); +} + +void handleReset() { + server.send(405, "text/html", "
" + "

Weather Sensor

" + "
ERROR - 3
" + "
Not implemented yet!
"); +} + +//########################################## + +void setup() { + print_init(); + + //enable configuration Pin + pinMode(CONFIG_PIN, INPUT); + + // read config from EEPROM + EEPROM.begin(CONFIG_MAX_SIZE); + EEPROM.get(0, config); + EEPROM.end(); + + if (digitalRead(CONFIG_PIN) == HIGH) { + mode = MODE_CONFIGURE; + //mode = MODE_TEST; + } + + if (config.state != CONFIG_VALID && mode != MODE_CONFIGURE) { + mode = MODE_CONFIGURE; + } + + switch(mode) { + case MODE_CONFIGURE: + print("config"); + pinMode(D4, OUTPUT); + digitalWrite(D4, LOW); + setup_access_point(); + return; + case MODE_RUN: + print("run"); + setup_wifi(); + setup_sensor(); + print("MQTT Addr: "); + print(config.mqtt_ip[0], false); + print(".", false); + print(config.mqtt_ip[1], false); + print(".", false); + print(config.mqtt_ip[2], false); + print(".", false); + print(config.mqtt_ip[3], false); + print(":", false); + print(config.mqtt_port); + client.setServer(IPAddress(config.mqtt_ip[0], config.mqtt_ip[1], config.mqtt_ip[2], config.mqtt_ip[3]), config.mqtt_port); + //client.setCallback(callback); + + if (!client.connected()) { + reconnect(); + } + delay(500); + client.loop(); + delay(500); + process_sensor(); + delay(500); + client.loop(); + delay(500); + ESP.deepSleep(300e6); // 300 sec = 5 min + return; + case MODE_TEST: + print("testing"); + WiFi.mode(WIFI_AP_STA); + WiFi.begin("AcS", "67993776724373201548"); + if (WiFi.waitForConnectResult() == WL_CONNECTED) { + print("Connected ", false); + print(WiFi.localIP()); + //server.on("/", handleRoot); + //server.on("/config", handleWriteConfig); + //todo file upload + server.begin(); + print("HTTP server started"); + } else { + print("WiFi Failed"); + } + return; } - delay(500); - client.loop(); - delay(500); - process_sensor(); - delay(500); - client.loop(); - delay(500); - ESP.deepSleep(300e6); } @@ -71,27 +322,26 @@ void setup() { void setup_wifi() { delay(10); // We start by connecting to a WiFi network - Serial.println(); - Serial.print("Connecting to "); - Serial.println(ssid); + print("Connecting to "); + print(config.ssid); - WiFi.begin(ssid, password); + WiFi.begin(config.ssid, config.password); while (WiFi.status() != WL_CONNECTED) { delay(500); - Serial.print("."); + print(".", false); } - Serial.println(""); - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); + print(""); + print("WiFi connected"); + print("IP address: ", false); + print(WiFi.localIP()); } void setup_sensor() { - Serial.print(F("BME280 setup... ")); + print(F("BME280 setup... ")); bool status; // default settings @@ -99,7 +349,7 @@ void setup_sensor() { status = bme.begin(); if (!status) { while(1) { - Serial.println("Could not find a valid BME280 sensor, check wiring!"); + print("Could not find a valid BME280 sensor, check wiring!"); //while (1); delay(2000); } @@ -137,20 +387,19 @@ void callback(char* topic, byte* payload, unsigned int length) { void reconnect() { // Loop until we're reconnected - const String start_topic = mqtt_client + String("/client"); + const String start_topic = config.topic_base + String("/client"); while (!client.connected()) { - Serial.print("Attempting MQTT connection..."); + print("Attempting MQTT connection...", false); // Attempt to connect - if (client.connect(mqtt_client.c_str())) { - Serial.println("connected"); + if (client.connect(config.topic_base)) { + print("connected"); // Once connected, publish an announcement... client.publish(start_topic.c_str(), "hello world"); // ... and resubscribe - client.subscribe(mqtt_topic_led.c_str()); + ///client.subscribe(mqtt_topic_led.c_str()); } else { - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); + sprintf(msg, "failed, rc=%d try again in 5 seconds", client.state()); + print(msg); // Wait 5 seconds before retrying delay(5000); } @@ -161,8 +410,8 @@ void reconnect() { void process_sensor() { unsigned long t1 = millis(); - Serial.print("ReadSensor: "); - Serial.println(t1-t0); + print("ReadSensor: ", false); + print(t1-t0); t0 = t1; auto temperatur = bme.readTemperature(); auto humidity = bme.readHumidity(); @@ -179,16 +428,20 @@ void process_sensor() { snprintf(msg, 75, "T: %0.2f *C, P: %0.2f hPa, H: %0.2f, L: %0.0f LED: %d", temperatur, pressure, humidity, light, led); - client.publish(mqtt_topic_t.c_str(), String(temperatur).c_str()); - client.publish(mqtt_topic_h.c_str(), String(humidity).c_str()); - client.publish(mqtt_topic_p.c_str(), String(pressure).c_str()); - client.publish(mqtt_topic_l.c_str(), String(light).c_str()); - client.publish(mqtt_topic_led_state.c_str(), String(led).c_str()); - Serial.println(msg); + client.publish(config.topic_temperature, String(temperatur).c_str()); + client.publish(config.topic_humidity, String(humidity).c_str()); + client.publish(config.topic_pressure, String(pressure).c_str()); + ///client.publish(mqtt_topic_l.c_str(), String(light).c_str()); + ///client.publish(mqtt_topic_led_state.c_str(), String(led).c_str()); + print(msg); } void loop() { - delay(500); + if (MODE_CONFIGURE == mode) { + server.handleClient(); + } else { + delay(500); + } }