From 5fa22654ad88c0a454c2b220ef01eebcba788690 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 17:55:25 +0000 Subject: [PATCH 1/3] Initial plan From e46adab97ee7e6c79a87338d513861d6ac099498 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 17:59:41 +0000 Subject: [PATCH 2/3] Fix serial debugging: use Serial by default, FOCCCI_LOGGING flag for uart mode Agent-Logs-Url: https://github.com/jsphuebner/esp32-web-interface/sessions/f401b500-2efc-4bbe-a23e-47b2e6af5390 Co-authored-by: jsphuebner <3882041+jsphuebner@users.noreply.github.com> --- esp32-web-interface.ino | 22 +++++++++++++++++++--- platformio.ini | 14 ++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/esp32-web-interface.ino b/esp32-web-interface.ino index 91f9889..c668452 100644 --- a/esp32-web-interface.ino +++ b/esp32-web-interface.ino @@ -67,10 +67,21 @@ #include "src/oi_can.h" #include "src/config.h" +#ifdef FOCCCI_LOGGING #define DBG_OUTPUT_PORT Serial2 #define INVERTER_PORT UART_NUM_0 #define INVERTER_RX 3 #define INVERTER_TX 1 +#define DBG_BAUD 921600 +#define INVERTER_BAUD 921600 +#else +#define DBG_OUTPUT_PORT Serial +#define INVERTER_PORT UART_NUM_2 +#define INVERTER_RX 16 +#define INVERTER_TX 17 +#define DBG_BAUD 115200 +#define INVERTER_BAUD 115200 +#endif #define UART_TIMEOUT (100 / portTICK_PERIOD_MS) #define UART_MESSBUF_SIZE 100 #ifndef LED_BUILTIN @@ -747,12 +758,12 @@ void staCheck(){ } void setup(void){ - DBG_OUTPUT_PORT.begin(921600); + DBG_OUTPUT_PORT.begin(DBG_BAUD); //Inverter.setRxBufferSize(50000); //Inverter.begin(115200, SERIAL_8N1, INVERTER_RX, INVERTER_TX); //Need to use low level Espressif IDF API instead of Serial to get high enough data rates uart_config_t uart_config = { - .baud_rate = 921600, + .baud_rate = INVERTER_BAUD, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, @@ -884,8 +895,11 @@ void binaryLoggingStart() { if(createNextSDFile()) { +#ifdef FOCCCI_LOGGING + //In FOCCCI mode data is received directly on INVERTER_PORT; no inverter commands needed fastLoggingActive = true; return; +#endif sendCommand(""); //flush out buffer in case just had power up delay(10); sendCommand("binarylogging 1"); //send start logging command to inverter @@ -914,10 +928,11 @@ void binaryLoggingStart() void binaryLoggingStop() { +#ifdef FOCCCI_LOGGING dataFile.flush(); //make sure up to date dataFile.close(); fastLoggingActive = false; - return; +#else uart_write_bytes(INVERTER_PORT, "\n", 1); delay(1); uart_write_bytes(INVERTER_PORT, "binarylogging 0", strlen("binarylogging 0")); @@ -943,6 +958,7 @@ void binaryLoggingStop() } delay(10); uart_flush(INVERTER_PORT); +#endif } void loop(void){ diff --git a/platformio.ini b/platformio.ini index 8921350..0fddb74 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,3 +66,17 @@ lib_deps = bblanchon/ArduinoJson@^7.1.0 bblanchon/StreamUtils@^1.7.3 SPI + +[env:foccci_logging] +build_flags = + ${env.build_flags} + -D RELEASE + -D FOCCCI_LOGGING + -Wall -Werror +build_type = release +lib_deps = + fbiego/ESP32Time@^2.0.0 + adafruit/RTClib@^2.1.1 + bblanchon/ArduinoJson@^7.1.0 + bblanchon/StreamUtils@^1.7.3 + SPI From c0d829b61cc7db3f858a3d8cd6147117638f640d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 09:09:44 +0000 Subject: [PATCH 3/3] Decouple UI hooks from inverter business logic Agent-Logs-Url: https://github.com/jsphuebner/esp32-web-interface/sessions/12758e19-e048-44e0-a630-6465025a85ea Co-authored-by: jsphuebner <3882041+jsphuebner@users.noreply.github.com> --- data/inverter.js | 67 ++++++++++++++++++++++++------------------------ data/ui.js | 35 +++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/data/inverter.js b/data/inverter.js index 5b1d875..0950a9e 100644 --- a/data/inverter.js +++ b/data/inverter.js @@ -67,6 +67,31 @@ var paramsCache = { var inverter = { firmwareVersion: 0, + uiHooks: { + onCommunicationError: function(_show) {}, + onCanMappingError: function(_message, _status) {}, + onSetParamProgress: function(_key, _value) {}, + onSetParamReply: function(_reply, _key, _value) {}, + onSetParamScroll: function() {}, + onRequestError: function(_requestName) {} + }, + + setUiHooks: function(hooks) + { + inverter.uiHooks = Object.assign(inverter.uiHooks, hooks || {}); + }, + + updateCommunicationState: function(status) + { + if (status != 200) { + paramsCache.failedFetchCount += 1; + } + else { + paramsCache.failedFetchCount = 0; + } + + inverter.uiHooks.onCommunicationError(paramsCache.failedFetchCount >= 2); + }, /** @brief send a command to the inverter */ sendCmd: function(cmd, replyFunc, repeat) @@ -80,18 +105,7 @@ var inverter = { xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState === XMLHttpRequest.DONE) { console.log(req + ": " + xmlhttp.status); - if (xmlhttp.status != 200) { - paramsCache.failedFetchCount += 1; - if ( paramsCache.failedFetchCount >= 2 && typeof ui !== 'undefined'){ - ui.showCommunicationErrorBar(); - } - } - else { - paramsCache.failedFetchCount = 0; - } - if ( paramsCache.failedFetchCount < 2 && typeof ui !== 'undefined') { - ui.hideCommunicationErrorBar(); - } + inverter.updateCommunicationState(xmlhttp.status); } } @@ -135,10 +149,7 @@ var inverter = { xmlhttp.onload = function() { if (xmlhttp.status != 200) { - var messageBox = document.getElementById("message"); - if (messageBox) { - messageBox.innerHTML = this.responseText; - } + inverter.uiHooks.onCanMappingError(this.responseText, xmlhttp.status); return; } @@ -148,18 +159,7 @@ var inverter = { xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState === XMLHttpRequest.DONE) { console.log(req + ": " + xmlhttp.status); - if (xmlhttp.status != 200) { - paramsCache.failedFetchCount += 1; - if ( paramsCache.failedFetchCount >= 2 && typeof ui !== 'undefined'){ - ui.showCommunicationErrorBar(); - } - } - else { - paramsCache.failedFetchCount = 0; - } - if ( paramsCache.failedFetchCount < 2 && typeof ui !== 'undefined') { - ui.hideCommunicationErrorBar(); - } + inverter.updateCommunicationState(xmlhttp.status); } } @@ -252,11 +252,10 @@ var inverter = { if (index < keys.length) { var key = keys[index]; - modal.appendToModal('large', "Setting " + key + " to " + params[key] + "
"); + inverter.uiHooks.onSetParamProgress(key, params[key]); inverter.sendCmd("set " + key + " " + params[key], function(reply) { - modal.appendToModal('large', reply + "
"); - // auto-scroll text in modal as it is added - modal.largeModalScrollToBottom(); + inverter.uiHooks.onSetParamReply(reply, key, params[key]); + inverter.uiHooks.onSetParamScroll(); inverter.setParam(params, index + 1); }); } @@ -275,7 +274,7 @@ var inverter = { } filesRequest.onerror = function() { - alert("error"); + inverter.uiHooks.onRequestError("getFiles"); } filesRequest.open("GET", "/list", true); filesRequest.send(); @@ -292,7 +291,7 @@ var inverter = { } deleteFileRequest.onerror = function() { - alert("error"); + inverter.uiHooks.onRequestError("deleteFile"); } deleteFileRequest.open("DELETE", "/edit?f=" + filename, true); deleteFileRequest.send(); diff --git a/data/ui.js b/data/ui.js index aca1a62..ace0a19 100644 --- a/data/ui.js +++ b/data/ui.js @@ -116,6 +116,39 @@ var ui = { } }, + bindInverterUiHooks: function() + { + inverter.setUiHooks({ + onCommunicationError: function(show) { + if (show) { + ui.showCommunicationErrorBar(); + } + else { + ui.hideCommunicationErrorBar(); + } + }, + onCanMappingError: function(message, _status) { + var messageBox = document.getElementById("message"); + if (messageBox) { + messageBox.innerHTML = message; + } + }, + onSetParamProgress: function(key, value) { + modal.appendToModal('large', "Setting " + key + " to " + value + "
"); + }, + onSetParamReply: function(reply, _key, _value) { + modal.appendToModal('large', reply + "
"); + }, + onSetParamScroll: function() { + // auto-scroll text in modal as it is added + modal.largeModalScrollToBottom(); + }, + onRequestError: function(_requestName) { + alert("error"); + } + }); + }, + /** @brief switch to a different page tab */ openPage: function(pageName, elmnt, color) { @@ -157,6 +190,8 @@ var ui = { /** @brief excutes when page finished loading. Creates tables and chart */ onLoad: function() { + ui.bindInverterUiHooks(); + // Set up listener to execute commands when enter is pressed (dashboard, command box) var commandinput = document.getElementById('commandinput'); commandinput.addEventListener("keyup", function(event)