From 31f2c7bca778ede4d4782b7807749710c1e275a4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 21 Jun 2024 18:44:32 +0200 Subject: [PATCH] Graphs --- include/YaSolR.h | 6 +- include/YaSolRDefines.h | 2 +- include/YaSolRWebsite.h | 10 +++ .../MycilaCircularBuffer.h | 17 ++++- lib/MycilaRouter/MycilaRouterOutput.h | 5 +- platformio.ini | 4 +- src/Website.cpp | 33 ++++++++- src/init/Config.cpp | 8 ++- src/init/Core.cpp | 3 +- src/init/Dashboard.cpp | 2 +- src/init/Debug.cpp | 6 +- src/main.cpp | 3 +- src/tasks/Dashboard.cpp | 7 +- src/tasks/MQTT.cpp | 72 ++++++------------- src/tasks/Router.cpp | 8 ++- 15 files changed, 114 insertions(+), 72 deletions(-) diff --git a/include/YaSolR.h b/include/YaSolR.h index 8cf4cb8..f6fc3d4 100644 --- a/include/YaSolR.h +++ b/include/YaSolR.h @@ -81,6 +81,7 @@ extern Mycila::ZCD zcd; extern Mycila::CircularBuffer gridPowerHistory; extern Mycila::CircularBuffer routedPowerHistory; extern Mycila::CircularBuffer routerTHDiHistory; +extern Mycila::CircularBuffer timeHistory; extern Mycila::TaskManager ioTaskManager; extern Mycila::Task haDiscoveryTask; @@ -104,7 +105,8 @@ extern Mycila::Task profilerTask; extern Mycila::Task resetTask; extern Mycila::Task restartTask; extern Mycila::Task routerDebugTask; -extern Mycila::Task dashboardTask; +extern Mycila::Task dashboardCards; +extern Mycila::Task dashboardCharts; #ifdef APP_MODEL_TRIAL extern Mycila::Task trialTask; #endif @@ -123,7 +125,7 @@ extern Mycila::Task routingTask; extern Mycila::Task bootTask; extern Mycila::Task initConfigTask; extern Mycila::Task initCoreTask; -extern Mycila::Task initDashboardTask; +extern Mycila::Task initdashboardCards; extern Mycila::Task initEventsTask; extern Mycila::Task initLoggingTask; extern Mycila::Task initMqttSubscribersTask; diff --git a/include/YaSolRDefines.h b/include/YaSolRDefines.h index ee969c0..d31d19b 100644 --- a/include/YaSolRDefines.h +++ b/include/YaSolRDefines.h @@ -150,7 +150,7 @@ #define YASOLR_RELAY_TYPE_NO "NO" #define YASOLR_SERIAL_BAUDRATE 115200 #define YASOLR_WEEK_DAYS "sun,mon,tue,wed,thu,fri,sat" -#define YASOLR_GRAPH_POINTS 30 +#define YASOLR_GRAPH_POINTS 60 // pinout diff --git a/include/YaSolRWebsite.h b/include/YaSolRWebsite.h index 032fea0..69732c4 100644 --- a/include/YaSolRWebsite.h +++ b/include/YaSolRWebsite.h @@ -11,6 +11,7 @@ #ifdef APP_MODEL_PRO #define PUSH_BUTTON_CARD_CB () #else + #define LINE_CHART BAR_CHART #define ENERGY_CARD GENERIC_CARD #define PUSH_BUTTON_CARD BUTTON_CARD #define PUSH_BUTTON_CARD_CB (int32_t value) @@ -22,6 +23,7 @@ namespace YaSolR { void initLayout(); void initCards(); void updateCards(); + void updateCharts(); private: // statistics @@ -82,6 +84,14 @@ namespace YaSolR { Card _gridPower = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_044, "W"); Card _routerDS18State = Card(&dashboard, TEMPERATURE_CARD, YASOLR_LBL_045, "°C"); + int _historyX[YASOLR_GRAPH_POINTS] = {0}; + float _gridPowerHistoryY[YASOLR_GRAPH_POINTS] = {0}; + float _routedPowerHistoryY[YASOLR_GRAPH_POINTS] = {0}; + float _routerTHDiHistoryY[YASOLR_GRAPH_POINTS] = {0}; + Chart _gridPowerHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_044 " (Watts)"); + Chart _routedPowerHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_036 " (Watts)"); + Chart _routerTHDiHistory = Chart(&dashboard, BAR_CHART, YASOLR_LBL_039 " (%)"); + #ifdef APP_MODEL_PRO // tabs icons: // https://en.wikipedia.org/wiki/List_of_Unicode_characters#Miscellaneous_Symbols diff --git a/lib/MycilaCircularBuffer/MycilaCircularBuffer.h b/lib/MycilaCircularBuffer/MycilaCircularBuffer.h index 20e48d5..eff0860 100644 --- a/lib/MycilaCircularBuffer/MycilaCircularBuffer.h +++ b/lib/MycilaCircularBuffer/MycilaCircularBuffer.h @@ -5,14 +5,18 @@ #pragma once #include + +#include #include namespace Mycila { - template + template class CircularBuffer { public: CircularBuffer() { reset(); } + T const& operator[](size_t index) const { return _buffer[(_index + index) % N]; } + size_t count() const { return _count; }; T avg() const { return _count == 0 ? 0 : _sum / _count; } T last() const { return _last; } @@ -37,6 +41,17 @@ namespace Mycila { return current; }; + size_t copy(T* dest, size_t size) const { // NOLINT (build/include_what_you_use) + size_t i = 0; + size_t j = _index; + while (i < size && i < _count) { + dest[i++] = _buffer[j++]; + if (j == N) + j = 0; + } + return i; + } + void reset() { _sum = 0; _last = 0; diff --git a/lib/MycilaRouter/MycilaRouterOutput.h b/lib/MycilaRouter/MycilaRouterOutput.h index fc8f8e7..f2191b8 100644 --- a/lib/MycilaRouter/MycilaRouterOutput.h +++ b/lib/MycilaRouter/MycilaRouterOutput.h @@ -85,7 +85,6 @@ namespace Mycila { const char* getStateName() const; const char* getName() const { return _name; } - bool isEnabled() const { return _dimmer->isEnabled(); } void listen(RouterOutputStateCallback callback) { _callback = callback; } #ifdef MYCILA_JSON_SUPPORT @@ -93,10 +92,10 @@ namespace Mycila { RouterOutputMetrics metrics; getMetrics(metrics); - root["enabled"] = isEnabled(); + root["enabled"] = isDimmerEnabled(); root["state"] = getStateName(); root["bypass"] = isBypassOn() ? "on" : "off"; - root["online"] = isDimmerEnabled(); + root["online"] = isDimmerConnected(); _dimmer->toJson(root["dimmer"].to()); _temperatureSensor->toJson(root["ds18"].to()); diff --git a/platformio.ini b/platformio.ini index 5797f63..660e67e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -68,9 +68,9 @@ build_flags = -D DASH_DEFAULT_CARD_SIZE_XL=6 -D DASH_DEFAULT_CARD_SIZE_XS=12 -D DASH_DEFAULT_CARD_SIZE_XXL=3 - -D DASH_JSON_SIZE=2048 + -D DASH_JSON_SIZE=4096 -D ELEGANTOTA_USE_ASYNC_WEBSERVER=1 - ; Fla gto disable mDNS which takes a lot of memory + ; Flag to disable mDNS which takes a lot of memory ; 25.6 KB …espressif__mdns/mdns.c ; -D ESPCONNECT_NO_MDNS ; Flag to disable secure clients diff --git a/src/Website.cpp b/src/Website.cpp index d372419..90f9c9e 100644 --- a/src/Website.cpp +++ b/src/Website.cpp @@ -6,10 +6,21 @@ #define HIDDEN_PWD "********" +#ifdef APP_MODEL_PRO +static const ChartSize chartSize = {.xs = 12, .sm = 12, .md = 12, .lg = 12, .xl = 12, .xxl = 12}; +#endif + void YaSolR::WebsiteClass::initLayout() { logger.debug(TAG, "Initializing layout..."); #ifdef APP_MODEL_PRO + dashboard.setChartAnimations(false); + + // graphs + _gridPowerHistory.setSize(chartSize); + _routedPowerHistory.setSize(chartSize); + _routerTHDiHistory.setSize(chartSize); + // output 1 (status) _output1State.setTab(&_output1Tab); _output1DS18State.setTab(&_output1Tab); @@ -634,6 +645,24 @@ void YaSolR::WebsiteClass::updateCards() { #endif } +void YaSolR::WebsiteClass::updateCharts() { + // graphs + for (size_t i = 0; i < YASOLR_GRAPH_POINTS; i++) + _historyX[i] = static_cast(timeHistory[i] / 1000); + + gridPowerHistory.copy(_gridPowerHistoryY, YASOLR_GRAPH_POINTS); + routedPowerHistory.copy(_routedPowerHistoryY, YASOLR_GRAPH_POINTS); + for (size_t i = 0; i < YASOLR_GRAPH_POINTS; i++) + _routerTHDiHistoryY[i] = routerTHDiHistory[i] * 100; + + _gridPowerHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); + _gridPowerHistory.updateY(_gridPowerHistoryY, YASOLR_GRAPH_POINTS); + _routedPowerHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); + _routedPowerHistory.updateY(_routedPowerHistoryY, YASOLR_GRAPH_POINTS); + _routerTHDiHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); + _routerTHDiHistory.updateY(_routerTHDiHistoryY, YASOLR_GRAPH_POINTS); +} + void YaSolR::WebsiteClass::_sliderConfig(Card& card, const char* key) { card.attachCallback([key, &card](int value) { config.set(key, String(value)); @@ -727,7 +756,7 @@ void YaSolR::WebsiteClass::_outputBypassSwitch(Card& card, Mycila::RouterOutput& } card.update(output.isBypassOn()); dashboard.refreshCard(&card); - dashboardTask.requestEarlyRun(); + dashboardCards.requestEarlyRun(); }); } @@ -738,7 +767,7 @@ void YaSolR::WebsiteClass::_outputDimmerSlider(Card& card, Mycila::RouterOutput& } card.update(output.getDimmerDuty()); dashboard.refreshCard(&card); - dashboardTask.requestEarlyRun(); + dashboardCards.requestEarlyRun(); }); } diff --git a/src/init/Config.cpp b/src/init/Config.cpp index 5dc24f1..87174a2 100644 --- a/src/init/Config.cpp +++ b/src/init/Config.cpp @@ -10,8 +10,10 @@ Mycila::Task initConfigTask("Init Config", [](void* params) { // Tasks configuration carouselTask.setEnabledWhen([]() { return display.isEnabled(); }); carouselTask.setIntervalSupplier([]() { return config.get(KEY_DISPLAY_SPEED).toInt() * Mycila::TaskDuration::SECONDS; }); - dashboardTask.setEnabledWhen([]() { return ESPConnect.isConnected() && dashboard.hasClient() && !dashboard.isAsyncAccessInProgress(); }); - dashboardTask.setInterval(751 * Mycila::TaskDuration::MILLISECONDS); + dashboardCards.setEnabledWhen([]() { return ESPConnect.isConnected() && dashboard.hasClient() && !dashboard.isAsyncAccessInProgress() && !routingTask.isRunning(); }); + dashboardCards.setInterval(751 * Mycila::TaskDuration::MILLISECONDS); + dashboardCharts.setEnabledWhen([]() { return ESPConnect.isConnected() && dashboard.hasClient() && !dashboard.isAsyncAccessInProgress() && !routingTask.isRunning(); }); + dashboardCharts.setInterval(2 * Mycila::TaskDuration::SECONDS); displayTask.setEnabledWhen([]() { return display.isEnabled(); }); displayTask.setInterval(293 * Mycila::TaskDuration::MILLISECONDS); ds18Task.setEnabledWhen([]() { return ds18Sys.isEnabled() || ds18O1.isEnabled() || ds18O2.isEnabled(); }); @@ -28,7 +30,7 @@ Mycila::Task initConfigTask("Init Config", [](void* params) { relayTask.setInterval(7 * Mycila::TaskDuration::SECONDS); routerDebugTask.setInterval(5 * Mycila::TaskDuration::SECONDS); routerTask.setInterval(537 * Mycila::TaskDuration::MILLISECONDS); - routingTask.setEnabledWhen([]() { return output1.isAutoDimmerEnabled() || output2.isAutoDimmerEnabled(); }); + routingTask.setEnabledWhen([]() { return output1.isDimmerEnabled() || output2.isDimmerEnabled(); }); #ifdef APP_MODEL_TRIAL trialTask.setInterval(30 * Mycila::TaskDuration::SECONDS); #endif diff --git a/src/init/Core.cpp b/src/init/Core.cpp index 1faf4a4..41d59f6 100644 --- a/src/init/Core.cpp +++ b/src/init/Core.cpp @@ -21,7 +21,8 @@ Mycila::Task initCoreTask("Init Core", [](void* params) { // coreTaskManager carouselTask.setManager(coreTaskManager); - dashboardTask.setManager(coreTaskManager); + dashboardCards.setManager(coreTaskManager); + dashboardCharts.setManager(coreTaskManager); displayTask.setManager(coreTaskManager); ds18Task.setManager(coreTaskManager); lightsTask.setManager(coreTaskManager); diff --git a/src/init/Dashboard.cpp b/src/init/Dashboard.cpp index 3ebc2a1..46dfc2c 100644 --- a/src/init/Dashboard.cpp +++ b/src/init/Dashboard.cpp @@ -5,7 +5,7 @@ #include #include -Mycila::Task initDashboardTask("Init Dashboard", [](void* params) { +Mycila::Task initdashboardCards("Init Dashboard", [](void* params) { logger.info(TAG, "Initializing dashboard..."); YaSolR::Website.initLayout(); YaSolR::Website.initCards(); diff --git a/src/init/Debug.cpp b/src/init/Debug.cpp index 8577374..3909f8f 100644 --- a/src/init/Debug.cpp +++ b/src/init/Debug.cpp @@ -23,7 +23,8 @@ Mycila::Task initLoggingTask("Init Logging", [](void* params) { if (debug) { // Enable profiling for some FOREVER tasks - dashboardTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); + dashboardCards.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); + dashboardCharts.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); displayTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); jsyTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); mqttPublishTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); @@ -32,7 +33,8 @@ Mycila::Task initLoggingTask("Init Logging", [](void* params) { routerTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); routingTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); } else { - dashboardTask.disableProfiling(); + dashboardCards.disableProfiling(); + dashboardCharts.disableProfiling(); displayTask.disableProfiling(); jsyTask.disableProfiling(); mqttPublishTask.disableProfiling(); diff --git a/src/main.cpp b/src/main.cpp index 25a1329..8e714b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ Mycila::RouterRelay routerRelay2(relay2); Mycila::CircularBuffer gridPowerHistory; Mycila::CircularBuffer routedPowerHistory; Mycila::CircularBuffer routerTHDiHistory; +Mycila::CircularBuffer timeHistory; AsyncWebServer webServer(80); ESPDash dashboard = ESPDash(&webServer, "/dashboard", false); @@ -56,7 +57,7 @@ void setup() { initWebTask.forceRun(); initRestApiTask.forceRun(); initMqttSubscribersTask.forceRun(); - initDashboardTask.forceRun(); + initdashboardCards.forceRun(); assert( coreTaskManager.asyncStart(1024 * 4, 1, 1, 100, true)); // NOLINT assert( ioTaskManager.asyncStart(1024 * 5, 1, 1, 100, false)); // NOLINT diff --git a/src/tasks/Dashboard.cpp b/src/tasks/Dashboard.cpp index e43a97e..c0ad202 100644 --- a/src/tasks/Dashboard.cpp +++ b/src/tasks/Dashboard.cpp @@ -5,7 +5,12 @@ #include #include -Mycila::Task dashboardTask("Dashboard", [](void* params) { +Mycila::Task dashboardCards("Dashboard Cards", [](void* params) { YaSolR::Website.updateCards(); dashboard.sendUpdates(); }); + +Mycila::Task dashboardCharts("Dashboard Charts", [](void* params) { + YaSolR::Website.updateCharts(); + dashboard.sendUpdates(); +}); diff --git a/src/tasks/MQTT.cpp b/src/tasks/MQTT.cpp index 3f87a46..419b5cf 100644 --- a/src/tasks/MQTT.cpp +++ b/src/tasks/MQTT.cpp @@ -35,35 +35,9 @@ Mycila::Task mqttPublishStaticTask("MQTT Static", Mycila::TaskType::ONCE, [](voi mqtt.publish(baseTopic + "/system/network/wifi/mac_address", ESPConnect.getMACAddress(ESPConnectMode::STA), true); yield(); - if (!output1.isEnabled()) { - mqtt.publish(baseTopic + "/router/output1/bypass", YASOLR_STATE(output1.isBypassOn()), true); - mqtt.publish(baseTopic + "/router/output1/state", output1.getStateName()); - mqtt.publish(baseTopic + "/router/output1/temperature", String(ds18O1.getValidTemperature(), 1), true); - mqtt.publish(baseTopic + "/router/output1/dimmer/duty", String(dimmerO1.getPowerDuty()), true); - mqtt.publish(baseTopic + "/router/output1/dimmer/duty_cycle", String(dimmerO1.getPowerDutyCycle() * 100), true); - mqtt.publish(baseTopic + "/router/output1/dimmer/state", YASOLR_STATE(dimmerO1.isOn()), true); - mqtt.publish(baseTopic + "/router/output1/relay/state", YASOLR_STATE(bypassRelayO1.isOn()), true); - mqtt.publish(baseTopic + "/router/output1/relay/switch_count", String(bypassRelayO1.getSwitchCount()), true); - yield(); - } - - if (!output2.isEnabled()) { - mqtt.publish(baseTopic + "/router/output2/bypass", YASOLR_STATE(output2.isBypassOn()), true); - mqtt.publish(baseTopic + "/router/output2/state", output2.getStateName()); - mqtt.publish(baseTopic + "/router/output2/temperature", String(ds18O2.getValidTemperature(), 1), true); - mqtt.publish(baseTopic + "/router/output2/dimmer/duty", String(dimmerO2.getPowerDuty()), true); - mqtt.publish(baseTopic + "/router/output2/dimmer/duty_cycle", String(dimmerO2.getPowerDutyCycle() * 100), true); - mqtt.publish(baseTopic + "/router/output2/dimmer/state", YASOLR_STATE(dimmerO2.isOn()), true); - mqtt.publish(baseTopic + "/router/output2/relay/state", YASOLR_STATE(bypassRelayO2.isOn()), true); - mqtt.publish(baseTopic + "/router/output2/relay/switch_count", String(bypassRelayO2.getSwitchCount()), true); - yield(); - } - - if (!relay1.isEnabled()) { - mqtt.publish(baseTopic + "/router/relay1/state", YASOLR_STATE(relay1.isOn()), true); - mqtt.publish(baseTopic + "/router/relay1/switch_count", String(relay1.getSwitchCount()), true); - yield(); - } + mqtt.publish(baseTopic + "/router/relay1/state", YASOLR_STATE(relay1.isOn()), true); + mqtt.publish(baseTopic + "/router/relay1/switch_count", String(relay1.getSwitchCount()), true); + yield(); if (!relay2.isEnabled()) { mqtt.publish(baseTopic + "/router/relay2/state", YASOLR_STATE(relay2.isOn()), true); @@ -145,29 +119,25 @@ Mycila::Task mqttPublishTask("MQTT", [](void* params) { mqtt.publish(baseTopic + "/router/virtual_grid_power", String(gridMetrics.power - routerMetrics.power, 3)); yield(); - if (output1.isEnabled()) { - mqtt.publish(baseTopic + "/router/output1/bypass", YASOLR_STATE(output1.isBypassOn())); - mqtt.publish(baseTopic + "/router/output1/state", output1.getStateName()); - mqtt.publish(baseTopic + "/router/output1/temperature", String(ds18O1.getValidTemperature(), 1)); - mqtt.publish(baseTopic + "/router/output1/dimmer/duty", String(dimmerO1.getPowerDuty())); - mqtt.publish(baseTopic + "/router/output1/dimmer/duty_cycle", String(dimmerO1.getPowerDutyCycle() * 100)); - mqtt.publish(baseTopic + "/router/output1/dimmer/state", YASOLR_STATE(dimmerO1.isOn())); - mqtt.publish(baseTopic + "/router/output1/relay/state", YASOLR_STATE(bypassRelayO1.isOn())); - mqtt.publish(baseTopic + "/router/output1/relay/switch_count", String(bypassRelayO1.getSwitchCount())); - yield(); - } + mqtt.publish(baseTopic + "/router/output1/bypass", YASOLR_STATE(output1.isBypassOn())); + mqtt.publish(baseTopic + "/router/output1/state", output1.getStateName()); + mqtt.publish(baseTopic + "/router/output1/temperature", String(ds18O1.getValidTemperature(), 1)); + mqtt.publish(baseTopic + "/router/output1/dimmer/duty", String(dimmerO1.getPowerDuty())); + mqtt.publish(baseTopic + "/router/output1/dimmer/duty_cycle", String(dimmerO1.getPowerDutyCycle() * 100)); + mqtt.publish(baseTopic + "/router/output1/dimmer/state", YASOLR_STATE(dimmerO1.isOn())); + mqtt.publish(baseTopic + "/router/output1/relay/state", YASOLR_STATE(bypassRelayO1.isOn())); + mqtt.publish(baseTopic + "/router/output1/relay/switch_count", String(bypassRelayO1.getSwitchCount())); + yield(); - if (output2.isEnabled()) { - mqtt.publish(baseTopic + "/router/output2/bypass", YASOLR_STATE(output2.isBypassOn())); - mqtt.publish(baseTopic + "/router/output2/state", output2.getStateName()); - mqtt.publish(baseTopic + "/router/output2/temperature", String(ds18O2.getValidTemperature(), 1)); - mqtt.publish(baseTopic + "/router/output2/dimmer/duty", String(dimmerO2.getPowerDuty())); - mqtt.publish(baseTopic + "/router/output2/dimmer/duty_cycle", String(dimmerO2.getPowerDutyCycle() * 100)); - mqtt.publish(baseTopic + "/router/output2/dimmer/state", YASOLR_STATE(dimmerO2.isOn())); - mqtt.publish(baseTopic + "/router/output2/relay/state", YASOLR_STATE(bypassRelayO2.isOn())); - mqtt.publish(baseTopic + "/router/output2/relay/switch_count", String(bypassRelayO2.getSwitchCount())); - yield(); - } + mqtt.publish(baseTopic + "/router/output2/bypass", YASOLR_STATE(output2.isBypassOn())); + mqtt.publish(baseTopic + "/router/output2/state", output2.getStateName()); + mqtt.publish(baseTopic + "/router/output2/temperature", String(ds18O2.getValidTemperature(), 1)); + mqtt.publish(baseTopic + "/router/output2/dimmer/duty", String(dimmerO2.getPowerDuty())); + mqtt.publish(baseTopic + "/router/output2/dimmer/duty_cycle", String(dimmerO2.getPowerDutyCycle() * 100)); + mqtt.publish(baseTopic + "/router/output2/dimmer/state", YASOLR_STATE(dimmerO2.isOn())); + mqtt.publish(baseTopic + "/router/output2/relay/state", YASOLR_STATE(bypassRelayO2.isOn())); + mqtt.publish(baseTopic + "/router/output2/relay/switch_count", String(bypassRelayO2.getSwitchCount())); + yield(); if (relay1.isEnabled()) { mqtt.publish(baseTopic + "/router/relay1/state", YASOLR_STATE(relay1.isOn())); diff --git a/src/tasks/Router.cpp b/src/tasks/Router.cpp index 82d7171..2fd83f5 100644 --- a/src/tasks/Router.cpp +++ b/src/tasks/Router.cpp @@ -34,12 +34,18 @@ Mycila::Task relayTask("Relay", [](void* params) { }); Mycila::Task routingTask("Routing", Mycila::TaskType::ONCE, [](void* params) { + // read metrics Mycila::GridMetrics gridMetrics; grid.getMetrics(gridMetrics); - Mycila::RouterMetrics routerMetrics; router.getMetrics(routerMetrics); + // update charts + timeHistory.add(millis()); + gridPowerHistory.add(gridMetrics.power); + routedPowerHistory.add(routerMetrics.power); + routerTHDiHistory.add(routerMetrics.thdi); + float virtualGridPower = gridMetrics.power - routerMetrics.power; // if (virtualGridPower < 0) {