diff --git a/src/core/configuration.h b/src/core/configuration.h index be44ff4..f1c7355 100644 --- a/src/core/configuration.h +++ b/src/core/configuration.h @@ -1,3 +1,3 @@ // Contains configuration constants: -#define FIRMWARE_VERSION "1.0.3" +#define FIRMWARE_VERSION "1.0.6" diff --git a/src/core/diagnostics_state.cpp b/src/core/diagnostics_state.cpp new file mode 100644 index 0000000..4f4221d --- /dev/null +++ b/src/core/diagnostics_state.cpp @@ -0,0 +1,41 @@ +#include "diagnostics_state.h" + + +void DiagnosticsState::update() +{ + current.timestamp = millis(); + current.freeHeap = + ESP.getFreeHeap(); + + current.minimumFreeHeap = + ESP.getMinFreeHeap(); + + current.cpuFrequency = + ESP.getCpuFreqMHz(); + + history[historyIndex] = current; + + historyIndex++; + if(historyIndex >= DIAGNOSTIC_HISTORY_SIZE) + { + historyIndex = 0; + } +} + + + +DiagnosticSample DiagnosticsState::getCurrent() +{ + return current; +} + + + +DiagnosticSample DiagnosticsState::getHistory(uint8_t index) +{ + if(index >= DIAGNOSTIC_HISTORY_SIZE) + { + return current; + } + return history[index]; +} diff --git a/src/core/diagnostics_state.h b/src/core/diagnostics_state.h new file mode 100644 index 0000000..c5873d6 --- /dev/null +++ b/src/core/diagnostics_state.h @@ -0,0 +1,34 @@ +#pragma once + +#include + + +#define DIAGNOSTIC_HISTORY_SIZE 60 + + +struct DiagnosticSample +{ + uint32_t timestamp; + uint32_t freeHeap; + uint32_t minimumFreeHeap; + uint32_t cpuFrequency; +}; + + +class DiagnosticsState +{ +public: + + void update(); + + + DiagnosticSample getCurrent(); + DiagnosticSample getHistory(uint8_t index); + + +private: + + DiagnosticSample current; + DiagnosticSample history[DIAGNOSTIC_HISTORY_SIZE]; + uint8_t historyIndex = 0; +}; diff --git a/src/main.cpp b/src/main.cpp index ba5f59e..111dee2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include #include "core/dashboard_state.h" +#include "core/diagnostics_state.h" #include "services/service_manager.h" #include "services/wifi_service.h" @@ -11,22 +12,24 @@ #include "services/web_service.h" #include "tasks/system_task.h" +#include "tasks/diagnostics_task.h" DashboardState dashboardState; +DiagnosticsState diagnosticsState; - +// Simple service scheduler nice for grouping tasks ServiceManager services; - WiFiService wifi; OTAService ota; -WebService web(dashboardState); +WebService web(dashboardState, diagnosticsState); +// Actual FreeRTOS tasks that are scheduled SystemTask systemTask(services); - +DiagnosticsTask diagnosticsTask(diagnosticsState); void setup() { @@ -38,6 +41,7 @@ void setup() systemTask.start(); + diagnosticsTask.start(); } diff --git a/src/services/web_service.cpp b/src/services/web_service.cpp index dc641ec..d10090d 100644 --- a/src/services/web_service.cpp +++ b/src/services/web_service.cpp @@ -1,9 +1,10 @@ #include "web_service.h" -WebService::WebService(DashboardState& state) +WebService::WebService(DashboardState& state, DiagnosticsState& diag_state) : Service("Web", 10), dashboardState(state), + diagnosticsState(diag_state), server(80), webSocket(81) { @@ -81,8 +82,11 @@ function connectWebSocket() { socket.onmessage = function(event) { const data = JSON.parse(event.data); - document.getElementById("uptime").innerHTML = data.uptime; - document.getElementById("firmware_version").innerHTML = data.version; + document.getElementById("uptime").innerHTML = data.system.uptime; + document.getElementById("firmware_version").innerHTML = data.system.version; + document.getElementById("free_heap").innerHTML = data.diagnostics.free_heap; + document.getElementById("minimum_free_heap").innerHTML = data.diagnostics.minimum_free_heap; + document.getElementById("cpu_frequency").innerHTML = data.diagnostics.cpu_frequency; }; socket.onclose = function() { @@ -103,17 +107,32 @@ window.onload = connectWebSocket;

Device uptime:

Loading...
+ +
+

Hub Diagnostics:

+

Free heap:

+
Loading...
+

Minimum free heap:

+
Loading...
+

CPU Frequency:

+
Loading...
+
+ +
Firmware Version:
Loading...
- )rawliteral"; void WebService::broadcastState() { + DiagnosticSample diagnostics = diagnosticsState.getCurrent(); String json = "{"; + // Opening system tag: + json += "\"system\":{"; + json += "\"uptime\":\""; json += dashboardState.uptime; json += "\","; @@ -122,8 +141,31 @@ void WebService::broadcastState() json += dashboardState.firmwareVersion; json += "\""; + json += "},"; // Close system tag + + // Opening diagnostic tag: + json += "\"diagnostics\":{"; + + json += "\"free_heap\":\""; + json += diagnostics.freeHeap; + json += "\","; + + json += "\"minimum_free_heap\":\""; + json += diagnostics.minimumFreeHeap; + json += "\","; + + json += "\"cpu_frequency\":\""; + json += diagnostics.cpuFrequency; + json += "\""; + + json += "}"; // Clost diagnostic tag + + + // Final close bracket json += "}"; + + Serial.println(json); webSocket.broadcastTXT(json); } diff --git a/src/services/web_service.h b/src/services/web_service.h index 69878df..841751e 100644 --- a/src/services/web_service.h +++ b/src/services/web_service.h @@ -6,12 +6,13 @@ #include "service.h" #include "../core/dashboard_state.h" +#include "../core/diagnostics_state.h" class WebService : public Service { public: - WebService(DashboardState& state); + WebService(DashboardState& state, DiagnosticsState& diag_state); void begin() override; void update() override; @@ -20,7 +21,9 @@ private: WebServer server; WebSocketsServer webSocket; + DashboardState dashboardState; + DiagnosticsState diagnosticsState; void handleWebSocketMessage(uint8_t clientNum, uint8_t *payload, size_t length); void broadcastState(); diff --git a/src/tasks/diagnostics_task.cpp b/src/tasks/diagnostics_task.cpp new file mode 100644 index 0000000..ae2d0e9 --- /dev/null +++ b/src/tasks/diagnostics_task.cpp @@ -0,0 +1,54 @@ +#include "diagnostics_task.h" + +DiagnosticsTask::DiagnosticsTask( + DiagnosticsState& state +) +: +diagnostics(state) +{ + +} + + +void DiagnosticsTask::start() +{ + + xTaskCreatePinnedToCore( + taskEntry, + "DiagnosticsTask", + 4096, + this, + 1, + &taskHandle, + 1 + ); +} + + +void DiagnosticsTask::taskEntry(void* parameter) +{ + + DiagnosticsTask* task = + static_cast(parameter); + + + task->run(); +} + + +void DiagnosticsTask::run() +{ + + TickType_t lastWake = + xTaskGetTickCount(); + + while(true) + { + diagnostics.update(); + + vTaskDelayUntil( + &lastWake, + pdMS_TO_TICKS(1000) + ); + } +} diff --git a/src/tasks/diagnostics_task.h b/src/tasks/diagnostics_task.h new file mode 100644 index 0000000..5b89bff --- /dev/null +++ b/src/tasks/diagnostics_task.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "../core/diagnostics_state.h" + + +class DiagnosticsTask +{ + +public: + + DiagnosticsTask( + DiagnosticsState& state + ); + + void start(); + +private: + + static void taskEntry(void* parameter); + void run(); + + DiagnosticsState& diagnostics; + + TaskHandle_t taskHandle = nullptr; + +};