From be1fac2f44e07f53034bab8ffce694c2af5839d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 19 Feb 2017 19:29:51 +0100 Subject: [PATCH] Using gulp to generate the embedded web contents, added Last-Modifier support to embedded home --- code/.gitignore | 4 ++-- code/build-data_h | 18 ----------------- code/espurna/config/general.h | 8 +++++++- code/espurna/espurna.ino | 34 +++++++++++++++---------------- code/espurna/web.ino | 38 +++++++++++++++++++++++++---------- code/gulpfile.js | 37 +++++++++++++++++++++++++++++----- 6 files changed, 85 insertions(+), 54 deletions(-) delete mode 100644 code/build-data_h 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