diff --git a/code/.gitignore b/code/.gitignore
index e05273b2..432d29e7 100644
--- a/code/.gitignore
+++ b/code/.gitignore
@@ -1,4 +1,4 @@
-.pioenvs
+.pio*
.clang_complete
.gcc-flags.json
-.piolibdeps
\ No newline at end of file
+espurna/config/data.h
diff --git a/code/build-data_h b/code/build-data_h
deleted file mode 100644
index 3df79488..00000000
--- a/code/build-data_h
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/python
-
-import binascii
-import string
-
-source = 'espurna/data/index.html.gz'
-destination = 'espurna/config/data.h'
-
-with open(source, 'rb') as f:
- content = f.read()
-
-array = map(lambda x: '0x%02x' % ord(x), content)
-
-with open(destination, 'w') as f:
- f.write("#define index_html_gz_len %d\n" % len(array))
- f.write("const uint8_t index_html_gz[] PROGMEM = {")
- f.write(string.join(array, ','))
- f.write("};\n")
diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h
index 6f62650e..a6596af2 100644
--- a/code/espurna/config/general.h
+++ b/code/espurna/config/general.h
@@ -103,7 +103,13 @@
#define AP_MODE_GW "192.168.4.1"
#define AP_MODE_MASK "255.255.255.0"
-#define EMBED_WEB_IN_FIRMWARE 0
+// This option builds the firmware with the web interface embedded.
+// You first have to build the data.h file that holds the contents
+// of the web interface by running "gulp buildfs_embed"
+
+#ifndef EMBEDDED_WEB
+#define EMBEDDED_WEB 0
+#endif
// -----------------------------------------------------------------------------
// OTA & NOFUSS
diff --git a/code/espurna/espurna.ino b/code/espurna/espurna.ino
index 46b910e9..898105de 100644
--- a/code/espurna/espurna.ino
+++ b/code/espurna/espurna.ino
@@ -21,12 +21,6 @@ along with this program. If not, see .
#include "config/all.h"
-// -----------------------------------------------------------------------------
-// GLOBALS
-// -----------------------------------------------------------------------------
-
-char apibuffer[64];
-
// -----------------------------------------------------------------------------
// METHODS
// -----------------------------------------------------------------------------
@@ -39,7 +33,9 @@ String getIdentifier() {
void hardwareSetup() {
Serial.begin(SERIAL_BAUDRATE);
- SPIFFS.begin();
+ #if not EMBEDDED_WEB
+ SPIFFS.begin();
+ #endif
}
void hardwareLoop() {
@@ -62,9 +58,9 @@ void hardwareLoop() {
void welcome() {
delay(2000);
+
DEBUG_MSG("%s %s\n", (char *) APP_NAME, (char *) APP_VERSION);
DEBUG_MSG("%s\n%s\n\n", (char *) APP_AUTHOR, (char *) APP_WEBSITE);
- //DEBUG_MSG("Device: %s\n", (char *) getIdentifier().c_str());
DEBUG_MSG("ChipID: %06X\n", ESP.getChipId());
DEBUG_MSG("CPU frequency: %d MHz\n", ESP.getCpuFreqMHz());
DEBUG_MSG("Last reset reason: %s\n", (char *) ESP.getResetReason().c_str());
@@ -72,15 +68,19 @@ void welcome() {
DEBUG_MSG("Free heap: %d bytes\n", ESP.getFreeHeap());
DEBUG_MSG("Firmware size: %d bytes\n", ESP.getSketchSize());
DEBUG_MSG("Free firmware space: %d bytes\n", ESP.getFreeSketchSpace());
- FSInfo fs_info;
- if (SPIFFS.info(fs_info)) {
- DEBUG_MSG("File system total size: %d bytes\n", fs_info.totalBytes);
- DEBUG_MSG(" used size : %d bytes\n", fs_info.usedBytes);
- DEBUG_MSG(" block size: %d bytes\n", fs_info.blockSize);
- DEBUG_MSG(" page size : %d bytes\n", fs_info.pageSize);
- DEBUG_MSG(" max files : %d\n", fs_info.maxOpenFiles);
- DEBUG_MSG(" max length: %d\n", fs_info.maxPathLength);
- }
+
+ #if not EMBEDDED_WEB
+ FSInfo fs_info;
+ if (SPIFFS.info(fs_info)) {
+ DEBUG_MSG("File system total size: %d bytes\n", fs_info.totalBytes);
+ DEBUG_MSG(" used size : %d bytes\n", fs_info.usedBytes);
+ DEBUG_MSG(" block size: %d bytes\n", fs_info.blockSize);
+ DEBUG_MSG(" page size : %d bytes\n", fs_info.pageSize);
+ DEBUG_MSG(" max files : %d\n", fs_info.maxOpenFiles);
+ DEBUG_MSG(" max length: %d\n", fs_info.maxPathLength);
+ }
+ #endif
+
DEBUG_MSG("\n\n");
}
diff --git a/code/espurna/web.ino b/code/espurna/web.ino
index fb3dcb21..4cacee4b 100644
--- a/code/espurna/web.ino
+++ b/code/espurna/web.ino
@@ -16,7 +16,7 @@ Copyright (C) 2016-2017 by Xose PĂ©rez
#include
#include
-#if EMBED_WEB_IN_FIRMWARE == 1
+#if EMBEDDED_WEB
#include "config/data.h"
#endif
@@ -37,6 +37,7 @@ typedef struct {
apiPutCallbackFunction putFn = NULL;
} web_api_t;
std::vector _apis;
+char _last_modified[50];
// -----------------------------------------------------------------------------
// WEBSOCKETS
@@ -706,12 +707,26 @@ void _onAuth(AsyncWebServerRequest *request) {
}
-#if EMBED_WEB_IN_FIRMWARE == 1
+#if EMBEDDED_WEB
void _onHome(AsyncWebServerRequest *request) {
- AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html_gz, index_html_gz_len);
- response->addHeader("Content-Encoding", "gzip");
- request->send(response);
+
+ webLogRequest(request);
+
+ if (request->header("If-Modified-Since").equals(_last_modified)) {
+
+ request->send(304);
+
+ } else {
+
+ AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html_gz, index_html_gz_len);
+ response->addHeader("Content-Encoding", "gzip");
+ response->addHeader("Last-Modified", _last_modified);
+ request->send(response);
+
+ }
+
}
+
#endif
void webSetup() {
@@ -723,6 +738,9 @@ void webSetup() {
ws.onEvent(_wsEvent);
mqttRegister(wsMQTTCallback);
+ // Cache the Last-Modifier header value
+ sprintf(_last_modified, "%s %s GMT", __DATE__, __TIME__);
+
// Setup webserver
_server->addHandler(&ws);
@@ -730,19 +748,17 @@ void webSetup() {
_server->rewrite("/", "/index.html");
// Serve home (basic authentication protection)
- #if EMBED_WEB_IN_FIRMWARE == 1
- _server->on("/index.html", HTTP_GET, _onHome);
+ #if EMBEDDED_WEB
+ _server->on("/index.html", HTTP_GET, _onHome);
#endif
_server->on("/auth", HTTP_GET, _onAuth);
_server->on("/apis", HTTP_GET, _onAPIs);
_server->on("/rpc", HTTP_GET, _onRPC);
// Serve static files
- #if EMBED_WEB_IN_FIRMWARE == 0
- char lastModified[50];
- sprintf(lastModified, "%s %s GMT", __DATE__, __TIME__);
+ #if not EMBEDDED_WEB
_server->serveStatic("/", SPIFFS, "/")
- .setLastModified(lastModified)
+ .setLastModified(_last_modified)
.setFilter([](AsyncWebServerRequest *request) -> bool {
webLogRequest(request);
return true;
diff --git a/code/gulpfile.js b/code/gulpfile.js
index 26f08893..05d63887 100644
--- a/code/gulpfile.js
+++ b/code/gulpfile.js
@@ -23,6 +23,7 @@ along with this program. If not, see .
// File system builder
// -----------------------------------------------------------------------------
+const fs = require('fs');
const gulp = require('gulp');
const plumber = require('gulp-plumber');
const htmlmin = require('gulp-htmlmin');
@@ -36,11 +37,11 @@ const inline = require('gulp-inline');
const inlineImages = require('gulp-css-base64');
const favicon = require('gulp-base64-favicon');
-const destination = 'espurna/data/';
+const dataFolder = 'espurna/data/';
/* Clean destination folder */
gulp.task('clean', function() {
- del([ destination + '*']);
+ del([ dataFolder + '*']);
return true;
});
@@ -50,7 +51,32 @@ gulp.task('files', function() {
'html/**/*.{jpg,jpeg,png,ico,gif}',
'html/fsversion'
])
- .pipe(gulp.dest(destination));
+ .pipe(gulp.dest(dataFolder));
+});
+
+gulp.task('embed', function() {
+
+ var source = dataFolder + 'index.html.gz';
+ var destination = dataFolder + '../config/data.h';
+
+ var wstream = fs.createWriteStream(destination);
+ wstream.on('error', function (err) {
+ console.log(err);
+ });
+
+ var data = fs.readFileSync(source);
+
+ wstream.write('#define index_html_gz_len ' + data.length + '\n');
+ wstream.write('const uint8_t index_html_gz[] PROGMEM = {')
+
+ for (i=0; i