diff --git a/code/lib/EmonLiteESP/EmonLiteESP.cpp b/code/lib/EmonLiteESP/EmonLiteESP.cpp index bcf7125b..9e4b6ea8 100644 --- a/code/lib/EmonLiteESP/EmonLiteESP.cpp +++ b/code/lib/EmonLiteESP/EmonLiteESP.cpp @@ -71,11 +71,7 @@ double EnergyMonitor::getCurrent(unsigned int samples) { double rms = int(sqrt(sum / samples) - 0.5); double current = _currentFactor * rms; - Serial.println(sum); - Serial.println(rms); - Serial.println(current); current = round(current * _multiplier) / _multiplier; - Serial.println(current); return current; }; diff --git a/code/platformio.ini b/code/platformio.ini index 3b16327b..c45f9cb4 100644 --- a/code/platformio.ini +++ b/code/platformio.ini @@ -24,20 +24,20 @@ platform = espressif framework = arduino board = esp01_1m -lib_install = 89,64 +lib_install = 89,64,19 build_flags = -Wl,-Tesp8266.flash.1m256.ld [env:node] platform = espressif framework = arduino board = nodemcuv2 -lib_install = 89,64 +lib_install = 89,64,19 [env:ota] platform = espressif framework = arduino board = esp01_1m -lib_install = 89,64 +lib_install = 89,64,19 build_flags = -Wl,-Tesp8266.flash.1m256.ld upload_speed = 115200 upload_port = "192.168.4.1" diff --git a/code/src/Config.cpp b/code/src/Config.cpp index 0d558627..d246ba6a 100644 --- a/code/src/Config.cpp +++ b/code/src/Config.cpp @@ -5,84 +5,109 @@ */ #include "Config.h" -#include "FS.h" +#include "EEPROM.h" + +#define DEBUG bool ConfigClass::save() { - File file = SPIFFS.open(CONFIG_PATH, "w"); - if (file) { - - file.println("hostname=" + hostname); - file.println("ssid0=" + ssid[0]); - file.println("pass0=" + pass[0]); - file.println("ssid1=" + ssid[1]); - file.println("pass1=" + pass[1]); - file.println("ssid2=" + ssid[2]); - file.println("pass2=" + pass[2]); - file.println("mqttServer=" + mqttServer); - file.println("mqttPort=" + mqttPort); - file.println("mqttTopic=" + mqttTopic); - file.println("rfChannel=" + rfChannel); - file.println("rfDevice=" + rfDevice); - file.println("otaServer=" + otaServer); - file.println("otaInterval=" + otaInterval); - file.println("pwMainsVoltage=" + pwMainsVoltage); - file.println("pwCurrentRatio=" + pwCurrentRatio); - - file.close(); - return true; + + #ifdef DEBUG + Serial.println("[CONFIG] Saving"); + #endif + + String content; + + content += "hostname=" + hostname + "|"; + content += "ssid0=" + ssid[0] + "|"; + content += "pass0=" + pass[0] + "|"; + content += "ssid1=" + ssid[1] + "|"; + content += "pass1=" + pass[1] + "|"; + content += "ssid2=" + ssid[2] + "|"; + content += "pass2=" + pass[2] + "|"; + content += "mqttServer=" + mqttServer + "|"; + content += "mqttPort=" + mqttPort + "|"; + content += "mqttTopic=" + mqttTopic + "|"; + content += "rfChannel=" + rfChannel + "|"; + content += "rfDevice=" + rfDevice + "|"; + content += "otaServer=" + otaServer + "|"; + content += "otaInterval=" + otaInterval + "|"; + content += "pwMainsVoltage=" + pwMainsVoltage + "|"; + content += "pwCurrentRatio=" + pwCurrentRatio + "|"; + + Serial.print("[CONFIG] "); + Serial.println(content); + + EEPROM.write(CONFIG_START, CONFIG_VERSION); + for (int i=0; i 0); + + Serial.print("[CONFIG] "); + Serial.println(content); + + int start = 0; + int end = content.indexOf("|", start); + while (end > 0) { + + String line = content.substring(start, end); + + if (line.startsWith("hostname=")) hostname = line.substring(9); + else if (line.startsWith("ssid0=")) ssid[0] = line.substring(6); + else if (line.startsWith("pass0=")) pass[0] = line.substring(6); + else if (line.startsWith("ssid1=")) ssid[1] = line.substring(6); + else if (line.startsWith("pass1=")) pass[1] = line.substring(6); + else if (line.startsWith("ssid2=")) ssid[2] = line.substring(6); + else if (line.startsWith("pass2=")) pass[2] = line.substring(6); + else if (line.startsWith("mqttServer=")) mqttServer = line.substring(11); + else if (line.startsWith("mqttPort=")) mqttPort = line.substring(9); + else if (line.startsWith("mqttTopic=")) mqttTopic = line.substring(10); + else if (line.startsWith("rfChannel=")) rfChannel = line.substring(10); + else if (line.startsWith("rfDevice=")) rfDevice = line.substring(9); + else if (line.startsWith("otaServer=")) otaServer = line.substring(10); + else if (line.startsWith("otaInterval=")) otaInterval = line.substring(12); + else if (line.startsWith("pwMainsVoltage=")) pwMainsVoltage = line.substring(15); + else if (line.startsWith("pwCurrentRatio=")) pwCurrentRatio = line.substring(15); + + if (end < 0) break; + start = end + 1; + end = content.indexOf("|", start); - // Read contents - File file = SPIFFS.open(CONFIG_PATH, "r"); - String content = file.readString(); - file.close(); - - // Parse contents - content.replace("\r\n", "\n"); - content.replace("\r", "\n"); - - int start = 0; - int end = content.indexOf("\n", start); - while (end > 0) { - - String line = content.substring(start, end); - - if (line.startsWith("hostname=")) hostname = line.substring(9); - else if (line.startsWith("ssid0=")) ssid[0] = line.substring(6); - else if (line.startsWith("pass0=")) pass[0] = line.substring(6); - else if (line.startsWith("ssid1=")) ssid[1] = line.substring(6); - else if (line.startsWith("pass1=")) pass[1] = line.substring(6); - else if (line.startsWith("ssid2=")) ssid[2] = line.substring(6); - else if (line.startsWith("pass2=")) pass[2] = line.substring(6); - else if (line.startsWith("mqttServer=")) mqttServer = line.substring(11); - else if (line.startsWith("mqttPort=")) mqttPort = line.substring(9); - else if (line.startsWith("mqttTopic=")) mqttTopic = line.substring(10); - else if (line.startsWith("rfChannel=")) rfChannel = line.substring(10); - else if (line.startsWith("rfDevice=")) rfDevice = line.substring(9); - else if (line.startsWith("otaServer=")) otaServer = line.substring(10); - else if (line.startsWith("otaInterval=")) otaInterval = line.substring(12); - else if (line.startsWith("pwMainsVoltage=")) pwMainsVoltage = line.substring(15); - else if (line.startsWith("pwCurrentRatio=")) pwCurrentRatio = line.substring(15); - - if (end < 0) break; - start = end + 1; - end = content.indexOf("\n", start); - - } - - return true; } - return false; + + #ifdef DEBUG + Serial.println("[CONFIG] OK"); + #endif + + return true; } diff --git a/code/src/Config.h b/code/src/Config.h index afb46919..483e827e 100644 --- a/code/src/Config.h +++ b/code/src/Config.h @@ -13,7 +13,8 @@ // Defaults // ----------------------------------------------------------------------------- -#define CONFIG_PATH "/.config" +#define CONFIG_START 128 +#define CONFIG_VERSION 0x81 #define NETWORK_BUFFER 3 diff --git a/code/src/main.cpp b/code/src/main.cpp index 3a9c7e34..77c11ff5 100644 --- a/code/src/main.cpp +++ b/code/src/main.cpp @@ -19,6 +19,7 @@ along with this program. If not, see . */ #include +#include #include #include @@ -36,6 +37,7 @@ along with this program. If not, see . #include #include #include +#include "DHT.h" // ----------------------------------------------------------------------------- // ConfiguraciĆ³ @@ -48,7 +50,8 @@ along with this program. If not, see . #define ENABLE_OTA_AUTO 0 #define ENABLE_MQTT 1 #define ENABLE_WEBSERVER 1 -#define ENABLE_ENERGYMONITOR 0 +#define ENABLE_ENERGYMONITOR 1 +#define ENABLE_DHT 1 #define APP_NAME "Espurna" #define APP_VERSION "0.9.3" @@ -56,8 +59,8 @@ along with this program. If not, see . #define APP_WEBSITE "http://tinkerman.cat" #define MANUFACTURER "ITEAD" -//#define MODEL "SONOFF" -#define MODEL "S20" +#define MODEL "SONOFF" +//#define MODEL "S20" #define BUTTON_PIN 0 #define RELAY_PIN 12 #define LED_PIN 13 @@ -69,11 +72,17 @@ along with this program. If not, see . #define RF_PIN 14 +#define DHT_PIN 14 +#define DHT_UPDATE_INTERVAL 300000 +#define DHT_TYPE DHT22 +#define DHT_TIMING 11 + #define MQTT_RECONNECT_DELAY 10000 #define MQTT_RETAIN true #define WIFI_CONNECT_TIMEOUT 5000 -#define WIFI_RECONNECT_DELAY 5000 +#define WIFI_RECONNECT_DELAY 2000 + #define WIFI_STATUS_CONNECTING 0 #define WIFI_STATUS_CONNECTED 1 #define WIFI_STATUS_AP 2 @@ -102,6 +111,10 @@ DebounceEvent button1 = false; PubSubClient mqtt(client); char mqttStatusTopic[40]; char mqttIPTopic[40]; + #if ENABLE_DHT + char mqttTemperatureTopic[40]; + char mqttHumidityTopic[40]; + #endif #if ENABLE_ENERGYMONITOR char mqttPowerTopic[40]; #endif @@ -114,6 +127,10 @@ DebounceEvent button1 = false; unsigned long rfCodeOFF = 0; #endif +#if ENABLE_DHT + DHT dht(DHT_PIN, DHT_TYPE, DHT_TIMING); +#endif + #if ENABLE_ENERGYMONITOR EnergyMonitor monitor; double current; @@ -188,7 +205,7 @@ void showStatus() { void switchRelayOn() { if (!digitalRead(RELAY_PIN)) { #ifdef DEBUG - Serial.println(F("Turning the relay ON")); + Serial.println(F("[RELAY] ON")); #endif #if ENABLE_MQTT if (!isMQTTMessage && mqtt.connected()) { @@ -206,7 +223,7 @@ void switchRelayOn() { void switchRelayOff() { if (digitalRead(RELAY_PIN)) { #ifdef DEBUG - Serial.println(F("Turning the relay OFF")); + Serial.println(F("[RELAY] OFF")); #endif #if ENABLE_MQTT if (!isMQTTMessage && mqtt.connected()) { @@ -375,7 +392,7 @@ void wifiSetupAP() { status = WIFI_STATUS_AP; delay(100); #ifdef DEBUG - Serial.print(F("[AP Mode] SSID: ")); + Serial.print(F("[WIFI] Mode: AP, SSID: ")); Serial.print(config.hostname); Serial.print(F(", Password: \"")); Serial.print(ADMIN_PASS); @@ -385,66 +402,62 @@ void wifiSetupAP() { } -void wifiSetupSTA(bool force) { +void wifiSetupSTA() { byte network = 0; - if (force || (WiFi.status() != WL_CONNECTED)) { - - // Set WIFI module to STA mode - WiFi.mode(WIFI_STA); - #ifdef DEBUG - WiFi.printDiag(Serial); - #endif - - #if ENABLE_MQTT - if (mqtt.connected()) mqtt.disconnect(); - #endif + // Set WIFI module to STA mode + WiFi.mode(WIFI_STA); + #ifdef DEBUG + //WiFi.printDiag(Serial); + #endif - #if ENABLE_RF - RemoteReceiver::disable(); - #endif + #if ENABLE_MQTT + if (mqtt.connected()) mqtt.disconnect(); + #endif - while (network < 3) { + #if ENABLE_RF + RemoteReceiver::disable(); + #endif - if (config.ssid[network].length() > 0) { + while (network < 3) { - WiFi.begin( - (const char *) config.ssid[network].c_str(), - (const char *) config.pass[network].c_str() - ); + if (config.ssid[network].length() > 0) { - #ifdef DEBUG - Serial.print(F("Connecting to WIFI ")); - Serial.println(config.ssid[network]); - #endif + WiFi.begin( + (const char *) config.ssid[network].c_str(), + (const char *) config.pass[network].c_str() + ); - // Wait - unsigned long timeout = millis() + WIFI_CONNECT_TIMEOUT; - while (timeout > millis()) { - showStatus(); - if (WiFi.status() == WL_CONNECTED) break; - delay(100); - } + #ifdef DEBUG + Serial.print(F("[WIFI] Connecting to ")); + Serial.println(config.ssid[network]); + #endif + // Wait + unsigned long timeout = millis() + WIFI_CONNECT_TIMEOUT; + while (timeout > millis()) { + showStatus(); + if (WiFi.status() == WL_CONNECTED) break; + delay(100); } - if (WiFi.status() == WL_CONNECTED) break; - network++; - } - #if ENABLE_RF - RemoteReceiver::enable(); - #endif + if (WiFi.status() == WL_CONNECTED) break; + network++; } + #if ENABLE_RF + RemoteReceiver::enable(); + #endif + if (WiFi.status() == WL_CONNECTED) { WiFi.setAutoConnect(true); status = WIFI_STATUS_CONNECTED; #ifdef DEBUG - Serial.print(F("[STA Mode] SSID: ")); + Serial.print(F("[WIFI] Mode: STA, SSID: ")); Serial.print(WiFi.SSID()); Serial.print(F(", IP address: ")); Serial.println(WiFi.localIP()); @@ -454,19 +467,34 @@ void wifiSetupSTA(bool force) { #endif } else { #ifdef DEBUG - Serial.println(F("[STA Mode] NOT CONNECTED")); + Serial.println(F("[WIFI] Not connected")); #endif - wifiSetupAP(); } } +void wifiSetup(bool force) { + if (force || (WiFi.status() != WL_CONNECTED)) { + wifiSetupSTA(); + if (WiFi.status() != WL_CONNECTED) wifiSetupAP(); + } +} + void wifiLoop() { - // Trying to reconnect in case of disconnection + static unsigned long last_check = 0; + + // Check disconnection if ((status == WIFI_STATUS_CONNECTED) && (WiFi.status() != WL_CONNECTED)) { status = WIFI_STATUS_CONNECTING; - wifiSetupSTA(false); + } + + // If not connected (either AP or STA) try to reconnect every WIFI_RECONNECT_DELAY + if (status == WIFI_STATUS_CONNECTING) { + if ((millis() - last_check) > WIFI_RECONNECT_DELAY) { + wifiSetup(false); + last_check = millis(); + } } } @@ -480,7 +508,7 @@ void wifiLoop() { void rfLoop() { if (rfCode == 0) return; #ifdef DEBUG - Serial.print(F("RF code: ")); + Serial.print(F("[RF] Received code: ")); Serial.println(rfCode); #endif if (rfCode == rfCodeON) switchRelayOn(); @@ -513,9 +541,9 @@ void wifiLoop() { rfCodeON = code + 6; #ifdef DEBUG - Serial.print(F("RF code ON: ")); + Serial.print(F("[RF] Code ON: ")); Serial.println(rfCodeON); - Serial.print(F("RF code OFF: ")); + Serial.print(F("[RF] Code OFF: ")); Serial.println(rfCodeOFF); #endif @@ -558,7 +586,7 @@ void wifiLoop() { void handleRelayOn() { #ifdef DEBUG - Serial.println(F("Request: /relay/on")); + Serial.println(F("[WEBSERVER] Request: /relay/on")); #endif switchRelayOn(); server.send(200, "text/plain", "ON"); @@ -566,7 +594,7 @@ void wifiLoop() { void handleRelayOff() { #ifdef DEBUG - Serial.println(F("Request: /relay/off")); + Serial.println(F("[WEBSERVER] Request: /relay/off")); #endif switchRelayOff(); server.send(200, "text/plain", "OFF"); @@ -575,7 +603,7 @@ void wifiLoop() { bool handleFileRead(String path) { #ifdef DEBUG - Serial.print(F("Request: ")); + Serial.print(F("[WEBSERVER] Request: ")); Serial.println(path); #endif @@ -599,7 +627,7 @@ void wifiLoop() { void handleInit() { #ifdef DEBUG - Serial.println("Request: /init"); + Serial.println("[WEBSERVER] Request: /init"); #endif char buffer[64]; @@ -652,7 +680,7 @@ void wifiLoop() { void handleStatus() { #ifdef DEBUG - //Serial.println("Request: /status"); + //Serial.println("[WEBSERVER] Request: /status"); #endif StaticJsonBuffer<256> jsonBuffer; @@ -674,7 +702,7 @@ void wifiLoop() { void handleSave() { #ifdef DEBUG - Serial.println(F("Request: /save")); + Serial.println(F("[WEBSERVER] Request: /save")); #endif if (server.hasArg("status")) { @@ -716,7 +744,7 @@ void wifiLoop() { #if ENABLE_ENERGYMONITOR monitor.setCurrentRatio(config.pwCurrentRatio.toFloat()); #endif - wifiSetupSTA(true); + wifiSetup(true); } @@ -791,12 +819,22 @@ void wifiLoop() { mqttPowerTopic[tmp.length()+1] = 0; #endif + // Get publish current topic + #if ENABLE_DHT + tmp = base + "/temperature"; + tmp.toCharArray(mqttTemperatureTopic, tmp.length()+1); + mqttTemperatureTopic[tmp.length()+1] = 0; + tmp = base + "/humidity"; + tmp.toCharArray(mqttHumidityTopic, tmp.length()+1); + mqttHumidityTopic[tmp.length()+1] = 0; + #endif + } void mqttCallback(char* topic, byte* payload, unsigned int length) { #ifdef DEBUG - Serial.print(F("MQTT message ")); + Serial.print(F("[MQTT] Message ")); Serial.print(topic); Serial.print(F(" => ")); for (int i = 0; i < length; i++) { @@ -829,7 +867,7 @@ void wifiLoop() { mqtt.setServer((const char *) config.mqttServer.c_str(), config.mqttPort.toInt()); #ifdef DEBUG - Serial.print(F("Connecting to MQTT broker at ")); + Serial.print(F("[MQTT] Connecting to broker at ")); Serial.print(config.mqttServer); #endif @@ -853,22 +891,23 @@ void wifiLoop() { if (mqtt.connected()) { - buildTopics(); - #ifdef DEBUG Serial.println(F("connected!")); - Serial.print(F("Subscribing to ")); - Serial.println(mqttStatusTopic); #endif + buildTopics(); + // Say hello and report our IP - String ipString = WiFi.localIP().toString(); - mqtt.publish(mqttIPTopic, (const char *) ipString.c_str(), MQTT_RETAIN); + mqtt.publish(mqttIPTopic, (const char *) WiFi.localIP().toString().c_str(), MQTT_RETAIN); // Publish current relay status mqtt.publish(mqttStatusTopic, digitalRead(RELAY_PIN) ? "1" : "0", MQTT_RETAIN); // Subscribe to topic + #ifdef DEBUG + Serial.print(F("[MQTT] Subscribing to ")); + Serial.println(mqttStatusTopic); + #endif mqtt.subscribe(mqttStatusTopic); @@ -903,6 +942,59 @@ void wifiLoop() { #endif +// ----------------------------------------------------------------------------- +// DHT +// ----------------------------------------------------------------------------- + +#if ENABLE_MQTT +#if ENABLE_DHT + + void dhtSetup() { + dht.begin(); + } + + void dhtLoop() { + + static unsigned long last_check = 0; + if (!mqtt.connected()) return; + if ((millis() - last_check) < DHT_UPDATE_INTERVAL) return; + last_check = millis(); + + char buffer[10]; + + float t = dht.readTemperature(); + if (isnan(t)) { + #ifdef DEBUG + Serial.println(F("[DHT] - Error reading temperature")); + #endif + } else { + dtostrf(t, 4, 1, buffer); + mqtt.publish(mqttTemperatureTopic, buffer, MQTT_RETAIN); + #ifdef DEBUG + Serial.print(F("[DHT] - Temperature: ")); + Serial.println(t); + #endif + } + + float h = dht.readHumidity(); + if (isnan(h)) { + #ifdef DEBUG + Serial.println(F("[DHT] - Error reading humidity")); + #endif + } else { + dtostrf(h, 4, 1, buffer); + mqtt.publish(mqttHumidityTopic, buffer, MQTT_RETAIN); + #ifdef DEBUG + Serial.print(F("[DHT] - Humidity: ")); + Serial.println(h); + #endif + } + + } + +#endif +#endif + // ----------------------------------------------------------------------------- // Energy Monitor // ----------------------------------------------------------------------------- @@ -941,7 +1033,7 @@ void wifiLoop() { char buffer[8]; sprintf(buffer, "%d", int(sum * config.pwMainsVoltage.toFloat() / measurements)); #ifdef DEBUG - Serial.print(F("Power: ")); + Serial.print(F("[ENERGY] Power: ")); Serial.println(buffer); #endif #if ENABLE_MQTT @@ -991,6 +1083,7 @@ void welcome() { char buffer[BUFFER_SIZE]; getCompileTime(buffer); Serial.println(); + Serial.println(); Serial.print(APP_NAME); Serial.print(F(" ")); Serial.print(APP_VERSION); @@ -1001,8 +1094,6 @@ void welcome() { Serial.println(); Serial.print(F("Device: ")); Serial.println(getIdentifier()); - Serial.print(F("Hostname: ")); - Serial.println(config.hostname); Serial.print(F("Last reset reason: ")); Serial.println(ESP.getResetReason()); FSInfo fs_info; @@ -1012,36 +1103,45 @@ void welcome() { Serial.print("File system used size : "); Serial.println(fs_info.usedBytes); } + + /* int value = EEPROM.read(10); Serial.println(value++); EEPROM.write(10, value); EEPROM.commit(); + */ + Serial.println(); } void setup() { hardwareSetup(); + delay(1000); + welcome(); config.load(); if (config.hostname.length() == 0) { config.hostname = getIdentifier(); } - delay(1000); - welcome(); + + // We are handling first connection in the loop + //wifiSetup(false); #if ENABLE_OTA OTASetup(); #endif - wifiSetupSTA(false); - #if ENABLE_WEBSERVER - webServerSetup(); - #endif #if ENABLE_MQTT mqttSetup(); #endif + #if ENABLE_WEBSERVER + webServerSetup(); + #endif #if ENABLE_RF rfSetup(); #endif + #if ENABLE_DHT + dhtSetup(); + #endif #if ENABLE_ENERGYMONITOR energyMonitorSetup(); #endif @@ -1050,23 +1150,28 @@ void setup() { void loop() { + wifiLoop(); + hardwareLoop(); + #if ENABLE_OTA OTALoop(); #endif - wifiLoop(); #if ENABLE_MQTT mqttLoop(); #endif + #if ENABLE_WEBSERVER + webServerLoop(); + #endif #if ENABLE_RF rfLoop(); #endif - #if ENABLE_WEBSERVER - webServerLoop(); + #if ENABLE_DHT + dhtLoop(); #endif #if ENABLE_ENERGYMONITOR energyMonitorLoop(); #endif - hardwareLoop(); + delay(1); }