diff --git a/code/html/custom.js b/code/html/custom.js
index 287f90e6..828c26dc 100644
--- a/code/html/custom.js
+++ b/code/html/custom.js
@@ -40,6 +40,11 @@ function toggleMenu() {
function processData(data) {
+ // messages
+ if ("message" in data) {
+ window.alert(data.message);
+ }
+
// pre-process
if ("network" in data) {
data.network = data.network.toUpperCase();
@@ -136,7 +141,8 @@ function init() {
$(".pure-menu-link").on('click', showPanel);
var host = window.location.hostname;
- websock = new WebSocket('ws://' + host + ':81/');
+ //host = '192.168.1.115';
+ websock = new WebSocket('ws://' + host + '/ws');
websock.onopen = function(evt) {};
websock.onclose = function(evt) {};
websock.onerror = function(evt) {};
diff --git a/code/html/fsversion b/code/html/fsversion
index e3e18070..3eefcb9d 100644
--- a/code/html/fsversion
+++ b/code/html/fsversion
@@ -1 +1 @@
-0.9.8
+1.0.0
diff --git a/code/html/index.html b/code/html/index.html
index 3b82523d..fcb2cfd9 100644
--- a/code/html/index.html
+++ b/code/html/index.html
@@ -167,6 +167,12 @@
+
+
+
Change the password for the 'admin' user to access this web interface.
+
+
+
diff --git a/code/platformio.ini b/code/platformio.ini
index 8400b7c6..a9cdcc9c 100644
--- a/code/platformio.ini
+++ b/code/platformio.ini
@@ -1,10 +1,13 @@
[platformio]
env_default = sonoff-pow-debug
+[common]
+lib_install = 19,31,44,64,305,306,346,727
+
[env:sonoff-debug]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF
@@ -12,7 +15,7 @@ build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF
[env:sonoff-debug-ota]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF
@@ -23,15 +26,26 @@ upload_flags = --auth=fibonacci --port 8266
[env:sonoff-pow-debug]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
+extra_script = pio_hooks.py
+board = esp01_1m
+build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF_POW
+
+[env:sonoff-pow-debug-ota]
+platform = espressif8266
+framework = arduino
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF_POW
+upload_speed = 115200
+upload_port = "192.168.4.1"
+upload_flags = --auth=fibonacci --port 8266
[env:slampher-debug]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSLAMPHER
@@ -39,7 +53,7 @@ build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSLAMPHER
[env:slampher-debug-ota]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSLAMPHER
@@ -50,7 +64,7 @@ upload_flags = --auth=fibonacci --port 8266
[env:s20-debug]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DS20
@@ -58,7 +72,7 @@ build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DS20
[env:s20-debug-ota]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DS20
@@ -69,7 +83,7 @@ upload_flags = --auth=fibonacci --port 8266
[env:node-debug]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = nodemcuv2
build_flags = -DNODEMCUV2 -DDEBUG_PORT=Serial
@@ -77,7 +91,7 @@ build_flags = -DNODEMCUV2 -DDEBUG_PORT=Serial
[env:node-debug-ota]
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = nodemcuv2
build_flags = -DNODEMCUV2 -DDEBUG_PORT=Serial
@@ -91,7 +105,7 @@ upload_flags = --auth=fibonacci --port 8266
topic = /home/cellar/airconditioner/ip
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DS20
@@ -103,7 +117,7 @@ upload_flags = --auth=fibonacci --port 8266
topic = /home/cellar/washer/ip
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
upload_speed = 115200
@@ -115,7 +129,7 @@ build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF -DENABLE
topic = /home/studio/lamp/ip
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF
@@ -127,7 +141,7 @@ upload_flags = --auth=fibonacci --port 8266
topic = /home/living/lamp/ip
platform = espressif8266
framework = arduino
-lib_install = 19,31,44,64,89,549,727
+lib_install = ${common.lib_install}
extra_script = pio_hooks.py
board = esp01_1m
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF
diff --git a/code/src/defaults.h b/code/src/defaults.h
index 996c05f3..bb99d593 100644
--- a/code/src/defaults.h
+++ b/code/src/defaults.h
@@ -87,6 +87,8 @@
#define MQTT_PORT 1883
#define MQTT_TOPIC "/test/switch/{identifier}"
#define MQTT_RETAIN true
+#define MQTT_QOS 0
+#define MQTT_KEEPALIVE 30
#define MQTT_RECONNECT_DELAY 10000
#define MQTT_STATUS_TOPIC ""
#define MQTT_IP_TOPIC "/ip"
diff --git a/code/src/main.ino b/code/src/main.ino
index 26b91b36..7b8e90ba 100644
--- a/code/src/main.ino
+++ b/code/src/main.ino
@@ -28,7 +28,8 @@ along with this program. If not, see .
// -----------------------------------------------------------------------------
#include
-#include
+#include
+#include
#include "FS.h"
String getSetting(const String& key, String defaultValue = "");
@@ -144,8 +145,7 @@ void setup() {
wifiSetup();
otaSetup();
mqttSetup();
- webServerSetup();
- webSocketSetup();
+ webSetup();
ntpSetup();
#if ENABLE_NOFUSS
@@ -174,8 +174,6 @@ void loop() {
wifiLoop();
otaLoop();
mqttLoop();
- webServerLoop();
- webSocketLoop();
ntpLoop();
#if ENABLE_NOFUSS
diff --git a/code/src/mqtt.ino b/code/src/mqtt.ino
index 90f46c94..aceb501b 100644
--- a/code/src/mqtt.ino
+++ b/code/src/mqtt.ino
@@ -7,12 +7,11 @@ Copyright (C) 2016 by Xose Pérez
*/
-#include
#include
+#include
+
+AsyncMqttClient mqtt;
-WiFiClient client;
-PubSubClient mqtt(client);
-boolean mqttStatus = false;
String mqttTopic;
bool isCallbackMessage = false;
@@ -39,19 +38,48 @@ void mqttSend(char * topic, char * message) {
if (isCallbackMessage) return;
String path = mqttTopic + String(topic);
DEBUG_MSG("[MQTT] Sending %s %s\n", (char *) path.c_str(), message);
- mqtt.publish(path.c_str(), message, MQTT_RETAIN);
+ mqtt.publish(path.c_str(), MQTT_QOS, MQTT_RETAIN, message);
}
-void mqttCallback(char* topic, byte* payload, unsigned int length) {
+void _mqttOnConnect(bool sessionPresent) {
+
+ DEBUG_MSG("[MQTT] Connected!\n");
+
+ // Send status via webSocket
+ webSocketSend((char *) "{\"mqttStatus\": true}");
+
+ // Build MQTT topics
+ buildTopics();
+
+ // Say hello and report our IP and VERSION
+ mqttSend((char *) MQTT_IP_TOPIC, (char *) getIP().c_str());
+ mqttSend((char *) MQTT_VERSION_TOPIC, (char *) APP_VERSION);
+ char buffer[10];
+ getFSVersion(buffer);
+ mqttSend((char *) MQTT_FSVERSION_TOPIC, buffer);
+
+ // Publish current relay status
+ mqttSend((char *) MQTT_STATUS_TOPIC, (char *) (digitalRead(RELAY_PIN) ? "1" : "0"));
+
+ // Subscribe to topic
+ DEBUG_MSG("[MQTT] Subscribing to %s\n", (char *) mqttTopic.c_str());
+ mqtt.subscribe(mqttTopic.c_str(), MQTT_QOS);
+
+}
+
+void _mqttOnDisconnect(AsyncMqttClientDisconnectReason reason) {
+
+ // Send status via webSocket
+ webSocketSend((char *) "{\"mqttStatus\": false}");
+
+}
+
+void _mqttOnMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
static bool isFirstMessage = true;
- #ifdef DEBUG_PORT
- char buffer[length+1];
- memcpy(buffer, payload, length);
- buffer[length] = 0;
- DEBUG_MSG("[MQTT] Received %s %s\n", topic, buffer);
- #endif
+ payload[len] = '\0';
+ DEBUG_MSG("[MQTT] Received %s %s\n", topic, payload);
// If relayMode is not SAME avoid responding to a retained message
if (isFirstMessage) {
@@ -89,52 +117,31 @@ void mqttConnect() {
if (host.length() == 0) return;
DEBUG_MSG("[MQTT] Connecting to broker at %s", (char *) host.c_str());
+
mqtt.setServer(host.c_str(), port.toInt());
+ 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: ", (char *) user.c_str());
- mqtt.connect(getSetting("hostname", HOSTNAME).c_str(), user.c_str(), pass.c_str());
+ DEBUG_MSG(" as user %s.\n", (char *) user.c_str());
+ mqtt.setCredentials(user.c_str(), pass.c_str());
} else {
- DEBUG_MSG(" anonymously: ");
- mqtt.connect(getSetting("hostname", HOSTNAME).c_str());
+ DEBUG_MSG(" anonymously\n");
}
- if (mqtt.connected()) {
+ mqtt.connect();
- DEBUG_MSG("connected!\n");
-
- buildTopics();
- mqttStatus = true;
-
- // Send status via webSocket
- webSocketSend((char *) "{\"mqttStatus\": true}");
-
- // Say hello and report our IP and VERSION
- mqttSend((char *) MQTT_IP_TOPIC, (char *) getIP().c_str());
- mqttSend((char *) MQTT_VERSION_TOPIC, (char *) APP_VERSION);
- char buffer[10];
- getFSVersion(buffer);
- mqttSend((char *) MQTT_FSVERSION_TOPIC, buffer);
-
- // Publish current relay status
- mqttSend((char *) MQTT_STATUS_TOPIC, (char *) (digitalRead(RELAY_PIN) ? "1" : "0"));
-
- // Subscribe to topic
- DEBUG_MSG("[MQTT] Subscribing to %s\n", (char *) mqttTopic.c_str());
- mqtt.subscribe(mqttTopic.c_str());
-
-
- } else {
-
- DEBUG_MSG("failed (rc=%d)\n", mqtt.state());
-
- }
}
}
void mqttSetup() {
- mqtt.setCallback(mqttCallback);
+ mqtt.onConnect(_mqttOnConnect);
+ mqtt.onDisconnect(_mqttOnDisconnect);
+ mqtt.onMessage(_mqttOnMessage);
}
void mqttLoop() {
@@ -145,11 +152,6 @@ void mqttLoop() {
if (!mqtt.connected()) {
- if (mqttStatus) {
- webSocketSend((char *) "{\"mqttStatus\": false}");
- mqttStatus = false;
- }
-
unsigned long currPeriod = millis() / MQTT_RECONNECT_DELAY;
if (currPeriod != lastPeriod) {
lastPeriod = currPeriod;
@@ -158,8 +160,6 @@ void mqttLoop() {
}
- if (mqtt.connected()) mqtt.loop();
-
}
}
diff --git a/code/src/version.h b/code/src/version.h
index 624ada9e..a2b73d73 100644
--- a/code/src/version.h
+++ b/code/src/version.h
@@ -1,4 +1,4 @@
#define APP_NAME "Espurna"
-#define APP_VERSION "0.9.9"
+#define APP_VERSION "1.0.0"
#define APP_AUTHOR "xose.perez@gmail.com"
#define APP_WEBSITE "http://tinkerman.cat"
diff --git a/code/src/websockets.ino b/code/src/web.ino
similarity index 65%
rename from code/src/websockets.ino
rename to code/src/web.ino
index 8bab19be..da532745 100644
--- a/code/src/websockets.ino
+++ b/code/src/web.ino
@@ -1,17 +1,22 @@
/*
-RENTALITO
+ESPurna
WEBSERVER MODULE
Copyright (C) 2016 by Xose Pérez
*/
-#include
+#include
+#include
+#include
+#include "FS.h"
#include
+#include "AsyncJson.h"
#include
-WebSocketsServer webSocket = WebSocketsServer(81);
+AsyncWebServer server(80);
+AsyncWebSocket ws("/ws");
// -----------------------------------------------------------------------------
// WEBSOCKETS
@@ -19,21 +24,22 @@ WebSocketsServer webSocket = WebSocketsServer(81);
bool webSocketSend(char * payload) {
//DEBUG_MSG("[WEBSOCKET] Broadcasting '%s'\n", payload);
- webSocket.broadcastTXT(payload);
+ ws.textAll(payload);
}
-bool webSocketSend(uint8_t num, char * payload) {
- //DEBUG_MSG("[WEBSOCKET] Sending '%s' to #%d\n", payload, num);
- webSocket.sendTXT(num, payload);
+bool webSocketSend(uint32_t client_id, char * payload) {
+ //DEBUG_MSG("[WEBSOCKET] Sending '%s' to #%ld\n", payload, client_id);
+ ws.text(client_id, payload);
}
-void webSocketParse(uint8_t num, uint8_t * payload, size_t length) {
+void webSocketParse(uint32_t client_id, uint8_t * payload, size_t length) {
// Parse JSON input
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject((char *) payload);
if (!root.success()) {
DEBUG_MSG("[WEBSOCKET] Error parsing data\n");
+ ws.text(client_id, "{\"message\": \"Error parsing data!\"}");
return;
}
@@ -62,8 +68,6 @@ void webSocketParse(uint8_t num, uint8_t * payload, size_t length) {
for (unsigned int i=0; iid());
+ DEBUG_MSG("[WEBSOCKET] #%u connected, ip: %d.%d.%d.%d, url: %s\n", client->id(), ip[0], ip[1], ip[2], ip[3], server->url());
+ }
+ #endif
+ webSocketStart(client->id());
+ } else if(type == WS_EVT_DISCONNECT) {
+ DEBUG_MSG("[WEBSOCKET] #%u disconnected\n", client->id());
+ } else if(type == WS_EVT_ERROR) {
+ DEBUG_MSG("[WEBSOCKET] #%u error(%u): %s\n", client->id(), *((uint16_t*)arg), (char*)data);
+ } else if(type == WS_EVT_PONG) {
+ DEBUG_MSG("[WEBSOCKET] #%u pong(%u): %s\n", client->id(), len, len ? (char*) data : "");
+ } else if(type == WS_EVT_DATA) {
+ webSocketParse(client->id(), data, len);
}
-
}
-void webSocketSetup() {
- webSocket.begin();
- webSocket.onEvent(webSocketEvent);
-}
+// -----------------------------------------------------------------------------
+// WEBSERVER
+// -----------------------------------------------------------------------------
+
+void webSetup() {
+
+ // Setup websocket plugin
+ ws.onEvent(webSocketEvent);
+ server.addHandler(&ws);
+
+ // Serve static files
+ server.serveStatic("/", SPIFFS, "/").setDefaultFile("/index.html");
+
+ // 404
+ server.onNotFound([](AsyncWebServerRequest *request){
+ request->send(404);
+ });
+
+ // Run server
+ server.begin();
-void webSocketLoop() {
- webSocket.loop();
}
diff --git a/code/src/webserver.ino b/code/src/webserver.ino
deleted file mode 100644
index 3374e958..00000000
--- a/code/src/webserver.ino
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-
-ESPurna
-WEBSERVER MODULE
-
-Copyright (C) 2016 by Xose Pérez
-
-*/
-
-#include
-#include
-#include "FS.h"
-
-ESP8266WebServer server(80);
-
-// -----------------------------------------------------------------------------
-// WEBSERVER
-// -----------------------------------------------------------------------------
-
-String getContentType(String filename) {
- if (server.hasArg("download")) return "application/octet-stream";
- else if (filename.endsWith(".htm")) return "text/html";
- else if (filename.endsWith(".html")) return "text/html";
- else if (filename.endsWith(".css")) return "text/css";
- else if (filename.endsWith(".js")) return "application/javascript";
- else if (filename.endsWith(".png")) return "image/png";
- else if (filename.endsWith(".gif")) return "image/gif";
- else if (filename.endsWith(".jpg")) return "image/jpeg";
- else if (filename.endsWith(".ico")) return "image/x-icon";
- else if (filename.endsWith(".xml")) return "text/xml";
- else if (filename.endsWith(".pdf")) return "application/x-pdf";
- else if (filename.endsWith(".zip")) return "application/x-zip";
- else if (filename.endsWith(".gz")) return "application/x-gzip";
- return "text/plain";
-}
-
-bool handleFileRead(String path) {
-
- DEBUG_MSG("[WEBSERVER] Request: %s\n", (char *) path.c_str());
-
- if (path.endsWith("/")) path += "index.html";
- String contentType = getContentType(path);
- String pathWithGz = path + ".gz";
- if (SPIFFS.exists(pathWithGz)) path = pathWithGz;
-
- if (SPIFFS.exists(path)) {
- File file = SPIFFS.open(path, "r");
- size_t sent = server.streamFile(file, contentType);
- size_t contentLength = file.size();
- file.close();
- return true;
- }
-
- return false;
-
-}
-
-void webServerSetup() {
-
- // Anything else
- server.onNotFound([]() {
-
- // Hidden files
- #ifndef DEBUG_PORT
- if (server.uri().startsWith("/.")) {
- server.send(403, "text/plain", "Forbidden");
- return;
- }
- #endif
-
- // Existing files in SPIFFS
- if (!handleFileRead(server.uri())) {
- server.send(404, "text/plain", "NotFound");
- return;
- }
-
- });
-
- // Run server
- server.begin();
-
-}
-
-void webServerLoop() {
- server.handleClient();
-}