diff --git a/app/package.json b/app/package.json index 87dfcf2..95c7c3e 100644 --- a/app/package.json +++ b/app/package.json @@ -32,7 +32,8 @@ "vue-router": "^3.1.5", "vue-svg-loader": "^0.16.0", "vue-template-compiler": "^2.6.11", - "vuetify-loader": "^1.3.0" + "vuetify-loader": "^1.3.0", + "webpack-version-file": "^0.1.6" }, "eslintConfig": { "root": true, diff --git a/app/version.ejs b/app/version.ejs new file mode 100644 index 0000000..9a7ed75 --- /dev/null +++ b/app/version.ejs @@ -0,0 +1,4 @@ +{ + "rev": "<%= commitHash %>", + "buildTime": <%= buildTime %> +} \ No newline at end of file diff --git a/app/vue.config.js b/app/vue.config.js index 4fcda86..6fd44fd 100644 --- a/app/vue.config.js +++ b/app/vue.config.js @@ -1,5 +1,32 @@ const webpack = require('webpack') const CompressionPlugin = require('compression-webpack-plugin') +const VersionFile = require('webpack-version-file') + +// get git info from command line +const commitHash = require('child_process') + .execSync('git rev-parse HEAD') + .toString() + +const buildInfo = { + commitHash: commitHash.trim(), + buildTime: JSON.stringify(new Date().getTime() / 1000 | 0), +} + +/* +const appVersionVue = new webpack.DefinePlugin({ + __COMMIT_HASH__: buildInfo.commitHash, + __BUILD_TIME__: buildInfo.buildTime, +}) +*/ + +const appVersionJson = new VersionFile({ + output: '../data/dist/version.json', + template: './version.ejs', + data: { + commitHash: buildInfo.commitHash, + buildTime: buildInfo.buildTime, + }, +}) module.exports = { outputDir: '../data/dist', @@ -11,7 +38,7 @@ module.exports = { devServer: { proxy: { '^/': { - target: 'http://paperdash-display-2:80', + target: 'http://paperdash-display:80', ws: true, changeOrigin: true, }, @@ -30,10 +57,20 @@ module.exports = { new CompressionPlugin({ deleteOriginalAssets: true, }), + // add version info + // appVersionVue, + appVersionJson, ], } } else { // mutate for development... + return { + plugins: [ + // add version info + // appVersionVue, + appVersionJson, + ], + } } }, } diff --git a/app/yarn.lock b/app/yarn.lock index a3dfda9..efce44f 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -4005,7 +4005,7 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.6.1: +ejs@^2.5.2, ejs@^2.6.1: version "2.7.4" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== @@ -10502,6 +10502,14 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-list-map "^2.0.0" source-map "~0.6.1" +webpack-version-file@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/webpack-version-file/-/webpack-version-file-0.1.6.tgz#b6d0ed23a8f98c37397827996ad36bbe47a9be21" + integrity sha512-vGc2h2i+3s15fidvzGxUIWrnZZvYlPDSlbowoI8SRW3MV5wS6IJJ8O3BRKXlTg+VwDxyiEXh67v1T28qRBoY2A== + dependencies: + chalk "^2.1.0" + ejs "^2.5.2" + webpack@^4.0.0: version "4.44.2" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72" diff --git a/lib/app/app.cpp b/lib/app/app.cpp index f93a415..a60fcd7 100644 --- a/lib/app/app.cpp +++ b/lib/app/app.cpp @@ -16,6 +16,15 @@ AsyncWebServer server(80); +struct AppConfig +{ + char buildRev[40 +1]; + uint32_t buildTime; +}; + +const char *jsonAppVersion = "/dist/version.json"; +AppConfig appConfig; + void setupApiDevice(); void setupApiSettings(); void setupApiWifi(); @@ -25,9 +34,45 @@ void setupOTA(); //flag to use from web update to update display bool updateDisplayRequired = false; +void loadAppVersion() +{ + File file = SPIFFS.open(jsonAppVersion); + if (!file) + { + Serial.print(F("Failed to open file: ")); + Serial.println(jsonAppVersion); + + return; + } + + // Allocate a temporary JsonDocument + const size_t capacity = JSON_OBJECT_SIZE(2) + 70; + StaticJsonDocument doc; + + // Deserialize the JSON document + DeserializationError error = deserializeJson(doc, file); + if (error) + { + Serial.println(F("Failed to version file:")); + Serial.println(error.c_str()); + + return; + } + + // get data + appConfig.buildTime = doc["buildTime"]; + strlcpy(appConfig.buildRev, + doc["rev"], + sizeof(appConfig.buildRev)); + + file.close(); +} + void setupApp() { - Serial.println("setup configure"); + Serial.println("setup app"); + + loadAppVersion(); // @see https://github.com/me-no-dev/ESPAsyncWebServer // @see https://arduinojson.org/v6/assistant/ @@ -53,7 +98,8 @@ void setupApp() // TODO response server.on("/stats", HTTP_GET, [](AsyncWebServerRequest *request) { AsyncResponseStream *response = request->beginResponseStream("application/json"); - DynamicJsonDocument doc(668); // https://arduinojson.org/v6/assistant/ + const size_t capacity = 5*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(8) + 410; + DynamicJsonDocument doc(capacity); doc["wifi"]["mac"] = WiFi.macAddress(); doc["wifi"]["ssid"] = WiFi.SSID(); @@ -77,8 +123,6 @@ void setupApp() doc["device"]["heap"]["total"] = ESP.getHeapSize(); doc["device"]["heap"]["free"] = ESP.getFreeHeap(); - doc["device"]["psram"]["total"] = ESP.getPsramSize(); - doc["device"]["psram"]["free"] = ESP.getFreePsram(); doc["playlist"]["current"] = PlaylistGetCurrentFace(); doc["playlist"]["remaining"] = (PlaylistGetRemainingTimeMs() / 1000) + 3; // + face rendering time 3s @@ -86,8 +130,11 @@ void setupApp() doc["firmware"]["created"] = FW_CREATED; doc["firmware"]["rev"] = FW_GIT_REV; - JsonArray capability = doc.createNestedArray("capability"); - capability.add("jpg"); + doc["app"]["created"] = appConfig.buildTime; + doc["app"]["rev"] = appConfig.buildRev; + + //JsonArray capability = doc.createNestedArray("capability"); + //capability.add("jpg"); //capability.add("wbmp"); serializeJson(doc, *response); @@ -100,7 +147,7 @@ void setupApp() server.begin(); - Serial.println("setup configure - done"); + Serial.println("setup app - done"); } void loopApp() @@ -408,7 +455,6 @@ void setupApiUpdate() /** * api data endpoint - * @todo */ void setupOTA() { @@ -418,7 +464,7 @@ void setupOTA() }); server.on( - "/update", HTTP_POST, [](AsyncWebServerRequest *request) { }, + "/update", HTTP_POST, [](AsyncWebServerRequest *request) {}, [](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { if (!index) {