diff --git a/code/src/Config.cpp b/code/src/Config.cpp deleted file mode 100644 index f4223003..00000000 --- a/code/src/Config.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - Config - - Configuration file -*/ - -#include "Config.h" -#include "EEPROM.h" - -bool ConfigClass::save() { - - #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 += "nofussServer=" + nofussServer + "|"; - content += "nofussInterval=" + nofussInterval + "|"; - 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("nofussServer=")) nofussServer = line.substring(13); - else if (line.startsWith("nofussInterval=")) nofussInterval = line.substring(15); - 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); - - } - - #ifdef DEBUG - Serial.println("[CONFIG] OK"); - #endif - - return true; - -} - -ConfigClass config; diff --git a/code/src/Config.h b/code/src/Config.h deleted file mode 100644 index 00403c4c..00000000 --- a/code/src/Config.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - Config - - Configuration file -*/ - -#ifndef Config_h -#define Config_h - -#include "Arduino.h" - -// ----------------------------------------------------------------------------- -// Defaults -// ----------------------------------------------------------------------------- - -#define CONFIG_START 128 -#define CONFIG_VERSION 0x81 - -#define NETWORK_BUFFER 3 - -#define MQTT_SERVER "192.168.1.100" -#define MQTT_PORT 1883 -#define MQTT_TOPIC "/test/switch/{identifier}" - -#define NOFUSS_SERVER "http://192.168.1.100" -#define NOFUSS_INTERVAL 600000 - -#define MAINS_VOLTAGE 230 -#define CURRENT_RATIO 180 - -#define RF_CHANNEL 31 -#define RF_DEVICE 1 - -// ----------------------------------------------------------------------------- -// Class definition -// ----------------------------------------------------------------------------- - -class ConfigClass { - - public: - - String hostname; - - String ssid[NETWORK_BUFFER]; - String pass[NETWORK_BUFFER]; - - String mqttServer = MQTT_SERVER; - String mqttPort = String(MQTT_PORT); - String mqttTopic = MQTT_TOPIC; - String mqttUser = ""; - String mqttPassword = ""; - - String rfChannel = String(RF_CHANNEL); - String rfDevice = String(RF_DEVICE); - - String nofussServer = String(NOFUSS_SERVER); - String nofussInterval = String(NOFUSS_INTERVAL); - - String pwMainsVoltage = String(MAINS_VOLTAGE); - String pwCurrentRatio = String(CURRENT_RATIO); - - bool save(); - bool load(); - -}; - -extern ConfigClass config; - -#endif diff --git a/code/src/defaults.h b/code/src/defaults.h index 171e1825..aebb64b0 100644 --- a/code/src/defaults.h +++ b/code/src/defaults.h @@ -54,6 +54,7 @@ #define HEARTBEAT_INTERVAL 60000 #define FS_VERSION_FILE "/fsversion" +#define WIFI_MAX_NETWORKS 3 #define WIFI_RECONNECT_INTERVAL 300000 #define RF_PIN 14 @@ -63,6 +64,9 @@ #define DHT_TYPE DHT22 #define DHT_TIMING 11 +#define MQTT_SERVER "192.168.1.100" +#define MQTT_PORT 1883 +#define MQTT_TOPIC "/test/switch/{identifier}" #define MQTT_RECONNECT_DELAY 10000 #define MQTT_RETAIN true #define MQTT_STATUS_TOPIC "" @@ -74,6 +78,12 @@ #define MQTT_TEMPERATURE_TOPIC "/temperature" #define MQTT_HUMIDITY_TOPIC "/humidity" +#define NOFUSS_SERVER "http://192.168.1.100" +#define NOFUSS_INTERVAL 600000 + +#define RF_CHANNEL 31 +#define RF_DEVICE 1 + #define EMON_CURRENT_PIN 0 #define EMON_SAMPLES 1000 #define EMON_INTERVAL 10000 @@ -82,3 +92,5 @@ #define EMON_REFERENCE_VOLTAGE 1.0 #define EMON_CURRENT_PRECISION 1 #define EMON_CURRENT_OFFSET 0.25 +#define EMON_MAINS_VOLTAGE 230 +#define EMON_CURRENT_RATIO 180 diff --git a/code/src/emon.ino b/code/src/emon.ino index 996600a6..9bae8611 100644 --- a/code/src/emon.ino +++ b/code/src/emon.ino @@ -11,24 +11,32 @@ Copyright (C) 2016 by Xose Pérez #include - EmonLiteESP power; + EmonLiteESP emon; double current; // ----------------------------------------------------------------------------- // EMON // ----------------------------------------------------------------------------- + void setCurrentRatio(float value) { + emon.setCurrentRatio(value); + } double getCurrent() { return current; } - + unsigned int currentCallback() { return analogRead(EMON_CURRENT_PIN); } void powerMonitorSetup() { - power.initCurrent(currentCallback, EMON_ADC_BITS, EMON_REFERENCE_VOLTAGE, config.pwCurrentRatio.toFloat()); - power.setPrecision(EMON_CURRENT_PRECISION); + emon.initCurrent( + currentCallback, + EMON_ADC_BITS, + EMON_REFERENCE_VOLTAGE, + getSetting("pwCurrentRatio", String(EMON_CURRENT_RATIO)).toFloat() + ); + emon.setPrecision(EMON_CURRENT_PRECISION); } void powerMonitorLoop() { @@ -47,7 +55,7 @@ Copyright (C) 2016 by Xose Pérez if (!digitalRead(RELAY_PIN)) { current = 0; } else { - current = power.getCurrent(EMON_SAMPLES); + current = emon.getCurrent(EMON_SAMPLES); current -= EMON_CURRENT_OFFSET; if (current < 0) current = 0; } @@ -61,15 +69,17 @@ Copyright (C) 2016 by Xose Pérez sum += current; ++measurements; + float mainsVoltage = getSetting("pwMainsVoltage", String(EMON_MAINS_VOLTAGE)).toFloat(); + #ifdef DEBUG Serial.print(F("[ENERGY] Power now: ")); - Serial.print(int(current * config.pwMainsVoltage.toFloat())); + Serial.print(int(current * mainsVoltage)); Serial.println(F("W")); #endif if (measurements == EMON_MEASUREMENTS) { char buffer[8]; - double power = (sum - max - min) * config.pwMainsVoltage.toFloat() / (measurements - 2); + double power = (sum - max - min) * mainsVoltage / (measurements - 2); sprintf(buffer, "%d", int(power)); mqttSend((char *) MQTT_POWER_TOPIC, buffer); sum = 0; diff --git a/code/src/main.ino b/code/src/main.ino index f8d62932..35e40f1b 100644 --- a/code/src/main.ino +++ b/code/src/main.ino @@ -18,15 +18,12 @@ along with this program. If not, see . */ -extern "C" { - #include "user_interface.h" -} - #include #include "version.h" #include "defaults.h" #include "FS.h" -#include "Config.h" + +String getSetting(const String& key, String defaultValue = ""); // ----------------------------------------------------------------------------- // Methods @@ -169,19 +166,16 @@ void welcome() { void setup() { hardwareSetup(); + settingsSetup(); + setSetting("hostname", String() + getIdentifier()); + saveSettings(); relaySetup(); - buttonSetup(); - delay(1000); + + delay(2000); welcome(); - config.load(); - // At the moment I am overriding any possible hostname stored in EEPROM - // with the generated one until I have a way to change them from the - // configuration interface - config.hostname = getIdentifier(); - wifi_station_set_hostname((char *) config.hostname.c_str()); + buttonSetup(); wifiSetup(); - otaSetup(); mqttSetup(); webServerSetup(); @@ -223,6 +217,8 @@ void loop() { powerMonitorLoop(); #endif + settingsLoop(); + delay(1); } diff --git a/code/src/mqtt.ino b/code/src/mqtt.ino index 8b64143d..bc54112a 100644 --- a/code/src/mqtt.ino +++ b/code/src/mqtt.ino @@ -23,10 +23,14 @@ bool mqttConnected() { return mqtt.connected(); } +void mqttDisconnect() { + mqtt.disconnect(); +} + void buildTopics() { // Replace identifier - mqttTopic = config.mqttTopic; - mqttTopic.replace("{identifier}", config.hostname); + mqttTopic = getSetting("mqttTopic", MQTT_TOPIC); + mqttTopic.replace("{identifier}", getSetting("hostname")); } void mqttSend(char * topic, char * message) { @@ -78,31 +82,36 @@ void mqttCallback(char* topic, byte* payload, unsigned int length) { void mqttConnect() { - if (!mqtt.connected() && (config.mqttServer.length()>0)) { + String mqttServer = getSetting("mqttServer", MQTT_SERVER); + int mqttPort = getSetting("mqttPort", String(MQTT_PORT)).toInt(); + String mqttUser = getSetting("mqttUser"); + String mqttPassword = getSetting("mqttPassword"); + + if (!mqtt.connected() && (mqttServer.length()>0)) { - mqtt.setServer((const char *) config.mqttServer.c_str(), config.mqttPort.toInt()); + mqtt.setServer((const char *) mqttServer.c_str(), mqttPort); #ifdef DEBUG Serial.print(F("[MQTT] Connecting to broker at ")); - Serial.print(config.mqttServer); + Serial.print(mqttServer); #endif - if (config.mqttUser.length() > 0) { + if (mqttUser.length() > 0) { #ifdef DEBUG Serial.print(F(" as user ")); - Serial.print(config.mqttUser); + Serial.print(mqttUser); Serial.print(F(": ")); #endif mqtt.connect( - config.hostname.c_str(), - (const char *) config.mqttUser.c_str(), - (const char *) config.mqttPassword.c_str() + getSetting("hostname").c_str(), + (const char *) mqttUser.c_str(), + (const char *) mqttPassword.c_str() ); } else { #ifdef DEBUG Serial.print(F(" anonymously: ")); #endif - mqtt.connect(config.hostname.c_str()); + mqtt.connect(getSetting("hostname").c_str()); } if (mqtt.connected()) { diff --git a/code/src/nofuss.ino b/code/src/nofuss.ino index bad87c36..02aa67b9 100644 --- a/code/src/nofuss.ino +++ b/code/src/nofuss.ino @@ -17,7 +17,7 @@ Copyright (C) 2016 by Xose Pérez void nofussSetup() { - NoFUSSClient.setServer(config.nofussServer); + NoFUSSClient.setServer(getSetting("nofussServer", NOFUSS_SERVER)); NoFUSSClient.setDevice(DEVICE); NoFUSSClient.setVersion(APP_VERSION); @@ -79,7 +79,8 @@ Copyright (C) 2016 by Xose Pérez static unsigned long last_check = 0; if (!wifiConnected()) return; - if ((last_check > 0) && ((millis() - last_check) < config.nofussInterval.toInt())) return; + unsigned long interval = getSetting("nofussInterval", String(NOFUSS_INTERVAL)).toInt(); + if ((last_check > 0) && ((millis() - last_check) < interval)) return; last_check = millis(); NoFUSSClient.handle(); diff --git a/code/src/ota.ino b/code/src/ota.ino index 3b6797d6..6a577cd5 100644 --- a/code/src/ota.ino +++ b/code/src/ota.ino @@ -17,7 +17,7 @@ Copyright (C) 2016 by Xose Pérez void otaSetup() { ArduinoOTA.setPort(OTA_PORT); - ArduinoOTA.setHostname(config.hostname.c_str()); + ArduinoOTA.setHostname(getSetting("hostname").c_str()); ArduinoOTA.setPassword((const char *) OTA_PASS); ArduinoOTA.onStart([]() { diff --git a/code/src/rf.ino b/code/src/rf.ino index 92cdfed1..44e5629e 100644 --- a/code/src/rf.ino +++ b/code/src/rf.ino @@ -43,7 +43,7 @@ Copyright (C) 2016 by Xose Pérez unsigned long code = 0; // channel - unsigned int channel = config.rfChannel.toInt(); + unsigned int channel = getSetting("rfChannel", String(RF_CHANNEL)).toInt(); for (byte i = 0; i < 5; i++) { code *= 3; if (channel & 1) code += 1; @@ -51,7 +51,7 @@ Copyright (C) 2016 by Xose Pérez } // device - unsigned int device = config.rfDevice.toInt(); + unsigned int device = getSetting("rfDevice", String(RF_DEVICE)).toInt(); for (byte i = 0; i < 5; i++) { code *= 3; if (device != i) code += 2; diff --git a/code/src/settings.ino b/code/src/settings.ino new file mode 100644 index 00000000..cad34b9b --- /dev/null +++ b/code/src/settings.ino @@ -0,0 +1,58 @@ +/* + +ESPurna +SETTINGS MODULE + +Copyright (C) 2016 by Xose Pérez + +*/ + +#include "Embedis.h" +#include +#include "spi_flash.h" + +#define AUTO_SAVE 0 + +Embedis embedis(Serial); + +// ----------------------------------------------------------------------------- +// Settings +// ----------------------------------------------------------------------------- + +void settingsSetup() { + EEPROM.begin(SPI_FLASH_SEC_SIZE); + Embedis::dictionary( F("EEPROM"), + SPI_FLASH_SEC_SIZE, + [](size_t pos) -> char { return EEPROM.read(pos); }, + [](size_t pos, char value) { EEPROM.write(pos, value); }, + #if AUTO_SAVE + []() { EEPROM.commit(); } + #else + []() {} + #endif + ); +} + +void settingsLoop() { + embedis.process(); +} + +String getSetting(const String& key, String defaultValue) { + String value; + if (!Embedis::get(key, value)) value = defaultValue; + return value; +} + +bool setSetting(const String& key, String& value) { + return Embedis::set(key, value); +} + +bool delSetting(const String& key) { + return Embedis::del(key); +} + +void saveSettings() { + #if not AUTO_SAVE + EEPROM.commit(); + #endif +} diff --git a/code/src/webserver.ino b/code/src/webserver.ino index 3417eb3f..80bf3185 100644 --- a/code/src/webserver.ino +++ b/code/src/webserver.ino @@ -91,32 +91,30 @@ void handleInit() { root["appname"] = String(buffer); root["manufacturer"] = String(MANUFACTURER); root["device"] = String(DEVICE); - root["hostname"] = config.hostname; - root["network"] = (WiFi.status() == WL_CONNECTED) ? WiFi.SSID() : "ACCESS POINT"; - root["ip"] = (WiFi.status() == WL_CONNECTED) ? WiFi.localIP().toString() : WiFi.softAPIP().toString(); + root["hostname"] = getSetting("hostname"); + root["network"] = getNetwork(); + root["ip"] = getIP(); root["updateInterval"] = STATUS_UPDATE_INTERVAL; - root["ssid0"] = config.ssid[0]; - root["pass0"] = config.pass[0]; - root["ssid1"] = config.ssid[1]; - root["pass1"] = config.pass[1]; - root["ssid2"] = config.ssid[2]; - root["pass2"] = config.pass[2]; + for (byte i=0; i jsonBuffer; JsonObject& root = jsonBuffer.createObject(); root["relay"] = digitalRead(RELAY_PIN) ? 1: 0; - root["mqtt"] = mqtt.connected() ? 1: 0; + root["mqtt"] = mqttConnected(); #if ENABLE_EMON - root["power"] = getCurrent() * config.pwMainsVoltage.toFloat(); + root["power"] = getCurrent() * getSetting("pwMainsVoltage", String(EMON_MAINS_VOLTAGE)).toFloat(); #endif #if ENABLE_DHT root["temperature"] = getTemperature(); @@ -158,48 +156,52 @@ void handleSave() { Serial.println(F("[WEBSERVER] Request: /save")); #endif - if (server.hasArg("status")) { - if (server.arg("status") == "1") { - switchRelayOn(); - } else { - switchRelayOff(); + bool disconnectMQTT = false; + + for (unsigned int i=0; i #include "JustWifi.h" +extern "C" { + #include "user_interface.h" +} + JustWifi jw; unsigned long wifiLastConnectionTime = 0; @@ -38,12 +42,14 @@ bool wifiConnected() { void wifiSetup() { + wifi_station_set_hostname((char *) getSetting("hostname").c_str()); + // Message callbacks jw.onMessage([](justwifi_messages_t code, char * parameter) { // Disconnect from MQTT server if no WIFI if (code != MESSAGE_CONNECTED) { - if (mqtt.connected()) mqtt.disconnect(); + if (mqttConnected()) mqttDisconnect(); } #if DEBUG @@ -109,7 +115,7 @@ void wifiSetup() { bool wifiAP() { //jw.disconnect(); - return jw.startAP((char *) config.hostname.c_str(), (char *) AP_PASS); + return jw.startAP((char *) getSetting("hostname").c_str(), (char *) AP_PASS); } void wifiConnect() { @@ -120,9 +126,9 @@ void wifiConnect() { // Set networks jw.cleanNetworks(); - jw.addNetwork((char *) config.ssid[0].c_str(), (char *) config.pass[0].c_str()); - jw.addNetwork((char *) config.ssid[1].c_str(), (char *) config.pass[1].c_str()); - jw.addNetwork((char *) config.ssid[2].c_str(), (char *) config.pass[2].c_str()); + jw.addNetwork((char *) getSetting("ssid0").c_str(), (char *) getSetting("pass0").c_str()); + jw.addNetwork((char *) getSetting("ssid1").c_str(), (char *) getSetting("pass1").c_str()); + jw.addNetwork((char *) getSetting("ssid2").c_str(), (char *) getSetting("pass2").c_str()); // Connecting if (!jw.autoConnect()) {