diff --git a/code/platformio.ini b/code/platformio.ini
index edc8d1d4..27a8e3b0 100644
--- a/code/platformio.ini
+++ b/code/platformio.ini
@@ -210,3 +210,24 @@ build_flags = -g -DDEBUG_PORT=Serial -DDEBUG_PORT=Serial -DESP_RELAY_BOARD -DENA
upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
+
+[env:ecoplug-debug]
+platform = espressif8266
+framework = arduino
+board = esp01_1m
+lib_deps = ${common.lib_deps}
+lib_ignore = ${common.lib_ignore}
+extra_script = pio_hooks.py
+build_flags = -g -Wl,-Tesp8266.flash.1m128.ld -DDEBUG_PORT=Serial -DECOPLUG
+
+[env:ecoplug-debug-ota]
+platform = espressif8266
+framework = arduino
+board = esp01_1m
+lib_deps = ${common.lib_deps}
+lib_ignore = ${common.lib_ignore}
+extra_script = pio_hooks.py
+build_flags = -g -Wl,-Tesp8266.flash.1m128.ld -DDEBUG_PORT=Serial -DECOPLUG
+upload_speed = 115200
+upload_port = "192.168.4.1"
+upload_flags = --auth=fibonacci --port 8266
diff --git a/code/src/config/general.h b/code/src/config/general.h
index 5e2e4c77..2124af7c 100644
--- a/code/src/config/general.h
+++ b/code/src/config/general.h
@@ -67,7 +67,7 @@
#define MQTT_QOS 0
#define MQTT_KEEPALIVE 30
#define MQTT_RECONNECT_DELAY 10000
-#define MQTT_RELAY_TOPIC "/relay/%d"
+#define MQTT_RELAY_TOPIC "/relay"
#define MQTT_IP_TOPIC "/ip"
#define MQTT_VERSION_TOPIC "/version"
#define MQTT_FSVERSION_TOPIC "/fsversion"
@@ -77,6 +77,12 @@
#define MQTT_DISCONNECT_EVENT 1
#define MQTT_MESSAGE_EVENT 2
+// Custom get and set postfixes
+// Use something like "/status" or "/set", with trailing slash
+#define MQTT_USE_GETTER ""
+#define MQTT_USE_SETTER ""
+
+
// -----------------------------------------------------------------------------
// NTP
// -----------------------------------------------------------------------------
diff --git a/code/src/emon.ino b/code/src/emon.ino
index c01ab157..7a85ba0a 100644
--- a/code/src/emon.ino
+++ b/code/src/emon.ino
@@ -39,10 +39,10 @@ void powerMonitorSetup() {
// backwards compatibility
String tmp;
- tmp = getSetting("pwMainsVoltage", String() + EMON_MAINS_VOLTAGE);
+ tmp = getSetting("pwMainsVoltage", EMON_MAINS_VOLTAGE);
setSetting("emonMains", tmp);
delSetting("pwMainsVoltage");
- tmp = getSetting("pwCurrentRatio", String() + EMON_CURRENT_RATIO);
+ tmp = getSetting("pwCurrentRatio", EMON_CURRENT_RATIO);
setSetting("emonRatio", tmp);
delSetting("pwCurrentRatio");
@@ -50,7 +50,7 @@ void powerMonitorSetup() {
currentCallback,
EMON_ADC_BITS,
EMON_REFERENCE_VOLTAGE,
- getSetting("emonRatio", String(EMON_CURRENT_RATIO)).toFloat()
+ getSetting("emonRatio", EMON_CURRENT_RATIO).toFloat()
);
emon.setPrecision(EMON_CURRENT_PRECISION);
}
@@ -91,7 +91,7 @@ void powerMonitorLoop() {
sum += current;
++measurements;
- float mainsVoltage = getSetting("emonMains", String(EMON_MAINS_VOLTAGE)).toFloat();
+ float mainsVoltage = getSetting("emonMains", EMON_MAINS_VOLTAGE).toFloat();
//DEBUG_MSG("[ENERGY] Power now: %dW\n", int(current * mainsVoltage));
diff --git a/code/src/fauxmo.ino b/code/src/fauxmo.ino
index 3d89669a..1d131892 100644
--- a/code/src/fauxmo.ino
+++ b/code/src/fauxmo.ino
@@ -18,7 +18,7 @@ fauxmoESP fauxmo;
// -----------------------------------------------------------------------------
void fauxmoConfigure() {
- fauxmo.enable(getSetting("fauxmoEnabled", String(FAUXMO_ENABLED)).toInt() == 1);
+ fauxmo.enable(getSetting("fauxmoEnabled", FAUXMO_ENABLED).toInt() == 1);
}
void fauxmoSetup() {
diff --git a/code/src/main.ino b/code/src/main.ino
index 2f1d0365..8019104d 100644
--- a/code/src/main.ino
+++ b/code/src/main.ino
@@ -29,9 +29,9 @@ along with this program. If not, see .
#include
#include
#include "FS.h"
-String getSetting(const String& key, String defaultValue = "");
-bool relayStatus(unsigned char id, bool status, bool report = true);
void mqttRegister(void (*callback)(unsigned int, const char *, const char *));
+template bool setSetting(const String& key, T value);
+template String getSetting(const String& key, T defaultValue);
// -----------------------------------------------------------------------------
// METHODS
@@ -112,7 +112,7 @@ void setup() {
settingsSetup();
if (getSetting("hostname").length() == 0) {
- setSetting("hostname", String() + getIdentifier());
+ setSetting("hostname", getIdentifier());
saveSettings();
}
diff --git a/code/src/mqtt.ino b/code/src/mqtt.ino
index f1507512..d69b5d82 100644
--- a/code/src/mqtt.ino
+++ b/code/src/mqtt.ino
@@ -57,6 +57,7 @@ void _mqttOnConnect(bool sessionPresent) {
// Build MQTT topics
buildTopics();
+ mqtt.setWill((mqttTopic + MQTT_HEARTBEAT_TOPIC).c_str(), MQTT_QOS, MQTT_RETAIN, (char *) "0");
// Say hello and report our IP and VERSION
mqttSend((char *) MQTT_IP_TOPIC, (char *) getIP().c_str());
@@ -100,7 +101,7 @@ void mqttConnect() {
if (!mqtt.connected()) {
String host = getSetting("mqttServer", MQTT_SERVER);
- String port = getSetting("mqttPort", String(MQTT_PORT));
+ String port = getSetting("mqttPort", MQTT_PORT);
String user = getSetting("mqttUser");
String pass = getSetting("mqttPassword");
@@ -112,12 +113,15 @@ void mqttConnect() {
mqtt
.setKeepAlive(MQTT_KEEPALIVE)
.setCleanSession(false)
- //.setWill("topic/online", 2, true, "no")
.setClientId(getSetting("hostname", HOSTNAME).c_str());
- if ((user != "") & (pass != "")) {
- DEBUG_MSG(" as user %s.\n", (char *) user.c_str());
- mqtt.setCredentials(user.c_str(), pass.c_str());
+ if ((user != "") && (pass != "")) {
+ DEBUG_MSG(" as user '%s'.\n", (char *) user.c_str());
+ char username[user.length()+1];
+ user.toCharArray(username, user.length()+1);
+ char password[pass.length()+1];
+ pass.toCharArray(password, pass.length()+1);
+ mqtt.setCredentials(username, password);
} else {
DEBUG_MSG(" anonymously\n");
}
diff --git a/code/src/nofuss.ino b/code/src/nofuss.ino
index bcb94415..35b1e20e 100644
--- a/code/src/nofuss.ino
+++ b/code/src/nofuss.ino
@@ -74,7 +74,7 @@ void nofussLoop() {
static unsigned long last_check = 0;
if (!wifiConnected()) return;
-unsigned long interval = getSetting("nofussInterval", String(NOFUSS_INTERVAL)).toInt();
+unsigned long interval = getSetting("nofussInterval", NOFUSS_INTERVAL).toInt();
if ((last_check > 0) && ((millis() - last_check) < interval)) return;
last_check = millis();
NoFUSSClient.handle();
diff --git a/code/src/pow.ino b/code/src/pow.ino
index 0676ead5..428838e5 100644
--- a/code/src/pow.ino
+++ b/code/src/pow.ino
@@ -41,18 +41,18 @@ void powDettachInterrupts() {
}
void powSaveCalibration() {
- setSetting("powPowerMult", String() + hlw8012.getPowerMultiplier());
- setSetting("powCurrentMult", String() + hlw8012.getCurrentMultiplier());
- setSetting("powVoltageMult", String() + hlw8012.getVoltageMultiplier());
+ setSetting("powPowerMult", hlw8012.getPowerMultiplier());
+ setSetting("powCurrentMult", hlw8012.getCurrentMultiplier());
+ setSetting("powVoltageMult", hlw8012.getVoltageMultiplier());
}
void powRetrieveCalibration() {
double value;
- value = getSetting("powPowerMult", "0").toFloat();
+ value = getSetting("powPowerMult", 0).toFloat();
if (value > 0) hlw8012.setPowerMultiplier((int) value);
- value = getSetting("powCurrentMult", "0").toFloat();
+ value = getSetting("powCurrentMult", 0).toFloat();
if (value > 0) hlw8012.setCurrentMultiplier((int) value);
- value = getSetting("powVoltageMult", "0").toFloat();
+ value = getSetting("powVoltageMult", 0).toFloat();
if (value > 0) hlw8012.setVoltageMultiplier((int) value);
}
diff --git a/code/src/relay.ino b/code/src/relay.ino
index 77b7cb92..ba26001c 100644
--- a/code/src/relay.ino
+++ b/code/src/relay.ino
@@ -22,8 +22,9 @@ bool recursive = false;
// -----------------------------------------------------------------------------
void relayMQTT(unsigned char id) {
- char buffer[10];
- sprintf(buffer, MQTT_RELAY_TOPIC, id);
+ String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER);
+ char buffer[strlen(MQTT_RELAY_TOPIC) + mqttGetter.length() + 3];
+ sprintf(buffer, "%s/%d%s", MQTT_RELAY_TOPIC, id, mqttGetter.c_str());
mqttSend(buffer, (char *) (relayStatus(id) ? "1" : "0"));
}
@@ -91,7 +92,11 @@ bool relayStatus(unsigned char id, bool status, bool report) {
if (report) relayMQTT(id);
if (!recursive) relayWS();
return changed;
-
+
+}
+
+bool relayStatus(unsigned char id, bool status) {
+ return relayStatus(id, status, true);
}
void relaySync(unsigned char id) {
@@ -100,7 +105,7 @@ void relaySync(unsigned char id) {
recursive = true;
- byte relaySync = getSetting("relaySync", String(RELAY_SYNC)).toInt();
+ byte relaySync = getSetting("relaySync", RELAY_SYNC).toInt();
bool status = relayStatus(id);
// If RELAY_SYNC_SAME all relays should have the same state
@@ -165,36 +170,41 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo
static bool isFirstMessage = true;
+ String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER);
+ String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER);
+ bool sameSetGet = mqttGetter.compareTo(mqttSetter) == 0;
+
if (type == MQTT_CONNECT_EVENT) {
relayMQTT();
- mqttSubscribe("/relay/#");
+ char buffer[strlen(MQTT_RELAY_TOPIC) + mqttSetter.length() + 3];
+ sprintf(buffer, "%s/+%s", MQTT_RELAY_TOPIC, mqttSetter.c_str());
+ mqttSubscribe(buffer);
}
if (type == MQTT_MESSAGE_EVENT) {
// Match topic
- if (memcmp("/relay/", topic, 7) != 0) return;
+ String t = String(topic);
+ if (!t.startsWith(MQTT_RELAY_TOPIC)) return;
+ if (!t.endsWith(mqttSetter)) return;
// If relayMode is not SAME avoid responding to a retained message
- if (isFirstMessage) {
+ if (sameSetGet && isFirstMessage) {
isFirstMessage = false;
- byte relayMode = getSetting("relayMode", String(RELAY_MODE)).toInt();
+ byte relayMode = getSetting("relayMode", RELAY_MODE).toInt();
if (relayMode != RELAY_MODE_SAME) return;
}
// Get relay ID
- unsigned int relayID = topic[strlen(topic)-1] - '0';
+ unsigned int relayID = topic[strlen(MQTT_RELAY_TOPIC)+1] - '0';
if (relayID >= relayCount()) relayID = 0;
// Action to perform
- if ((char)payload[0] == '0') {
- relayStatus(relayID, false, false);
- }
- if ((char)payload[0] == '1') {
- relayStatus(relayID, true, false);
- }
- if ((char)payload[0] == '2') {
+ unsigned int value = (char)payload[0] - '0';
+ if (value == 2) {
relayToggle(relayID);
+ } else {
+ relayStatus(relayID, value > 0, !sameSetGet);
}
}
@@ -227,7 +237,7 @@ void relaySetup() {
#endif
EEPROM.begin(4096);
- byte relayMode = getSetting("relayMode", String(RELAY_MODE)).toInt();
+ byte relayMode = getSetting("relayMode", RELAY_MODE).toInt();
for (unsigned int i=0; i < _relays.size(); i++) {
pinMode(_relays[i], OUTPUT);
diff --git a/code/src/rf.ino b/code/src/rf.ino
index 8a07f9d7..817c0a8e 100644
--- a/code/src/rf.ino
+++ b/code/src/rf.ino
@@ -33,7 +33,7 @@ void rfBuildCodes() {
unsigned long code = 0;
// channel
- unsigned int channel = getSetting("rfChannel", String(RF_CHANNEL)).toInt();
+ unsigned int channel = getSetting("rfChannel", RF_CHANNEL).toInt();
for (byte i = 0; i < 5; i++) {
code *= 3;
if (channel & 1) code += 1;
@@ -41,7 +41,7 @@ void rfBuildCodes() {
}
// device
- unsigned int device = getSetting("rfDevice", String(RF_DEVICE)).toInt();
+ unsigned int device = getSetting("rfDevice", 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
index 29e0826d..b5093d72 100644
--- a/code/src/settings.ino
+++ b/code/src/settings.ino
@@ -20,6 +20,21 @@ Embedis embedis(Serial);
// Settings
// -----------------------------------------------------------------------------
+unsigned long settingsSize() {
+ bool zero = false;
+ unsigned long size = 0;
+ for (unsigned int i = SPI_FLASH_SEC_SIZE; i>0; i--) {
+ size++;
+ if (EEPROM.read(i) == 0) {
+ if (zero) break;
+ zero = true;
+ } else {
+ zero = false;
+ }
+ }
+ return size-2;
+}
+
void settingsSetup() {
EEPROM.begin(SPI_FLASH_SEC_SIZE);
@@ -35,24 +50,46 @@ void settingsSetup() {
#endif
);
- Embedis::hardware( F("wifi"), [](Embedis* e) {
+ Embedis::hardware( F("WIFI"), [](Embedis* e) {
StreamString s;
WiFi.printDiag(s);
e->response(s);
}, 0);
- Embedis::command( F("reconnect"), [](Embedis* e) {
+ Embedis::command( F("RECONNECT"), [](Embedis* e) {
wifiConfigure();
wifiDisconnect();
e->response(Embedis::OK);
});
- Embedis::command( F("reset"), [](Embedis* e) {
+ Embedis::command( F("RESET"), [](Embedis* e) {
e->response(Embedis::OK);
ESP.reset();
});
- DEBUG_MSG("[SETTINGS] Initialized\n");
+ Embedis::command( F("EEPROM.DUMP"), [](Embedis* e) {
+ for (unsigned int i = 0; i < SPI_FLASH_SEC_SIZE; i++) {
+ if (i % 16 == 0) Serial.printf("\n[%04X] ", i);
+ Serial.printf("%02X ", EEPROM.read(i));
+ }
+ Serial.printf("\n");
+ e->response(Embedis::OK);
+ });
+
+ Embedis::command( F("EEPROM.ERASE"), [](Embedis* e) {
+ for (unsigned int i = 0; i < SPI_FLASH_SEC_SIZE; i++) {
+ EEPROM.write(i, 0xFF);
+ }
+ EEPROM.commit();
+ e->response(Embedis::OK);
+ });
+
+ Embedis::command( F("SETTINGS.SIZE"), [](Embedis* e) {
+ e->response(String(settingsSize()));
+ });
+
+ DEBUG_MSG("[SETTINGS] EEPROM size: %d bytes\n", SPI_FLASH_SEC_SIZE);
+ DEBUG_MSG("[SETTINGS] Settings size: %d bytes\n", settingsSize());
}
@@ -60,14 +97,18 @@ void settingsLoop() {
embedis.process();
}
-String getSetting(const String& key, String defaultValue) {
+template String getSetting(const String& key, T defaultValue) {
String value;
- if (!Embedis::get(key, value)) value = defaultValue;
+ if (!Embedis::get(key, value)) value = String(defaultValue);
return value;
}
-bool setSetting(const String& key, String& value) {
- return Embedis::set(key, value);
+String getSetting(const String& key) {
+ return getSetting(key, "");
+}
+
+template bool setSetting(const String& key, T value) {
+ return Embedis::set(key, String(value));
}
bool delSetting(const String& key) {
diff --git a/code/src/web.ino b/code/src/web.ino
index 5645a24b..6419bf2a 100644
--- a/code/src/web.ino
+++ b/code/src/web.ino
@@ -155,12 +155,12 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) {
// Checkboxes
if (apiEnabled != (getSetting("apiEnabled").toInt() == 1)) {
- setSetting("apiEnabled", String() + (apiEnabled ? 1 : 0));
+ setSetting("apiEnabled", apiEnabled);
dirty = true;
}
#if ENABLE_FAUXMO
if (fauxmoEnabled != (getSetting("fauxmoEnabled").toInt() == 1)) {
- setSetting("fauxmoEnabled", String() + (fauxmoEnabled ? 1 : 0));
+ setSetting("fauxmoEnabled", fauxmoEnabled);
dirty = true;
}
#endif
@@ -224,7 +224,7 @@ void _wsStart(uint32_t client_id) {
root["mqttStatus"] = mqttConnected();
root["mqttServer"] = getSetting("mqttServer", MQTT_SERVER);
- root["mqttPort"] = getSetting("mqttPort", String(MQTT_PORT));
+ root["mqttPort"] = getSetting("mqttPort", MQTT_PORT);
root["mqttUser"] = getSetting("mqttUser");
root["mqttPassword"] = getSetting("mqttPassword");
root["mqttTopic"] = getSetting("mqttTopic", MQTT_TOPIC);
@@ -233,10 +233,10 @@ void _wsStart(uint32_t client_id) {
for (unsigned char relayID=0; relayID 1) {
root["multirelayVisible"] = 1;
- root["relaySync"] = getSetting("relaySync", String(RELAY_SYNC));
+ root["relaySync"] = getSetting("relaySync", RELAY_SYNC);
}
root["apiEnabled"] = getSetting("apiEnabled").toInt() == 1;
@@ -244,7 +244,7 @@ void _wsStart(uint32_t client_id) {
#if ENABLE_FAUXMO
root["fauxmoVisible"] = 1;
- root["fauxmoEnabled"] = getSetting("fauxmoEnabled", String(FAUXMO_ENABLED)).toInt() == 1;
+ root["fauxmoEnabled"] = getSetting("fauxmoEnabled", FAUXMO_ENABLED).toInt() == 1;
#endif
#if ENABLE_DS18B20
@@ -260,15 +260,15 @@ void _wsStart(uint32_t client_id) {
#if ENABLE_RF
root["rfVisible"] = 1;
- root["rfChannel"] = getSetting("rfChannel", String(RF_CHANNEL));
- root["rfDevice"] = getSetting("rfDevice", String(RF_DEVICE));
+ root["rfChannel"] = getSetting("rfChannel", RF_CHANNEL);
+ root["rfDevice"] = getSetting("rfDevice", RF_DEVICE);
#endif
#if ENABLE_EMON
root["emonVisible"] = 1;
root["emonPower"] = getPower();
- root["emonMains"] = getSetting("emonMains", String(EMON_MAINS_VOLTAGE));
- root["emonRatio"] = getSetting("emonRatio", String(EMON_CURRENT_RATIO));
+ root["emonMains"] = getSetting("emonMains", EMON_MAINS_VOLTAGE);
+ root["emonRatio"] = getSetting("emonRatio", EMON_CURRENT_RATIO);
#endif
#if ENABLE_POW
@@ -502,7 +502,7 @@ void webSetup() {
char lastModified[50];
sprintf(lastModified, "%s %s GMT", __DATE__, __TIME__);
server.serveStatic("/", SPIFFS, "/").setLastModified(lastModified);
-
+
// 404
server.onNotFound([](AsyncWebServerRequest *request){
request->send(404);
diff --git a/code/src/wifi.ino b/code/src/wifi.ino
index f291af12..e8c1bb39 100644
--- a/code/src/wifi.ino
+++ b/code/src/wifi.ino
@@ -164,5 +164,7 @@ void wifiSetup() {
void wifiLoop() {
jw.loop();
- dnsServer.processNextRequest();
+ if (WiFi.getMode() == WIFI_AP) {
+ dnsServer.processNextRequest();
+ }
}